diff --git a/pkg/api.go b/pkg/api.go
index cf180d2..2e0b00a 100644
--- a/pkg/api.go
+++ b/pkg/api.go
@@ -45,11 +45,6 @@ func (api *PublicStateDiffAPI) StateDiffAt(ctx context.Context, blockNumber uint
return api.sds.StateDiffAt(blockNumber, params)
}
-// StateTrieAt returns a state trie payload at the specific blockheight
-func (api *PublicStateDiffAPI) StateTrieAt(ctx context.Context, blockNumber uint64, params sd.Params) (*sd.Payload, error) {
- return api.sds.StateTrieAt(blockNumber, params)
-}
-
// WriteStateDiffAt writes a state diff object directly to DB at the specific blockheight
func (api *PublicStateDiffAPI) WriteStateDiffAt(ctx context.Context, blockNumber uint64, params sd.Params) error {
return api.sds.WriteStateDiffAt(blockNumber, params)
diff --git a/pkg/builder.go b/pkg/builder.go
index 33fe5df..936ad45 100644
--- a/pkg/builder.go
+++ b/pkg/builder.go
@@ -55,24 +55,24 @@ func NewBuilder(stateCache state.Database, workers uint) (sd.Builder, error) {
// BuildStateDiffObject builds a statediff object from two blocks and the provided parameters
func (sdb *builder) BuildStateDiffObject(args sd.Args, params sd.Params) (sdtypes.StateObject, error) {
- var stateNodes []sdtypes.StateNode
- var codeAndCodeHashes []sdtypes.CodeAndCodeHash
+ var stateNodes []sdtypes.StateLeafNode
+ var codeAndCodeHashes []sdtypes.IPLD
err := sdb.WriteStateDiffObject(
args,
- params, sd.StateNodeAppender(&stateNodes), sd.CodeMappingAppender(&codeAndCodeHashes))
+ params, sd.StateNodeAppender(&stateNodes), sd.IPLDMappingAppender(&codeAndCodeHashes))
if err != nil {
return sdtypes.StateObject{}, err
}
return sdtypes.StateObject{
- BlockHash: args.BlockHash,
- BlockNumber: args.BlockNumber,
- Nodes: stateNodes,
- CodeAndCodeHashes: codeAndCodeHashes,
+ BlockHash: args.BlockHash,
+ BlockNumber: args.BlockNumber,
+ Nodes: stateNodes,
+ IPLDs: codeAndCodeHashes,
}, nil
}
// WriteStateDiffObject writes a statediff object to output callback
-func (sdb *builder) WriteStateDiffObject(args sd.Args, params sd.Params, output sdtypes.StateNodeSink, codeOutput sdtypes.CodeSink) error {
+func (sdb *builder) WriteStateDiffObject(args sd.Args, params sd.Params, output sdtypes.StateNodeSink, codeOutput sdtypes.IPLDSink) error {
// Load tries for old and new states
oldTrie, err := sdb.StateCache.OpenTrie(args.OldStateRoot)
if err != nil {
@@ -101,12 +101,12 @@ func (sdb *builder) WriteStateDiffObject(args sd.Args, params sd.Params, output
}
// Dispatch workers to process trie data; sync and collect results here via channels
- nodeChan := make(chan sdtypes.StateNode)
- codeChan := make(chan sdtypes.CodeAndCodeHash)
+ nodeChan := make(chan sdtypes.StateLeafNode)
+ codeChan := make(chan sdtypes.IPLD)
go func() {
- nodeSender := func(node sdtypes.StateNode) error { nodeChan <- node; return nil }
- codeSender := func(code sdtypes.CodeAndCodeHash) error { codeChan <- code; return nil }
+ nodeSender := func(node sdtypes.StateLeafNode) error { nodeChan <- node; return nil }
+ ipldSender := func(code sdtypes.IPLD) error { codeChan <- code; return nil }
var wg sync.WaitGroup
for w := uint(0); w < sdb.numWorkers; w++ {
@@ -115,12 +115,7 @@ func (sdb *builder) WriteStateDiffObject(args sd.Args, params sd.Params, output
defer wg.Done()
var err error
logger := log.New("hash", args.BlockHash.Hex(), "number", args.BlockNumber)
- if !params.IntermediateStateNodes {
- err = sdb.BuildStateDiffWithoutIntermediateStateNodes(iterPairs[worker], params, nodeSender, codeSender, logger)
- } else {
- err = sdb.BuildStateDiffWithIntermediateStateNodes(iterPairs[worker], params, nodeSender, codeSender, logger)
- }
-
+ err = sdb.BuildStateDiffWithIntermediateStateNodes(iterPairs[worker], params, nodeSender, ipldSender, logger)
if err != nil {
logrus.Errorf("buildStateDiff error for worker %d, params %+v", worker, params)
}
diff --git a/pkg/builder_test.go b/pkg/builder_test.go
index b6843be..7221dac 100644
--- a/pkg/builder_test.go
+++ b/pkg/builder_test.go
@@ -18,7 +18,10 @@ package statediff_test
import (
"bytes"
+ "encoding/json"
+ "fmt"
"math/big"
+ "os"
"sort"
"testing"
@@ -26,28 +29,26 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
- sd "github.com/ethereum/go-ethereum/statediff"
+ "github.com/ethereum/go-ethereum/statediff"
+ ipld2 "github.com/ethereum/go-ethereum/statediff/indexer/ipld"
+ "github.com/ethereum/go-ethereum/statediff/indexer/shared"
"github.com/ethereum/go-ethereum/statediff/test_helpers"
- sdtypes "github.com/ethereum/go-ethereum/statediff/types"
-
- pkg "github.com/cerc-io/eth-statediff-service/pkg"
+ types2 "github.com/ethereum/go-ethereum/statediff/types"
)
var (
contractLeafKey []byte
- emptyDiffs = make([]sdtypes.StateNode, 0)
- emptyStorage = make([]sdtypes.StorageNode, 0)
+ emptyDiffs = make([]types2.StateLeafNode, 0)
+ emptyStorage = make([]types2.StorageLeafNode, 0)
block0, block1, block2, block3, block4, block5, block6 *types.Block
- builder sd.Builder
- miningReward = int64(2000000000000000000)
+ builder statediff.Builder
minerAddress = common.HexToAddress("0x0")
minerLeafKey = test_helpers.AddressToLeafKey(minerAddress)
- workerCounts = []uint{0, 1, 2, 4, 8}
- slot0 = common.HexToHash("0")
- slot1 = common.HexToHash("1")
- slot2 = common.HexToHash("2")
- slot3 = common.HexToHash("3")
+ slot0 = common.BigToHash(big.NewInt(0))
+ slot1 = common.BigToHash(big.NewInt(1))
+ slot2 = common.BigToHash(big.NewInt(2))
+ slot3 = common.BigToHash(big.NewInt(3))
slot0StorageKey = crypto.Keccak256Hash(slot0[:])
slot1StorageKey = crypto.Keccak256Hash(slot1[:])
@@ -75,214 +76,230 @@ var (
common.Hex2Bytes("32575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b"),
slot3StorageValue,
})
-
- contractAccountAtBlock2, _ = rlp.EncodeToBytes(&types.StateAccount{
+ contractAccountAtBlock2 = &types.StateAccount{
Nonce: 1,
Balance: big.NewInt(0),
CodeHash: common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127").Bytes(),
Root: crypto.Keccak256Hash(block2StorageBranchRootNode),
- })
+ }
+ contractAccountAtBlock2RLP, _ = rlp.EncodeToBytes(contractAccountAtBlock2)
contractAccountAtBlock2LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45"),
- contractAccountAtBlock2,
+ contractAccountAtBlock2RLP,
})
- contractAccountAtBlock3, _ = rlp.EncodeToBytes(&types.StateAccount{
+ contractAccountAtBlock3 = &types.StateAccount{
Nonce: 1,
Balance: big.NewInt(0),
CodeHash: common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127").Bytes(),
Root: crypto.Keccak256Hash(block3StorageBranchRootNode),
- })
+ }
+ contractAccountAtBlock3RLP, _ = rlp.EncodeToBytes(contractAccountAtBlock3)
contractAccountAtBlock3LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45"),
- contractAccountAtBlock3,
+ contractAccountAtBlock3RLP,
})
- contractAccountAtBlock4, _ = rlp.EncodeToBytes(&types.StateAccount{
+ contractAccountAtBlock4 = &types.StateAccount{
Nonce: 1,
Balance: big.NewInt(0),
CodeHash: common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127").Bytes(),
Root: crypto.Keccak256Hash(block4StorageBranchRootNode),
- })
+ }
+ contractAccountAtBlock4RLP, _ = rlp.EncodeToBytes(contractAccountAtBlock4)
contractAccountAtBlock4LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45"),
- contractAccountAtBlock4,
+ contractAccountAtBlock4RLP,
})
- contractAccountAtBlock5, _ = rlp.EncodeToBytes(&types.StateAccount{
+ contractAccountAtBlock5 = &types.StateAccount{
Nonce: 1,
Balance: big.NewInt(0),
CodeHash: common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127").Bytes(),
Root: crypto.Keccak256Hash(block5StorageBranchRootNode),
- })
+ }
+ contractAccountAtBlock5RLP, _ = rlp.EncodeToBytes(contractAccountAtBlock5)
contractAccountAtBlock5LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45"),
- contractAccountAtBlock5,
+ contractAccountAtBlock5RLP,
})
-
- minerAccountAtBlock1, _ = rlp.EncodeToBytes(&types.StateAccount{
+ minerAccountAtBlock1 = &types.StateAccount{
Nonce: 0,
Balance: big.NewInt(2000002625000000000),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ minerAccountAtBlock1RLP, _ = rlp.EncodeToBytes(minerAccountAtBlock1)
minerAccountAtBlock1LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"),
- minerAccountAtBlock1,
+ minerAccountAtBlock1RLP,
})
- minerAccountAtBlock2, _ = rlp.EncodeToBytes(&types.StateAccount{
+ minerAccountAtBlock2 = &types.StateAccount{
Nonce: 0,
Balance: big.NewInt(4000111203461610525),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ minerAccountAtBlock2RLP, _ = rlp.EncodeToBytes(minerAccountAtBlock2)
minerAccountAtBlock2LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"),
- minerAccountAtBlock2,
+ minerAccountAtBlock2RLP,
})
- account1AtBlock1, _ = rlp.EncodeToBytes(&types.StateAccount{
+ account1AtBlock1 = &types.StateAccount{
Nonce: 0,
Balance: test_helpers.Block1Account1Balance,
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ account1AtBlock1RLP, _ = rlp.EncodeToBytes(account1AtBlock1)
account1AtBlock1LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"),
- account1AtBlock1,
+ account1AtBlock1RLP,
})
- account1AtBlock2, _ = rlp.EncodeToBytes(&types.StateAccount{
+ account1AtBlock2 = &types.StateAccount{
Nonce: 2,
Balance: big.NewInt(999555797000009000),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ account1AtBlock2RLP, _ = rlp.EncodeToBytes(account1AtBlock2)
account1AtBlock2LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"),
- account1AtBlock2,
+ account1AtBlock2RLP,
})
- account1AtBlock5, _ = rlp.EncodeToBytes(&types.StateAccount{
+ account1AtBlock5 = &types.StateAccount{
Nonce: 2,
Balance: big.NewInt(2999586469962854280),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ account1AtBlock5RLP, _ = rlp.EncodeToBytes(account1AtBlock5)
account1AtBlock5LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"),
- account1AtBlock5,
+ account1AtBlock5RLP,
})
- account1AtBlock6, _ = rlp.EncodeToBytes(&types.StateAccount{
+ account1AtBlock6 = &types.StateAccount{
Nonce: 3,
Balance: big.NewInt(2999557977962854280),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ account1AtBlock6RLP, _ = rlp.EncodeToBytes(account1AtBlock6)
account1AtBlock6LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"),
- account1AtBlock6,
+ account1AtBlock6RLP,
})
-
- account2AtBlock2, _ = rlp.EncodeToBytes(&types.StateAccount{
+ account2AtBlock2 = &types.StateAccount{
Nonce: 0,
Balance: big.NewInt(1000),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ account2AtBlock2RLP, _ = rlp.EncodeToBytes(account2AtBlock2)
account2AtBlock2LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45"),
- account2AtBlock2,
+ account2AtBlock2RLP,
})
- account2AtBlock3, _ = rlp.EncodeToBytes(&types.StateAccount{
+ account2AtBlock3 = &types.StateAccount{
Nonce: 0,
Balance: big.NewInt(2000013574009435976),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ account2AtBlock3RLP, _ = rlp.EncodeToBytes(account2AtBlock3)
account2AtBlock3LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45"),
- account2AtBlock3,
+ account2AtBlock3RLP,
})
- account2AtBlock4, _ = rlp.EncodeToBytes(&types.StateAccount{
+ account2AtBlock4 = &types.StateAccount{
Nonce: 0,
Balance: big.NewInt(4000048088163070348),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ account2AtBlock4RLP, _ = rlp.EncodeToBytes(account2AtBlock4)
account2AtBlock4LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45"),
- account2AtBlock4,
+ account2AtBlock4RLP,
})
- account2AtBlock6, _ = rlp.EncodeToBytes(&types.StateAccount{
+ account2AtBlock6 = &types.StateAccount{
Nonce: 0,
Balance: big.NewInt(6000063258066544204),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ account2AtBlock6RLP, _ = rlp.EncodeToBytes(account2AtBlock6)
account2AtBlock6LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45"),
- account2AtBlock6,
+ account2AtBlock6RLP,
})
-
- bankAccountAtBlock0, _ = rlp.EncodeToBytes(&types.StateAccount{
+ bankAccountAtBlock0 = &types.StateAccount{
Nonce: 0,
Balance: big.NewInt(test_helpers.TestBankFunds.Int64()),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ bankAccountAtBlock0RLP, _ = rlp.EncodeToBytes(bankAccountAtBlock0)
bankAccountAtBlock0LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("2000bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"),
- bankAccountAtBlock0,
+ bankAccountAtBlock0RLP,
})
- block1BankBalance = big.NewInt(test_helpers.TestBankFunds.Int64() - test_helpers.BalanceChange10000 - test_helpers.GasFees)
- bankAccountAtBlock1, _ = rlp.EncodeToBytes(&types.StateAccount{
+ block1BankBalance = big.NewInt(test_helpers.TestBankFunds.Int64() - test_helpers.BalanceChange10000 - test_helpers.GasFees)
+ bankAccountAtBlock1 = &types.StateAccount{
Nonce: 1,
Balance: block1BankBalance,
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ bankAccountAtBlock1RLP, _ = rlp.EncodeToBytes(bankAccountAtBlock1)
bankAccountAtBlock1LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"),
- bankAccountAtBlock1,
+ bankAccountAtBlock1RLP,
})
- block2BankBalance = block1BankBalance.Int64() - test_helpers.BalanceChange1Ether - test_helpers.GasFees
- bankAccountAtBlock2, _ = rlp.EncodeToBytes(&types.StateAccount{
+ block2BankBalance = block1BankBalance.Int64() - test_helpers.BalanceChange1Ether - test_helpers.GasFees
+ bankAccountAtBlock2 = &types.StateAccount{
Nonce: 2,
Balance: big.NewInt(block2BankBalance),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ bankAccountAtBlock2RLP, _ = rlp.EncodeToBytes(bankAccountAtBlock2)
bankAccountAtBlock2LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"),
- bankAccountAtBlock2,
+ bankAccountAtBlock2RLP,
})
- bankAccountAtBlock3, _ = rlp.EncodeToBytes(&types.StateAccount{
+ bankAccountAtBlock3 = &types.StateAccount{
Nonce: 3,
Balance: big.NewInt(999914255999990000),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ bankAccountAtBlock3RLP, _ = rlp.EncodeToBytes(bankAccountAtBlock3)
bankAccountAtBlock3LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"),
- bankAccountAtBlock3,
+ bankAccountAtBlock3RLP,
})
- bankAccountAtBlock4, _ = rlp.EncodeToBytes(&types.StateAccount{
+ bankAccountAtBlock4 = &types.StateAccount{
Nonce: 6,
Balance: big.NewInt(999826859999990000),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ bankAccountAtBlock4RLP, _ = rlp.EncodeToBytes(&bankAccountAtBlock4)
bankAccountAtBlock4LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"),
- bankAccountAtBlock4,
+ bankAccountAtBlock4RLP,
})
- bankAccountAtBlock5, _ = rlp.EncodeToBytes(&types.StateAccount{
+ bankAccountAtBlock5 = &types.StateAccount{
Nonce: 8,
Balance: big.NewInt(999761283999990000),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ bankAccountAtBlock5RLP, _ = rlp.EncodeToBytes(bankAccountAtBlock5)
bankAccountAtBlock5LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"),
- bankAccountAtBlock5,
+ bankAccountAtBlock5RLP,
})
block1BranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{
@@ -478,6 +495,13 @@ var (
})
)
+func init() {
+ if os.Getenv("MODE") != "statediff" {
+ fmt.Println("Skipping statediff test")
+ os.Exit(0)
+ }
+}
+
func TestBuilder(t *testing.T) {
blocks, chain := test_helpers.MakeChain(3, test_helpers.Genesis, test_helpers.TestChainGen)
contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr)
@@ -486,22 +510,23 @@ func TestBuilder(t *testing.T) {
block1 = blocks[0]
block2 = blocks[1]
block3 = blocks[2]
- params := sd.Params{}
+ params := statediff.Params{}
+ builder = statediff.NewBuilder(chain.StateCache())
var tests = []struct {
name string
- startingArguments sd.Args
- expected *sdtypes.StateObject
+ startingArguments statediff.Args
+ expected *types2.StateObject
}{
{
"testEmptyDiff",
- sd.Args{
+ statediff.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block0.Root(),
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
Nodes: emptyDiffs,
@@ -510,22 +535,33 @@ func TestBuilder(t *testing.T) {
{
"testBlock0",
//10000 transferred from testBankAddress to account1Addr
- sd.Args{
+ statediff.Args{
OldStateRoot: test_helpers.NullHash,
NewStateRoot: block0.Root(),
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock0LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: bankAccountAtBlock0,
+ LeafKey: test_helpers.BankLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock0LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock0LeafNode)).String(),
+ Content: bankAccountAtBlock0LeafNode,
},
},
},
@@ -533,36 +569,69 @@ func TestBuilder(t *testing.T) {
{
"testBlock1",
//10000 transferred from testBankAddress to account1Addr
- sd.Args{
+ statediff.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block1.Root(),
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock1LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: bankAccountAtBlock1,
+ LeafKey: test_helpers.BankLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock1LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
{
- Path: []byte{'\x05'},
- NodeType: sdtypes.Leaf,
- LeafKey: minerLeafKey,
- NodeValue: minerAccountAtBlock1LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: minerAccountAtBlock1,
+ LeafKey: minerLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(minerAccountAtBlock1LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
{
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock1LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account1AtBlock1,
+ LeafKey: test_helpers.Account1LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock1LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block1BranchRootNode)).String(),
+ Content: block1BranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock1LeafNode)).String(),
+ Content: bankAccountAtBlock1LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(minerAccountAtBlock1LeafNode)).String(),
+ Content: minerAccountAtBlock1LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock1LeafNode)).String(),
+ Content: account1AtBlock1LeafNode,
},
},
},
@@ -572,69 +641,130 @@ func TestBuilder(t *testing.T) {
// 1000 transferred from testBankAddress to account1Addr
// 1000 transferred from account1Addr to account2Addr
// account1addr creates a new contract
- sd.Args{
+ statediff.Args{
OldStateRoot: block1.Root(),
NewStateRoot: block2.Root(),
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock2LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: bankAccountAtBlock2,
+ LeafKey: test_helpers.BankLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock2LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
{
- Path: []byte{'\x05'},
- NodeType: sdtypes.Leaf,
- LeafKey: minerLeafKey,
- NodeValue: minerAccountAtBlock2LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: minerAccountAtBlock2,
+ LeafKey: minerLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(minerAccountAtBlock2LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
{
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock2LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account1AtBlock2,
+ LeafKey: test_helpers.Account1LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock2LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
{
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock2LeafNode,
- StorageNodes: []sdtypes.StorageNode{
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock2,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock2LeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
{
- Path: []byte{'\x02'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot0StorageKey.Bytes(),
- NodeValue: slot0StorageLeafNode,
+ Removed: false,
+ Value: slot0StorageValue,
+ LeafKey: slot0StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot0StorageLeafNode)).String(),
},
{
- Path: []byte{'\x0b'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot1StorageKey.Bytes(),
- NodeValue: slot1StorageLeafNode,
+ Removed: false,
+ Value: slot1StorageValue,
+ LeafKey: slot1StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(),
},
},
},
{
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account2LeafKey,
- NodeValue: account2AtBlock2LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account2AtBlock2,
+ LeafKey: test_helpers.Account2LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account2AtBlock2LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
},
- CodeAndCodeHashes: []sdtypes.CodeAndCodeHash{
+ IPLDs: []types2.IPLD{
{
- Hash: test_helpers.CodeHash,
- Code: test_helpers.ByteCodeAfterDeployment,
+ CID: ipld2.Keccak256ToCid(ipld2.RawBinary, test_helpers.CodeHash.Bytes()).String(),
+ Content: test_helpers.ByteCodeAfterDeployment,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block2BranchRootNode)).String(),
+ Content: block2BranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock2LeafNode)).String(),
+ Content: bankAccountAtBlock2LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(minerAccountAtBlock2LeafNode)).String(),
+ Content: minerAccountAtBlock2LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock2LeafNode)).String(),
+ Content: account1AtBlock2LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock2LeafNode)).String(),
+ Content: contractAccountAtBlock2LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block2StorageBranchRootNode)).String(),
+ Content: block2StorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot0StorageLeafNode)).String(),
+ Content: slot0StorageLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(),
+ Content: slot1StorageLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account2AtBlock2LeafNode)).String(),
+ Content: account2AtBlock2LeafNode,
},
},
},
@@ -643,350 +773,130 @@ func TestBuilder(t *testing.T) {
"testBlock3",
//the contract's storage is changed
//and the block is mined by account 2
- sd.Args{
+ statediff.Args{
OldStateRoot: block2.Root(),
NewStateRoot: block3.Root(),
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock3LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: bankAccountAtBlock3,
+ LeafKey: test_helpers.BankLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock3LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
{
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock3LeafNode,
- StorageNodes: []sdtypes.StorageNode{
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock3,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock3LeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
{
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: slot3StorageLeafNode,
+ Removed: false,
+ Value: slot3StorageValue,
+ LeafKey: slot3StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot3StorageLeafNode)).String(),
},
},
},
{
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account2LeafKey,
- NodeValue: account2AtBlock3LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account2AtBlock3,
+ LeafKey: test_helpers.Account2LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account2AtBlock3LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block3BranchRootNode)).String(),
+ Content: block3BranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock3LeafNode)).String(),
+ Content: bankAccountAtBlock3LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock3LeafNode)).String(),
+ Content: contractAccountAtBlock3LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3StorageBranchRootNode)).String(),
+ Content: block3StorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot3StorageLeafNode)).String(),
+ Content: slot3StorageLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account2AtBlock3LeafNode)).String(),
+ Content: account2AtBlock3LeafNode,
},
},
},
},
}
- for _, workers := range workerCounts {
- builder, _ = pkg.NewBuilder(chain.StateCache(), workers)
- for _, test := range tests {
- diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
+ for _, test := range tests {
+ diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
+ if err != nil {
+ t.Error(err)
+ }
+ receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
+ if err != nil {
+ t.Error(err)
+ }
+ expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
+ sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
+ sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
+ if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
+ actual, err := json.Marshal(diff)
if err != nil {
t.Error(err)
}
- receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
+ expected, err := json.Marshal(test.expected)
if err != nil {
t.Error(err)
}
- expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
- if err != nil {
- t.Error(err)
- }
- sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
- sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
- if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
- t.Logf("Test failed: %s", test.name)
- t.Errorf("actual state diff: %+v\nexpected state diff: %+v", diff, test.expected)
- }
+ t.Logf("Test failed: %s", test.name)
+ t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected)
}
}
-}
-
-func TestBuilderWithIntermediateNodes(t *testing.T) {
- blocks, chain := test_helpers.MakeChain(3, test_helpers.Genesis, test_helpers.TestChainGen)
- contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr)
- defer chain.Stop()
- block0 = test_helpers.Genesis
- block1 = blocks[0]
- block2 = blocks[1]
- block3 = blocks[2]
- blocks = append([]*types.Block{block0}, blocks...)
- params := sd.Params{
- IntermediateStateNodes: true,
- IntermediateStorageNodes: true,
+ // Let's also confirm that our root state nodes form the state root hash in the headers
+ if !bytes.Equal(block0.Root().Bytes(), crypto.Keccak256(bankAccountAtBlock0LeafNode)) {
+ t.Errorf("block0 expected root %x does not match actual root %x", block0.Root().Bytes(), crypto.Keccak256(bankAccountAtBlock0LeafNode))
}
-
- var tests = []struct {
- name string
- startingArguments sd.Args
- expected *sdtypes.StateObject
- }{
- {
- "testEmptyDiff",
- sd.Args{
- OldStateRoot: block0.Root(),
- NewStateRoot: block0.Root(),
- BlockNumber: block0.Number(),
- BlockHash: block0.Hash(),
- },
- &sdtypes.StateObject{
- BlockNumber: block0.Number(),
- BlockHash: block0.Hash(),
- Nodes: emptyDiffs,
- },
- },
- {
- "testBlock0",
- //10000 transferred from testBankAddress to account1Addr
- sd.Args{
- OldStateRoot: test_helpers.NullHash,
- NewStateRoot: block0.Root(),
- BlockNumber: block0.Number(),
- BlockHash: block0.Hash(),
- },
- &sdtypes.StateObject{
- BlockNumber: block0.Number(),
- BlockHash: block0.Hash(),
- Nodes: []sdtypes.StateNode{
- {
- Path: []byte{},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock0LeafNode,
- StorageNodes: emptyStorage,
- },
- },
- },
- },
- {
- "testBlock1",
- //10000 transferred from testBankAddress to account1Addr
- sd.Args{
- OldStateRoot: block0.Root(),
- NewStateRoot: block1.Root(),
- BlockNumber: block1.Number(),
- BlockHash: block1.Hash(),
- },
- &sdtypes.StateObject{
- BlockNumber: block1.Number(),
- BlockHash: block1.Hash(),
- Nodes: []sdtypes.StateNode{
- {
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block1BranchRootNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock1LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x05'},
- NodeType: sdtypes.Leaf,
- LeafKey: minerLeafKey,
- NodeValue: minerAccountAtBlock1LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock1LeafNode,
- StorageNodes: emptyStorage,
- },
- },
- },
- },
- {
- "testBlock2",
- // 1000 transferred from testBankAddress to account1Addr
- // 1000 transferred from account1Addr to account2Addr
- // account1addr creates a new contract
- sd.Args{
- OldStateRoot: block1.Root(),
- NewStateRoot: block2.Root(),
- BlockNumber: block2.Number(),
- BlockHash: block2.Hash(),
- },
- &sdtypes.StateObject{
- BlockNumber: block2.Number(),
- BlockHash: block2.Hash(),
- Nodes: []sdtypes.StateNode{
- {
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block2BranchRootNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock2LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x05'},
- NodeType: sdtypes.Leaf,
- LeafKey: minerLeafKey,
- NodeValue: minerAccountAtBlock2LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock2LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock2LeafNode,
- StorageNodes: []sdtypes.StorageNode{
- {
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block2StorageBranchRootNode,
- },
- {
- Path: []byte{'\x02'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot0StorageKey.Bytes(),
- NodeValue: slot0StorageLeafNode,
- },
- {
- Path: []byte{'\x0b'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot1StorageKey.Bytes(),
- NodeValue: slot1StorageLeafNode,
- },
- },
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account2LeafKey,
- NodeValue: account2AtBlock2LeafNode,
- StorageNodes: emptyStorage,
- },
- },
- CodeAndCodeHashes: []sdtypes.CodeAndCodeHash{
- {
- Hash: test_helpers.CodeHash,
- Code: test_helpers.ByteCodeAfterDeployment,
- },
- },
- },
- },
- {
- "testBlock3",
- //the contract's storage is changed
- //and the block is mined by account 2
- sd.Args{
- OldStateRoot: block2.Root(),
- NewStateRoot: block3.Root(),
- BlockNumber: block3.Number(),
- BlockHash: block3.Hash(),
- },
- &sdtypes.StateObject{
- BlockNumber: block3.Number(),
- BlockHash: block3.Hash(),
- Nodes: []sdtypes.StateNode{
- {
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block3BranchRootNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock3LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock3LeafNode,
- StorageNodes: []sdtypes.StorageNode{
- {
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block3StorageBranchRootNode,
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: slot3StorageLeafNode,
- },
- },
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account2LeafKey,
- NodeValue: account2AtBlock3LeafNode,
- StorageNodes: emptyStorage,
- },
- },
- },
- },
+ if !bytes.Equal(block1.Root().Bytes(), crypto.Keccak256(block1BranchRootNode)) {
+ t.Errorf("block1 expected root %x does not match actual root %x", block1.Root().Bytes(), crypto.Keccak256(block1BranchRootNode))
}
-
- for _, workers := range workerCounts {
- builder, _ = pkg.NewBuilder(chain.StateCache(), workers)
- for i, test := range tests {
- diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
- if err != nil {
- t.Error(err)
- }
- receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
- if err != nil {
- t.Error(err)
- }
- expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
- if err != nil {
- t.Error(err)
- }
- sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
- sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
- if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
- t.Logf("Test failed: %s", test.name)
- t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected)
- }
- // Let's also confirm that our root state nodes form the state root hash in the headers
- if i > 0 {
- block := blocks[i-1]
- expectedStateRoot := block.Root()
- for _, node := range test.expected.Nodes {
- if bytes.Equal(node.Path, []byte{}) {
- stateRoot := crypto.Keccak256Hash(node.NodeValue)
- if !bytes.Equal(expectedStateRoot.Bytes(), stateRoot.Bytes()) {
- t.Logf("Test failed: %s", test.name)
- t.Errorf("actual stateroot: %x\r\nexpected stateroot: %x", stateRoot.Bytes(), expectedStateRoot.Bytes())
- }
- }
- }
- }
- }
+ if !bytes.Equal(block2.Root().Bytes(), crypto.Keccak256(block2BranchRootNode)) {
+ t.Errorf("block2 expected root %x does not match actual root %x", block2.Root().Bytes(), crypto.Keccak256(block2BranchRootNode))
+ }
+ if !bytes.Equal(block3.Root().Bytes(), crypto.Keccak256(block3BranchRootNode)) {
+ t.Errorf("block3 expected root %x does not match actual root %x", block3.Root().Bytes(), crypto.Keccak256(block3BranchRootNode))
}
}
@@ -998,27 +908,26 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
block1 = blocks[0]
block2 = blocks[1]
block3 = blocks[2]
- params := sd.Params{
- IntermediateStateNodes: true,
- IntermediateStorageNodes: true,
- WatchedAddresses: []common.Address{test_helpers.Account1Addr, test_helpers.ContractAddr},
+ params := statediff.Params{
+ WatchedAddresses: []common.Address{test_helpers.Account1Addr, test_helpers.ContractAddr},
}
params.ComputeWatchedAddressesLeafPaths()
+ builder = statediff.NewBuilder(chain.StateCache())
var tests = []struct {
name string
- startingArguments sd.Args
- expected *sdtypes.StateObject
+ startingArguments statediff.Args
+ expected *types2.StateObject
}{
{
"testEmptyDiff",
- sd.Args{
+ statediff.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block0.Root(),
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
Nodes: emptyDiffs,
@@ -1027,13 +936,13 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
{
"testBlock0",
//10000 transferred from testBankAddress to account1Addr
- sd.Args{
+ statediff.Args{
OldStateRoot: test_helpers.NullHash,
NewStateRoot: block0.Root(),
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
Nodes: emptyDiffs,
@@ -1042,28 +951,37 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
{
"testBlock1",
//10000 transferred from testBankAddress to account1Addr
- sd.Args{
+ statediff.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block1.Root(),
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block1BranchRootNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account1AtBlock1,
+ LeafKey: test_helpers.Account1LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock1LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block1BranchRootNode)).String(),
+ Content: block1BranchRootNode,
},
{
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock1LeafNode,
- StorageNodes: emptyStorage,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock1LeafNode)).String(),
+ Content: account1AtBlock1LeafNode,
},
},
},
@@ -1072,59 +990,82 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
"testBlock2",
//1000 transferred from testBankAddress to account1Addr
//1000 transferred from account1Addr to account2Addr
- sd.Args{
+ statediff.Args{
OldStateRoot: block1.Root(),
NewStateRoot: block2.Root(),
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block2BranchRootNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock2LeafNode,
- StorageNodes: []sdtypes.StorageNode{
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock2,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock2LeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block2StorageBranchRootNode,
+ Removed: false,
+ Value: slot0StorageValue,
+ LeafKey: slot0StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot0StorageLeafNode)).String(),
},
{
- Path: []byte{'\x02'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot0StorageKey.Bytes(),
- NodeValue: slot0StorageLeafNode,
- },
- {
- Path: []byte{'\x0b'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot1StorageKey.Bytes(),
- NodeValue: slot1StorageLeafNode,
+ Removed: false,
+ Value: slot1StorageValue,
+ LeafKey: slot1StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(),
},
},
},
{
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock2LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account1AtBlock2,
+ LeafKey: test_helpers.Account1LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock2LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
},
- CodeAndCodeHashes: []sdtypes.CodeAndCodeHash{
+ IPLDs: []types2.IPLD{
{
- Hash: test_helpers.CodeHash,
- Code: test_helpers.ByteCodeAfterDeployment,
+ CID: ipld2.Keccak256ToCid(ipld2.RawBinary, test_helpers.CodeHash.Bytes()).String(),
+ Content: test_helpers.ByteCodeAfterDeployment,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block2BranchRootNode)).String(),
+ Content: block2BranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock2LeafNode)).String(),
+ Content: contractAccountAtBlock2LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block2StorageBranchRootNode)).String(),
+ Content: block2StorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot0StorageLeafNode)).String(),
+ Content: slot0StorageLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(),
+ Content: slot1StorageLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock2LeafNode)).String(),
+ Content: account1AtBlock2LeafNode,
},
},
},
@@ -1133,68 +1074,98 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
"testBlock3",
//the contract's storage is changed
//and the block is mined by account 2
- sd.Args{
+ statediff.Args{
OldStateRoot: block2.Root(),
NewStateRoot: block3.Root(),
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block3BranchRootNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock3LeafNode,
- StorageNodes: []sdtypes.StorageNode{
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock3,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock3LeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block3StorageBranchRootNode,
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: slot3StorageLeafNode,
+ Removed: false,
+ Value: slot3StorageValue,
+ LeafKey: slot3StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot3StorageLeafNode)).String(),
},
},
},
},
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block3BranchRootNode)).String(),
+ Content: block3BranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock3LeafNode)).String(),
+ Content: contractAccountAtBlock3LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3StorageBranchRootNode)).String(),
+ Content: block3StorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot3StorageLeafNode)).String(),
+ Content: slot3StorageLeafNode,
+ },
+ },
},
},
}
- for _, workers := range workerCounts {
- builder, _ = pkg.NewBuilder(chain.StateCache(), workers)
- for _, test := range tests {
- diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
- if err != nil {
- t.Error(err)
- }
- receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
- if err != nil {
- t.Error(err)
- }
- expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
- if err != nil {
- t.Error(err)
- }
- sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
- sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
- if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
- t.Logf("Test failed: %s", test.name)
- t.Errorf("actual state diff: %+v\nexpected state diff: %+v", diff, test.expected)
- }
+ for _, test := range tests {
+ diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
+ if err != nil {
+ t.Error(err)
}
+ receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
+ if err != nil {
+ t.Error(err)
+ }
+ expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
+ sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
+ sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
+ if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
+ actual, err := json.Marshal(diff)
+ if err != nil {
+ t.Error(err)
+ }
+ expected, err := json.Marshal(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
+ t.Logf("Test failed: %s", test.name)
+ t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected)
+ }
+ }
+ // Let's also confirm that our root state nodes form the state root hash in the headers
+ if !bytes.Equal(block0.Root().Bytes(), crypto.Keccak256(bankAccountAtBlock0LeafNode)) {
+ t.Errorf("block0 expected root %x does not match actual root %x", block0.Root().Bytes(), crypto.Keccak256(bankAccountAtBlock0LeafNode))
+ }
+ if !bytes.Equal(block1.Root().Bytes(), crypto.Keccak256(block1BranchRootNode)) {
+ t.Errorf("block1 expected root %x does not match actual root %x", block1.Root().Bytes(), crypto.Keccak256(block1BranchRootNode))
+ }
+ if !bytes.Equal(block2.Root().Bytes(), crypto.Keccak256(block2BranchRootNode)) {
+ t.Errorf("block2 expected root %x does not match actual root %x", block2.Root().Bytes(), crypto.Keccak256(block2BranchRootNode))
+ }
+ if !bytes.Equal(block3.Root().Bytes(), crypto.Keccak256(block3BranchRootNode)) {
+ t.Errorf("block3 expected root %x does not match actual root %x", block3.Root().Bytes(), crypto.Keccak256(block3BranchRootNode))
}
}
@@ -1206,429 +1177,318 @@ func TestBuilderWithRemovedAccountAndStorage(t *testing.T) {
block4 = blocks[3]
block5 = blocks[4]
block6 = blocks[5]
- params := sd.Params{
- IntermediateStateNodes: true,
- IntermediateStorageNodes: true,
- }
+ params := statediff.Params{}
+ builder = statediff.NewBuilder(chain.StateCache())
var tests = []struct {
name string
- startingArguments sd.Args
- expected *sdtypes.StateObject
+ startingArguments statediff.Args
+ expected *types2.StateObject
}{
// blocks 0-3 are the same as in TestBuilderWithIntermediateNodes
{
"testBlock4",
- sd.Args{
+ statediff.Args{
OldStateRoot: block3.Root(),
NewStateRoot: block4.Root(),
BlockNumber: block4.Number(),
BlockHash: block4.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block4.Number(),
BlockHash: block4.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block4BranchRootNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: bankAccountAtBlock4,
+ LeafKey: test_helpers.BankLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock4LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
{
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock4LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock4LeafNode,
- StorageNodes: []sdtypes.StorageNode{
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock4,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock4LeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block4StorageBranchRootNode,
+ Removed: false,
+ Value: slot2StorageValue,
+ LeafKey: slot2StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot2StorageLeafNode)).String(),
},
{
- Path: []byte{'\x04'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot2StorageKey.Bytes(),
- NodeValue: slot2StorageLeafNode,
+ Removed: true,
+ LeafKey: slot1StorageKey.Bytes(),
+ CID: shared.RemovedNodeStorageCID,
+ Value: []byte{},
},
{
- Path: []byte{'\x0b'},
- NodeType: sdtypes.Removed,
- LeafKey: slot1StorageKey.Bytes(),
- NodeValue: []byte{},
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Removed,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: []byte{},
+ Removed: true,
+ LeafKey: slot3StorageKey.Bytes(),
+ CID: shared.RemovedNodeStorageCID,
+ Value: []byte{},
},
},
},
{
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account2LeafKey,
- NodeValue: account2AtBlock4LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account2AtBlock4,
+ LeafKey: test_helpers.Account2LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account2AtBlock4LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block4BranchRootNode)).String(),
+ Content: block4BranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock4LeafNode)).String(),
+ Content: bankAccountAtBlock4LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock4LeafNode)).String(),
+ Content: contractAccountAtBlock4LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block4StorageBranchRootNode)).String(),
+ Content: block4StorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot2StorageLeafNode)).String(),
+ Content: slot2StorageLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account2AtBlock4LeafNode)).String(),
+ Content: account2AtBlock4LeafNode,
},
},
},
},
{
"testBlock5",
- sd.Args{
+ statediff.Args{
OldStateRoot: block4.Root(),
NewStateRoot: block5.Root(),
BlockNumber: block5.Number(),
BlockHash: block5.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block5.Number(),
BlockHash: block5.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block5BranchRootNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: bankAccountAtBlock5,
+ LeafKey: test_helpers.BankLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock5LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
{
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock5LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock5LeafNode,
- StorageNodes: []sdtypes.StorageNode{
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock5,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock5LeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block5StorageBranchRootNode,
+ Removed: false,
+ Value: slot3StorageValue,
+ LeafKey: slot3StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot3StorageLeafNode)).String(),
},
{
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: slot3StorageLeafNode,
- },
- {
- Path: []byte{'\x04'},
- NodeType: sdtypes.Removed,
- LeafKey: slot2StorageKey.Bytes(),
- NodeValue: []byte{},
+ Removed: true,
+ LeafKey: slot2StorageKey.Bytes(),
+ CID: shared.RemovedNodeStorageCID,
+ Value: []byte{},
},
},
},
{
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock5LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account1AtBlock5,
+ LeafKey: test_helpers.Account1LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock5LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block5BranchRootNode)).String(),
+ Content: block5BranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock5LeafNode)).String(),
+ Content: bankAccountAtBlock5LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock5LeafNode)).String(),
+ Content: contractAccountAtBlock5LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block5StorageBranchRootNode)).String(),
+ Content: block5StorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot3StorageLeafNode)).String(),
+ Content: slot3StorageLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock5LeafNode)).String(),
+ Content: account1AtBlock5LeafNode,
},
},
},
},
{
"testBlock6",
- sd.Args{
+ statediff.Args{
OldStateRoot: block5.Root(),
NewStateRoot: block6.Root(),
BlockNumber: block6.Number(),
BlockHash: block6.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block6.Number(),
BlockHash: block6.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block6BranchRootNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Removed,
- LeafKey: contractLeafKey,
- NodeValue: []byte{},
- StorageNodes: []sdtypes.StorageNode{
+ Removed: true,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: nil,
+ LeafKey: contractLeafKey,
+ CID: shared.RemovedNodeStateCID},
+ StorageDiff: []types2.StorageLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Removed,
- NodeValue: []byte{},
+ Removed: true,
+ LeafKey: slot0StorageKey.Bytes(),
+ CID: shared.RemovedNodeStorageCID,
+ Value: []byte{},
},
{
- Path: []byte{'\x02'},
- NodeType: sdtypes.Removed,
- LeafKey: slot0StorageKey.Bytes(),
- NodeValue: []byte{},
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Removed,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: []byte{},
+ Removed: true,
+ LeafKey: slot3StorageKey.Bytes(),
+ CID: shared.RemovedNodeStorageCID,
+ Value: []byte{},
},
},
},
{
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account2LeafKey,
- NodeValue: account2AtBlock6LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account2AtBlock6,
+ LeafKey: test_helpers.Account2LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account2AtBlock6LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
{
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock6LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account1AtBlock6,
+ LeafKey: test_helpers.Account1LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock6LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block6BranchRootNode)).String(),
+ Content: block6BranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account2AtBlock6LeafNode)).String(),
+ Content: account2AtBlock6LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock6LeafNode)).String(),
+ Content: account1AtBlock6LeafNode,
},
},
},
},
}
- for _, workers := range workerCounts {
- builder, _ = pkg.NewBuilder(chain.StateCache(), workers)
- for index, test := range tests {
- if index != 1 {
- continue
- }
- diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
+ for _, test := range tests {
+ diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
+ if err != nil {
+ t.Error(err)
+ }
+ receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
+ if err != nil {
+ t.Error(err)
+ }
+ expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
+ sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
+ sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
+ if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
+ actual, err := json.Marshal(diff)
if err != nil {
t.Error(err)
}
- receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
+ expected, err := json.Marshal(test.expected)
if err != nil {
t.Error(err)
}
- expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
- if err != nil {
- t.Error(err)
- }
- sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
- sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
- if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
- t.Logf("Test failed: %s", test.name)
- t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected)
- }
+ t.Logf("Test failed: %s", test.name)
+ t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected)
}
}
-}
-
-func TestBuilderWithRemovedAccountAndStorageWithoutIntermediateNodes(t *testing.T) {
- blocks, chain := test_helpers.MakeChain(6, test_helpers.Genesis, test_helpers.TestChainGen)
- contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr)
- defer chain.Stop()
- block3 = blocks[2]
- block4 = blocks[3]
- block5 = blocks[4]
- block6 = blocks[5]
- params := sd.Params{
- IntermediateStateNodes: false,
- IntermediateStorageNodes: false,
+ // Let's also confirm that our root state nodes form the state root hash in the headers
+ if !bytes.Equal(block4.Root().Bytes(), crypto.Keccak256(block4BranchRootNode)) {
+ t.Errorf("block4 expected root %x does not match actual root %x", block4.Root().Bytes(), crypto.Keccak256(block4BranchRootNode))
}
-
- var tests = []struct {
- name string
- startingArguments sd.Args
- expected *sdtypes.StateObject
- }{
- // blocks 0-3 are the same as in TestBuilderWithIntermediateNodes
- {
- "testBlock4",
- sd.Args{
- OldStateRoot: block3.Root(),
- NewStateRoot: block4.Root(),
- BlockNumber: block4.Number(),
- BlockHash: block4.Hash(),
- },
- &sdtypes.StateObject{
- BlockNumber: block4.Number(),
- BlockHash: block4.Hash(),
- Nodes: []sdtypes.StateNode{
- {
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock4LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock4LeafNode,
- StorageNodes: []sdtypes.StorageNode{
- {
- Path: []byte{'\x04'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot2StorageKey.Bytes(),
- NodeValue: slot2StorageLeafNode,
- },
- {
- Path: []byte{'\x0b'},
- NodeType: sdtypes.Removed,
- LeafKey: slot1StorageKey.Bytes(),
- NodeValue: []byte{},
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Removed,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: []byte{},
- },
- },
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account2LeafKey,
- NodeValue: account2AtBlock4LeafNode,
- StorageNodes: emptyStorage,
- },
- },
- },
- },
- {
- "testBlock5",
- sd.Args{
- OldStateRoot: block4.Root(),
- NewStateRoot: block5.Root(),
- BlockNumber: block5.Number(),
- BlockHash: block5.Hash(),
- },
- &sdtypes.StateObject{
- BlockNumber: block5.Number(),
- BlockHash: block5.Hash(),
- Nodes: []sdtypes.StateNode{
- {
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock5LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock5LeafNode,
- StorageNodes: []sdtypes.StorageNode{
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: slot3StorageLeafNode,
- },
- {
- Path: []byte{'\x04'},
- NodeType: sdtypes.Removed,
- LeafKey: slot2StorageKey.Bytes(),
- NodeValue: []byte{},
- },
- },
- },
- {
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock5LeafNode,
- StorageNodes: emptyStorage,
- },
- },
- },
- },
- {
- "testBlock6",
- sd.Args{
- OldStateRoot: block5.Root(),
- NewStateRoot: block6.Root(),
- BlockNumber: block6.Number(),
- BlockHash: block6.Hash(),
- },
- &sdtypes.StateObject{
- BlockNumber: block6.Number(),
- BlockHash: block6.Hash(),
- Nodes: []sdtypes.StateNode{
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Removed,
- LeafKey: contractLeafKey,
- NodeValue: []byte{},
- StorageNodes: []sdtypes.StorageNode{
- {
- Path: []byte{'\x02'},
- NodeType: sdtypes.Removed,
- LeafKey: slot0StorageKey.Bytes(),
- NodeValue: []byte{},
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Removed,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: []byte{},
- },
- },
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account2LeafKey,
- NodeValue: account2AtBlock6LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock6LeafNode,
- StorageNodes: emptyStorage,
- },
- },
- },
- },
+ if !bytes.Equal(block5.Root().Bytes(), crypto.Keccak256(block5BranchRootNode)) {
+ t.Errorf("block5 expected root %x does not match actual root %x", block5.Root().Bytes(), crypto.Keccak256(block5BranchRootNode))
}
-
- for _, workers := range workerCounts {
- builder, _ = pkg.NewBuilder(chain.StateCache(), workers)
- for _, test := range tests {
- diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
- if err != nil {
- t.Error(err)
- }
- receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
- if err != nil {
- t.Error(err)
- }
- expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
- if err != nil {
- t.Error(err)
- }
- sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
- sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
- if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
- t.Logf("Test failed: %s", test.name)
- t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected)
- }
- }
+ if !bytes.Equal(block6.Root().Bytes(), crypto.Keccak256(block6BranchRootNode)) {
+ t.Errorf("block6 expected root %x does not match actual root %x", block6.Root().Bytes(), crypto.Keccak256(block6BranchRootNode))
}
}
@@ -1640,133 +1500,185 @@ func TestBuilderWithRemovedNonWatchedAccount(t *testing.T) {
block4 = blocks[3]
block5 = blocks[4]
block6 = blocks[5]
- params := sd.Params{
- IntermediateStateNodes: true,
- IntermediateStorageNodes: true,
- WatchedAddresses: []common.Address{test_helpers.Account1Addr, test_helpers.Account2Addr},
+ params := statediff.Params{
+ WatchedAddresses: []common.Address{test_helpers.Account1Addr, test_helpers.Account2Addr},
}
params.ComputeWatchedAddressesLeafPaths()
+ builder = statediff.NewBuilder(chain.StateCache())
var tests = []struct {
name string
- startingArguments sd.Args
- expected *sdtypes.StateObject
+ startingArguments statediff.Args
+ expected *types2.StateObject
}{
{
"testBlock4",
- sd.Args{
+ statediff.Args{
OldStateRoot: block3.Root(),
NewStateRoot: block4.Root(),
BlockNumber: block4.Number(),
BlockHash: block4.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block4.Number(),
BlockHash: block4.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block4BranchRootNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account2AtBlock4,
+ LeafKey: test_helpers.Account2LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account2AtBlock4LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block4BranchRootNode)).String(),
+ Content: block4BranchRootNode,
},
{
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account2LeafKey,
- NodeValue: account2AtBlock4LeafNode,
- StorageNodes: emptyStorage,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account2AtBlock4LeafNode)).String(),
+ Content: account2AtBlock4LeafNode,
},
},
},
},
{
"testBlock5",
- sd.Args{
+ statediff.Args{
OldStateRoot: block4.Root(),
NewStateRoot: block5.Root(),
BlockNumber: block5.Number(),
BlockHash: block5.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block5.Number(),
BlockHash: block5.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block5BranchRootNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account1AtBlock5,
+ LeafKey: test_helpers.Account1LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock5LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block5BranchRootNode)).String(),
+ Content: block5BranchRootNode,
},
{
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock5LeafNode,
- StorageNodes: emptyStorage,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock5LeafNode)).String(),
+ Content: account1AtBlock5LeafNode,
},
},
},
},
{
"testBlock6",
- sd.Args{
+ statediff.Args{
OldStateRoot: block5.Root(),
NewStateRoot: block6.Root(),
BlockNumber: block6.Number(),
BlockHash: block6.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block6.Number(),
BlockHash: block6.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block6BranchRootNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account2AtBlock6,
+ LeafKey: test_helpers.Account2LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account2AtBlock6LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
{
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account2LeafKey,
- NodeValue: account2AtBlock6LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account1AtBlock6,
+ LeafKey: test_helpers.Account1LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock6LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block6BranchRootNode)).String(),
+ Content: block6BranchRootNode,
},
{
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock6LeafNode,
- StorageNodes: emptyStorage,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account2AtBlock6LeafNode)).String(),
+ Content: account2AtBlock6LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock6LeafNode)).String(),
+ Content: account1AtBlock6LeafNode,
},
},
},
},
}
- for _, workers := range workerCounts {
- builder, _ = pkg.NewBuilder(chain.StateCache(), workers)
- for _, test := range tests {
- diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
- if err != nil {
- t.Error(err)
- }
- receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
- if err != nil {
- t.Error(err)
- }
- expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
- if err != nil {
- t.Error(err)
- }
- sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
- sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
- if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
- t.Logf("Test failed: %s", test.name)
- t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected)
- }
+ for _, test := range tests {
+ diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
+ if err != nil {
+ t.Error(err)
}
+ receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
+ if err != nil {
+ t.Error(err)
+ }
+
+ expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
+
+ sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
+ sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
+ if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
+ actual, err := json.Marshal(diff)
+ if err != nil {
+ t.Error(err)
+ }
+ expected, err := json.Marshal(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
+ t.Logf("Test failed: %s", test.name)
+ t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected)
+ }
+ }
+ // Let's also confirm that our root state nodes form the state root hash in the headers
+ if !bytes.Equal(block4.Root().Bytes(), crypto.Keccak256(block4BranchRootNode)) {
+ t.Errorf("block4 expected root %x does not match actual root %x", block4.Root().Bytes(), crypto.Keccak256(block4BranchRootNode))
+ }
+ if !bytes.Equal(block5.Root().Bytes(), crypto.Keccak256(block5BranchRootNode)) {
+ t.Errorf("block5 expected root %x does not match actual root %x", block5.Root().Bytes(), crypto.Keccak256(block5BranchRootNode))
+ }
+ if !bytes.Equal(block6.Root().Bytes(), crypto.Keccak256(block6BranchRootNode)) {
+ t.Errorf("block6 expected root %x does not match actual root %x", block6.Root().Bytes(), crypto.Keccak256(block6BranchRootNode))
}
}
@@ -1778,200 +1690,258 @@ func TestBuilderWithRemovedWatchedAccount(t *testing.T) {
block4 = blocks[3]
block5 = blocks[4]
block6 = blocks[5]
- params := sd.Params{
- IntermediateStateNodes: true,
- IntermediateStorageNodes: true,
- WatchedAddresses: []common.Address{test_helpers.Account1Addr, test_helpers.ContractAddr},
+ params := statediff.Params{
+ WatchedAddresses: []common.Address{test_helpers.Account1Addr, test_helpers.ContractAddr},
}
params.ComputeWatchedAddressesLeafPaths()
+ builder = statediff.NewBuilder(chain.StateCache())
var tests = []struct {
name string
- startingArguments sd.Args
- expected *sdtypes.StateObject
+ startingArguments statediff.Args
+ expected *types2.StateObject
}{
{
"testBlock4",
- sd.Args{
+ statediff.Args{
OldStateRoot: block3.Root(),
NewStateRoot: block4.Root(),
BlockNumber: block4.Number(),
BlockHash: block4.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block4.Number(),
BlockHash: block4.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block4BranchRootNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock4LeafNode,
- StorageNodes: []sdtypes.StorageNode{
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock4,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock4LeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block4StorageBranchRootNode,
+ Removed: false,
+ LeafKey: slot2StorageKey.Bytes(),
+ Value: slot2StorageValue,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot2StorageLeafNode)).String(),
},
{
- Path: []byte{'\x04'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot2StorageKey.Bytes(),
- NodeValue: slot2StorageLeafNode,
+ Removed: true,
+ LeafKey: slot1StorageKey.Bytes(),
+ CID: shared.RemovedNodeStorageCID,
+ Value: []byte{},
},
{
- Path: []byte{'\x0b'},
- NodeType: sdtypes.Removed,
- LeafKey: slot1StorageKey.Bytes(),
- NodeValue: []byte{},
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Removed,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: []byte{},
+ Removed: true,
+ LeafKey: slot3StorageKey.Bytes(),
+ CID: shared.RemovedNodeStorageCID,
+ Value: []byte{},
},
},
},
},
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block4BranchRootNode)).String(),
+ Content: block4BranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock4LeafNode)).String(),
+ Content: contractAccountAtBlock4LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block4StorageBranchRootNode)).String(),
+ Content: block4StorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot2StorageLeafNode)).String(),
+ Content: slot2StorageLeafNode,
+ },
+ },
},
},
{
"testBlock5",
- sd.Args{
+ statediff.Args{
OldStateRoot: block4.Root(),
NewStateRoot: block5.Root(),
BlockNumber: block5.Number(),
BlockHash: block5.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block5.Number(),
BlockHash: block5.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block5BranchRootNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock5LeafNode,
- StorageNodes: []sdtypes.StorageNode{
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock5,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock5LeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block5StorageBranchRootNode,
+ Removed: false,
+ LeafKey: slot3StorageKey.Bytes(),
+ Value: slot3StorageValue,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot3StorageLeafNode)).String(),
},
{
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: slot3StorageLeafNode,
- },
- {
- Path: []byte{'\x04'},
- NodeType: sdtypes.Removed,
- LeafKey: slot2StorageKey.Bytes(),
- NodeValue: []byte{},
+ Removed: true,
+ LeafKey: slot2StorageKey.Bytes(),
+ CID: shared.RemovedNodeStorageCID,
+ Value: []byte{},
},
},
},
{
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock5LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account1AtBlock5,
+ LeafKey: test_helpers.Account1LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock5LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block5BranchRootNode)).String(),
+ Content: block5BranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock5LeafNode)).String(),
+ Content: contractAccountAtBlock5LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block5StorageBranchRootNode)).String(),
+ Content: block5StorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot3StorageLeafNode)).String(),
+ Content: slot3StorageLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock5LeafNode)).String(),
+ Content: account1AtBlock5LeafNode,
},
},
},
},
{
"testBlock6",
- sd.Args{
+ statediff.Args{
OldStateRoot: block5.Root(),
NewStateRoot: block6.Root(),
BlockNumber: block6.Number(),
BlockHash: block6.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block6.Number(),
BlockHash: block6.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block6BranchRootNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Removed,
- LeafKey: contractLeafKey,
- NodeValue: []byte{},
- StorageNodes: []sdtypes.StorageNode{
+ Removed: true,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: nil,
+ LeafKey: contractLeafKey,
+ CID: shared.RemovedNodeStateCID},
+ StorageDiff: []types2.StorageLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Removed,
- NodeValue: []byte{},
+ Removed: true,
+ LeafKey: slot0StorageKey.Bytes(),
+ CID: shared.RemovedNodeStorageCID,
+ Value: []byte{},
},
{
- Path: []byte{'\x02'},
- NodeType: sdtypes.Removed,
- LeafKey: slot0StorageKey.Bytes(),
- NodeValue: []byte{},
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Removed,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: []byte{},
+ Removed: true,
+ LeafKey: slot3StorageKey.Bytes(),
+ CID: shared.RemovedNodeStorageCID,
+ Value: []byte{},
},
},
},
{
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock6LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account1AtBlock6,
+ LeafKey: test_helpers.Account1LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock6LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block6BranchRootNode)).String(),
+ Content: block6BranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock6LeafNode)).String(),
+ Content: account1AtBlock6LeafNode,
},
},
},
},
}
- for _, workers := range workerCounts {
- builder, _ = pkg.NewBuilder(chain.StateCache(), workers)
- for _, test := range tests {
- diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
- if err != nil {
- t.Error(err)
- }
- receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
- if err != nil {
- t.Error(err)
- }
- expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
- if err != nil {
- t.Error(err)
- }
- sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
- sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
- if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
- t.Logf("Test failed: %s", test.name)
- t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected)
- }
+ for _, test := range tests {
+ diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
+ if err != nil {
+ t.Error(err)
}
+ receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
+ if err != nil {
+ t.Error(err)
+ }
+
+ expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
+
+ sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
+ sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
+ if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
+ actual, err := json.Marshal(diff)
+ if err != nil {
+ t.Error(err)
+ }
+ expected, err := json.Marshal(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
+ t.Logf("Test failed: %s", test.name)
+ t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected)
+ }
+ }
+ // Let's also confirm that our root state nodes form the state root hash in the headers
+ if !bytes.Equal(block4.Root().Bytes(), crypto.Keccak256(block4BranchRootNode)) {
+ t.Errorf("block4 expected root %x does not match actual root %x", block4.Root().Bytes(), crypto.Keccak256(block4BranchRootNode))
+ }
+ if !bytes.Equal(block5.Root().Bytes(), crypto.Keccak256(block5BranchRootNode)) {
+ t.Errorf("block5 expected root %x does not match actual root %x", block5.Root().Bytes(), crypto.Keccak256(block5BranchRootNode))
+ }
+ if !bytes.Equal(block6.Root().Bytes(), crypto.Keccak256(block6BranchRootNode)) {
+ t.Errorf("block6 expected root %x does not match actual root %x", block6.Root().Bytes(), crypto.Keccak256(block6BranchRootNode))
}
}
@@ -1983,36 +1953,39 @@ var (
slot00StorageValue,
})
- contractAccountAtBlock01, _ = rlp.EncodeToBytes(&types.StateAccount{
+ contractAccountAtBlock01 = &types.StateAccount{
Nonce: 1,
Balance: big.NewInt(0),
CodeHash: common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127").Bytes(),
Root: crypto.Keccak256Hash(block01StorageBranchRootNode),
- })
+ }
+ contractAccountAtBlock01RLP, _ = rlp.EncodeToBytes(contractAccountAtBlock01)
contractAccountAtBlock01LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("3cb2583748c26e89ef19c2a8529b05a270f735553b4d44b6f2a1894987a71c8b"),
- contractAccountAtBlock01,
+ contractAccountAtBlock01RLP,
})
- bankAccountAtBlock01, _ = rlp.EncodeToBytes(&types.StateAccount{
+ bankAccountAtBlock01 = &types.StateAccount{
Nonce: 1,
Balance: big.NewInt(3999629697375000000),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ bankAccountAtBlock01RLP, _ = rlp.EncodeToBytes(bankAccountAtBlock01)
bankAccountAtBlock01LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"),
- bankAccountAtBlock01,
+ bankAccountAtBlock01RLP,
})
- bankAccountAtBlock02, _ = rlp.EncodeToBytes(&types.StateAccount{
+ bankAccountAtBlock02 = &types.StateAccount{
Nonce: 2,
Balance: big.NewInt(5999607323457344852),
CodeHash: test_helpers.NullCodeHash.Bytes(),
Root: test_helpers.EmptyContractRoot,
- })
+ }
+ bankAccountAtBlock02RLP, _ = rlp.EncodeToBytes(bankAccountAtBlock02)
bankAccountAtBlock02LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
common.Hex2Bytes("2000bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"),
- bankAccountAtBlock02,
+ bankAccountAtBlock02RLP,
})
block01BranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{
@@ -2063,490 +2036,150 @@ func TestBuilderWithMovedAccount(t *testing.T) {
block0 = test_helpers.Genesis
block1 = blocks[0]
block2 = blocks[1]
- params := sd.Params{
- IntermediateStateNodes: true,
- IntermediateStorageNodes: true,
- }
+ params := statediff.Params{}
+ builder = statediff.NewBuilder(chain.StateCache())
var tests = []struct {
name string
- startingArguments sd.Args
- expected *sdtypes.StateObject
+ startingArguments statediff.Args
+ expected *types2.StateObject
}{
{
"testBlock1",
- sd.Args{
+ statediff.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block1.Root(),
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block01BranchRootNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: bankAccountAtBlock01,
+ LeafKey: test_helpers.BankLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock01LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
{
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock01LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x01'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock01LeafNode,
- StorageNodes: []sdtypes.StorageNode{
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock01,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock01LeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block01StorageBranchRootNode,
+ Removed: false,
+ LeafKey: slot0StorageKey.Bytes(),
+ Value: slot00StorageValue,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot00StorageLeafNode)).String(),
},
{
- Path: []byte{'\x02'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot0StorageKey.Bytes(),
- NodeValue: slot00StorageLeafNode,
- },
- {
- Path: []byte{'\x0b'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot1StorageKey.Bytes(),
- NodeValue: slot1StorageLeafNode,
+ Removed: false,
+ LeafKey: slot1StorageKey.Bytes(),
+ Value: slot1StorageValue,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(),
},
},
},
},
- CodeAndCodeHashes: []sdtypes.CodeAndCodeHash{
+ IPLDs: []types2.IPLD{
{
- Hash: test_helpers.CodeHash,
- Code: test_helpers.ByteCodeAfterDeployment,
+ CID: ipld2.Keccak256ToCid(ipld2.RawBinary, test_helpers.CodeHash.Bytes()).String(),
+ Content: test_helpers.ByteCodeAfterDeployment,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block01BranchRootNode)).String(),
+ Content: block01BranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock01LeafNode)).String(),
+ Content: bankAccountAtBlock01LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock01LeafNode)).String(),
+ Content: contractAccountAtBlock01LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block01StorageBranchRootNode)).String(),
+ Content: block01StorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot00StorageLeafNode)).String(),
+ Content: slot00StorageLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(),
+ Content: slot1StorageLeafNode,
},
},
},
},
{
"testBlock2",
- sd.Args{
+ statediff.Args{
OldStateRoot: block1.Root(),
NewStateRoot: block2.Root(),
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
},
- &sdtypes.StateObject{
+ &types2.StateObject{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
- Nodes: []sdtypes.StateNode{
+ Nodes: []types2.StateLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock02LeafNode,
- StorageNodes: emptyStorage,
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: bankAccountAtBlock02,
+ LeafKey: test_helpers.BankLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock02LeafNode)).String()},
+ StorageDiff: emptyStorage,
},
{
- Path: []byte{'\x01'},
- NodeType: sdtypes.Removed,
- LeafKey: contractLeafKey,
- NodeValue: []byte{},
- StorageNodes: []sdtypes.StorageNode{
+ Removed: true,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: nil,
+ LeafKey: contractLeafKey,
+ CID: shared.RemovedNodeStateCID},
+ StorageDiff: []types2.StorageLeafNode{
{
- Path: []byte{},
- NodeType: sdtypes.Removed,
+ Removed: true,
+ LeafKey: slot0StorageKey.Bytes(),
+ CID: shared.RemovedNodeStorageCID,
+ Value: []byte{},
},
{
- Path: []byte{'\x02'},
- NodeType: sdtypes.Removed,
- LeafKey: slot0StorageKey.Bytes(),
- },
- {
- Path: []byte{'\x0b'},
- NodeType: sdtypes.Removed,
- LeafKey: slot1StorageKey.Bytes(),
- },
- },
- },
- {
- Path: []byte{'\x00'},
- NodeType: sdtypes.Removed,
- NodeValue: []byte{},
- },
- },
- },
- },
- }
-
- for _, workers := range workerCounts {
- builder, _ = pkg.NewBuilder(chain.StateCache(), workers)
- for _, test := range tests {
- diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
- if err != nil {
- t.Error(err)
- }
- receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
- if err != nil {
- t.Error(err)
- }
- expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
- if err != nil {
- t.Error(err)
- }
- sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
- sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
- if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
- t.Logf("Test failed: %s", test.name)
- t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected)
- }
- }
- }
-}
-
-func TestBuilderWithMovedAccountOnlyLeafs(t *testing.T) {
- blocks, chain := test_helpers.MakeChain(2, test_helpers.Genesis, test_helpers.TestSelfDestructChainGen)
- contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr)
- defer chain.Stop()
- block0 = test_helpers.Genesis
- block1 = blocks[0]
- block2 = blocks[1]
- params := sd.Params{
- IntermediateStateNodes: false,
- IntermediateStorageNodes: false,
- }
-
- var tests = []struct {
- name string
- startingArguments sd.Args
- expected *sdtypes.StateObject
- }{
- {
- "testBlock1",
- sd.Args{
- OldStateRoot: block0.Root(),
- NewStateRoot: block1.Root(),
- BlockNumber: block1.Number(),
- BlockHash: block1.Hash(),
- },
- &sdtypes.StateObject{
- BlockNumber: block1.Number(),
- BlockHash: block1.Hash(),
- Nodes: []sdtypes.StateNode{
- {
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock01LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x01'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock01LeafNode,
- StorageNodes: []sdtypes.StorageNode{
- {
- Path: []byte{'\x02'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot0StorageKey.Bytes(),
- NodeValue: slot00StorageLeafNode,
- },
- {
- Path: []byte{'\x0b'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot1StorageKey.Bytes(),
- NodeValue: slot1StorageLeafNode,
+ Removed: true,
+ LeafKey: slot1StorageKey.Bytes(),
+ CID: shared.RemovedNodeStorageCID,
+ Value: []byte{},
},
},
},
},
- CodeAndCodeHashes: []sdtypes.CodeAndCodeHash{
+ IPLDs: []types2.IPLD{
{
- Hash: test_helpers.CodeHash,
- Code: test_helpers.ByteCodeAfterDeployment,
- },
- },
- },
- },
- {
- "testBlock2",
- sd.Args{
- OldStateRoot: block1.Root(),
- NewStateRoot: block2.Root(),
- BlockNumber: block2.Number(),
- BlockHash: block2.Hash(),
- },
- &sdtypes.StateObject{
- BlockNumber: block2.Number(),
- BlockHash: block2.Hash(),
- Nodes: []sdtypes.StateNode{
- {
- Path: []byte{},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock02LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x01'},
- NodeType: sdtypes.Removed,
- LeafKey: contractLeafKey,
- NodeValue: []byte{},
- StorageNodes: []sdtypes.StorageNode{
- {
- Path: []byte{'\x02'},
- NodeType: sdtypes.Removed,
- LeafKey: slot0StorageKey.Bytes(),
- },
- {
- Path: []byte{'\x0b'},
- NodeType: sdtypes.Removed,
- LeafKey: slot1StorageKey.Bytes(),
- },
- },
- },
- {
- Path: []byte{'\x00'},
- NodeType: sdtypes.Removed,
- NodeValue: []byte{},
- },
- },
- },
- },
- }
-
- for _, workers := range workerCounts {
- builder, _ = pkg.NewBuilder(chain.StateCache(), workers)
- for _, test := range tests {
- diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
- if err != nil {
- t.Error(err)
- }
- receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
- if err != nil {
- t.Error(err)
- }
- expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
- if err != nil {
- t.Error(err)
- }
- sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
- sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
- if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
- t.Logf("Test failed: %s", test.name)
- t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected)
- }
- }
- }
-}
-
-func TestBuildStateTrie(t *testing.T) {
- blocks, chain := test_helpers.MakeChain(3, test_helpers.Genesis, test_helpers.TestChainGen)
- contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr)
- defer chain.Stop()
- block1 = blocks[0]
- block2 = blocks[1]
- block3 = blocks[2]
-
- var tests = []struct {
- name string
- block *types.Block
- expected *sdtypes.StateObject
- }{
- {
- "testBlock1",
- block1,
- &sdtypes.StateObject{
- BlockNumber: block1.Number(),
- BlockHash: block1.Hash(),
- Nodes: []sdtypes.StateNode{
- {
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block1BranchRootNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock1LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x05'},
- NodeType: sdtypes.Leaf,
- LeafKey: minerLeafKey,
- NodeValue: minerAccountAtBlock1LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock1LeafNode,
- StorageNodes: emptyStorage,
- },
- },
- },
- },
- {
- "testBlock2",
- block2,
- &sdtypes.StateObject{
- BlockNumber: block2.Number(),
- BlockHash: block2.Hash(),
- Nodes: []sdtypes.StateNode{
- {
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block2BranchRootNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock2LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x05'},
- NodeType: sdtypes.Leaf,
- LeafKey: minerLeafKey,
- NodeValue: minerAccountAtBlock2LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock2LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock2LeafNode,
- StorageNodes: []sdtypes.StorageNode{
- {
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block2StorageBranchRootNode,
- },
- {
- Path: []byte{'\x02'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot0StorageKey.Bytes(),
- NodeValue: slot0StorageLeafNode,
- },
- {
- Path: []byte{'\x0b'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot1StorageKey.Bytes(),
- NodeValue: slot1StorageLeafNode,
- },
- },
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account2LeafKey,
- NodeValue: account2AtBlock2LeafNode,
- StorageNodes: emptyStorage,
- },
- },
- CodeAndCodeHashes: []sdtypes.CodeAndCodeHash{
- {
- Hash: test_helpers.CodeHash,
- Code: test_helpers.ByteCodeAfterDeployment,
- },
- },
- },
- },
- {
- "testBlock3",
- block3,
- &sdtypes.StateObject{
- BlockNumber: block3.Number(),
- BlockHash: block3.Hash(),
- Nodes: []sdtypes.StateNode{
- {
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block3BranchRootNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x00'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.BankLeafKey,
- NodeValue: bankAccountAtBlock3LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x05'},
- NodeType: sdtypes.Leaf,
- LeafKey: minerLeafKey,
- NodeValue: minerAccountAtBlock2LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x0e'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account1LeafKey,
- NodeValue: account1AtBlock2LeafNode,
- StorageNodes: emptyStorage,
- },
- {
- Path: []byte{'\x06'},
- NodeType: sdtypes.Leaf,
- LeafKey: contractLeafKey,
- NodeValue: contractAccountAtBlock3LeafNode,
- StorageNodes: []sdtypes.StorageNode{
- {
- Path: []byte{},
- NodeType: sdtypes.Branch,
- NodeValue: block3StorageBranchRootNode,
- },
- {
- Path: []byte{'\x02'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot0StorageKey.Bytes(),
- NodeValue: slot0StorageLeafNode,
- },
- {
- Path: []byte{'\x0b'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot1StorageKey.Bytes(),
- NodeValue: slot1StorageLeafNode,
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: slot3StorageKey.Bytes(),
- NodeValue: slot3StorageLeafNode,
- },
- },
- },
- {
- Path: []byte{'\x0c'},
- NodeType: sdtypes.Leaf,
- LeafKey: test_helpers.Account2LeafKey,
- NodeValue: account2AtBlock3LeafNode,
- StorageNodes: emptyStorage,
- },
- },
- CodeAndCodeHashes: []sdtypes.CodeAndCodeHash{
- {
- Hash: test_helpers.CodeHash,
- Code: test_helpers.ByteCodeAfterDeployment,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock02LeafNode)).String(),
+ Content: bankAccountAtBlock02LeafNode,
},
},
},
@@ -2554,25 +2187,41 @@ func TestBuildStateTrie(t *testing.T) {
}
for _, test := range tests {
- diff, err := builder.BuildStateTrieObject(test.block)
+ diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
if err != nil {
t.Error(err)
}
- receivedStateTrieRlp, err := rlp.EncodeToBytes(&diff)
+ receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
if err != nil {
t.Error(err)
}
- expectedStateTrieRlp, err := rlp.EncodeToBytes(test.expected)
+ expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
if err != nil {
t.Error(err)
}
- sort.Slice(receivedStateTrieRlp, func(i, j int) bool { return receivedStateTrieRlp[i] < receivedStateTrieRlp[j] })
- sort.Slice(expectedStateTrieRlp, func(i, j int) bool { return expectedStateTrieRlp[i] < expectedStateTrieRlp[j] })
- if !bytes.Equal(receivedStateTrieRlp, expectedStateTrieRlp) {
+
+ sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
+ sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
+ if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
+ actual, err := json.Marshal(diff)
+ if err != nil {
+ t.Error(err)
+ }
+ expected, err := json.Marshal(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
t.Logf("Test failed: %s", test.name)
- t.Errorf("actual state trie: %+v\r\n\r\n\r\nexpected state trie: %+v", diff, test.expected)
+ t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected)
}
}
+ // Let's also confirm that our root state nodes form the state root hash in the headers
+ if !bytes.Equal(block1.Root().Bytes(), crypto.Keccak256(block01BranchRootNode)) {
+ t.Errorf("block01 expected root %x does not match actual root %x", block1.Root().Bytes(), crypto.Keccak256(block01BranchRootNode))
+ }
+ if !bytes.Equal(block2.Root().Bytes(), crypto.Keccak256(bankAccountAtBlock02LeafNode)) {
+ t.Errorf("block02 expected root %x does not match actual root %x", block2.Root().Bytes(), crypto.Keccak256(bankAccountAtBlock02LeafNode))
+ }
}
/*
@@ -2605,3 +2254,853 @@ contract test {
}
}
*/
+
+var (
+ b = big.NewInt(0).Sub(test_helpers.TestBIGBankFunds, test_helpers.BalanceChangeBIG)
+ block1BankBigBalance = big.NewInt(0).Sub(b, big.NewInt(test_helpers.GasFees2))
+ bankAccountAtBlock1b = &types.StateAccount{
+ Nonce: 1,
+ Balance: block1BankBigBalance,
+ CodeHash: test_helpers.NullCodeHash.Bytes(),
+ Root: test_helpers.EmptyContractRoot,
+ }
+ bankAccountAtBlock1bRLP, _ = rlp.EncodeToBytes(bankAccountAtBlock1b)
+ bankAccountAtBlock1bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
+ common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"),
+ bankAccountAtBlock1bRLP,
+ })
+
+ account1AtBlock1b = &types.StateAccount{
+ Nonce: 0,
+ Balance: test_helpers.Block1bAccount1Balance,
+ CodeHash: test_helpers.NullCodeHash.Bytes(),
+ Root: test_helpers.EmptyContractRoot,
+ }
+ account1AtBlock1bRLP, _ = rlp.EncodeToBytes(account1AtBlock1b)
+ account1AtBlock1bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
+ common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"),
+ account1AtBlock1bRLP,
+ })
+
+ account1AtBlock2bBalance, _ = big.NewInt(0).SetString("1999999999999999999999999761539571000000000", 10)
+ account1AtBlock2b = &types.StateAccount{
+ Nonce: 1,
+ Balance: account1AtBlock2bBalance,
+ CodeHash: test_helpers.NullCodeHash.Bytes(),
+ Root: test_helpers.EmptyContractRoot,
+ }
+ account1AtBlock2bRLP, _ = rlp.EncodeToBytes(account1AtBlock2b)
+ account1AtBlock2bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
+ common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"),
+ account1AtBlock2bRLP,
+ })
+
+ minerAccountAtBlock2b = &types.StateAccount{
+ Nonce: 0,
+ Balance: big.NewInt(4055891787808414571),
+ CodeHash: test_helpers.NullCodeHash.Bytes(),
+ Root: test_helpers.EmptyContractRoot,
+ }
+ minerAccountAtBlock2bRLP, _ = rlp.EncodeToBytes(minerAccountAtBlock2b)
+ minerAccountAtBlock2bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
+ common.Hex2Bytes("3380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"),
+ minerAccountAtBlock2bRLP,
+ })
+
+ contractAccountAtBlock2b = &types.StateAccount{
+ Nonce: 1,
+ Balance: big.NewInt(0),
+ CodeHash: test_helpers.CodeHashForInternalizedLeafNode.Bytes(),
+ Root: crypto.Keccak256Hash(block2StorageBranchRootNode),
+ }
+ contractAccountAtBlock2bRLP, _ = rlp.EncodeToBytes(contractAccountAtBlock2b)
+ contractAccountAtBlock2bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
+ common.Hex2Bytes("3d7e14f1723fa19b5d6d9f8b86b49acefbc9c400bf4ed686c10d6b6467fc5b3a"),
+ contractAccountAtBlock2bRLP,
+ })
+
+ bankAccountAtBlock3bBalance, _ = big.NewInt(0).SetString("18000000000000000000000001999920365757724976", 10)
+ bankAccountAtBlock3b = &types.StateAccount{
+ Nonce: 3,
+ Balance: bankAccountAtBlock3bBalance,
+ CodeHash: test_helpers.NullCodeHash.Bytes(),
+ Root: test_helpers.EmptyContractRoot,
+ }
+ bankAccountAtBlock3bRLP, _ = rlp.EncodeToBytes(bankAccountAtBlock3b)
+ bankAccountAtBlock3bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
+ common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"),
+ bankAccountAtBlock3bRLP,
+ })
+
+ contractAccountAtBlock3b = &types.StateAccount{
+ Nonce: 1,
+ Balance: big.NewInt(0),
+ CodeHash: test_helpers.CodeHashForInternalizedLeafNode.Bytes(),
+ Root: crypto.Keccak256Hash(block3bStorageBranchRootNode),
+ }
+ contractAccountAtBlock3bRLP, _ = rlp.EncodeToBytes(contractAccountAtBlock3b)
+ contractAccountAtBlock3bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
+ common.Hex2Bytes("3d7e14f1723fa19b5d6d9f8b86b49acefbc9c400bf4ed686c10d6b6467fc5b3a"),
+ contractAccountAtBlock3bRLP,
+ })
+
+ slot40364 = common.BigToHash(big.NewInt(40364))
+ slot105566 = common.BigToHash(big.NewInt(105566))
+
+ slot40364StorageValue = common.Hex2Bytes("01")
+ slot105566StorageValue = common.Hex2Bytes("02")
+
+ slot40364StorageKey = crypto.Keccak256Hash(slot40364[:])
+ slot105566StorageKey = crypto.Keccak256Hash(slot105566[:])
+
+ slot40364StorageInternalLeafNode = []interface{}{
+ common.Hex2Bytes("3077bbc951a04529defc15da8c06e427cde0d7a1499c50975bbe8aab"),
+ slot40364StorageValue,
+ }
+ slot105566StorageInternalLeafNode = []interface{}{
+ common.Hex2Bytes("3c62586c18bf1ecfda161ced374b7a894630e2db426814c24e5d42af"),
+ slot105566StorageValue,
+ }
+
+ block3bStorageBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{
+ []byte{},
+ []byte{},
+ crypto.Keccak256(slot0StorageLeafNode),
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ crypto.Keccak256(slot1StorageLeafNode),
+ []byte{},
+ []byte{},
+ []byte{},
+ crypto.Keccak256(block3bStorageExtensionNode),
+ []byte{},
+ })
+
+ block3bStorageExtensionNode, _ = rlp.EncodeToBytes(&[]interface{}{
+ common.Hex2Bytes("1291631c"),
+ crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves),
+ })
+
+ block3bStorageBranchNodeWithInternalLeaves, _ = rlp.EncodeToBytes(&[]interface{}{
+ slot105566StorageInternalLeafNode,
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ slot40364StorageInternalLeafNode,
+ []byte{},
+ []byte{},
+ []byte{},
+ })
+
+ block1bBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{
+ crypto.Keccak256(bankAccountAtBlock1bLeafNode),
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ crypto.Keccak256(minerAccountAtBlock1LeafNode),
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ crypto.Keccak256(account1AtBlock1bLeafNode),
+ []byte{},
+ []byte{},
+ })
+
+ block2bBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{
+ crypto.Keccak256(bankAccountAtBlock1bLeafNode),
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ crypto.Keccak256(minerAccountAtBlock2bLeafNode),
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ crypto.Keccak256(account1AtBlock2bLeafNode),
+ crypto.Keccak256(contractAccountAtBlock2bLeafNode),
+ []byte{},
+ })
+
+ block3bBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{
+ crypto.Keccak256(bankAccountAtBlock3bLeafNode),
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ crypto.Keccak256(minerAccountAtBlock2bLeafNode),
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ []byte{},
+ crypto.Keccak256(account1AtBlock2bLeafNode),
+ crypto.Keccak256(contractAccountAtBlock3bLeafNode),
+ []byte{},
+ })
+)
+
+func TestBuilderWithInternalizedLeafNode(t *testing.T) {
+ blocks, chain := test_helpers.MakeChain(3, test_helpers.GenesisForInternalLeafNodeTest, test_helpers.TestChainGenWithInternalLeafNode)
+ contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr)
+ defer chain.Stop()
+ block0 = test_helpers.Genesis
+ block1 = blocks[0]
+ block2 = blocks[1]
+ block3 = blocks[2]
+ params := statediff.Params{}
+ builder = statediff.NewBuilder(chain.StateCache())
+
+ var tests = []struct {
+ name string
+ startingArguments statediff.Args
+ expected *types2.StateObject
+ }{
+ {
+ "testEmptyDiff",
+ statediff.Args{
+ OldStateRoot: block0.Root(),
+ NewStateRoot: block0.Root(),
+ BlockNumber: block0.Number(),
+ BlockHash: block0.Hash(),
+ },
+ &types2.StateObject{
+ BlockNumber: block0.Number(),
+ BlockHash: block0.Hash(),
+ Nodes: emptyDiffs,
+ },
+ },
+ {
+ "testBlock0",
+ //10000 transferred from testBankAddress to account1Addr
+ statediff.Args{
+ OldStateRoot: test_helpers.NullHash,
+ NewStateRoot: block0.Root(),
+ BlockNumber: block0.Number(),
+ BlockHash: block0.Hash(),
+ },
+ &types2.StateObject{
+ BlockNumber: block0.Number(),
+ BlockHash: block0.Hash(),
+ Nodes: []types2.StateLeafNode{
+ {
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: bankAccountAtBlock0,
+ LeafKey: test_helpers.BankLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock0LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock0LeafNode)).String(),
+ Content: bankAccountAtBlock0LeafNode,
+ },
+ },
+ },
+ },
+ {
+ "testBlock1",
+ //10000 transferred from testBankAddress to account1Addr
+ statediff.Args{
+ OldStateRoot: block0.Root(),
+ NewStateRoot: block1.Root(),
+ BlockNumber: block1.Number(),
+ BlockHash: block1.Hash(),
+ },
+ &types2.StateObject{
+ BlockNumber: block1.Number(),
+ BlockHash: block1.Hash(),
+ Nodes: []types2.StateLeafNode{
+ {
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: bankAccountAtBlock1b,
+ LeafKey: test_helpers.BankLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock1bLeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ {
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: minerAccountAtBlock1,
+ LeafKey: minerLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(minerAccountAtBlock1LeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ {
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account1AtBlock1b,
+ LeafKey: test_helpers.Account1LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock1bLeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block1bBranchRootNode)).String(),
+ Content: block1bBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock1bLeafNode)).String(),
+ Content: bankAccountAtBlock1bLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(minerAccountAtBlock1LeafNode)).String(),
+ Content: minerAccountAtBlock1LeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock1bLeafNode)).String(),
+ Content: account1AtBlock1bLeafNode,
+ },
+ },
+ },
+ },
+ {
+ "testBlock2",
+ // 1000 transferred from testBankAddress to account1Addr
+ // 1000 transferred from account1Addr to account2Addr
+ // account1addr creates a new contract
+ statediff.Args{
+ OldStateRoot: block1.Root(),
+ NewStateRoot: block2.Root(),
+ BlockNumber: block2.Number(),
+ BlockHash: block2.Hash(),
+ },
+ &types2.StateObject{
+ BlockNumber: block2.Number(),
+ BlockHash: block2.Hash(),
+ Nodes: []types2.StateLeafNode{
+ {
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: minerAccountAtBlock2b,
+ LeafKey: minerLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(minerAccountAtBlock2bLeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ {
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: account1AtBlock2b,
+ LeafKey: test_helpers.Account1LeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock2bLeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ {
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock2b,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock2bLeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
+ {
+ Removed: false,
+ Value: slot0StorageValue,
+ LeafKey: slot0StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot0StorageLeafNode)).String(),
+ },
+ {
+ Removed: false,
+ Value: slot1StorageValue,
+ LeafKey: slot1StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(),
+ },
+ },
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.RawBinary, test_helpers.CodeHashForInternalizedLeafNode.Bytes()).String(),
+ Content: test_helpers.ByteCodeAfterDeploymentForInternalLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block2bBranchRootNode)).String(),
+ Content: block2bBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(minerAccountAtBlock2bLeafNode)).String(),
+ Content: minerAccountAtBlock2bLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock2bLeafNode)).String(),
+ Content: account1AtBlock2bLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock2bLeafNode)).String(),
+ Content: contractAccountAtBlock2bLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block2StorageBranchRootNode)).String(),
+ Content: block2StorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot0StorageLeafNode)).String(),
+ Content: slot0StorageLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(),
+ Content: slot1StorageLeafNode,
+ },
+ },
+ },
+ },
+ {
+ "testBlock3",
+ //the contract's storage is changed
+ //and the block is mined by account 2
+ statediff.Args{
+ OldStateRoot: block2.Root(),
+ NewStateRoot: block3.Root(),
+ BlockNumber: block3.Number(),
+ BlockHash: block3.Hash(),
+ },
+ &types2.StateObject{
+ BlockNumber: block3.Number(),
+ BlockHash: block3.Hash(),
+ Nodes: []types2.StateLeafNode{
+ {
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: bankAccountAtBlock3b,
+ LeafKey: test_helpers.BankLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock3bLeafNode)).String()},
+ StorageDiff: emptyStorage,
+ },
+ {
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock3b,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock3bLeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
+ {
+ Removed: false,
+ Value: slot105566StorageValue,
+ LeafKey: slot105566StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves)).String(),
+ },
+ {
+ Removed: false,
+ Value: slot40364StorageValue,
+ LeafKey: slot40364StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves)).String(),
+ },
+ },
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block3bBranchRootNode)).String(),
+ Content: block3bBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock3bLeafNode)).String(),
+ Content: bankAccountAtBlock3bLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock3bLeafNode)).String(),
+ Content: contractAccountAtBlock3bLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchRootNode)).String(),
+ Content: block3bStorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageExtensionNode)).String(),
+ Content: block3bStorageExtensionNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves)).String(),
+ Content: block3bStorageBranchNodeWithInternalLeaves,
+ },
+ },
+ },
+ },
+ }
+
+ for _, test := range tests {
+ diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
+ if err != nil {
+ t.Error(err)
+ }
+ receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
+ if err != nil {
+ t.Error(err)
+ }
+ expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
+ sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
+ sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
+ if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
+ actual, err := json.Marshal(diff)
+ if err != nil {
+ t.Error(err)
+ }
+ expected, err := json.Marshal(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
+ t.Logf("Test failed: %s", test.name)
+ t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected)
+ }
+ }
+ // Let's also confirm that our root state nodes form the state root hash in the headers
+ if !bytes.Equal(block1.Root().Bytes(), crypto.Keccak256(block1bBranchRootNode)) {
+ t.Errorf("block1 expected root %x does not match actual root %x", block1.Root().Bytes(), crypto.Keccak256(block1bBranchRootNode))
+ }
+ if !bytes.Equal(block2.Root().Bytes(), crypto.Keccak256(block2bBranchRootNode)) {
+ t.Errorf("block2 expected root %x does not match actual root %x", block2.Root().Bytes(), crypto.Keccak256(block2bBranchRootNode))
+ }
+ if !bytes.Equal(block3.Root().Bytes(), crypto.Keccak256(block3bBranchRootNode)) {
+ t.Errorf("block3 expected root %x does not match actual root %x", block3.Root().Bytes(), crypto.Keccak256(block3bBranchRootNode))
+ }
+}
+
+func TestBuilderWithInternalizedLeafNodeAndWatchedAddress(t *testing.T) {
+ blocks, chain := test_helpers.MakeChain(3, test_helpers.GenesisForInternalLeafNodeTest, test_helpers.TestChainGenWithInternalLeafNode)
+ contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr)
+ defer chain.Stop()
+ block0 = test_helpers.Genesis
+ block1 = blocks[0]
+ block2 = blocks[1]
+ block3 = blocks[2]
+ params := statediff.Params{
+ WatchedAddresses: []common.Address{
+ test_helpers.ContractAddr,
+ },
+ }
+ params.ComputeWatchedAddressesLeafPaths()
+ builder = statediff.NewBuilder(chain.StateCache())
+
+ var tests = []struct {
+ name string
+ startingArguments statediff.Args
+ expected *types2.StateObject
+ }{
+ {
+ "testEmptyDiff",
+ statediff.Args{
+ OldStateRoot: block0.Root(),
+ NewStateRoot: block0.Root(),
+ BlockNumber: block0.Number(),
+ BlockHash: block0.Hash(),
+ },
+ &types2.StateObject{
+ BlockNumber: block0.Number(),
+ BlockHash: block0.Hash(),
+ Nodes: emptyDiffs,
+ },
+ },
+ {
+ "testBlock0",
+ //10000 transferred from testBankAddress to account1Addr
+ statediff.Args{
+ OldStateRoot: test_helpers.NullHash,
+ NewStateRoot: block0.Root(),
+ BlockNumber: block0.Number(),
+ BlockHash: block0.Hash(),
+ },
+ &types2.StateObject{
+ BlockNumber: block0.Number(),
+ BlockHash: block0.Hash(),
+ Nodes: []types2.StateLeafNode{},
+ IPLDs: []types2.IPLD{}, // there's some kind of weird behavior where if our root node is a leaf node
+ // even though it is along the path to the watched leaf (necessarily, as it is the root) it doesn't get included
+ // unconsequential, but kinda odd.
+ },
+ },
+ {
+ "testBlock1",
+ //10000 transferred from testBankAddress to account1Addr
+ statediff.Args{
+ OldStateRoot: block0.Root(),
+ NewStateRoot: block1.Root(),
+ BlockNumber: block1.Number(),
+ BlockHash: block1.Hash(),
+ },
+ &types2.StateObject{
+ BlockNumber: block1.Number(),
+ BlockHash: block1.Hash(),
+ Nodes: []types2.StateLeafNode{},
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block1bBranchRootNode)).String(),
+ Content: block1bBranchRootNode,
+ },
+ },
+ },
+ },
+ {
+ "testBlock2",
+ // 1000 transferred from testBankAddress to account1Addr
+ // 1000 transferred from account1Addr to account2Addr
+ // account1addr creates a new contract
+ statediff.Args{
+ OldStateRoot: block1.Root(),
+ NewStateRoot: block2.Root(),
+ BlockNumber: block2.Number(),
+ BlockHash: block2.Hash(),
+ },
+ &types2.StateObject{
+ BlockNumber: block2.Number(),
+ BlockHash: block2.Hash(),
+ Nodes: []types2.StateLeafNode{
+ {
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock2b,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock2bLeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
+ {
+ Removed: false,
+ Value: slot0StorageValue,
+ LeafKey: slot0StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot0StorageLeafNode)).String(),
+ },
+ {
+ Removed: false,
+ Value: slot1StorageValue,
+ LeafKey: slot1StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(),
+ },
+ },
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.RawBinary, test_helpers.CodeHashForInternalizedLeafNode.Bytes()).String(),
+ Content: test_helpers.ByteCodeAfterDeploymentForInternalLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block2bBranchRootNode)).String(),
+ Content: block2bBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock2bLeafNode)).String(),
+ Content: contractAccountAtBlock2bLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block2StorageBranchRootNode)).String(),
+ Content: block2StorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot0StorageLeafNode)).String(),
+ Content: slot0StorageLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(),
+ Content: slot1StorageLeafNode,
+ },
+ },
+ },
+ },
+ {
+ "testBlock3",
+ //the contract's storage is changed
+ //and the block is mined by account 2
+ statediff.Args{
+ OldStateRoot: block2.Root(),
+ NewStateRoot: block3.Root(),
+ BlockNumber: block3.Number(),
+ BlockHash: block3.Hash(),
+ },
+ &types2.StateObject{
+ BlockNumber: block3.Number(),
+ BlockHash: block3.Hash(),
+ Nodes: []types2.StateLeafNode{
+ {
+ Removed: false,
+ AccountWrapper: struct {
+ Account *types.StateAccount
+ LeafKey []byte
+ CID string
+ }{
+ Account: contractAccountAtBlock3b,
+ LeafKey: contractLeafKey,
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock3bLeafNode)).String()},
+ StorageDiff: []types2.StorageLeafNode{
+ {
+ Removed: false,
+ Value: slot105566StorageValue,
+ LeafKey: slot105566StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves)).String(),
+ },
+ {
+ Removed: false,
+ Value: slot40364StorageValue,
+ LeafKey: slot40364StorageKey.Bytes(),
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves)).String(),
+ },
+ },
+ },
+ },
+ IPLDs: []types2.IPLD{
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block3bBranchRootNode)).String(),
+ Content: block3bBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock3bLeafNode)).String(),
+ Content: contractAccountAtBlock3bLeafNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchRootNode)).String(),
+ Content: block3bStorageBranchRootNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageExtensionNode)).String(),
+ Content: block3bStorageExtensionNode,
+ },
+ {
+ CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves)).String(),
+ Content: block3bStorageBranchNodeWithInternalLeaves,
+ },
+ },
+ },
+ },
+ }
+
+ for _, test := range tests {
+ diff, err := builder.BuildStateDiffObject(test.startingArguments, params)
+ if err != nil {
+ t.Error(err)
+ }
+ receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff)
+ if err != nil {
+ t.Error(err)
+ }
+ expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
+ sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] })
+ sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] })
+ if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) {
+ actual, err := json.Marshal(diff)
+ if err != nil {
+ t.Error(err)
+ }
+ expected, err := json.Marshal(test.expected)
+ if err != nil {
+ t.Error(err)
+ }
+ t.Logf("Test failed: %s", test.name)
+ t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected)
+ }
+ }
+ // Let's also confirm that our root state nodes form the state root hash in the headers
+ if !bytes.Equal(block1.Root().Bytes(), crypto.Keccak256(block1bBranchRootNode)) {
+ t.Errorf("block1 expected root %x does not match actual root %x", block1.Root().Bytes(), crypto.Keccak256(block1bBranchRootNode))
+ }
+ if !bytes.Equal(block2.Root().Bytes(), crypto.Keccak256(block2bBranchRootNode)) {
+ t.Errorf("block2 expected root %x does not match actual root %x", block2.Root().Bytes(), crypto.Keccak256(block2bBranchRootNode))
+ }
+ if !bytes.Equal(block3.Root().Bytes(), crypto.Keccak256(block3bBranchRootNode)) {
+ t.Errorf("block3 expected root %x does not match actual root %x", block3.Root().Bytes(), crypto.Keccak256(block3bBranchRootNode))
+ }
+}
+
+/*
+pragma solidity ^0.5.10;
+
+contract test {
+ address payable owner;
+
+ modifier onlyOwner {
+ require(
+ msg.sender == owner,
+ "Only owner can call this function."
+ );
+ _;
+ }
+
+ uint256[105566] data;
+
+ constructor() public {
+ owner = msg.sender;
+ data = [1];
+ }
+
+ function Put(uint256 addr, uint256 value) public {
+ data[addr] = value;
+ }
+
+ function close() public onlyOwner { //onlyOwner is custom modifier
+ selfdestruct(owner); // `owner` is the owners address
+ }
+}
+*/
diff --git a/pkg/helpers.go b/pkg/helpers.go
deleted file mode 100644
index ae0d1b0..0000000
--- a/pkg/helpers.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2019 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains a batch of utility type declarations used by the tests. As the node
-// operates on unique types, a lot of them are needed to check various features.
-
-package statediff
-
-import (
- "sort"
- "strings"
-)
-
-func sortKeys(data AccountMap) []string {
- keys := make([]string, 0, len(data))
- for key := range data {
- keys = append(keys, key)
- }
- sort.Strings(keys)
-
- return keys
-}
-
-// findIntersection finds the set of strings from both arrays that are equivalent
-// a and b must first be sorted
-// this is used to find which keys have been both "deleted" and "created" i.e. they were updated
-func findIntersection(a, b []string) []string {
- lenA := len(a)
- lenB := len(b)
- iOfA, iOfB := 0, 0
- updates := make([]string, 0)
- if iOfA >= lenA || iOfB >= lenB {
- return updates
- }
- for {
- switch strings.Compare(a[iOfA], b[iOfB]) {
- // -1 when a[iOfA] < b[iOfB]
- case -1:
- iOfA++
- if iOfA >= lenA {
- return updates
- }
- // 0 when a[iOfA] == b[iOfB]
- case 0:
- updates = append(updates, a[iOfA])
- iOfA++
- iOfB++
- if iOfA >= lenA || iOfB >= lenB {
- return updates
- }
- // 1 when a[iOfA] > b[iOfB]
- case 1:
- iOfB++
- if iOfB >= lenB {
- return updates
- }
- }
- }
-}
diff --git a/pkg/rpc/check.go b/pkg/rpc/check.go
deleted file mode 100644
index 0921568..0000000
--- a/pkg/rpc/check.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// VulcanizeDB
-// Copyright © 2020 Vulcanize
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package rpc
-
-import "github.com/ethereum/go-ethereum/rpc"
-
-// checkModuleAvailability check that all names given in modules are actually
-// available API services.
-func checkModuleAvailability(modules []string, apis []rpc.API) (bad, available []string) {
- availableSet := make(map[string]struct{})
- for _, api := range apis {
- if _, ok := availableSet[api.Namespace]; !ok {
- availableSet[api.Namespace] = struct{}{}
- available = append(available, api.Namespace)
- }
- }
- for _, name := range modules {
- if _, ok := availableSet[name]; !ok {
- bad = append(bad, name)
- }
- }
- return bad, available
-}
diff --git a/pkg/service.go b/pkg/service.go
index b179001..bde2a9d 100644
--- a/pkg/service.go
+++ b/pkg/service.go
@@ -53,8 +53,6 @@ type StateDiffService interface {
StateDiffAt(blockNumber uint64, params sd.Params) (*sd.Payload, error)
// StateDiffFor method to get state diff object at specific block
StateDiffFor(blockHash common.Hash, params sd.Params) (*sd.Payload, error)
- // StateTrieAt method to get state trie object at specific block
- StateTrieAt(blockNumber uint64, params sd.Params) (*sd.Payload, error)
// WriteStateDiffAt method to write state diff object directly to DB
WriteStateDiffAt(blockNumber uint64, params sd.Params) error
// WriteStateDiffFor method to get state trie object at specific block
@@ -344,34 +342,6 @@ func (sds *Service) newPayload(stateObject []byte, block *types.Block, params sd
return payload, nil
}
-// StateTrieAt returns a state trie object payload at the specified blockheight
-// This operation cannot be performed back past the point of db pruning; it requires an archival node for historical data
-func (sds *Service) StateTrieAt(blockNumber uint64, params sd.Params) (*sd.Payload, error) {
- currentBlock, err := sds.lvlDBReader.GetBlockByNumber(blockNumber)
- if err != nil {
- return nil, err
- }
- logrus.Infof("sending state trie at block %d", blockNumber)
-
- // compute leaf paths of watched addresses in the params
- params.ComputeWatchedAddressesLeafPaths()
-
- return sds.processStateTrie(currentBlock, params)
-}
-
-func (sds *Service) processStateTrie(block *types.Block, params sd.Params) (*sd.Payload, error) {
- stateNodes, err := sds.Builder.BuildStateTrieObject(block)
- if err != nil {
- return nil, err
- }
- stateTrieRlp, err := rlp.EncodeToBytes(&stateNodes)
- if err != nil {
- return nil, err
- }
- logrus.Infof("state trie object at block %d is %d bytes in length", block.Number().Uint64(), len(stateTrieRlp))
- return sds.newPayload(stateTrieRlp, block, params)
-}
-
// Start is used to begin the service
func (sds *Service) Start() error {
logrus.Info("starting statediff service")
@@ -461,11 +431,11 @@ func (sds *Service) writeStateDiff(block *types.Block, parentRoot common.Hash, p
return err
}
// defer handling of commit/rollback for any return case
- output := func(node sdtypes.StateNode) error {
+ output := func(node sdtypes.StateLeafNode) error {
return sds.indexer.PushStateNode(tx, node, block.Hash().String())
}
- codeOutput := func(c sdtypes.CodeAndCodeHash) error {
- return sds.indexer.PushCodeAndCodeHash(tx, c)
+ codeOutput := func(c sdtypes.IPLD) error {
+ return sds.indexer.PushIPLD(tx, c)
}
prom.SetTimeMetric(prom.T_BLOCK_PROCESSING, time.Now().Sub(t))
t = time.Now()
diff --git a/pkg/types.go b/pkg/types.go
index 3aad530..0a7e89e 100644
--- a/pkg/types.go
+++ b/pkg/types.go
@@ -20,23 +20,9 @@
package statediff
import (
- "github.com/ethereum/go-ethereum/core/types"
sd "github.com/ethereum/go-ethereum/statediff"
- sdTypes "github.com/ethereum/go-ethereum/statediff/types"
)
-// AccountMap is a mapping of hex encoded path => account wrapper
-type AccountMap map[string]accountWrapper
-
-// accountWrapper is used to temporary associate the unpacked node with its raw values
-type accountWrapper struct {
- Account *types.StateAccount
- NodeType sdTypes.NodeType
- Path []byte
- NodeValue []byte
- LeafKey []byte
-}
-
// RangeRequest holds range quest work params
type RangeRequest struct {
Start, Stop uint64