finish testing known edge cases

This commit is contained in:
Ian Norden 2020-05-18 01:27:58 -05:00
parent e3b6d3df1c
commit f572e8d716
5 changed files with 249 additions and 27 deletions

View File

@ -23,10 +23,9 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"

View File

@ -464,7 +464,7 @@ var (
) )
func TestBuilder(t *testing.T) { func TestBuilder(t *testing.T) {
blocks, chain := testhelpers.MakeChain(3, testhelpers.Genesis) blocks, chain := testhelpers.MakeChain(3, testhelpers.Genesis, testhelpers.TestChainGen)
contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr) contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr)
defer chain.Stop() defer chain.Stop()
block0 = testhelpers.Genesis block0 = testhelpers.Genesis
@ -689,7 +689,7 @@ func TestBuilder(t *testing.T) {
} }
func TestBuilderWithIntermediateNodes(t *testing.T) { func TestBuilderWithIntermediateNodes(t *testing.T) {
blocks, chain := testhelpers.MakeChain(3, testhelpers.Genesis) blocks, chain := testhelpers.MakeChain(3, testhelpers.Genesis, testhelpers.TestChainGen)
contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr) contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr)
defer chain.Stop() defer chain.Stop()
block0 = testhelpers.Genesis block0 = testhelpers.Genesis
@ -960,7 +960,7 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
} }
func TestBuilderWithWatchedAddressList(t *testing.T) { func TestBuilderWithWatchedAddressList(t *testing.T) {
blocks, chain := testhelpers.MakeChain(3, testhelpers.Genesis) blocks, chain := testhelpers.MakeChain(3, testhelpers.Genesis, testhelpers.TestChainGen)
contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr) contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr)
defer chain.Stop() defer chain.Stop()
block0 = testhelpers.Genesis block0 = testhelpers.Genesis
@ -1129,7 +1129,7 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
} }
func TestBuilderWithWatchedAddressAndStorageKeyList(t *testing.T) { func TestBuilderWithWatchedAddressAndStorageKeyList(t *testing.T) {
blocks, chain := testhelpers.MakeChain(3, testhelpers.Genesis) blocks, chain := testhelpers.MakeChain(3, testhelpers.Genesis, testhelpers.TestChainGen)
contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr) contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr)
defer chain.Stop() defer chain.Stop()
block0 = testhelpers.Genesis block0 = testhelpers.Genesis
@ -1286,7 +1286,7 @@ func TestBuilderWithWatchedAddressAndStorageKeyList(t *testing.T) {
} }
func TestBuilderWithRemovedAccountAndStorage(t *testing.T) { func TestBuilderWithRemovedAccountAndStorage(t *testing.T) {
blocks, chain := testhelpers.MakeChain(6, testhelpers.Genesis) blocks, chain := testhelpers.MakeChain(6, testhelpers.Genesis, testhelpers.TestChainGen)
contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr) contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr)
defer chain.Stop() defer chain.Stop()
block3 = blocks[2] block3 = blocks[2]
@ -1492,8 +1492,8 @@ func TestBuilderWithRemovedAccountAndStorage(t *testing.T) {
} }
} }
func TestBuilderWithRemovedAccountAndStorageWithoutIntermediateStateNodes(t *testing.T) { func TestBuilderWithRemovedAccountAndStorageWithoutIntermediateNodes(t *testing.T) {
blocks, chain := testhelpers.MakeChain(6, testhelpers.Genesis) blocks, chain := testhelpers.MakeChain(6, testhelpers.Genesis, testhelpers.TestChainGen)
contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr) contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr)
defer chain.Stop() defer chain.Stop()
block3 = blocks[2] block3 = blocks[2]
@ -1502,7 +1502,7 @@ func TestBuilderWithRemovedAccountAndStorageWithoutIntermediateStateNodes(t *tes
block6 = blocks[5] block6 = blocks[5]
params := statediff.Params{ params := statediff.Params{
IntermediateStateNodes: false, IntermediateStateNodes: false,
IntermediateStorageNodes: true, IntermediateStorageNodes: false,
} }
builder = statediff.NewBuilder(chain.StateCache()) builder = statediff.NewBuilder(chain.StateCache())
@ -1537,11 +1537,6 @@ func TestBuilderWithRemovedAccountAndStorageWithoutIntermediateStateNodes(t *tes
LeafKey: contractLeafKey, LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock4LeafNode, NodeValue: contractAccountAtBlock4LeafNode,
StorageDiffs: []statediff.StorageNode{ StorageDiffs: []statediff.StorageNode{
{
Path: []byte{},
NodeType: statediff.Branch,
NodeValue: block4StorageBranchRootNode,
},
{ {
Path: []byte{'\x04'}, Path: []byte{'\x04'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
@ -1681,6 +1676,214 @@ func TestBuilderWithRemovedAccountAndStorageWithoutIntermediateStateNodes(t *tes
} }
} }
var (
slot00StorageValue = common.Hex2Bytes("9471562b71999873db5b286df957af199ec94617f7") // prefixed TestBankAddress
slot00StorageLeafNode, _ = rlp.EncodeToBytes([]interface{}{
common.Hex2Bytes("390decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"),
slot00StorageValue,
})
contractAccountAtBlock01, _ = rlp.EncodeToBytes(state.Account{
Nonce: 1,
Balance: big.NewInt(0),
CodeHash: common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127").Bytes(),
Root: crypto.Keccak256Hash(block01StorageBranchRootNode),
})
contractAccountAtBlock01LeafNode, _ = rlp.EncodeToBytes([]interface{}{
common.Hex2Bytes("3cb2583748c26e89ef19c2a8529b05a270f735553b4d44b6f2a1894987a71c8b"),
contractAccountAtBlock01,
})
bankAccountAtBlock01, _ = rlp.EncodeToBytes(state.Account{
Nonce: 1,
Balance: big.NewInt(testhelpers.TestBankFunds.Int64() + miningReward),
CodeHash: testhelpers.NullCodeHash.Bytes(),
Root: testhelpers.EmptyContractRoot,
})
bankAccountAtBlock01LeafNode, _ = rlp.EncodeToBytes([]interface{}{
common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"),
bankAccountAtBlock01,
})
bankAccountAtBlock02, _ = rlp.EncodeToBytes(state.Account{
Nonce: 2,
Balance: big.NewInt(testhelpers.TestBankFunds.Int64() + miningReward*2),
CodeHash: testhelpers.NullCodeHash.Bytes(),
Root: testhelpers.EmptyContractRoot,
})
bankAccountAtBlock02LeafNode, _ = rlp.EncodeToBytes([]interface{}{
common.Hex2Bytes("2000bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"),
bankAccountAtBlock02,
})
block01BranchRootNode, _ = rlp.EncodeToBytes([]interface{}{
crypto.Keccak256Hash(bankAccountAtBlock01LeafNode),
crypto.Keccak256Hash(contractAccountAtBlock01LeafNode),
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
})
block01StorageBranchRootNode, _ = rlp.EncodeToBytes([]interface{}{
[]byte{},
[]byte{},
crypto.Keccak256(slot00StorageLeafNode),
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
crypto.Keccak256(slot1StorageLeafNode),
[]byte{},
[]byte{},
[]byte{},
[]byte{},
[]byte{},
})
)
func TestBuilderWithMovedAccount(t *testing.T) {
blocks, chain := testhelpers.MakeChain(2, testhelpers.Genesis, testhelpers.TestSelfDestructChainGen)
contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr)
defer chain.Stop()
block0 = testhelpers.Genesis
block1 = blocks[0]
block2 = blocks[1]
params := statediff.Params{
IntermediateStateNodes: true,
IntermediateStorageNodes: true,
}
builder = statediff.NewBuilder(chain.StateCache())
var tests = []struct {
name string
startingArguments statediff.Args
expected *statediff.StateDiff
}{
{
"testBlock1",
statediff.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block1.Root(),
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
},
&statediff.StateDiff{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
Nodes: []statediff.StateNode{
{
Path: []byte{},
NodeType: statediff.Branch,
NodeValue: block01BranchRootNode,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x00'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock01LeafNode,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x01'},
NodeType: statediff.Leaf,
LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock01LeafNode,
StorageDiffs: []statediff.StorageNode{
{
Path: []byte{},
NodeType: statediff.Branch,
NodeValue: block01StorageBranchRootNode,
},
{
Path: []byte{'\x02'},
NodeType: statediff.Leaf,
LeafKey: slot0StorageKey.Bytes(),
NodeValue: slot00StorageLeafNode,
},
{
Path: []byte{'\x0b'},
NodeType: statediff.Leaf,
LeafKey: slot1StorageKey.Bytes(),
NodeValue: slot1StorageLeafNode,
},
},
},
},
},
},
{
"testBlock2",
statediff.Args{
OldStateRoot: block1.Root(),
NewStateRoot: block2.Root(),
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
},
&statediff.StateDiff{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
Nodes: []statediff.StateNode{
{
Path: []byte{},
NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock02LeafNode,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x01'},
NodeType: statediff.Removed,
NodeValue: []byte{},
},
{
Path: []byte{'\x00'},
NodeType: statediff.Removed,
NodeValue: []byte{},
},
},
},
},
}
for _, test := range tests {
diff, err := builder.BuildStateDiff(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)
}
}
}
/* /*
pragma solidity ^0.5.10; pragma solidity ^0.5.10;

View File

@ -52,7 +52,7 @@ var (
// block 1 data // block 1 data
block1CoinbaseAccount, _ = rlp.EncodeToBytes(state.Account{ block1CoinbaseAccount, _ = rlp.EncodeToBytes(state.Account{
Nonce: testhelpers.Nonce0, Nonce: 0,
Balance: big.NewInt(5000000000000000000), Balance: big.NewInt(5000000000000000000),
CodeHash: testhelpers.NullCodeHash.Bytes(), CodeHash: testhelpers.NullCodeHash.Bytes(),
Root: testhelpers.EmptyContractRoot, Root: testhelpers.EmptyContractRoot,
@ -124,7 +124,7 @@ var (
// block 2 data // block 2 data
block2CoinbaseAccount, _ = rlp.EncodeToBytes(state.Account{ block2CoinbaseAccount, _ = rlp.EncodeToBytes(state.Account{
Nonce: testhelpers.Nonce0, Nonce: 0,
Balance: big.NewInt(5000000000000000000), Balance: big.NewInt(5000000000000000000),
CodeHash: testhelpers.NullCodeHash.Bytes(), CodeHash: testhelpers.NullCodeHash.Bytes(),
Root: testhelpers.EmptyContractRoot, Root: testhelpers.EmptyContractRoot,
@ -136,7 +136,7 @@ var (
block2CoinbaseLeafNodeHash = crypto.Keccak256(block2CoinbaseLeafNode) block2CoinbaseLeafNodeHash = crypto.Keccak256(block2CoinbaseLeafNode)
block2MovedPremineBalance, _ = new(big.Int).SetString("4000000000000000000000", 10) block2MovedPremineBalance, _ = new(big.Int).SetString("4000000000000000000000", 10)
block2MovedPremineAccount, _ = rlp.EncodeToBytes(state.Account{ block2MovedPremineAccount, _ = rlp.EncodeToBytes(state.Account{
Nonce: testhelpers.Nonce0, Nonce: 0,
Balance: block2MovedPremineBalance, Balance: block2MovedPremineBalance,
CodeHash: testhelpers.NullCodeHash.Bytes(), CodeHash: testhelpers.NullCodeHash.Bytes(),
Root: testhelpers.EmptyContractRoot, Root: testhelpers.EmptyContractRoot,
@ -230,7 +230,7 @@ var (
// path 060e0f // path 060e0f
blcok3CoinbaseBalance, _ = new(big.Int).SetString("5156250000000000000", 10) blcok3CoinbaseBalance, _ = new(big.Int).SetString("5156250000000000000", 10)
block3CoinbaseAccount, _ = rlp.EncodeToBytes(state.Account{ block3CoinbaseAccount, _ = rlp.EncodeToBytes(state.Account{
Nonce: testhelpers.Nonce0, Nonce: 0,
Balance: blcok3CoinbaseBalance, Balance: blcok3CoinbaseBalance,
CodeHash: testhelpers.NullCodeHash.Bytes(), CodeHash: testhelpers.NullCodeHash.Bytes(),
Root: testhelpers.EmptyContractRoot, Root: testhelpers.EmptyContractRoot,
@ -243,7 +243,7 @@ var (
// path 0c0e050703 // path 0c0e050703
block3MovedPremineBalance1, _ = new(big.Int).SetString("3750000000000000000", 10) block3MovedPremineBalance1, _ = new(big.Int).SetString("3750000000000000000", 10)
block3MovedPremineAccount1, _ = rlp.EncodeToBytes(state.Account{ block3MovedPremineAccount1, _ = rlp.EncodeToBytes(state.Account{
Nonce: testhelpers.Nonce0, Nonce: 0,
Balance: block3MovedPremineBalance1, Balance: block3MovedPremineBalance1,
CodeHash: testhelpers.NullCodeHash.Bytes(), CodeHash: testhelpers.NullCodeHash.Bytes(),
Root: testhelpers.EmptyContractRoot, Root: testhelpers.EmptyContractRoot,
@ -256,7 +256,7 @@ var (
// path 0c0e050708 // path 0c0e050708
block3MovedPremineBalance2, _ = new(big.Int).SetString("1999944000000000000000", 10) block3MovedPremineBalance2, _ = new(big.Int).SetString("1999944000000000000000", 10)
block3MovedPremineAccount2, _ = rlp.EncodeToBytes(state.Account{ block3MovedPremineAccount2, _ = rlp.EncodeToBytes(state.Account{
Nonce: testhelpers.Nonce0, Nonce: 0,
Balance: block3MovedPremineBalance2, Balance: block3MovedPremineBalance2,
CodeHash: testhelpers.NullCodeHash.Bytes(), CodeHash: testhelpers.NullCodeHash.Bytes(),
Root: testhelpers.EmptyContractRoot, Root: testhelpers.EmptyContractRoot,

View File

@ -30,14 +30,34 @@ import (
// MakeChain creates a chain of n blocks starting at and including parent. // MakeChain creates a chain of n blocks starting at and including parent.
// the returned hash chain is ordered head->parent. // the returned hash chain is ordered head->parent.
func MakeChain(n int, parent *types.Block) ([]*types.Block, *core.BlockChain) { func MakeChain(n int, parent *types.Block, chainGen func(int, *core.BlockGen)) ([]*types.Block, *core.BlockChain) {
config := params.TestChainConfig config := params.TestChainConfig
blocks, _ := core.GenerateChain(config, parent, ethash.NewFaker(), Testdb, n, testChainGen) blocks, _ := core.GenerateChain(config, parent, ethash.NewFaker(), Testdb, n, chainGen)
chain, _ := core.NewBlockChain(Testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil) chain, _ := core.NewBlockChain(Testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil)
return blocks, chain return blocks, chain
} }
func testChainGen(i int, block *core.BlockGen) { func TestSelfDestructChainGen(i int, block *core.BlockGen) {
signer := types.HomesteadSigner{}
switch i {
case 0:
// Block 1 is mined by Account1Addr
// Account1Addr creates a new contract
block.SetCoinbase(TestBankAddress)
tx, _ := types.SignTx(types.NewContractCreation(0, big.NewInt(0), 1000000, big.NewInt(0), ContractCode), signer, TestBankKey)
ContractAddr = crypto.CreateAddress(TestBankAddress, 0)
block.AddTx(tx)
case 1:
// Block 2 is mined by Account1Addr
// Account1Addr self-destructs the contract
block.SetCoinbase(TestBankAddress)
data := common.Hex2Bytes("43D726D6")
tx, _ := types.SignTx(types.NewTransaction(1, ContractAddr, big.NewInt(0), 100000, nil, data), signer, TestBankKey)
block.AddTx(tx)
}
}
func TestChainGen(i int, block *core.BlockGen) {
signer := types.HomesteadSigner{} signer := types.HomesteadSigner{}
switch i { switch i {
case 0: case 0:
@ -53,7 +73,7 @@ func testChainGen(i int, block *core.BlockGen) {
tx2, _ := types.SignTx(types.NewTransaction(nonce, Account2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, Account1Key) tx2, _ := types.SignTx(types.NewTransaction(nonce, Account2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, Account1Key)
nonce++ nonce++
tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 1000000, big.NewInt(0), ContractCode), signer, Account1Key) tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 1000000, big.NewInt(0), ContractCode), signer, Account1Key)
ContractAddr = crypto.CreateAddress(Account1Addr, nonce) //0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592 ContractAddr = crypto.CreateAddress(Account1Addr, nonce)
block.AddTx(tx1) block.AddTx(tx1)
block.AddTx(tx2) block.AddTx(tx2)
block.AddTx(tx3) block.AddTx(tx3)

View File

@ -81,7 +81,7 @@ func TestAPI(t *testing.T) {
} }
func testSubscriptionAPI(t *testing.T) { func testSubscriptionAPI(t *testing.T) {
blocks, chain := testhelpers.MakeChain(1, testhelpers.Genesis) blocks, chain := testhelpers.MakeChain(1, testhelpers.Genesis, testhelpers.TestChainGen)
defer chain.Stop() defer chain.Stop()
block0 = testhelpers.Genesis block0 = testhelpers.Genesis
block1 = blocks[0] block1 = blocks[0]
@ -165,7 +165,7 @@ func testSubscriptionAPI(t *testing.T) {
} }
func testHTTPAPI(t *testing.T) { func testHTTPAPI(t *testing.T) {
blocks, chain := testhelpers.MakeChain(1, testhelpers.Genesis) blocks, chain := testhelpers.MakeChain(1, testhelpers.Genesis, testhelpers.TestChainGen)
defer chain.Stop() defer chain.Stop()
block0 = testhelpers.Genesis block0 = testhelpers.Genesis
block1 = blocks[0] block1 = blocks[0]