collect and emit codehash=>code mappings in state objects #27
@ -36,6 +36,7 @@ var (
|
|||||||
nullHashBytes = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")
|
nullHashBytes = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")
|
||||||
emptyNode, _ = rlp.EncodeToBytes([]byte{})
|
emptyNode, _ = rlp.EncodeToBytes([]byte{})
|
||||||
emptyContractRoot = crypto.Keccak256Hash(emptyNode)
|
emptyContractRoot = crypto.Keccak256Hash(emptyNode)
|
||||||
|
nullCodeHash = crypto.Keccak256Hash([]byte{}).Bytes()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Builder interface exposes the method for building a state diff between two blocks
|
// Builder interface exposes the method for building a state diff between two blocks
|
||||||
@ -62,19 +63,21 @@ func (sdb *builder) BuildStateTrieObject(current *types.Block) (StateObject, err
|
|||||||
return StateObject{}, fmt.Errorf("error creating trie for block %d: %v", current.Number(), err)
|
return StateObject{}, fmt.Errorf("error creating trie for block %d: %v", current.Number(), err)
|
||||||
}
|
}
|
||||||
it := currentTrie.NodeIterator([]byte{})
|
it := currentTrie.NodeIterator([]byte{})
|
||||||
stateNodes, err := sdb.buildStateTrie(it)
|
stateNodes, codeAndCodeHashes, err := sdb.buildStateTrie(it)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return StateObject{}, fmt.Errorf("error collecting state nodes for block %d: %v", current.Number(), err)
|
return StateObject{}, fmt.Errorf("error collecting state nodes for block %d: %v", current.Number(), err)
|
||||||
}
|
}
|
||||||
return StateObject{
|
return StateObject{
|
||||||
BlockNumber: current.Number(),
|
BlockNumber: current.Number(),
|
||||||
BlockHash: current.Hash(),
|
BlockHash: current.Hash(),
|
||||||
Nodes: stateNodes,
|
Nodes: stateNodes,
|
||||||
|
CodeAndCodeHashes: codeAndCodeHashes,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sdb *builder) buildStateTrie(it trie.NodeIterator) ([]StateNode, error) {
|
func (sdb *builder) buildStateTrie(it trie.NodeIterator) ([]StateNode, []CodeAndCodeHash, error) {
|
||||||
stateNodes := make([]StateNode, 0)
|
stateNodes := make([]StateNode, 0)
|
||||||
|
codeAndCodeHashes := make([]CodeAndCodeHash, 0)
|
||||||
for it.Next(true) {
|
for it.Next(true) {
|
||||||
// skip value nodes
|
// skip value nodes
|
||||||
if it.Leaf() {
|
if it.Leaf() {
|
||||||
@ -87,37 +90,51 @@ func (sdb *builder) buildStateTrie(it trie.NodeIterator) ([]StateNode, error) {
|
|||||||
copy(nodePath, it.Path())
|
copy(nodePath, it.Path())
|
||||||
node, err := sdb.stateCache.TrieDB().Node(it.Hash())
|
node, err := sdb.stateCache.TrieDB().Node(it.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
var nodeElements []interface{}
|
var nodeElements []interface{}
|
||||||
if err := rlp.DecodeBytes(node, &nodeElements); err != nil {
|
if err := rlp.DecodeBytes(node, &nodeElements); err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
ty, err := CheckKeyType(nodeElements)
|
ty, err := CheckKeyType(nodeElements)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
switch ty {
|
switch ty {
|
||||||
case Leaf:
|
case Leaf:
|
||||||
var account state.Account
|
var account state.Account
|
||||||
if err := rlp.DecodeBytes(nodeElements[1].([]byte), &account); err != nil {
|
if err := rlp.DecodeBytes(nodeElements[1].([]byte), &account); err != nil {
|
||||||
return nil, fmt.Errorf("error decoding account for leaf node at path %x nerror: %v", nodePath, err)
|
return nil, nil, fmt.Errorf("error decoding account for leaf node at path %x nerror: %v", nodePath, err)
|
||||||
}
|
}
|
||||||
partialPath := trie.CompactToHex(nodeElements[0].([]byte))
|
partialPath := trie.CompactToHex(nodeElements[0].([]byte))
|
||||||
valueNodePath := append(nodePath, partialPath...)
|
valueNodePath := append(nodePath, partialPath...)
|
||||||
encodedPath := trie.HexToCompact(valueNodePath)
|
encodedPath := trie.HexToCompact(valueNodePath)
|
||||||
leafKey := encodedPath[1:]
|
leafKey := encodedPath[1:]
|
||||||
storageNodes, err := sdb.buildStorageNodesEventual(account.Root, nil, true)
|
node := StateNode{
|
||||||
if err != nil {
|
NodeType: ty,
|
||||||
return nil, fmt.Errorf("failed building eventual storage diffs for account %+v\r\nerror: %v", account, err)
|
Path: nodePath,
|
||||||
|
LeafKey: leafKey,
|
||||||
|
NodeValue: node,
|
||||||
}
|
}
|
||||||
stateNodes = append(stateNodes, StateNode{
|
if !bytes.Equal(account.CodeHash, nullCodeHash) {
|
||||||
NodeType: ty,
|
storageNodes, err := sdb.buildStorageNodesEventual(account.Root, nil, true)
|
||||||
Path: nodePath,
|
if err != nil {
|
||||||
LeafKey: leafKey,
|
return nil, nil, fmt.Errorf("failed building eventual storage diffs for account %+v\r\nerror: %v", account, err)
|
||||||
NodeValue: node,
|
}
|
||||||
StorageNodes: storageNodes,
|
node.StorageNodes = storageNodes
|
||||||
})
|
// emit codehash => code mappings for cod
|
||||||
|
codeHash := common.BytesToHash(account.CodeHash)
|
||||||
|
addrHash := common.BytesToHash(leafKey)
|
||||||
|
code, err := sdb.stateCache.ContractCode(addrHash, codeHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to retrieve code for codehash %s for account with leafkey %s\r\n error: %v", codeHash.String(), addrHash.String(), err)
|
||||||
|
}
|
||||||
|
codeAndCodeHashes = append(codeAndCodeHashes, CodeAndCodeHash{
|
||||||
|
Hash: codeHash,
|
||||||
|
Code: code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
stateNodes = append(stateNodes, node)
|
||||||
case Extension, Branch:
|
case Extension, Branch:
|
||||||
stateNodes = append(stateNodes, StateNode{
|
stateNodes = append(stateNodes, StateNode{
|
||||||
NodeType: ty,
|
NodeType: ty,
|
||||||
@ -125,10 +142,10 @@ func (sdb *builder) buildStateTrie(it trie.NodeIterator) ([]StateNode, error) {
|
|||||||
NodeValue: node,
|
NodeValue: node,
|
||||||
})
|
})
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected node type %s", ty)
|
return nil, nil, fmt.Errorf("unexpected node type %s", ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stateNodes, it.Error()
|
return stateNodes, codeAndCodeHashes, it.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildStateDiffObject builds a statediff object from two blocks and the provided parameters
|
// BuildStateDiffObject builds a statediff object from two blocks and the provided parameters
|
||||||
@ -181,16 +198,17 @@ func (sdb *builder) buildStateDiffWithIntermediateStateNodes(args Args, params P
|
|||||||
return StateObject{}, fmt.Errorf("error building diff for updated accounts: %v", err)
|
return StateObject{}, fmt.Errorf("error building diff for updated accounts: %v", err)
|
||||||
}
|
}
|
||||||
// build the diff nodes for created accounts
|
// build the diff nodes for created accounts
|
||||||
createdAccounts, err := sdb.buildAccountCreations(diffAccountsAtB, params.WatchedStorageSlots, params.IntermediateStorageNodes)
|
createdAccounts, codeAndCodeHashes, err := sdb.buildAccountCreations(diffAccountsAtB, params.WatchedStorageSlots, params.IntermediateStorageNodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return StateObject{}, fmt.Errorf("error building diff for created accounts: %v", err)
|
return StateObject{}, fmt.Errorf("error building diff for created accounts: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// assemble all of the nodes into the statediff object, including the intermediate nodes
|
// assemble all of the nodes into the statediff object, including the intermediate nodes
|
||||||
return StateObject{
|
return StateObject{
|
||||||
BlockNumber: args.BlockNumber,
|
BlockNumber: args.BlockNumber,
|
||||||
BlockHash: args.BlockHash,
|
BlockHash: args.BlockHash,
|
||||||
Nodes: append(append(append(updatedAccounts, createdAccounts...), createdOrUpdatedIntermediateNodes...), emptiedPaths...),
|
Nodes: append(append(append(updatedAccounts, createdAccounts...), createdOrUpdatedIntermediateNodes...), emptiedPaths...),
|
||||||
|
CodeAndCodeHashes: codeAndCodeHashes,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,16 +253,17 @@ func (sdb *builder) buildStateDiffWithoutIntermediateStateNodes(args Args, param
|
|||||||
return StateObject{}, fmt.Errorf("error building diff for updated accounts: %v", err)
|
return StateObject{}, fmt.Errorf("error building diff for updated accounts: %v", err)
|
||||||
}
|
}
|
||||||
// build the diff nodes for created accounts
|
// build the diff nodes for created accounts
|
||||||
createdAccounts, err := sdb.buildAccountCreations(diffAccountsAtB, params.WatchedStorageSlots, params.IntermediateStorageNodes)
|
createdAccounts, codeAndCodeHashes, err := sdb.buildAccountCreations(diffAccountsAtB, params.WatchedStorageSlots, params.IntermediateStorageNodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return StateObject{}, fmt.Errorf("error building diff for created accounts: %v", err)
|
return StateObject{}, fmt.Errorf("error building diff for created accounts: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// assemble all of the nodes into the statediff object
|
// assemble all of the nodes into the statediff object
|
||||||
return StateObject{
|
return StateObject{
|
||||||
BlockNumber: args.BlockNumber,
|
BlockNumber: args.BlockNumber,
|
||||||
BlockHash: args.BlockHash,
|
BlockHash: args.BlockHash,
|
||||||
Nodes: append(append(updatedAccounts, createdAccounts...), emptiedPaths...),
|
Nodes: append(append(updatedAccounts, createdAccounts...), emptiedPaths...),
|
||||||
|
CodeAndCodeHashes: codeAndCodeHashes,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,24 +489,40 @@ func (sdb *builder) buildAccountUpdates(creations, deletions AccountMap, updated
|
|||||||
}
|
}
|
||||||
|
|
||||||
// buildAccountCreations returns the statediff node objects for all the accounts that exist at B but not at A
|
// buildAccountCreations returns the statediff node objects for all the accounts that exist at B but not at A
|
||||||
func (sdb *builder) buildAccountCreations(accounts AccountMap, watchedStorageKeys []common.Hash, intermediateStorageNodes bool) ([]StateNode, error) {
|
// it also returns the code and codehash for created contract accounts
|
||||||
|
func (sdb *builder) buildAccountCreations(accounts AccountMap, watchedStorageKeys []common.Hash, intermediateStorageNodes bool) ([]StateNode, []CodeAndCodeHash, error) {
|
||||||
accountDiffs := make([]StateNode, 0, len(accounts))
|
accountDiffs := make([]StateNode, 0, len(accounts))
|
||||||
|
codeAndCodeHashes := make([]CodeAndCodeHash, 0)
|
||||||
for _, val := range accounts {
|
for _, val := range accounts {
|
||||||
// For account creations, any storage node contained is a diff
|
diff := StateNode{
|
||||||
storageDiffs, err := sdb.buildStorageNodesEventual(val.Account.Root, watchedStorageKeys, intermediateStorageNodes)
|
NodeType: val.NodeType,
|
||||||
if err != nil {
|
Path: val.Path,
|
||||||
return nil, fmt.Errorf("failed building eventual storage diffs for node %x\r\nerror: %v", val.Path, err)
|
LeafKey: val.LeafKey,
|
||||||
|
NodeValue: val.NodeValue,
|
||||||
}
|
}
|
||||||
accountDiffs = append(accountDiffs, StateNode{
|
if !bytes.Equal(val.Account.CodeHash, nullCodeHash) {
|
||||||
NodeType: val.NodeType,
|
// For contract creations, any storage node contained is a diff
|
||||||
Path: val.Path,
|
storageDiffs, err := sdb.buildStorageNodesEventual(val.Account.Root, watchedStorageKeys, intermediateStorageNodes)
|
||||||
LeafKey: val.LeafKey,
|
if err != nil {
|
||||||
NodeValue: val.NodeValue,
|
return nil, nil, fmt.Errorf("failed building eventual storage diffs for node %x\r\nerror: %v", val.Path, err)
|
||||||
StorageNodes: storageDiffs,
|
}
|
||||||
})
|
diff.StorageNodes = storageDiffs
|
||||||
|
// emit codehash => code mappings for cod
|
||||||
|
codeHash := common.BytesToHash(val.Account.CodeHash)
|
||||||
|
addrHash := common.BytesToHash(val.LeafKey)
|
||||||
|
code, err := sdb.stateCache.ContractCode(addrHash, codeHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to retrieve code for codehash %s for account with leafkey %s\r\n error: %v", codeHash.String(), addrHash.String(), err)
|
||||||
|
}
|
||||||
|
codeAndCodeHashes = append(codeAndCodeHashes, CodeAndCodeHash{
|
||||||
|
Hash: codeHash,
|
||||||
|
Code: code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
accountDiffs = append(accountDiffs, diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
return accountDiffs, nil
|
return accountDiffs, codeAndCodeHashes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildStorageNodesEventual builds the storage diff node objects for a created account
|
// buildStorageNodesEventual builds the storage diff node objects for a created account
|
||||||
|
@ -617,6 +617,12 @@ func TestBuilder(t *testing.T) {
|
|||||||
StorageNodes: emptyStorage,
|
StorageNodes: emptyStorage,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
CodeAndCodeHashes: []statediff.CodeAndCodeHash{
|
||||||
|
{
|
||||||
|
Hash: testhelpers.CodeHash,
|
||||||
|
Code: testhelpers.ByteCodeAfterDeployment,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -863,6 +869,12 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
|
|||||||
StorageNodes: emptyStorage,
|
StorageNodes: emptyStorage,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
CodeAndCodeHashes: []statediff.CodeAndCodeHash{
|
||||||
|
{
|
||||||
|
Hash: testhelpers.CodeHash,
|
||||||
|
Code: testhelpers.ByteCodeAfterDeployment,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1071,6 +1083,12 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
|
|||||||
StorageNodes: emptyStorage,
|
StorageNodes: emptyStorage,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
CodeAndCodeHashes: []statediff.CodeAndCodeHash{
|
||||||
|
{
|
||||||
|
Hash: testhelpers.CodeHash,
|
||||||
|
Code: testhelpers.ByteCodeAfterDeployment,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1235,6 +1253,12 @@ func TestBuilderWithWatchedAddressAndStorageKeyList(t *testing.T) {
|
|||||||
StorageNodes: emptyStorage,
|
StorageNodes: emptyStorage,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
CodeAndCodeHashes: []statediff.CodeAndCodeHash{
|
||||||
|
{
|
||||||
|
Hash: testhelpers.CodeHash,
|
||||||
|
Code: testhelpers.ByteCodeAfterDeployment,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1826,6 +1850,12 @@ func TestBuilderWithMovedAccount(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
CodeAndCodeHashes: []statediff.CodeAndCodeHash{
|
||||||
|
{
|
||||||
|
Hash: testhelpers.CodeHash,
|
||||||
|
Code: testhelpers.ByteCodeAfterDeployment,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1942,6 +1972,12 @@ func TestBuilderWithMovedAccountOnlyLeafs(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
CodeAndCodeHashes: []statediff.CodeAndCodeHash{
|
||||||
|
{
|
||||||
|
Hash: testhelpers.CodeHash,
|
||||||
|
Code: testhelpers.ByteCodeAfterDeployment,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2118,6 +2154,12 @@ func TestBuildStateTrie(t *testing.T) {
|
|||||||
StorageNodes: emptyStorage,
|
StorageNodes: emptyStorage,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
CodeAndCodeHashes: []statediff.CodeAndCodeHash{
|
||||||
|
{
|
||||||
|
Hash: testhelpers.CodeHash,
|
||||||
|
Code: testhelpers.ByteCodeAfterDeployment,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2193,6 +2235,12 @@ func TestBuildStateTrie(t *testing.T) {
|
|||||||
StorageNodes: emptyStorage,
|
StorageNodes: emptyStorage,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
CodeAndCodeHashes: []statediff.CodeAndCodeHash{
|
||||||
|
{
|
||||||
|
Hash: testhelpers.CodeHash,
|
||||||
|
Code: testhelpers.ByteCodeAfterDeployment,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -57,14 +57,16 @@ var (
|
|||||||
TestBankFunds = big.NewInt(100000000)
|
TestBankFunds = big.NewInt(100000000)
|
||||||
Genesis = core.GenesisBlockForTesting(Testdb, TestBankAddress, TestBankFunds)
|
Genesis = core.GenesisBlockForTesting(Testdb, TestBankAddress, TestBankFunds)
|
||||||
|
|
||||||
Account1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
|
Account1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
|
||||||
Account2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
|
Account2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
|
||||||
Account1Addr = crypto.PubkeyToAddress(Account1Key.PublicKey) //0x703c4b2bD70c169f5717101CaeE543299Fc946C7
|
Account1Addr = crypto.PubkeyToAddress(Account1Key.PublicKey) //0x703c4b2bD70c169f5717101CaeE543299Fc946C7
|
||||||
Account2Addr = crypto.PubkeyToAddress(Account2Key.PublicKey) //0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e
|
Account2Addr = crypto.PubkeyToAddress(Account2Key.PublicKey) //0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e
|
||||||
Account1LeafKey = AddressToLeafKey(Account1Addr)
|
Account1LeafKey = AddressToLeafKey(Account1Addr)
|
||||||
Account2LeafKey = AddressToLeafKey(Account2Addr)
|
Account2LeafKey = AddressToLeafKey(Account2Addr)
|
||||||
ContractCode = common.Hex2Bytes("608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060200160405280600160ff16815250600190600161007492919061007a565b506100e4565b82606481019282156100ae579160200282015b828111156100ad578251829060ff1690559160200191906001019061008d565b5b5090506100bb91906100bf565b5090565b6100e191905b808211156100dd5760008160009055506001016100c5565b5090565b90565b6101ca806100f36000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806343d726d61461003b578063c16431b914610045575b600080fd5b61004361007d565b005b61007b6004803603604081101561005b57600080fd5b81019080803590602001909291908035906020019092919050505061015c565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610122576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101746022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b806001836064811061016a57fe5b0181905550505056fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a72305820e3747183708fb6bff3f6f7a80fb57dcc1c19f83f9cb25457a3ed5c0424bde66864736f6c634300050a0032")
|
ContractCode = common.Hex2Bytes("608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060200160405280600160ff16815250600190600161007492919061007a565b506100e4565b82606481019282156100ae579160200282015b828111156100ad578251829060ff1690559160200191906001019061008d565b5b5090506100bb91906100bf565b5090565b6100e191905b808211156100dd5760008160009055506001016100c5565b5090565b90565b6101ca806100f36000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806343d726d61461003b578063c16431b914610045575b600080fd5b61004361007d565b005b61007b6004803603604081101561005b57600080fd5b81019080803590602001909291908035906020019092919050505061015c565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610122576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101746022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b806001836064811061016a57fe5b0181905550505056fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a72305820e3747183708fb6bff3f6f7a80fb57dcc1c19f83f9cb25457a3ed5c0424bde66864736f6c634300050a0032")
|
||||||
ContractAddr common.Address
|
ByteCodeAfterDeployment = common.Hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c806343d726d61461003b578063c16431b914610045575b600080fd5b61004361007d565b005b61007b6004803603604081101561005b57600080fd5b81019080803590602001909291908035906020019092919050505061015c565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610122576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101746022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b806001836064811061016a57fe5b0181905550505056fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a72305820e3747183708fb6bff3f6f7a80fb57dcc1c19f83f9cb25457a3ed5c0424bde66864736f6c634300050a0032")
|
||||||
|
CodeHash = common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127")
|
||||||
|
ContractAddr common.Address
|
||||||
|
|
||||||
EmptyRootNode, _ = rlp.EncodeToBytes([]byte{})
|
EmptyRootNode, _ = rlp.EncodeToBytes([]byte{})
|
||||||
EmptyContractRoot = crypto.Keccak256Hash(EmptyRootNode)
|
EmptyContractRoot = crypto.Keccak256Hash(EmptyRootNode)
|
||||||
|
@ -41,6 +41,7 @@ type Params struct {
|
|||||||
IncludeBlock bool
|
IncludeBlock bool
|
||||||
IncludeReceipts bool
|
IncludeReceipts bool
|
||||||
IncludeTD bool
|
IncludeTD bool
|
||||||
|
IncludeCode bool
|
||||||
WatchedAddresses []common.Address
|
WatchedAddresses []common.Address
|
||||||
WatchedStorageSlots []common.Hash
|
WatchedStorageSlots []common.Hash
|
||||||
}
|
}
|
||||||
@ -82,9 +83,17 @@ func (sd *Payload) Encode() ([]byte, error) {
|
|||||||
|
|
||||||
// StateObject is the final output structure from the builder
|
// StateObject is the final output structure from the builder
|
||||||
type StateObject struct {
|
type StateObject struct {
|
||||||
BlockNumber *big.Int `json:"blockNumber" gencodec:"required"`
|
BlockNumber *big.Int `json:"blockNumber" gencodec:"required"`
|
||||||
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
|
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
|
||||||
Nodes []StateNode `json:"nodes" gencodec:"required"`
|
Nodes []StateNode `json:"nodes" gencodec:"required"`
|
||||||
|
CodeAndCodeHashes []CodeAndCodeHash `json:"codeMapping"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CodeAndCodeHash struct for holding codehash => code mappings
|
||||||
|
// we can't use an actual map because they are not rlp serializable
|
||||||
|
type CodeAndCodeHash struct {
|
||||||
|
Hash common.Hash
|
||||||
|
Code []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// StateNode holds the data for a single state diff node
|
// StateNode holds the data for a single state diff node
|
||||||
|
Loading…
Reference in New Issue
Block a user