mirror of
https://github.com/luxfi/evm.git
synced 2026-09-24 00:27:44 +00:00
167 lines
5.5 KiB
Go
167 lines
5.5 KiB
Go
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/luxfi/evm/plugin/evm/message"
|
|
"github.com/luxfi/evm/sync/handlers/stats/statstest"
|
|
"github.com/luxfi/geth/common"
|
|
"github.com/luxfi/geth/core/rawdb"
|
|
"github.com/luxfi/ids"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestCodeRequestHandler(t *testing.T) {
|
|
tests := map[string]struct {
|
|
codeBytes [][]byte
|
|
codeHashes []common.Hash
|
|
expectedBytes [][]byte
|
|
assertStats func(t *testing.T, stats *statstest.TestHandlerStats)
|
|
}{
|
|
"zero hashes": {
|
|
codeBytes: nil,
|
|
codeHashes: []common.Hash{},
|
|
expectedBytes: [][]byte{},
|
|
assertStats: func(t *testing.T, stats *statstest.TestHandlerStats) {
|
|
assert.Equal(t, uint32(1), stats.CodeRequestCount)
|
|
assert.Equal(t, uint32(0), stats.DuplicateHashesRequested)
|
|
assert.Equal(t, uint32(0), stats.TooManyHashesRequested)
|
|
assert.Equal(t, uint32(0), stats.MissingCodeHashCount)
|
|
assert.Equal(t, uint32(0), stats.CodeBytesReturnedSum)
|
|
},
|
|
},
|
|
"single code": {
|
|
codeBytes: [][]byte{{1, 2, 3}},
|
|
codeHashes: []common.Hash{{1}},
|
|
expectedBytes: [][]byte{{1, 2, 3}},
|
|
assertStats: func(t *testing.T, stats *statstest.TestHandlerStats) {
|
|
assert.Equal(t, uint32(1), stats.CodeRequestCount)
|
|
assert.Equal(t, uint32(0), stats.DuplicateHashesRequested)
|
|
assert.Equal(t, uint32(0), stats.TooManyHashesRequested)
|
|
assert.Equal(t, uint32(0), stats.MissingCodeHashCount)
|
|
assert.Equal(t, uint32(3), stats.CodeBytesReturnedSum)
|
|
},
|
|
},
|
|
"multiple hashes": {
|
|
codeBytes: [][]byte{{1, 2, 3}, {1}, {255, 0, 15, 16}},
|
|
codeHashes: []common.Hash{{1}, {2}, {3}},
|
|
expectedBytes: [][]byte{{1, 2, 3}, {1}, {255, 0, 15, 16}},
|
|
assertStats: func(t *testing.T, stats *statstest.TestHandlerStats) {
|
|
assert.Equal(t, uint32(1), stats.CodeRequestCount)
|
|
assert.Equal(t, uint32(0), stats.DuplicateHashesRequested)
|
|
assert.Equal(t, uint32(0), stats.TooManyHashesRequested)
|
|
assert.Equal(t, uint32(0), stats.MissingCodeHashCount)
|
|
assert.Equal(t, uint32(8), stats.CodeBytesReturnedSum)
|
|
},
|
|
},
|
|
"not found code": {
|
|
codeBytes: [][]byte{{1, 2, 3}, nil, {255, 0, 15, 16}},
|
|
codeHashes: []common.Hash{{1}, {2}, {3}},
|
|
expectedBytes: nil,
|
|
assertStats: func(t *testing.T, stats *statstest.TestHandlerStats) {
|
|
assert.Equal(t, uint32(1), stats.CodeRequestCount)
|
|
assert.Equal(t, uint32(0), stats.DuplicateHashesRequested)
|
|
assert.Equal(t, uint32(0), stats.TooManyHashesRequested)
|
|
assert.Equal(t, uint32(1), stats.MissingCodeHashCount)
|
|
assert.Equal(t, uint32(0), stats.CodeBytesReturnedSum)
|
|
},
|
|
},
|
|
"too many hashes": {
|
|
codeBytes: make([][]byte, message.MaxCodeHashesPerRequest+1),
|
|
codeHashes: make([]common.Hash, message.MaxCodeHashesPerRequest+1),
|
|
expectedBytes: nil,
|
|
assertStats: func(t *testing.T, stats *statstest.TestHandlerStats) {
|
|
assert.Equal(t, uint32(1), stats.CodeRequestCount)
|
|
assert.Equal(t, uint32(0), stats.DuplicateHashesRequested)
|
|
assert.Equal(t, uint32(1), stats.TooManyHashesRequested)
|
|
assert.Equal(t, uint32(0), stats.MissingCodeHashCount)
|
|
assert.Equal(t, uint32(0), stats.CodeBytesReturnedSum)
|
|
},
|
|
},
|
|
"duplicate hashes": {
|
|
codeBytes: [][]byte{{1, 2, 3}, {1}, {255, 0, 15, 16}},
|
|
codeHashes: []common.Hash{{1}, {2}, {1}},
|
|
expectedBytes: nil,
|
|
assertStats: func(t *testing.T, stats *statstest.TestHandlerStats) {
|
|
assert.Equal(t, uint32(1), stats.CodeRequestCount)
|
|
assert.Equal(t, uint32(1), stats.DuplicateHashesRequested)
|
|
assert.Equal(t, uint32(0), stats.TooManyHashesRequested)
|
|
assert.Equal(t, uint32(0), stats.MissingCodeHashCount)
|
|
assert.Equal(t, uint32(0), stats.CodeBytesReturnedSum)
|
|
},
|
|
},
|
|
}
|
|
|
|
for name, test := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
db := rawdb.NewMemoryDatabase()
|
|
|
|
assert.Equal(t, len(test.codeBytes), len(test.codeHashes))
|
|
codeMap := make(map[common.Hash][]byte)
|
|
for i, codeBytes := range test.codeBytes {
|
|
if codeBytes != nil {
|
|
codeMap[test.codeHashes[i]] = codeBytes
|
|
rawdb.WriteCode(db, test.codeHashes[i], codeBytes)
|
|
}
|
|
}
|
|
|
|
codeRequest := message.CodeRequest{
|
|
Hashes: test.codeHashes,
|
|
}
|
|
|
|
testStats := &statstest.TestHandlerStats{}
|
|
codeRequestHandler := NewCodeRequestHandler(db, message.Codec, testStats)
|
|
responseBytes, err := codeRequestHandler.OnCodeRequest(context.Background(), ids.GenerateTestNodeID(), 1, codeRequest)
|
|
assert.NoError(t, err)
|
|
|
|
if test.expectedBytes == nil {
|
|
assert.Nil(t, responseBytes)
|
|
} else {
|
|
var response message.CodeResponse
|
|
_, err = message.Codec.Unmarshal(responseBytes, &response)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, test.expectedBytes, response.Data)
|
|
}
|
|
|
|
test.assertStats(t, testStats)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsUnique(t *testing.T) {
|
|
tests := map[string]struct {
|
|
hashes []common.Hash
|
|
expectUnique bool
|
|
}{
|
|
"unique": {
|
|
hashes: []common.Hash{{1}, {2}, {3}},
|
|
expectUnique: true,
|
|
},
|
|
"not unique": {
|
|
hashes: []common.Hash{{1}, {2}, {1}},
|
|
expectUnique: false,
|
|
},
|
|
"empty": {
|
|
hashes: []common.Hash{},
|
|
expectUnique: true,
|
|
},
|
|
"single": {
|
|
hashes: []common.Hash{{1}},
|
|
expectUnique: true,
|
|
},
|
|
"all same": {
|
|
hashes: []common.Hash{{1}, {1}, {1}},
|
|
expectUnique: false,
|
|
},
|
|
}
|
|
|
|
for name, test := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert.Equal(t, test.expectUnique, isUnique(test.hashes))
|
|
})
|
|
}
|
|
} |