Statediff into postgres v1.9.24 #38

Closed
roysc wants to merge 3 commits from statediff-into-postgres_v1.9.24 into v1.9.24-statediff
10 changed files with 208 additions and 204 deletions

View File

@ -182,7 +182,7 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
dbParams = new(statediff.DBParams)
dbParams.ConnectionURL = ctx.GlobalString(utils.StateDiffDBFlag.Name)
if ctx.GlobalIsSet(utils.StateDiffDBNodeIDFlag.Name) {
dbParams.ID = ctx.GlobalString(utils.StateDiffDBNodeIDFlag.Name)
dbParams.NodeID = ctx.GlobalString(utils.StateDiffDBNodeIDFlag.Name)
} else {
utils.Fatalf("Must specify node ID for statediff DB output")
}

View File

@ -1746,7 +1746,8 @@ func RegisterGraphQLService(stack *node.Node, backend ethapi.Backend, cfg node.C
// RegisterStateDiffService configures and registers a service to stream state diff data over RPC
// dbParams are: Postgres connection URI, Node ID, client name
func RegisterStateDiffService(stack *node.Node, ethServ *eth.Ethereum, dbParams *statediff.DBParams, startWriteLoop bool) {
if err := statediff.New(stack, ethServ, dbParams, startWriteLoop); err != nil {
err := statediff.New(stack, ethServ, dbParams, startWriteLoop)
if err != nil {
Fatalf("Failed to register the Statediff service: %v", err)
}
}

View File

@ -472,23 +472,23 @@ func TestBuilder(t *testing.T) {
block1 = blocks[0]
block2 = blocks[1]
block3 = blocks[2]
params := statediff.Params{}
params := sdtypes.Params{}
builder = statediff.NewBuilder(chain.StateCache())
var tests = []struct {
name string
startingArguments statediff.Args
expected *statediff.StateObject
startingArguments sdtypes.Args
expected *sdtypes.StateObject
}{
{
"testEmptyDiff",
statediff.Args{
sdtypes.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block0.Root(),
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
Nodes: emptyDiffs,
@ -497,13 +497,13 @@ func TestBuilder(t *testing.T) {
{
"testBlock0",
//10000 transferred from testBankAddress to account1Addr
statediff.Args{
sdtypes.Args{
OldStateRoot: testhelpers.NullHash,
NewStateRoot: block0.Root(),
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
Nodes: []sdtypes.StateNode{
@ -520,13 +520,13 @@ func TestBuilder(t *testing.T) {
{
"testBlock1",
//10000 transferred from testBankAddress to account1Addr
statediff.Args{
sdtypes.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block1.Root(),
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
Nodes: []sdtypes.StateNode{
@ -559,13 +559,13 @@ func TestBuilder(t *testing.T) {
// 1000 transferred from testBankAddress to account1Addr
// 1000 transferred from account1Addr to account2Addr
// account1addr creates a new contract
statediff.Args{
sdtypes.Args{
OldStateRoot: block1.Root(),
NewStateRoot: block2.Root(),
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
Nodes: []sdtypes.StateNode{
@ -630,13 +630,13 @@ func TestBuilder(t *testing.T) {
"testBlock3",
//the contract's storage is changed
//and the block is mined by account 2
statediff.Args{
sdtypes.Args{
OldStateRoot: block2.Root(),
NewStateRoot: block3.Root(),
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
Nodes: []sdtypes.StateNode{
@ -704,7 +704,7 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
block2 = blocks[1]
block3 = blocks[2]
blocks = append([]*types.Block{block0}, blocks...)
params := statediff.Params{
params := sdtypes.Params{
IntermediateStateNodes: true,
IntermediateStorageNodes: true,
}
@ -712,18 +712,18 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
var tests = []struct {
name string
startingArguments statediff.Args
expected *statediff.StateObject
startingArguments sdtypes.Args
expected *sdtypes.StateObject
}{
{
"testEmptyDiff",
statediff.Args{
sdtypes.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block0.Root(),
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
Nodes: emptyDiffs,
@ -732,13 +732,13 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
{
"testBlock0",
//10000 transferred from testBankAddress to account1Addr
statediff.Args{
sdtypes.Args{
OldStateRoot: testhelpers.NullHash,
NewStateRoot: block0.Root(),
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
Nodes: []sdtypes.StateNode{
@ -755,13 +755,13 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
{
"testBlock1",
//10000 transferred from testBankAddress to account1Addr
statediff.Args{
sdtypes.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block1.Root(),
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
Nodes: []sdtypes.StateNode{
@ -800,13 +800,13 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
// 1000 transferred from testBankAddress to account1Addr
// 1000 transferred from account1Addr to account2Addr
// account1addr creates a new contract
statediff.Args{
sdtypes.Args{
OldStateRoot: block1.Root(),
NewStateRoot: block2.Root(),
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
Nodes: []sdtypes.StateNode{
@ -882,13 +882,13 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
"testBlock3",
//the contract's storage is changed
//and the block is mined by account 2
statediff.Args{
sdtypes.Args{
OldStateRoot: block2.Root(),
NewStateRoot: block3.Root(),
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
Nodes: []sdtypes.StateNode{
@ -980,25 +980,25 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
block1 = blocks[0]
block2 = blocks[1]
block3 = blocks[2]
params := statediff.Params{
params := sdtypes.Params{
WatchedAddresses: []common.Address{testhelpers.Account1Addr, testhelpers.ContractAddr},
}
builder = statediff.NewBuilder(chain.StateCache())
var tests = []struct {
name string
startingArguments statediff.Args
expected *statediff.StateObject
startingArguments sdtypes.Args
expected *sdtypes.StateObject
}{
{
"testEmptyDiff",
statediff.Args{
sdtypes.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block0.Root(),
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
Nodes: emptyDiffs,
@ -1007,13 +1007,13 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
{
"testBlock0",
//10000 transferred from testBankAddress to account1Addr
statediff.Args{
sdtypes.Args{
OldStateRoot: testhelpers.NullHash,
NewStateRoot: block0.Root(),
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
Nodes: emptyDiffs,
@ -1022,13 +1022,13 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
{
"testBlock1",
//10000 transferred from testBankAddress to account1Addr
statediff.Args{
sdtypes.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block1.Root(),
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
Nodes: []sdtypes.StateNode{
@ -1046,13 +1046,13 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
"testBlock2",
//1000 transferred from testBankAddress to account1Addr
//1000 transferred from account1Addr to account2Addr
statediff.Args{
sdtypes.Args{
OldStateRoot: block1.Root(),
NewStateRoot: block2.Root(),
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
Nodes: []sdtypes.StateNode{
@ -1096,13 +1096,13 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
"testBlock3",
//the contract's storage is changed
//and the block is mined by account 2
statediff.Args{
sdtypes.Args{
OldStateRoot: block2.Root(),
NewStateRoot: block3.Root(),
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
Nodes: []sdtypes.StateNode{
@ -1155,7 +1155,7 @@ func TestBuilderWithWatchedAddressAndStorageKeyList(t *testing.T) {
block1 = blocks[0]
block2 = blocks[1]
block3 = blocks[2]
params := statediff.Params{
params := sdtypes.Params{
WatchedAddresses: []common.Address{testhelpers.Account1Addr, testhelpers.ContractAddr},
WatchedStorageSlots: []common.Hash{slot1StorageKey},
}
@ -1163,18 +1163,18 @@ func TestBuilderWithWatchedAddressAndStorageKeyList(t *testing.T) {
var tests = []struct {
name string
startingArguments statediff.Args
expected *statediff.StateObject
startingArguments sdtypes.Args
expected *sdtypes.StateObject
}{
{
"testEmptyDiff",
statediff.Args{
sdtypes.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block0.Root(),
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
Nodes: emptyDiffs,
@ -1183,13 +1183,13 @@ func TestBuilderWithWatchedAddressAndStorageKeyList(t *testing.T) {
{
"testBlock0",
//10000 transferred from testBankAddress to account1Addr
statediff.Args{
sdtypes.Args{
OldStateRoot: testhelpers.NullHash,
NewStateRoot: block0.Root(),
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
Nodes: emptyDiffs,
@ -1198,13 +1198,13 @@ func TestBuilderWithWatchedAddressAndStorageKeyList(t *testing.T) {
{
"testBlock1",
//10000 transferred from testBankAddress to account1Addr
statediff.Args{
sdtypes.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block1.Root(),
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
Nodes: []sdtypes.StateNode{
@ -1222,13 +1222,13 @@ func TestBuilderWithWatchedAddressAndStorageKeyList(t *testing.T) {
"testBlock2",
//1000 transferred from testBankAddress to account1Addr
//1000 transferred from account1Addr to account2Addr
statediff.Args{
sdtypes.Args{
OldStateRoot: block1.Root(),
NewStateRoot: block2.Root(),
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
Nodes: []sdtypes.StateNode{
@ -1266,13 +1266,13 @@ func TestBuilderWithWatchedAddressAndStorageKeyList(t *testing.T) {
"testBlock3",
//the contract's storage is changed
//and the block is mined by account 2
statediff.Args{
sdtypes.Args{
OldStateRoot: block2.Root(),
NewStateRoot: block3.Root(),
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
Nodes: []sdtypes.StateNode{
@ -1318,7 +1318,7 @@ func TestBuilderWithRemovedAccountAndStorage(t *testing.T) {
block4 = blocks[3]
block5 = blocks[4]
block6 = blocks[5]
params := statediff.Params{
params := sdtypes.Params{
IntermediateStateNodes: true,
IntermediateStorageNodes: true,
}
@ -1326,19 +1326,19 @@ func TestBuilderWithRemovedAccountAndStorage(t *testing.T) {
var tests = []struct {
name string
startingArguments statediff.Args
expected *statediff.StateObject
startingArguments sdtypes.Args
expected *sdtypes.StateObject
}{
// blocks 0-3 are the same as in TestBuilderWithIntermediateNodes
{
"testBlock4",
statediff.Args{
sdtypes.Args{
OldStateRoot: block3.Root(),
NewStateRoot: block4.Root(),
BlockNumber: block4.Number(),
BlockHash: block4.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block4.Number(),
BlockHash: block4.Hash(),
Nodes: []sdtypes.StateNode{
@ -1396,13 +1396,13 @@ func TestBuilderWithRemovedAccountAndStorage(t *testing.T) {
},
{
"testBlock5",
statediff.Args{
sdtypes.Args{
OldStateRoot: block4.Root(),
NewStateRoot: block5.Root(),
BlockNumber: block5.Number(),
BlockHash: block5.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block5.Number(),
BlockHash: block5.Hash(),
Nodes: []sdtypes.StateNode{
@ -1455,13 +1455,13 @@ func TestBuilderWithRemovedAccountAndStorage(t *testing.T) {
},
{
"testBlock6",
statediff.Args{
sdtypes.Args{
OldStateRoot: block5.Root(),
NewStateRoot: block6.Root(),
BlockNumber: block6.Number(),
BlockHash: block6.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block6.Number(),
BlockHash: block6.Hash(),
Nodes: []sdtypes.StateNode{
@ -1525,7 +1525,7 @@ func TestBuilderWithRemovedAccountAndStorageWithoutIntermediateNodes(t *testing.
block4 = blocks[3]
block5 = blocks[4]
block6 = blocks[5]
params := statediff.Params{
params := sdtypes.Params{
IntermediateStateNodes: false,
IntermediateStorageNodes: false,
}
@ -1533,19 +1533,19 @@ func TestBuilderWithRemovedAccountAndStorageWithoutIntermediateNodes(t *testing.
var tests = []struct {
name string
startingArguments statediff.Args
expected *statediff.StateObject
startingArguments sdtypes.Args
expected *sdtypes.StateObject
}{
// blocks 0-3 are the same as in TestBuilderWithIntermediateNodes
{
"testBlock4",
statediff.Args{
sdtypes.Args{
OldStateRoot: block3.Root(),
NewStateRoot: block4.Root(),
BlockNumber: block4.Number(),
BlockHash: block4.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block4.Number(),
BlockHash: block4.Hash(),
Nodes: []sdtypes.StateNode{
@ -1592,13 +1592,13 @@ func TestBuilderWithRemovedAccountAndStorageWithoutIntermediateNodes(t *testing.
},
{
"testBlock5",
statediff.Args{
sdtypes.Args{
OldStateRoot: block4.Root(),
NewStateRoot: block5.Root(),
BlockNumber: block5.Number(),
BlockHash: block5.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block5.Number(),
BlockHash: block5.Hash(),
Nodes: []sdtypes.StateNode{
@ -1645,13 +1645,13 @@ func TestBuilderWithRemovedAccountAndStorageWithoutIntermediateNodes(t *testing.
},
{
"testBlock6",
statediff.Args{
sdtypes.Args{
OldStateRoot: block5.Root(),
NewStateRoot: block6.Root(),
BlockNumber: block6.Number(),
BlockHash: block6.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block6.Number(),
BlockHash: block6.Hash(),
Nodes: []sdtypes.StateNode{
@ -1789,7 +1789,7 @@ func TestBuilderWithMovedAccount(t *testing.T) {
block0 = testhelpers.Genesis
block1 = blocks[0]
block2 = blocks[1]
params := statediff.Params{
params := sdtypes.Params{
IntermediateStateNodes: true,
IntermediateStorageNodes: true,
}
@ -1797,18 +1797,18 @@ func TestBuilderWithMovedAccount(t *testing.T) {
var tests = []struct {
name string
startingArguments statediff.Args
expected *statediff.StateObject
startingArguments sdtypes.Args
expected *sdtypes.StateObject
}{
{
"testBlock1",
statediff.Args{
sdtypes.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block1.Root(),
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
Nodes: []sdtypes.StateNode{
@ -1861,13 +1861,13 @@ func TestBuilderWithMovedAccount(t *testing.T) {
},
{
"testBlock2",
statediff.Args{
sdtypes.Args{
OldStateRoot: block1.Root(),
NewStateRoot: block2.Root(),
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
Nodes: []sdtypes.StateNode{
@ -1922,7 +1922,7 @@ func TestBuilderWithMovedAccountOnlyLeafs(t *testing.T) {
block0 = testhelpers.Genesis
block1 = blocks[0]
block2 = blocks[1]
params := statediff.Params{
params := sdtypes.Params{
IntermediateStateNodes: false,
IntermediateStorageNodes: false,
}
@ -1930,18 +1930,18 @@ func TestBuilderWithMovedAccountOnlyLeafs(t *testing.T) {
var tests = []struct {
name string
startingArguments statediff.Args
expected *statediff.StateObject
startingArguments sdtypes.Args
expected *sdtypes.StateObject
}{
{
"testBlock1",
statediff.Args{
sdtypes.Args{
OldStateRoot: block0.Root(),
NewStateRoot: block1.Root(),
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
Nodes: []sdtypes.StateNode{
@ -1983,13 +1983,13 @@ func TestBuilderWithMovedAccountOnlyLeafs(t *testing.T) {
},
{
"testBlock2",
statediff.Args{
sdtypes.Args{
OldStateRoot: block1.Root(),
NewStateRoot: block2.Root(),
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
},
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
Nodes: []sdtypes.StateNode{
@ -2049,12 +2049,12 @@ func TestBuildStateTrie(t *testing.T) {
var tests = []struct {
name string
block *types.Block
expected *statediff.StateObject
expected *sdtypes.StateObject
}{
{
"testBlock1",
block1,
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
Nodes: []sdtypes.StateNode{
@ -2091,7 +2091,7 @@ func TestBuildStateTrie(t *testing.T) {
{
"testBlock2",
block2,
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
Nodes: []sdtypes.StateNode{
@ -2166,7 +2166,7 @@ func TestBuildStateTrie(t *testing.T) {
{
"testBlock3",
block3,
&statediff.StateObject{
&sdtypes.StateObject{
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
Nodes: []sdtypes.StateNode{

View File

@ -35,14 +35,13 @@ func ExpectEqual(t *testing.T, got interface{}, want interface{}) {
// SetupDB is use to setup a db for watcher tests
func SetupDB() (*postgres.DB, error) {
uri := postgres.DbConnectionString(postgres.ConnectionParams{
User: "postgres",
Password: "",
params := postgres.ConnectionParams{
User: "vulcanize",
Hostname: "localhost",
Name: "vulcanize_testing",
Port: 5432,
})
return postgres.NewDB(uri, postgres.ConnectionConfig{}, node.Info{})
}
return postgres.NewDB(postgres.DbConnectionString(params), postgres.ConnectionConfig{}, node.Info{})
}
// ListContainsString used to check if a list of strings contains a particular string

View File

@ -18,6 +18,7 @@ package statediff
import (
"bytes"
"errors"
"math/big"
"strconv"
"sync"
@ -40,7 +41,6 @@ import (
ind "github.com/ethereum/go-ethereum/statediff/indexer"
nodeinfo "github.com/ethereum/go-ethereum/statediff/indexer/node"
"github.com/ethereum/go-ethereum/statediff/indexer/postgres"
"github.com/ethereum/go-ethereum/statediff/indexer/prom"
. "github.com/ethereum/go-ethereum/statediff/types"
)
@ -119,16 +119,22 @@ type lastBlockCache struct {
block *types.Block
}
// New creates a new statediff.Service
type DBParams struct {
ConnectionURL string
NodeID string
ClientName string
}
// New creates a new statediff Service
func New(stack *node.Node, ethServ *eth.Ethereum, dbParams *DBParams, enableWriteLoop bool) error {
blockChain := ethServ.BlockChain()
var indexer ind.Indexer
blockChain := ethServ.BlockChain()
if dbParams != nil {
info := nodeinfo.Info{
GenesisBlock: blockChain.Genesis().Hash().Hex(),
NetworkID: strconv.FormatUint(ethServ.NetVersion(), 10),
ChainID: blockChain.Config().ChainID.Uint64(),
ID: dbParams.ID,
ID: dbParams.NodeID,
ClientName: dbParams.ClientName,
}
@ -139,7 +145,7 @@ func New(stack *node.Node, ethServ *eth.Ethereum, dbParams *DBParams, enableWrit
}
indexer = ind.NewStateDiffIndexer(blockChain.Config(), db)
}
prom.Init()
sds := &Service{
Mutex: sync.Mutex{},
BlockChain: blockChain,
@ -172,6 +178,7 @@ func (sds *Service) APIs() []rpc.API {
}
}
// Swap out the cached block
func (lbc *lastBlockCache) replace(currentBlock *types.Block, bc blockChain) *types.Block {
lbc.Lock()
parentHash := currentBlock.ParentHash()
@ -510,6 +517,10 @@ func (sds *Service) StreamCodeAndCodeHash(blockNumber uint64, outChan chan<- Cod
// This operation cannot be performed back past the point of db pruning; it requires an archival node
// for historical data
func (sds *Service) WriteStateDiffAt(blockNumber uint64, params Params) error {
if sds.indexer == nil {
return errors.New("Database not configured for direct statediff writing")
}
log.Info("Writing state diff", "block height", blockNumber)
currentBlock := sds.BlockChain.GetBlockByNumber(blockNumber)
parentRoot := common.Hash{}
if blockNumber != 0 {
@ -521,7 +532,6 @@ func (sds *Service) WriteStateDiffAt(blockNumber uint64, params Params) error {
// Writes a state diff from the current block, parent state root, and provided params
func (sds *Service) writeStateDiff(block *types.Block, parentRoot common.Hash, params Params) error {
log.Info("writing state diff", "block height", block.Number().Uint64())
var totalDifficulty *big.Int
var receipts types.Receipts
if params.IncludeTD {

View File

@ -31,8 +31,9 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
statediff "github.com/ethereum/go-ethereum/statediff"
"github.com/ethereum/go-ethereum/statediff"
"github.com/ethereum/go-ethereum/statediff/testhelpers/mocks"
sdtypes "github.com/ethereum/go-ethereum/statediff/types"
)
func TestServiceLoop(t *testing.T) {
@ -75,7 +76,7 @@ var (
event2 = core.ChainEvent{Block: testBlock2}
event3 = core.ChainEvent{Block: testBlock3}
defaultParams = statediff.Params{
defaultParams = sdtypes.Params{
IncludeBlock: true,
IncludeReceipts: true,
IncludeTD: true,
@ -93,9 +94,9 @@ func testErrorInChainEventLoop(t *testing.T) {
BlockChain: &blockChain,
QuitChan: serviceQuit,
Subscriptions: make(map[common.Hash]map[rpc.ID]statediff.Subscription),
SubscriptionTypes: make(map[common.Hash]statediff.Params),
SubscriptionTypes: make(map[common.Hash]sdtypes.Params),
}
payloadChan := make(chan statediff.Payload, 2)
payloadChan := make(chan sdtypes.Payload, 2)
quitChan := make(chan bool)
service.Subscribe(rpc.NewID(), payloadChan, quitChan, defaultParams)
testRoot2 = common.HexToHash("0xTestRoot2")
@ -107,7 +108,7 @@ func testErrorInChainEventLoop(t *testing.T) {
blockChain.SetReceiptsForHash(testBlock1.Hash(), testReceipts1)
blockChain.SetReceiptsForHash(testBlock2.Hash(), testReceipts2)
payloads := make([]statediff.Payload, 0, 2)
payloads := make([]sdtypes.Payload, 0, 2)
wg := new(sync.WaitGroup)
go func() {
wg.Add(1)
@ -176,9 +177,9 @@ func testErrorInBlockLoop(t *testing.T) {
BlockChain: &blockChain,
QuitChan: make(chan bool),
Subscriptions: make(map[common.Hash]map[rpc.ID]statediff.Subscription),
SubscriptionTypes: make(map[common.Hash]statediff.Params),
SubscriptionTypes: make(map[common.Hash]sdtypes.Params),
}
payloadChan := make(chan statediff.Payload)
payloadChan := make(chan sdtypes.Payload)
quitChan := make(chan bool)
service.Subscribe(rpc.NewID(), payloadChan, quitChan, defaultParams)
blockMapping := make(map[common.Hash]*types.Block)
@ -216,7 +217,7 @@ func TestGetStateDiffAt(t *testing.T) {
}
func testErrorInStateDiffAt(t *testing.T) {
mockStateDiff := statediff.StateObject{
mockStateDiff := sdtypes.StateObject{
BlockNumber: testBlock1.Number(),
BlockHash: testBlock1.Hash(),
}
@ -232,7 +233,7 @@ func testErrorInStateDiffAt(t *testing.T) {
if err != nil {
t.Error(err)
}
expectedStateDiffPayload := statediff.Payload{
expectedStateDiffPayload := sdtypes.Payload{
StateObjectRlp: expectedStateDiffRlp,
ReceiptsRlp: expectedReceiptsRlp,
BlockRlp: expectedBlockRlp,
@ -255,7 +256,7 @@ func testErrorInStateDiffAt(t *testing.T) {
BlockChain: &blockChain,
QuitChan: make(chan bool),
Subscriptions: make(map[common.Hash]map[rpc.ID]statediff.Subscription),
SubscriptionTypes: make(map[common.Hash]statediff.Params),
SubscriptionTypes: make(map[common.Hash]sdtypes.Params),
}
stateDiffPayload, err := service.StateDiffAt(testBlock1.NumberU64(), defaultParams)
if err != nil {

View File

@ -18,23 +18,22 @@ package mocks
import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/statediff"
sdtypes "github.com/ethereum/go-ethereum/statediff/types"
)
// Builder is a mock state diff builder
type Builder struct {
Args statediff.Args
Params statediff.Params
StateRoots statediff.StateRoots
stateDiff statediff.StateObject
Args sdtypes.Args
Params sdtypes.Params
StateRoots sdtypes.StateRoots
stateDiff sdtypes.StateObject
block *types.Block
stateTrie statediff.StateObject
stateTrie sdtypes.StateObject
builderError error
}
// BuildStateDiffObject mock method
func (builder *Builder) BuildStateDiffObject(args statediff.Args, params statediff.Params) (statediff.StateObject, error) {
func (builder *Builder) BuildStateDiffObject(args sdtypes.Args, params sdtypes.Params) (sdtypes.StateObject, error) {
builder.Args = args
builder.Params = params
@ -42,7 +41,7 @@ func (builder *Builder) BuildStateDiffObject(args statediff.Args, params statedi
}
// BuildStateDiffObject mock method
func (builder *Builder) WriteStateDiffObject(args statediff.StateRoots, params statediff.Params, output sdtypes.StateNodeSink, codeOutput sdtypes.CodeSink) error {
func (builder *Builder) WriteStateDiffObject(args sdtypes.StateRoots, params sdtypes.Params, output sdtypes.StateNodeSink, codeOutput sdtypes.CodeSink) error {
builder.StateRoots = args
builder.Params = params
@ -50,14 +49,14 @@ func (builder *Builder) WriteStateDiffObject(args statediff.StateRoots, params s
}
// BuildStateTrieObject mock method
func (builder *Builder) BuildStateTrieObject(block *types.Block) (statediff.StateObject, error) {
func (builder *Builder) BuildStateTrieObject(block *types.Block) (sdtypes.StateObject, error) {
builder.block = block
return builder.stateTrie, builder.builderError
}
// SetStateDiffToBuild mock method
func (builder *Builder) SetStateDiffToBuild(stateDiff statediff.StateObject) {
func (builder *Builder) SetStateDiffToBuild(stateDiff sdtypes.StateObject) {
builder.stateDiff = stateDiff
}

View File

@ -46,7 +46,7 @@ type MockStateDiffService struct {
ParentBlockChan chan *types.Block
QuitChan chan bool
Subscriptions map[common.Hash]map[rpc.ID]statediff.Subscription
SubscriptionTypes map[common.Hash]statediff.Params
SubscriptionTypes map[common.Hash]sdtypes.Params
}
// Protocols mock method
@ -120,7 +120,7 @@ func (sds *MockStateDiffService) streamStateDiff(currentBlock *types.Block, pare
}
// StateDiffAt mock method
func (sds *MockStateDiffService) StateDiffAt(blockNumber uint64, params statediff.Params) (*statediff.Payload, error) {
func (sds *MockStateDiffService) StateDiffAt(blockNumber uint64, params sdtypes.Params) (*sdtypes.Payload, error) {
currentBlock := sds.BlockChain.GetBlockByNumber(blockNumber)
log.Info(fmt.Sprintf("sending state diff at %d", blockNumber))
if blockNumber == 0 {
@ -131,8 +131,8 @@ func (sds *MockStateDiffService) StateDiffAt(blockNumber uint64, params statedif
}
// processStateDiff method builds the state diff payload from the current block, parent state root, and provided params
func (sds *MockStateDiffService) processStateDiff(currentBlock *types.Block, parentRoot common.Hash, params statediff.Params) (*statediff.Payload, error) {
stateDiff, err := sds.Builder.BuildStateDiffObject(statediff.Args{
func (sds *MockStateDiffService) processStateDiff(currentBlock *types.Block, parentRoot common.Hash, params sdtypes.Params) (*sdtypes.Payload, error) {
stateDiff, err := sds.Builder.BuildStateDiffObject(sdtypes.Args{
NewStateRoot: currentBlock.Root(),
OldStateRoot: parentRoot,
BlockHash: currentBlock.Hash(),
@ -148,8 +148,8 @@ func (sds *MockStateDiffService) processStateDiff(currentBlock *types.Block, par
return sds.newPayload(stateDiffRlp, currentBlock, params)
}
func (sds *MockStateDiffService) newPayload(stateObject []byte, block *types.Block, params statediff.Params) (*statediff.Payload, error) {
payload := &statediff.Payload{
func (sds *MockStateDiffService) newPayload(stateObject []byte, block *types.Block, params sdtypes.Params) (*sdtypes.Payload, error) {
payload := &sdtypes.Payload{
StateObjectRlp: stateObject,
}
if params.IncludeBlock {
@ -174,7 +174,7 @@ func (sds *MockStateDiffService) newPayload(stateObject []byte, block *types.Blo
}
// WriteStateDiffAt mock method
func (sds *MockStateDiffService) WriteStateDiffAt(blockNumber uint64, params statediff.Params) error {
func (sds *MockStateDiffService) WriteStateDiffAt(blockNumber uint64, params sdtypes.Params) error {
// TODO: something useful here
return nil
}
@ -195,7 +195,7 @@ func (sds *MockStateDiffService) WriteLoop(chan core.ChainEvent) {
continue
}
// TODO:
// sds.writeStateDiff(currentBlock, parentBlock.Root(), statediff.Params{})
// sds.writeStateDiff(currentBlock, parentBlock.Root(), sdtypes.Params{})
case <-sds.QuitChan:
log.Debug("Quitting the statediff block channel")
sds.close()
@ -205,13 +205,13 @@ func (sds *MockStateDiffService) WriteLoop(chan core.ChainEvent) {
}
// StateTrieAt mock method
func (sds *MockStateDiffService) StateTrieAt(blockNumber uint64, params statediff.Params) (*statediff.Payload, error) {
func (sds *MockStateDiffService) StateTrieAt(blockNumber uint64, params sdtypes.Params) (*sdtypes.Payload, error) {
currentBlock := sds.BlockChain.GetBlockByNumber(blockNumber)
log.Info(fmt.Sprintf("sending state trie at %d", blockNumber))
return sds.stateTrieAt(currentBlock, params)
}
func (sds *MockStateDiffService) stateTrieAt(block *types.Block, params statediff.Params) (*statediff.Payload, error) {
func (sds *MockStateDiffService) stateTrieAt(block *types.Block, params sdtypes.Params) (*sdtypes.Payload, error) {
stateNodes, err := sds.Builder.BuildStateTrieObject(block)
if err != nil {
return nil, err
@ -224,7 +224,7 @@ func (sds *MockStateDiffService) stateTrieAt(block *types.Block, params statedif
}
// Subscribe is used by the API to subscribe to the service loop
func (sds *MockStateDiffService) Subscribe(id rpc.ID, sub chan<- statediff.Payload, quitChan chan<- bool, params statediff.Params) {
func (sds *MockStateDiffService) Subscribe(id rpc.ID, sub chan<- sdtypes.Payload, quitChan chan<- bool, params sdtypes.Params) {
// Subscription type is defined as the hash of the rlp-serialized subscription params
by, err := rlp.EncodeToBytes(params)
if err != nil {

View File

@ -20,86 +20,16 @@
package statediff
import (
"encoding/json"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/statediff/types"
)
// Subscription struct holds our subscription channels
type Subscription struct {
PayloadChan chan<- Payload
PayloadChan chan<- types.Payload
QuitChan chan<- bool
}
// DBParams holds params for Postgres db connection
type DBParams struct {
ConnectionURL string
ID string
ClientName string
}
// Params is used to carry in parameters from subscribing/requesting clients configuration
type Params struct {
IntermediateStateNodes bool
IntermediateStorageNodes bool
IncludeBlock bool
IncludeReceipts bool
IncludeTD bool
IncludeCode bool
WatchedAddresses []common.Address
WatchedStorageSlots []common.Hash
}
// Args bundles the arguments for the state diff builder
type Args struct {
OldStateRoot, NewStateRoot, BlockHash common.Hash
BlockNumber *big.Int
}
type StateRoots struct {
OldStateRoot, NewStateRoot common.Hash
}
// Payload packages the data to send to statediff subscriptions
type Payload struct {
BlockRlp []byte `json:"blockRlp"`
TotalDifficulty *big.Int `json:"totalDifficulty"`
ReceiptsRlp []byte `json:"receiptsRlp"`
StateObjectRlp []byte `json:"stateObjectRlp" gencodec:"required"`
encoded []byte
err error
}
func (sd *Payload) ensureEncoded() {
if sd.encoded == nil && sd.err == nil {
sd.encoded, sd.err = json.Marshal(sd)
}
}
// Length to implement Encoder interface for Payload
func (sd *Payload) Length() int {
sd.ensureEncoded()
return len(sd.encoded)
}
// Encode to implement Encoder interface for Payload
func (sd *Payload) Encode() ([]byte, error) {
sd.ensureEncoded()
return sd.encoded, sd.err
}
// StateObject is the final output structure from the builder
type StateObject struct {
BlockNumber *big.Int `json:"blockNumber" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Nodes []types.StateNode `json:"nodes" gencodec:"required"`
CodeAndCodeHashes []types.CodeAndCodeHash `json:"codeMapping"`
}
// AccountMap is a mapping of hex encoded path => account wrapper
type AccountMap map[string]accountWrapper

View File

@ -19,7 +19,12 @@
package types
import "github.com/ethereum/go-ethereum/common"
import (
"encoding/json"
"math/big"
"github.com/ethereum/go-ethereum/common"
)
// NodeType for explicitly setting type of node
type NodeType string
@ -59,3 +64,62 @@ type CodeAndCodeHash struct {
type StateNodeSink func(StateNode) error
type StorageNodeSink func(StorageNode) error
type CodeSink func(CodeAndCodeHash) error
// Params is used to carry in parameters from subscribing/requesting clients configuration
type Params struct {
IntermediateStateNodes bool
IntermediateStorageNodes bool
IncludeBlock bool
IncludeReceipts bool
IncludeTD bool
IncludeCode bool
WatchedAddresses []common.Address
WatchedStorageSlots []common.Hash
}
// Args bundles the arguments for the state diff builder
type Args struct {
OldStateRoot, NewStateRoot, BlockHash common.Hash
BlockNumber *big.Int
}
type StateRoots struct {
OldStateRoot, NewStateRoot common.Hash
}
// Payload packages the data to send to statediff subscriptions
type Payload struct {
BlockRlp []byte `json:"blockRlp"`
TotalDifficulty *big.Int `json:"totalDifficulty"`
ReceiptsRlp []byte `json:"receiptsRlp"`
StateObjectRlp []byte `json:"stateObjectRlp" gencodec:"required"`
encoded []byte
err error
}
func (sd *Payload) ensureEncoded() {
if sd.encoded == nil && sd.err == nil {
sd.encoded, sd.err = json.Marshal(sd)
}
}
// Length to implement Encoder interface for Payload
func (sd *Payload) Length() int {
sd.ensureEncoded()
return len(sd.encoded)
}
// Encode to implement Encoder interface for Payload
func (sd *Payload) Encode() ([]byte, error) {
sd.ensureEncoded()
return sd.encoded, sd.err
}
// StateObject is the final output structure from the builder
type StateObject struct {
BlockNumber *big.Int `json:"blockNumber" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Nodes []StateNode `json:"nodes" gencodec:"required"`
CodeAndCodeHashes []CodeAndCodeHash `json:"codeMapping"`
}