From 29607e93b399d15b46d457d625fb00820cb6bd24 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 17 May 2021 18:27:17 +0100 Subject: [PATCH 1/6] Skip FIO analysis on data continuation --- codetrie/codetrie.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/codetrie/codetrie.go b/codetrie/codetrie.go index 2999890c323..5216b41ea18 100644 --- a/codetrie/codetrie.go +++ b/codetrie/codetrie.go @@ -3,6 +3,7 @@ package codetrie import ( "encoding/binary" "errors" + "fmt" "math" sszlib "github.com/ferranbt/fastssz" @@ -32,13 +33,17 @@ type CodeTrie interface { GetTree() (*sszlib.Node, error) } +const ( + FIOUnset = 0xff +) + type Chunk struct { fio uint8 // firstInstructionOffset code []byte } func NewChunk() *Chunk { - return &Chunk{fio: 0, code: nil} + return &Chunk{fio: FIOUnset, code: nil} } func (c *Chunk) Serialize() []byte { @@ -203,11 +208,21 @@ func Chunkify(code []byte, chunkSize uint) []*Chunk { if i == numChunks-1 { endIdx = uint(len(code)) } - chunks[i] = &Chunk{fio: 0, code: code[startIdx:endIdx]} + chunks[i] = &Chunk{fio: FIOUnset, code: code[startIdx:endIdx]} } setFIO(chunks) + // Sanity check that all chunks were processed + for i, _ := range chunks { + if i == len(chunks)-1 { + break + } + if chunks[i].fio == FIOUnset { + panic(fmt.Sprintf("Chunk %d has unprocessed FIO", i)) + } + } + return chunks } @@ -223,6 +238,11 @@ func setFIO(chunks []*Chunk) { break } + // This chunk was already processed (it is a data chunk continuation) + if chunks[i].fio != FIOUnset { + continue + } + for j, op := range chunk.code { opcode := OpCode(op) // Push is the only opcode with immediate From a030facc28ca85a52edb44461b5e6744d93d86f2 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 17 May 2021 19:20:27 +0100 Subject: [PATCH 2/6] Add failing case of block 6028221 --- codetrie/codetrie_test.go | 111 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/codetrie/codetrie_test.go b/codetrie/codetrie_test.go index 3a165f44119..18403bad548 100644 --- a/codetrie/codetrie_test.go +++ b/codetrie/codetrie_test.go @@ -107,6 +107,117 @@ func TestMerkleize(t *testing.T) { }, CodeRoot: "792f6e1cff9922e35e32b8db08807e9f8af007267565d6cadb4edec84c1fc300", }, + { + // Test of https://etherscan.io/tx/0x8217ac6d4c0578a3d954c6800ab59060a3c376c81ee17c3726bd4bcc7167e12e + Input: "6060604052341561000f57600080fd5b60405160208061031d8339810160405280805160008054600160a060020a03909216600160a060020a031990921691909117905550506102c9806100546000396000f3006060604052600436106100325763ffffffff60e060020a60003504166362c067678114610034578063c0ee0b8a14610070575b005b341561003f57600080fd5b61005c600160a060020a03600435811690602435166044356100d5565b604051901515815260200160405180910390f35b341561007b57600080fd5b61003260048035600160a060020a03169060248035919060649060443590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061029895505050505050565b60008054819081908190600160a060020a0316637bd163f33360405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561012c57600080fd5b5af1151561013957600080fd5b505050604051805190501561028e5760009250600160a060020a038716156102455786915081600160a060020a03166370a082313060405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b15156101ac57600080fd5b5af115156101b957600080fd5b505050604051805190508511156101d3576000935061028e565b81600160a060020a031663a9059cbb878760405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b151561022757600080fd5b5af1151561023457600080fd5b50505060405180519050925061028a565b5083600160a060020a03301631811115610262576000935061028e565b600160a060020a03861681156108fc0282604051600060405180830381858888f19650505050505b8293505b5050509392505050565b5050505600a165627a7a7230582046a5a4b3a9b14ddd4256f8e7eb73e2c2bbd4c592872abc481eac2c78cc12de470029000000000000000000000000c3dd239cdd4ecf76bd7e67f50129c7dd8be5dab6", + Chunks: []TChunk{ + { + fio: 0, + code: "6060604052341561000f57600080fd5b60405160208061031d83398101604052", + }, + { + fio: 0, + code: "80805160008054600160a060020a03909216600160a060020a03199092169190", + }, + { + fio: 0, + code: "9117905550506102c9806100546000396000f300606060405260043610610032", + }, + { + fio: 0, + code: "5763ffffffff60e060020a60003504166362c067678114610034578063c0ee0b", + }, + { + fio: 1, + code: "8a14610070575b005b341561003f57600080fd5b61005c600160a060020a0360", + }, + { + fio: 1, + code: "0435811690602435166044356100d5565b604051901515815260200160405180", + }, + { + fio: 0, + code: "910390f35b341561007b57600080fd5b61003260048035600160a060020a0316", + }, + { + fio: 6, + code: "9060248035919060649060443590810190830135806020601f82018190048102", + }, + { + fio: 0, + code: "0160405190810160405281815292919060208401838380828437509496506102", + }, + { + fio: 1, + code: "9895505050505050565b60008054819081908190600160a060020a0316637bd1", + }, + { + fio: 27, + code: "63f33360405160e060020a63ffffffff8416028152600160a060020a03909116", + }, + { + fio: 0, + code: "6004820152602401602060405180830381600087803b151561012c57600080fd", + }, + { + fio: 0, + code: "5b5af1151561013957600080fd5b505050604051805190501561028e57600092", + }, + { + fio: 0, + code: "50600160a060020a038716156102455786915081600160a060020a03166370a0", + }, + { + fio: 16, + code: "82313060405160e060020a63ffffffff8416028152600160a060020a03909116", + }, + { + fio: 0, + code: "6004820152602401602060405180830381600087803b15156101ac57600080fd", + }, + { + fio: 0, + code: "5b5af115156101b957600080fd5b505050604051805190508511156101d35760", + }, + { + fio: 1, + code: "00935061028e565b81600160a060020a031663a9059cbb878760405160e06002", + }, + { + fio: 0, + code: "0a63ffffffff8516028152600160a060020a0390921660048301526024820152", + }, + { + fio: 0, + code: "604401602060405180830381600087803b151561022757600080fd5b5af11515", + }, + { + fio: 0, + code: "61023457600080fd5b50505060405180519050925061028a565b5083600160a0", + }, + { + fio: 0, + code: "60020a03301631811115610262576000935061028e565b600160a060020a0386", + }, + { + fio: 0, + code: "1681156108fc0282604051600060405180830381858888f19650505050505b82", + }, + { + fio: 0, + code: "93505b5050509392505050565b5050505600a165627a7a7230582046a5a4b3a9", + }, + { + fio: 11, + code: "b14ddd4256f8e7eb73e2c2bbd4c592872abc481eac2c78cc12de470029000000", + }, + { + fio: 16, + code: "000000000000000000c3dd239cdd4ecf76bd7e67f50129c7dd8be5dab6", + }, + }, + CodeRoot: "64de863ab0272175abd6d9014ebcd4e72b794fe22477da118cda27c05345eb11", + }, } for _, c := range testCases { From c1043439c741cbc92279809a95df1099499118d1 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 17 May 2021 19:29:29 +0100 Subject: [PATCH 3/6] Revert "Skip FIO analysis on data continuation" This reverts commit 29607e93b399d15b46d457d625fb00820cb6bd24. --- codetrie/codetrie.go | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/codetrie/codetrie.go b/codetrie/codetrie.go index 5216b41ea18..2999890c323 100644 --- a/codetrie/codetrie.go +++ b/codetrie/codetrie.go @@ -3,7 +3,6 @@ package codetrie import ( "encoding/binary" "errors" - "fmt" "math" sszlib "github.com/ferranbt/fastssz" @@ -33,17 +32,13 @@ type CodeTrie interface { GetTree() (*sszlib.Node, error) } -const ( - FIOUnset = 0xff -) - type Chunk struct { fio uint8 // firstInstructionOffset code []byte } func NewChunk() *Chunk { - return &Chunk{fio: FIOUnset, code: nil} + return &Chunk{fio: 0, code: nil} } func (c *Chunk) Serialize() []byte { @@ -208,21 +203,11 @@ func Chunkify(code []byte, chunkSize uint) []*Chunk { if i == numChunks-1 { endIdx = uint(len(code)) } - chunks[i] = &Chunk{fio: FIOUnset, code: code[startIdx:endIdx]} + chunks[i] = &Chunk{fio: 0, code: code[startIdx:endIdx]} } setFIO(chunks) - // Sanity check that all chunks were processed - for i, _ := range chunks { - if i == len(chunks)-1 { - break - } - if chunks[i].fio == FIOUnset { - panic(fmt.Sprintf("Chunk %d has unprocessed FIO", i)) - } - } - return chunks } @@ -238,11 +223,6 @@ func setFIO(chunks []*Chunk) { break } - // This chunk was already processed (it is a data chunk continuation) - if chunks[i].fio != FIOUnset { - continue - } - for j, op := range chunk.code { opcode := OpCode(op) // Push is the only opcode with immediate From f9f1b5b651b776da387d574130d6f38f1162cb1f Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 17 May 2021 19:04:24 +0100 Subject: [PATCH 4/6] Properly skip bytes prior to FIO --- codetrie/codetrie.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/codetrie/codetrie.go b/codetrie/codetrie.go index 2999890c323..63fcb092f84 100644 --- a/codetrie/codetrie.go +++ b/codetrie/codetrie.go @@ -224,6 +224,11 @@ func setFIO(chunks []*Chunk) { } for j, op := range chunk.code { + // Skip bytes part of a data + if int(chunks[i].fio) > j { + continue + } + opcode := OpCode(op) // Push is the only opcode with immediate if !opcode.IsPush() { From 9801741964fb4343a9ffb274a1edddac7a289263 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 18 May 2021 00:17:31 +0100 Subject: [PATCH 5/6] Add test suite for 24-byte chunks --- codetrie/codetrie_test.go | 341 +++++++++++++++++++++++++++++++++++++- 1 file changed, 340 insertions(+), 1 deletion(-) diff --git a/codetrie/codetrie_test.go b/codetrie/codetrie_test.go index 18403bad548..b011d07e998 100644 --- a/codetrie/codetrie_test.go +++ b/codetrie/codetrie_test.go @@ -29,7 +29,7 @@ type MerkleizeTest struct { CodeRoot string } -func TestMerkleize(t *testing.T) { +func TestMerkleize32(t *testing.T) { testCases := []MerkleizeTest{ { Input: "6000", @@ -267,6 +267,345 @@ func TestMerkleize(t *testing.T) { } } +func TestMerkleize24(t *testing.T) { + testCases := []MerkleizeTest{ + { + Input: "6000", + Chunks: []TChunk{ + { + fio: 0, + code: "6000", + }, + }, + CodeRoot: "fe1d3dcb57f6b06c53aaf7c6d33ae49f132472983798526b61e5a999fb37032d", + }, + { + Input: strings.Repeat("6000", 15) + "00", // Len: 31 + Chunks: []TChunk{ + { + fio: 0, + code: strings.Repeat("6000", 12), + }, + { + fio: 0, + code: strings.Repeat("6000", 3) + "00", + }, + }, + CodeRoot: "a983e1f939935bf5c32bc34f3c6e388d83d0a5283b3f60faa790fa0908791902", + }, + { + Input: strings.Repeat("6000", 16), // Len: 32 + Chunks: []TChunk{ + { + fio: 0, + code: strings.Repeat("6000", 12), + }, + { + fio: 0, + code: strings.Repeat("6000", 4), + }, + }, + CodeRoot: "7965257957593eb9061d320e17ef59feec179cfebf93cbb25cfe51898ef6c918", + }, + { + Input: strings.Repeat("6000", 17), // Len: 34 + Chunks: []TChunk{ + { + fio: 0, + code: strings.Repeat("6000", 12), + }, + { + fio: 0, + code: strings.Repeat("6000", 5), + }, + }, + CodeRoot: "b4d1d2394738ccdde1ad0dcc38924a7b68767d59a001d83af0e3a32836638800", + }, + { + Input: strings.Repeat("58", 31) + "605b" + strings.Repeat("58", 30), // Len: 63 + Chunks: []TChunk{ + { + fio: 0, + code: strings.Repeat("58", 24), + }, + { + fio: 0, + code: strings.Repeat("58", 7) + "605b" + strings.Repeat("58", 15), + }, + { + fio: 0, + code: strings.Repeat("58", 15), + }, + }, + CodeRoot: "a9e011b8aa7f7fd15c0d2918d2d604a6dc489c2e90f5dfbcf3d43fc943fb6950", + }, + { + Input: strings.Repeat("58", 31) + "7f" + strings.Repeat("5b", 32) + strings.Repeat("58", 30), // Len: 94 + Chunks: []TChunk{ + { + fio: 0, + code: strings.Repeat("58", 24), + }, + { + fio: 0, + code: strings.Repeat("58", 7) + "7f" + strings.Repeat("5b", 16), + }, + { + fio: 16, + code: strings.Repeat("5b", 16) + strings.Repeat("58", 8), + }, + { + fio: 0, + code: strings.Repeat("58", 22), + }, + }, + CodeRoot: "f41f007c3e0341a908c42cc854bbf2b61dbf97e5bd5e65b4867c6be80c9efc6a", + }, + { + // Oversized push contains a PUSH32 byte + Input: "7f" + strings.Repeat("58", 23) + "7f" + strings.Repeat("58", 8) + "60006000fe", + Chunks: []TChunk{ + { + fio: 0, + code: "7f" + strings.Repeat("58", 23), + }, + { + fio: 9, + code: "7f" + strings.Repeat("58", 8) + "60006000fe", + }, + }, + CodeRoot: "fa2bf0e8ed8d155b3fd38010b81c6381ab2f9b5daf141ce625c3913ba0ac65fb", + }, + { + // Oversized push spanning 3 chunks + Input: strings.Repeat("58", 23) + "7f" + strings.Repeat("58", 23) + "7f7f" + strings.Repeat("58", 7) + "60006000fe", + Chunks: []TChunk{ + { + fio: 0, + code: strings.Repeat("58", 23) + "7f", + }, + { + fio: 24, + code: strings.Repeat("58", 23) + "7f", + }, + { + fio: 8, + code: "7f" + strings.Repeat("58", 7) + "60006000fe", + }, + }, + CodeRoot: "3788a496364cc5f3263c195f5ed633cf5e96fa89aa7521c946b85bc3e94f1ec9", + }, + { + // Push data is truncated (i.e. Solidity metadata) + Input: strings.Repeat("58", 23) + "7f" + strings.Repeat("58", 3), + Chunks: []TChunk{ + { + fio: 0, + code: strings.Repeat("58", 23) + "7f", + }, + { + fio: 0, + code: strings.Repeat("58", 3), + }, + }, + CodeRoot: "7e4cf3548c4896daa1c463be7016156e6324c3eac239df2d668deb833d8e725e", + }, + { + // Test of https://etherscan.io/tx/0x8217ac6d4c0578a3d954c6800ab59060a3c376c81ee17c3726bd4bcc7167e12e + Input: "6060604052341561000f57600080fd5b60405160208061031d8339810160405280805160008054600160a060020a03909216600160a060020a031990921691909117905550506102c9806100546000396000f3006060604052600436106100325763ffffffff60e060020a60003504166362c067678114610034578063c0ee0b8a14610070575b005b341561003f57600080fd5b61005c600160a060020a03600435811690602435166044356100d5565b604051901515815260200160405180910390f35b341561007b57600080fd5b61003260048035600160a060020a03169060248035919060649060443590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061029895505050505050565b60008054819081908190600160a060020a0316637bd163f33360405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b151561012c57600080fd5b5af1151561013957600080fd5b505050604051805190501561028e5760009250600160a060020a038716156102455786915081600160a060020a03166370a082313060405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b15156101ac57600080fd5b5af115156101b957600080fd5b505050604051805190508511156101d3576000935061028e565b81600160a060020a031663a9059cbb878760405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b151561022757600080fd5b5af1151561023457600080fd5b50505060405180519050925061028a565b5083600160a060020a03301631811115610262576000935061028e565b600160a060020a03861681156108fc0282604051600060405180830381858888f19650505050505b8293505b5050509392505050565b5050505600a165627a7a7230582046a5a4b3a9b14ddd4256f8e7eb73e2c2bbd4c592872abc481eac2c78cc12de470029000000000000000000000000c3dd239cdd4ecf76bd7e67f50129c7dd8be5dab6", + Chunks: []TChunk{ + { + fio: 0, + code: "6060604052341561000f57600080fd5b6040516020806103", + }, + { + fio: 1, + code: "1d8339810160405280805160008054600160a060020a0390", + }, + { + fio: 0, + code: "9216600160a060020a031990921691909117905550506102", + }, + { + fio: 1, + code: "c9806100546000396000f300606060405260043610610032", + }, + { + fio: 0, + code: "5763ffffffff60e060020a60003504166362c06767811461", + }, + { + fio: 2, + code: "0034578063c0ee0b8a14610070575b005b341561003f5760", + }, + { + fio: 1, + code: "0080fd5b61005c600160a060020a03600435811690602435", + }, + { + fio: 0, + code: "166044356100d5565b604051901515815260200160405180", + }, + { + fio: 0, + code: "910390f35b341561007b57600080fd5b6100326004803560", + }, + { + fio: 1, + code: "0160a060020a031690602480359190606490604435908101", + }, + { + fio: 0, + code: "90830135806020601f820181900481020160405190810160", + }, + { + fio: 1, + code: "405281815292919060208401838380828437509496506102", + }, + { + fio: 1, + code: "9895505050505050565b60008054819081908190600160a0", + }, + { + fio: 0, + code: "60020a0316637bd163f33360405160e060020a63ffffffff", + }, + { + fio: 11, + code: "8416028152600160a060020a039091166004820152602401", + }, + { + fio: 0, + code: "602060405180830381600087803b151561012c57600080fd", + }, + { + fio: 0, + code: "5b5af1151561013957600080fd5b50505060405180519050", + }, + { + fio: 0, + code: "1561028e5760009250600160a060020a0387161561024557", + }, + { + fio: 0, + code: "86915081600160a060020a03166370a082313060405160e0", + }, + { + fio: 8, + code: "60020a63ffffffff8416028152600160a060020a03909116", + }, + { + fio: 0, + code: "6004820152602401602060405180830381600087803b1515", + }, + { + fio: 0, + code: "6101ac57600080fd5b5af115156101b957600080fd5b5050", + }, + { + fio: 0, + code: "50604051805190508511156101d3576000935061028e565b", + }, + { + fio: 0, + code: "81600160a060020a031663a9059cbb878760405160e06002", + }, + { + fio: 0, + code: "0a63ffffffff8516028152600160a060020a039092166004", + }, + { + fio: 0, + code: "830152602482015260440160206040518083038160008780", + }, + { + fio: 0, + code: "3b151561022757600080fd5b5af1151561023457600080fd", + }, + { + fio: 0, + code: "5b50505060405180519050925061028a565b5083600160a0", + }, + { + fio: 0, + code: "60020a03301631811115610262576000935061028e565b60", + }, + { + fio: 1, + code: "0160a060020a03861681156108fc02826040516000604051", + }, + { + fio: 0, + code: "80830381858888f19650505050505b8293505b5050509392", + }, + { + fio: 0, + code: "505050565b5050505600a165627a7a7230582046a5a4b3a9", + }, + { + fio: 11, + code: "b14ddd4256f8e7eb73e2c2bbd4c592872abc481eac2c78cc", + }, + { + fio: 24, + code: "12de470029000000000000000000000000c3dd239cdd4ecf", + }, + { + fio: 0, + code: "76bd7e67f50129c7dd8be5dab6", + }, + }, + CodeRoot: "aa90663202260f3ee4a782c1b4d5edd94d88b1ea14dcc67bc6548e3a7f848be6", + }, + } + + for _, c := range testCases { + code, err := hex.DecodeString(c.Input) + if err != nil { + t.Error(err) + } + chunks := Chunkify(code, 24) + if len(chunks) != len(c.Chunks) { + t.Errorf("%v: invalid number of chunks: expected %d, got %d\n", t.Name(), len(c.Chunks), len(chunks)) + } + for i, chunk := range chunks { + expectedChunk := c.Chunks[i] + if chunk.fio != expectedChunk.fio { + t.Errorf("%v: invalid chunk FIO: expected %d, got %d\n", t.Name(), expectedChunk.fio, chunk.fio) + } + expectedCode, err := hex.DecodeString(expectedChunk.code) + if err != nil { + t.Error(err) + } + if !bytes.Equal(chunk.code, expectedCode) { + t.Errorf("%v: invalid chunk code: expected %s, got %s\n", t.Name(), expectedChunk.code, hex.EncodeToString(chunk.code)) + } + } + + expectedRoot, err := hex.DecodeString(c.CodeRoot) + if err != nil { + t.Error(err) + } + + root, err := MerkleizeInMemory(code, 24) + if err != nil { + t.Error(err) + } + if !bytes.Equal(root.Bytes(), expectedRoot) { + t.Errorf("%v: invalid code root: expected %s, got %s\n", t.Name(), c.CodeRoot, root.Hex()) + } + + // Test StackTrie impl + stackRoot, err := MerkleizeStack(code, 24) + if err != nil { + t.Error(err) + } + if !bytes.Equal(stackRoot.Bytes(), expectedRoot) { + t.Errorf("%v: invalid code root for MerkleizeStack: expected %s, got %s\n", t.Name(), c.CodeRoot, stackRoot.Hex()) + } + } +} + func TestChunkifySize(t *testing.T) { testCases := []ChunkifyTest{ { From 20006f7a289bfb84223ed92e73692c323602563b Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 18 May 2021 01:11:07 +0100 Subject: [PATCH 6/6] Use correct FIO for even truncated code --- codetrie/codetrie.go | 19 ++++++++++--------- codetrie/codetrie_test.go | 4 ++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/codetrie/codetrie.go b/codetrie/codetrie.go index 63fcb092f84..d8671c04e48 100644 --- a/codetrie/codetrie.go +++ b/codetrie/codetrie.go @@ -212,6 +212,7 @@ func Chunkify(code []byte, chunkSize uint) []*Chunk { } func setFIO(chunks []*Chunk) { + // Abort if there is only one chunk if len(chunks) < 2 { return } @@ -219,13 +220,14 @@ func setFIO(chunks []*Chunk) { chunkSize := len(chunks[0].code) for i, chunk := range chunks { + // Skip last chunk (as there's no chunk following) if i == len(chunks)-1 { break } for j, op := range chunk.code { // Skip bytes part of a data - if int(chunks[i].fio) > j { + if j < int(chunks[i].fio) { continue } @@ -244,20 +246,19 @@ func setFIO(chunks []*Chunk) { // If chunkSize < 32, then data could span multiple chunks. // restData is number of data bytes in next chunks. restData := (j + size + 1) - chunkSize - spanningChunks := int(math.Ceil(float64(restData) / float64(chunkSize))) - // Mostly happens in case of Solidity metadata at - // the end of code. - if i+spanningChunks >= len(chunks) { - continue - } k := 1 for restData > chunkSize { - chunks[i+k].fio = uint8(chunkSize) + // We may be trying to access non-existing chunks in case of truncated or invalid code + if (i+k) <= len(chunks)-1 { + chunks[i+k].fio = uint8(chunkSize) + } k++ restData -= chunkSize } if restData > 0 { - chunks[i+k].fio = uint8(restData) + if (i+k) <= len(chunks)-1 { + chunks[i+k].fio = uint8(restData) + } } } } diff --git a/codetrie/codetrie_test.go b/codetrie/codetrie_test.go index b011d07e998..a9602f49df2 100644 --- a/codetrie/codetrie_test.go +++ b/codetrie/codetrie_test.go @@ -404,11 +404,11 @@ func TestMerkleize24(t *testing.T) { code: strings.Repeat("58", 23) + "7f", }, { - fio: 0, + fio: 24, code: strings.Repeat("58", 3), }, }, - CodeRoot: "7e4cf3548c4896daa1c463be7016156e6324c3eac239df2d668deb833d8e725e", + CodeRoot: "b2cf2c424ea0e1b43b0d2d2fb9b2b4983a9aac4a2319af47806e6b9625767a44", }, { // Test of https://etherscan.io/tx/0x8217ac6d4c0578a3d954c6800ab59060a3c376c81ee17c3726bd4bcc7167e12e