update to work with updated state diffing code
This commit is contained in:
parent
3108957e5f
commit
671a324294
@ -52,7 +52,7 @@
|
|||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/ethereum/go-ethereum"
|
name = "github.com/ethereum/go-ethereum"
|
||||||
source = "github.com/vulcanize/go-ethereum"
|
source = "github.com/vulcanize/go-ethereum"
|
||||||
branch = "rpc_statediffs_at_head"
|
branch = "rpc_statediffing"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/vulcanize/eth-block-extractor"
|
name = "github.com/vulcanize/eth-block-extractor"
|
||||||
|
@ -4,6 +4,7 @@ CREATE TABLE public.header_cids (
|
|||||||
block_number BIGINT NOT NULL,
|
block_number BIGINT NOT NULL,
|
||||||
block_hash VARCHAR(66) NOT NULL,
|
block_hash VARCHAR(66) NOT NULL,
|
||||||
cid TEXT NOT NULL,
|
cid TEXT NOT NULL,
|
||||||
|
uncle BOOLEAN NOT NULL,
|
||||||
UNIQUE (block_number, block_hash)
|
UNIQUE (block_number, block_hash)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
CREATE TABLE public.state_cids (
|
CREATE TABLE public.state_cids (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
header_id INTEGER NOT NULL REFERENCES header_cids (id) ON DELETE CASCADE,
|
header_id INTEGER NOT NULL REFERENCES header_cids (id) ON DELETE CASCADE,
|
||||||
account_key VARCHAR(66) NOT NULL,
|
state_key VARCHAR(66) NOT NULL,
|
||||||
|
leaf BOOLEAN NOT NULL,
|
||||||
cid TEXT NOT NULL,
|
cid TEXT NOT NULL,
|
||||||
UNIQUE (header_id, account_key)
|
UNIQUE (header_id, state_key)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- +goose Down
|
-- +goose Down
|
||||||
|
@ -3,6 +3,7 @@ CREATE TABLE public.storage_cids (
|
|||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
state_id INTEGER NOT NULL REFERENCES state_cids (id) ON DELETE CASCADE,
|
state_id INTEGER NOT NULL REFERENCES state_cids (id) ON DELETE CASCADE,
|
||||||
storage_key VARCHAR(66) NOT NULL,
|
storage_key VARCHAR(66) NOT NULL,
|
||||||
|
leaf BOOLEAN NOT NULL,
|
||||||
cid TEXT NOT NULL,
|
cid TEXT NOT NULL,
|
||||||
UNIQUE (state_id, storage_key)
|
UNIQUE (state_id, storage_key)
|
||||||
);
|
);
|
||||||
|
@ -63,8 +63,8 @@ func (pc *Converter) Convert(payload statediff.Payload) (*IPLDPayload, error) {
|
|||||||
TrxMetaData: make([]*TrxMetaData, 0, trxLen),
|
TrxMetaData: make([]*TrxMetaData, 0, trxLen),
|
||||||
Receipts: make(types.Receipts, 0, trxLen),
|
Receipts: make(types.Receipts, 0, trxLen),
|
||||||
ReceiptMetaData: make([]*ReceiptMetaData, 0, trxLen),
|
ReceiptMetaData: make([]*ReceiptMetaData, 0, trxLen),
|
||||||
StateLeafs: make(map[common.Hash][]byte),
|
StateNodes: make(map[common.Hash]StateNode),
|
||||||
StorageLeafs: make(map[common.Hash]map[common.Hash][]byte),
|
StorageNodes: make(map[common.Hash][]StorageNode),
|
||||||
}
|
}
|
||||||
for gethTransactionIndex, trx := range block.Transactions() {
|
for gethTransactionIndex, trx := range block.Transactions() {
|
||||||
// Extract to and from data from the the transactions for indexing
|
// Extract to and from data from the the transactions for indexing
|
||||||
@ -105,25 +105,49 @@ func (pc *Converter) Convert(payload statediff.Payload) (*IPLDPayload, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for addr, createdAccount := range stateDiff.CreatedAccounts {
|
for _, createdAccount := range stateDiff.CreatedAccounts {
|
||||||
convertedPayload.StateLeafs[addr] = createdAccount.Value
|
hashKey := common.BytesToHash(createdAccount.Key)
|
||||||
convertedPayload.StorageLeafs[addr] = make(map[common.Hash][]byte)
|
convertedPayload.StateNodes[hashKey] = StateNode{
|
||||||
|
Value: createdAccount.Value,
|
||||||
|
Leaf: createdAccount.Leaf,
|
||||||
|
}
|
||||||
|
convertedPayload.StorageNodes[hashKey] = make([]StorageNode, 0)
|
||||||
for _, storageDiff := range createdAccount.Storage {
|
for _, storageDiff := range createdAccount.Storage {
|
||||||
convertedPayload.StorageLeafs[addr][common.BytesToHash(storageDiff.Key)] = storageDiff.Value
|
convertedPayload.StorageNodes[hashKey] = append(convertedPayload.StorageNodes[hashKey], StorageNode{
|
||||||
|
Key: common.BytesToHash(storageDiff.Key),
|
||||||
|
Value: storageDiff.Value,
|
||||||
|
Leaf: storageDiff.Leaf,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for addr, deletedAccount := range stateDiff.DeletedAccounts {
|
for _, deletedAccount := range stateDiff.DeletedAccounts {
|
||||||
convertedPayload.StateLeafs[addr] = deletedAccount.Value
|
hashKey := common.BytesToHash(deletedAccount.Key)
|
||||||
convertedPayload.StorageLeafs[addr] = make(map[common.Hash][]byte)
|
convertedPayload.StateNodes[hashKey] = StateNode{
|
||||||
|
Value: deletedAccount.Value,
|
||||||
|
Leaf: deletedAccount.Leaf,
|
||||||
|
}
|
||||||
|
convertedPayload.StorageNodes[hashKey] = make([]StorageNode, 0)
|
||||||
for _, storageDiff := range deletedAccount.Storage {
|
for _, storageDiff := range deletedAccount.Storage {
|
||||||
convertedPayload.StorageLeafs[addr][common.BytesToHash(storageDiff.Key)] = storageDiff.Value
|
convertedPayload.StorageNodes[hashKey] = append(convertedPayload.StorageNodes[hashKey], StorageNode{
|
||||||
|
Key: common.BytesToHash(storageDiff.Key),
|
||||||
|
Value: storageDiff.Value,
|
||||||
|
Leaf: storageDiff.Leaf,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for addr, updatedAccount := range stateDiff.UpdatedAccounts {
|
for _, updatedAccount := range stateDiff.UpdatedAccounts {
|
||||||
convertedPayload.StateLeafs[addr] = updatedAccount.Value
|
hashKey := common.BytesToHash(updatedAccount.Key)
|
||||||
convertedPayload.StorageLeafs[addr] = make(map[common.Hash][]byte)
|
convertedPayload.StateNodes[hashKey] = StateNode{
|
||||||
|
Value: updatedAccount.Value,
|
||||||
|
Leaf: updatedAccount.Leaf,
|
||||||
|
}
|
||||||
|
convertedPayload.StorageNodes[hashKey] = make([]StorageNode, 0)
|
||||||
for _, storageDiff := range updatedAccount.Storage {
|
for _, storageDiff := range updatedAccount.Storage {
|
||||||
convertedPayload.StorageLeafs[addr][common.BytesToHash(storageDiff.Key)] = storageDiff.Value
|
convertedPayload.StorageNodes[hashKey] = append(convertedPayload.StorageNodes[hashKey], StorageNode{
|
||||||
|
Key: common.BytesToHash(storageDiff.Key),
|
||||||
|
Value: storageDiff.Value,
|
||||||
|
Leaf: storageDiff.Leaf,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return convertedPayload, nil
|
return convertedPayload, nil
|
||||||
|
@ -34,9 +34,5 @@ var _ = Describe("Converter", func() {
|
|||||||
Expect(ipldPayload).To(Equal(&test_helpers.MockIPLDPayload))
|
Expect(ipldPayload).To(Equal(&test_helpers.MockIPLDPayload))
|
||||||
Expect(mockConverter.PassedStatediffPayload).To(Equal(test_helpers.MockStatediffPayload))
|
Expect(mockConverter.PassedStatediffPayload).To(Equal(test_helpers.MockStatediffPayload))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Fails if", func() {
|
|
||||||
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -24,37 +24,31 @@ import (
|
|||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IPLDFetcher is the interface for fetching IPLD objects from IPFS
|
// IPLDFetcher is the underlying struct which supports a IPLD fetching interface
|
||||||
type IPLDFetcher interface {
|
type IPLDFetcher struct {
|
||||||
Fetch(cid cid.Cid) (blocks.Block, error)
|
|
||||||
FetchBatch(cids []cid.Cid) []blocks.Block
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetcher is the underlying struct which supports the IPLDFetcher interface
|
|
||||||
type Fetcher struct {
|
|
||||||
BlockService blockservice.BlockService
|
BlockService blockservice.BlockService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIPLDFetcher creates a pointer to a new Fetcher which satisfies the IPLDFetcher interface
|
// NewIPLDFetcher creates a pointer to a new IPLDFetcher
|
||||||
func NewIPLDFetcher(ipfsPath string) (*Fetcher, error) {
|
func NewIPLDFetcher(ipfsPath string) (*IPLDFetcher, error) {
|
||||||
blockService, err := InitIPFSBlockService(ipfsPath)
|
blockService, err := InitIPFSBlockService(ipfsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Fetcher{
|
return &IPLDFetcher{
|
||||||
BlockService: blockService,
|
BlockService: blockService,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch is used to fetch a batch of IPFS data blocks by cid
|
// Fetch is used to fetch a single block of IPFS data by cid
|
||||||
func (f *Fetcher) Fetch(cid cid.Cid) (blocks.Block, error) {
|
func (f *IPLDFetcher) Fetch(cid cid.Cid) (blocks.Block, error) {
|
||||||
return f.BlockService.GetBlock(context.Background(), cid)
|
return f.BlockService.GetBlock(context.Background(), cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchBatch is used to fetch a batch of IPFS data blocks by cid
|
// FetchBatch is used to fetch a batch of IPFS data blocks by cid
|
||||||
// There is no guarantee all are fetched, and no error in such a case, so
|
// There is no guarantee all are fetched, and no error in such a case, so
|
||||||
// downstream we will need to confirm which CIDs were fetched in the result set
|
// downstream we will need to confirm which CIDs were fetched in the result set
|
||||||
func (f *Fetcher) FetchBatch(cids []cid.Cid) []blocks.Block {
|
func (f *IPLDFetcher) FetchBatch(cids []cid.Cid) []blocks.Block {
|
||||||
fetchedBlocks := make([]blocks.Block, 0, len(cids))
|
fetchedBlocks := make([]blocks.Block, 0, len(cids))
|
||||||
blockChan := f.BlockService.GetBlocks(context.Background(), cids)
|
blockChan := f.BlockService.GetBlocks(context.Background(), cids)
|
||||||
for block := range blockChan {
|
for block := range blockChan {
|
||||||
|
@ -17,10 +17,11 @@
|
|||||||
package ipfs_test
|
package ipfs_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
@ -72,8 +72,8 @@ func (i *Processor) Process(wg *sync.WaitGroup) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
wg.Add(1)
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case payload := <-i.PayloadChan:
|
case payload := <-i.PayloadChan:
|
||||||
@ -98,6 +98,7 @@ func (i *Processor) Process(wg *sync.WaitGroup) error {
|
|||||||
case err = <-sub.Err():
|
case err = <-sub.Err():
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
case <-i.QuitChan:
|
case <-i.QuitChan:
|
||||||
|
println("quiting")
|
||||||
log.Info("quiting IPFSProcessor")
|
log.Info("quiting IPFSProcessor")
|
||||||
wg.Done()
|
wg.Done()
|
||||||
return
|
return
|
||||||
|
@ -18,6 +18,7 @@ package ipfs_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/ethereum/go-ethereum/statediff"
|
"github.com/ethereum/go-ethereum/statediff"
|
||||||
@ -34,36 +35,43 @@ var _ = Describe("Processor", func() {
|
|||||||
Describe("Process", func() {
|
Describe("Process", func() {
|
||||||
It("Streams StatediffPayloads, converts them to IPLDPayloads, publishes IPLDPayloads, and indexes CIDPayloads", func() {
|
It("Streams StatediffPayloads, converts them to IPLDPayloads, publishes IPLDPayloads, and indexes CIDPayloads", func() {
|
||||||
wg := new(sync.WaitGroup)
|
wg := new(sync.WaitGroup)
|
||||||
payloadChan := make(chan statediff.Payload, 800)
|
payloadChan := make(chan statediff.Payload, 1)
|
||||||
processor := ipfs.Processor{
|
quitChan := make(chan bool, 1)
|
||||||
Repository: &mocks.CIDRepository{
|
mockCidRepo := &mocks.CIDRepository{
|
||||||
ReturnErr: nil,
|
ReturnErr: nil,
|
||||||
},
|
}
|
||||||
Publisher: &mocks.IPLDPublisher{
|
mockPublisher := &mocks.IPLDPublisher{
|
||||||
ReturnCIDPayload: &test_helpers.MockCIDPayload,
|
ReturnCIDPayload: &test_helpers.MockCIDPayload,
|
||||||
ReturnErr: nil,
|
ReturnErr: nil,
|
||||||
},
|
}
|
||||||
Streamer: &mocks.StateDiffStreamer{
|
mockStreamer := &mocks.StateDiffStreamer{
|
||||||
ReturnSub: &rpc.ClientSubscription{},
|
ReturnSub: &rpc.ClientSubscription{},
|
||||||
StreamPayloads: []statediff.Payload{
|
StreamPayloads: []statediff.Payload{
|
||||||
test_helpers.MockStatediffPayload,
|
test_helpers.MockStatediffPayload,
|
||||||
},
|
|
||||||
ReturnErr: nil,
|
|
||||||
WaitGroup: wg,
|
|
||||||
},
|
|
||||||
Converter: &mocks.PayloadConverter{
|
|
||||||
ReturnIPLDPayload: &test_helpers.MockIPLDPayload,
|
|
||||||
ReturnErr: nil,
|
|
||||||
},
|
},
|
||||||
|
ReturnErr: nil,
|
||||||
|
}
|
||||||
|
mockConverter := &mocks.PayloadConverter{
|
||||||
|
ReturnIPLDPayload: &test_helpers.MockIPLDPayload,
|
||||||
|
ReturnErr: nil,
|
||||||
|
}
|
||||||
|
processor := &ipfs.Processor{
|
||||||
|
Repository: mockCidRepo,
|
||||||
|
Publisher: mockPublisher,
|
||||||
|
Streamer: mockStreamer,
|
||||||
|
Converter: mockConverter,
|
||||||
PayloadChan: payloadChan,
|
PayloadChan: payloadChan,
|
||||||
|
QuitChan: quitChan,
|
||||||
}
|
}
|
||||||
err := processor.Process(wg)
|
err := processor.Process(wg)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
quitChan <- true
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
})
|
Expect(mockConverter.PassedStatediffPayload).To(Equal(test_helpers.MockStatediffPayload))
|
||||||
|
Expect(mockCidRepo.PassedCIDPayload).To(Equal(&test_helpers.MockCIDPayload))
|
||||||
It("Fails if", func() {
|
Expect(mockPublisher.PassedIPLDPayload).To(Equal(&test_helpers.MockIPLDPayload))
|
||||||
|
Expect(mockStreamer.PassedPayloadChan).To(Equal(payloadChan))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -98,27 +98,27 @@ func (pub *Publisher) Publish(payload *IPLDPayload) (*CIDPayload, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process and publish state leafs
|
// Process and publish state leafs
|
||||||
stateLeafCids, err := pub.publishStateLeafs(payload.StateLeafs)
|
stateLeafCids, err := pub.publishStateNodes(payload.StateNodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process and publish storage leafs
|
// Process and publish storage leafs
|
||||||
storageLeafCids, err := pub.publishStorageLeafs(payload.StorageLeafs)
|
storageLeafCids, err := pub.publishStorageNodes(payload.StorageNodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Package CIDs into a single struct
|
// Package CIDs into a single struct
|
||||||
return &CIDPayload{
|
return &CIDPayload{
|
||||||
BlockHash: payload.BlockHash.Hex(),
|
BlockHash: payload.BlockHash,
|
||||||
BlockNumber: payload.BlockNumber.String(),
|
BlockNumber: payload.BlockNumber.String(),
|
||||||
HeaderCID: headerCid,
|
HeaderCID: headerCid,
|
||||||
UncleCIDS: uncleCids,
|
UncleCIDS: uncleCids,
|
||||||
TransactionCIDs: transactionCids,
|
TransactionCIDs: transactionCids,
|
||||||
ReceiptCIDs: receiptsCids,
|
ReceiptCIDs: receiptsCids,
|
||||||
StateLeafCIDs: stateLeafCids,
|
StateNodeCIDs: stateLeafCids,
|
||||||
StorageLeafCIDs: storageLeafCids,
|
StorageNodeCIDs: storageLeafCids,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,34 +165,41 @@ func (pub *Publisher) publishReceipts(receipts types.Receipts, receiptMeta []*Re
|
|||||||
return mappedRctCids, nil
|
return mappedRctCids, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pub *Publisher) publishStateLeafs(stateLeafs map[common.Hash][]byte) (map[common.Hash]string, error) {
|
func (pub *Publisher) publishStateNodes(stateNodes map[common.Hash]StateNode) (map[common.Hash]StateNodeCID, error) {
|
||||||
stateLeafCids := make(map[common.Hash]string)
|
stateNodeCids := make(map[common.Hash]StateNodeCID)
|
||||||
for addr, leaf := range stateLeafs {
|
for addr, node := range stateNodes {
|
||||||
stateLeafCid, err := pub.StatePutter.DagPut(leaf)
|
stateNodeCid, err := pub.StatePutter.DagPut(node.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(stateLeafCid) != 1 {
|
if len(stateNodeCid) != 1 {
|
||||||
return nil, errors.New("single CID expected to be returned for state leaf")
|
return nil, errors.New("single CID expected to be returned for state leaf")
|
||||||
}
|
}
|
||||||
stateLeafCids[addr] = stateLeafCid[0]
|
stateNodeCids[addr] = StateNodeCID{
|
||||||
|
CID: stateNodeCid[0],
|
||||||
|
Leaf: node.Leaf,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return stateLeafCids, nil
|
return stateNodeCids, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pub *Publisher) publishStorageLeafs(storageLeafs map[common.Hash]map[common.Hash][]byte) (map[common.Hash]map[common.Hash]string, error) {
|
func (pub *Publisher) publishStorageNodes(storageNodes map[common.Hash][]StorageNode) (map[common.Hash][]StorageNodeCID, error) {
|
||||||
storageLeafCids := make(map[common.Hash]map[common.Hash]string)
|
storageLeafCids := make(map[common.Hash][]StorageNodeCID)
|
||||||
for addr, storageTrie := range storageLeafs {
|
for addr, storageTrie := range storageNodes {
|
||||||
storageLeafCids[addr] = make(map[common.Hash]string)
|
storageLeafCids[addr] = make([]StorageNodeCID, 0)
|
||||||
for key, leaf := range storageTrie {
|
for _, node := range storageTrie {
|
||||||
storageLeafCid, err := pub.StoragePutter.DagPut(leaf)
|
storageNodeCid, err := pub.StoragePutter.DagPut(node.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(storageLeafCid) != 1 {
|
if len(storageNodeCid) != 1 {
|
||||||
return nil, errors.New("single CID expected to be returned for storage leaf")
|
return nil, errors.New("single CID expected to be returned for storage leaf")
|
||||||
}
|
}
|
||||||
storageLeafCids[addr][key] = storageLeafCid[0]
|
storageLeafCids[addr] = append(storageLeafCids[addr], StorageNodeCID{
|
||||||
|
Key: node.Key,
|
||||||
|
CID: storageNodeCid[0],
|
||||||
|
Leaf: node.Leaf,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return storageLeafCids, nil
|
return storageLeafCids, nil
|
||||||
|
@ -34,9 +34,5 @@ var _ = Describe("Publisher", func() {
|
|||||||
Expect(cidPayload).To(Equal(&test_helpers.MockCIDPayload))
|
Expect(cidPayload).To(Equal(&test_helpers.MockCIDPayload))
|
||||||
Expect(mockPublisher.PassedIPLDPayload).To(Equal(&test_helpers.MockIPLDPayload))
|
Expect(mockPublisher.PassedIPLDPayload).To(Equal(&test_helpers.MockIPLDPayload))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Fails if", func() {
|
|
||||||
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -43,11 +43,14 @@ func NewCIDRepository(db *postgres.DB) *Repository {
|
|||||||
// Index indexes a cidPayload in Postgres
|
// Index indexes a cidPayload in Postgres
|
||||||
func (repo *Repository) Index(cidPayload *CIDPayload) error {
|
func (repo *Repository) Index(cidPayload *CIDPayload) error {
|
||||||
tx, _ := repo.db.Beginx()
|
tx, _ := repo.db.Beginx()
|
||||||
headerID, err := repo.indexHeaderCID(tx, cidPayload.HeaderCID, cidPayload.BlockNumber, cidPayload.BlockHash)
|
headerID, err := repo.indexHeaderCID(tx, cidPayload.HeaderCID, cidPayload.BlockNumber, cidPayload.BlockHash.Hex())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
for uncleHash, cid := range cidPayload.UncleCIDS {
|
||||||
|
err = repo.indexUncleCID(tx, cid, cidPayload.BlockNumber, uncleHash.Hex())
|
||||||
|
}
|
||||||
err = repo.indexTransactionAndReceiptCIDs(tx, cidPayload, headerID)
|
err = repo.indexTransactionAndReceiptCIDs(tx, cidPayload, headerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
@ -63,13 +66,20 @@ func (repo *Repository) Index(cidPayload *CIDPayload) error {
|
|||||||
|
|
||||||
func (repo *Repository) indexHeaderCID(tx *sqlx.Tx, cid, blockNumber, hash string) (int64, error) {
|
func (repo *Repository) indexHeaderCID(tx *sqlx.Tx, cid, blockNumber, hash string) (int64, error) {
|
||||||
var headerID int64
|
var headerID int64
|
||||||
err := tx.QueryRowx(`INSERT INTO public.header_cids (block_number, block_hash, cid) VALUES ($1, $2, $3)
|
err := tx.QueryRowx(`INSERT INTO public.header_cids (block_number, block_hash, cid, uncle) VALUES ($1, $2, $3, $4)
|
||||||
ON CONFLICT DO UPDATE SET cid = $3
|
ON CONFLICT DO UPDATE SET (cid, uncle) = ($3, $4)
|
||||||
RETURNING id`,
|
RETURNING id`,
|
||||||
blockNumber, hash, cid).Scan(&headerID)
|
blockNumber, hash, cid, false).Scan(&headerID)
|
||||||
return headerID, err
|
return headerID, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *Repository) indexUncleCID(tx *sqlx.Tx, cid, blockNumber, hash string) error {
|
||||||
|
_, err := tx.Queryx(`INSERT INTO public.header_cids (block_number, block_hash, cid, uncle) VALUES ($1, $2, $3, $4)
|
||||||
|
ON CONFLICT DO UPDATE SET (cid, uncle) = ($3, $4)`,
|
||||||
|
blockNumber, hash, cid, true)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (repo *Repository) indexTransactionAndReceiptCIDs(tx *sqlx.Tx, payload *CIDPayload, headerID int64) error {
|
func (repo *Repository) indexTransactionAndReceiptCIDs(tx *sqlx.Tx, payload *CIDPayload, headerID int64) error {
|
||||||
for hash, trxCidMeta := range payload.TransactionCIDs {
|
for hash, trxCidMeta := range payload.TransactionCIDs {
|
||||||
var txID int64
|
var txID int64
|
||||||
@ -98,17 +108,17 @@ func (repo *Repository) indexReceiptCID(tx *sqlx.Tx, cidMeta *ReceiptMetaData, t
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repository) indexStateAndStorageCIDs(tx *sqlx.Tx, payload *CIDPayload, headerID int64) error {
|
func (repo *Repository) indexStateAndStorageCIDs(tx *sqlx.Tx, payload *CIDPayload, headerID int64) error {
|
||||||
for accountKey, stateCID := range payload.StateLeafCIDs {
|
for accountKey, stateCID := range payload.StateNodeCIDs {
|
||||||
var stateID int64
|
var stateID int64
|
||||||
err := tx.QueryRowx(`INSERT INTO public.state_cids (header_id, account_key, cid) VALUES ($1, $2, $3)
|
err := tx.QueryRowx(`INSERT INTO public.state_cids (header_id, state_key, cid, leaf) VALUES ($1, $2, $3, $4)
|
||||||
ON CONFLICT DO UPDATE SET cid = $3
|
ON CONFLICT DO UPDATE SET (cid, leaf) = ($3, $4)
|
||||||
RETURNING id`,
|
RETURNING id`,
|
||||||
headerID, accountKey.Hex(), stateCID).Scan(&stateID)
|
headerID, accountKey.Hex(), stateCID.CID, stateCID.Leaf).Scan(&stateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for storageKey, storageCID := range payload.StorageLeafCIDs[accountKey] {
|
for _, storageCID := range payload.StorageNodeCIDs[accountKey] {
|
||||||
err = repo.indexStorageCID(tx, storageKey.Hex(), storageCID, stateID)
|
err = repo.indexStorageCID(tx, storageCID, stateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -117,8 +127,9 @@ func (repo *Repository) indexStateAndStorageCIDs(tx *sqlx.Tx, payload *CIDPayloa
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repository) indexStorageCID(tx *sqlx.Tx, key, cid string, stateID int64) error {
|
func (repo *Repository) indexStorageCID(tx *sqlx.Tx, storageCID StorageNodeCID, stateID int64) error {
|
||||||
_, err := repo.db.Exec(`INSERT INTO public.storage_cids (state_id, storage_key, cid) VALUES ($1, $2, $3)
|
_, err := repo.db.Exec(`INSERT INTO public.storage_cids (state_id, storage_key, cid, leaf) VALUES ($1, $2, $3, $4)
|
||||||
ON CONFLICT DO UPDATE SET cid = $3`, stateID, key, cid)
|
ON CONFLICT DO UPDATE SET (cid, leaf) = ($3, $4)`,
|
||||||
|
stateID, storageCID.Key, storageCID.CID, storageCID.Leaf)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,5 @@ var _ = Describe("Repository", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(mockRepo.PassedCIDPayload).To(Equal(&test_helpers.MockCIDPayload))
|
Expect(mockRepo.PassedCIDPayload).To(Equal(&test_helpers.MockCIDPayload))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Fails if", func() {
|
|
||||||
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
package ipfs_test
|
package ipfs_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/ethereum/go-ethereum/statediff"
|
"github.com/ethereum/go-ethereum/statediff"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
@ -31,25 +29,18 @@ import (
|
|||||||
var _ = Describe("Streamer", func() {
|
var _ = Describe("Streamer", func() {
|
||||||
Describe("Stream", func() {
|
Describe("Stream", func() {
|
||||||
It("Streams StatediffPayloads from a Geth RPC subscription", func() {
|
It("Streams StatediffPayloads from a Geth RPC subscription", func() {
|
||||||
wg := new(sync.WaitGroup)
|
|
||||||
mockStreamer := mocks.StateDiffStreamer{}
|
mockStreamer := mocks.StateDiffStreamer{}
|
||||||
mockStreamer.ReturnSub = &rpc.ClientSubscription{}
|
mockStreamer.ReturnSub = &rpc.ClientSubscription{}
|
||||||
mockStreamer.WaitGroup = wg
|
|
||||||
mockStreamer.StreamPayloads = []statediff.Payload{
|
mockStreamer.StreamPayloads = []statediff.Payload{
|
||||||
test_helpers.MockStatediffPayload,
|
test_helpers.MockStatediffPayload,
|
||||||
}
|
}
|
||||||
payloadChan := make(chan statediff.Payload, 1)
|
payloadChan := make(chan statediff.Payload, 1)
|
||||||
sub, err := mockStreamer.Stream(payloadChan)
|
sub, err := mockStreamer.Stream(payloadChan)
|
||||||
wg.Wait()
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(sub).To(Equal(&rpc.ClientSubscription{}))
|
Expect(sub).To(Equal(&rpc.ClientSubscription{}))
|
||||||
Expect(mockStreamer.PassedPayloadChan).To(Equal(payloadChan))
|
Expect(mockStreamer.PassedPayloadChan).To(Equal(payloadChan))
|
||||||
streamedPayload := <-payloadChan
|
streamedPayload := <-payloadChan
|
||||||
Expect(streamedPayload).To(Equal(test_helpers.MockStatediffPayload))
|
Expect(streamedPayload).To(Equal(test_helpers.MockStatediffPayload))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Fails if", func() {
|
|
||||||
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
package mocks
|
package mocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/ethereum/go-ethereum/statediff"
|
"github.com/ethereum/go-ethereum/statediff"
|
||||||
)
|
)
|
||||||
@ -29,7 +27,6 @@ type StateDiffStreamer struct {
|
|||||||
ReturnSub *rpc.ClientSubscription
|
ReturnSub *rpc.ClientSubscription
|
||||||
ReturnErr error
|
ReturnErr error
|
||||||
StreamPayloads []statediff.Payload
|
StreamPayloads []statediff.Payload
|
||||||
WaitGroup *sync.WaitGroup
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream is the main loop for subscribing to data from the Geth state diff process
|
// Stream is the main loop for subscribing to data from the Geth state diff process
|
||||||
@ -37,11 +34,9 @@ func (sds *StateDiffStreamer) Stream(payloadChan chan statediff.Payload) (*rpc.C
|
|||||||
sds.PassedPayloadChan = payloadChan
|
sds.PassedPayloadChan = payloadChan
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
sds.WaitGroup.Add(1)
|
|
||||||
for _, payload := range sds.StreamPayloads {
|
for _, payload := range sds.StreamPayloads {
|
||||||
sds.PassedPayloadChan <- payload
|
sds.PassedPayloadChan <- payload
|
||||||
}
|
}
|
||||||
sds.WaitGroup.Done()
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return sds.ReturnSub, sds.ReturnErr
|
return sds.ReturnSub, sds.ReturnErr
|
||||||
|
@ -38,7 +38,7 @@ func AddressToLeafKey(address common.Address) common.Hash {
|
|||||||
|
|
||||||
// Test variables
|
// Test variables
|
||||||
var (
|
var (
|
||||||
BlockNumber = rand.Int63()
|
BlockNumber = big.NewInt(rand.Int63())
|
||||||
BlockHash = "0xfa40fbe2d98d98b3363a778d52f2bcd29d6790b9b3f3cab2b167fd12d3550f73"
|
BlockHash = "0xfa40fbe2d98d98b3363a778d52f2bcd29d6790b9b3f3cab2b167fd12d3550f73"
|
||||||
CodeHash = common.Hex2Bytes("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
|
CodeHash = common.Hex2Bytes("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
|
||||||
NewNonceValue = rand.Uint64()
|
NewNonceValue = rand.Uint64()
|
||||||
@ -65,26 +65,26 @@ var (
|
|||||||
CodeHash: CodeHash,
|
CodeHash: CodeHash,
|
||||||
}
|
}
|
||||||
valueBytes, _ = rlp.EncodeToBytes(testAccount)
|
valueBytes, _ = rlp.EncodeToBytes(testAccount)
|
||||||
CreatedAccountDiffs = statediff.AccountDiffsMap{
|
CreatedAccountDiffs = []statediff.AccountDiff{
|
||||||
ContractLeafKey: {
|
{
|
||||||
Key: ContractLeafKey.Bytes(),
|
Key: ContractLeafKey.Bytes(),
|
||||||
Value: valueBytes,
|
Value: valueBytes,
|
||||||
Storage: storage,
|
Storage: storage,
|
||||||
},
|
},
|
||||||
AnotherContractLeafKey: {
|
{
|
||||||
Key: AnotherContractLeafKey.Bytes(),
|
Key: AnotherContractLeafKey.Bytes(),
|
||||||
Value: valueBytes,
|
Value: valueBytes,
|
||||||
Storage: emptyStorage,
|
Storage: emptyStorage,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatedAccountDiffs = statediff.AccountDiffsMap{ContractLeafKey: {
|
UpdatedAccountDiffs = []statediff.AccountDiff{{
|
||||||
Key: ContractLeafKey.Bytes(),
|
Key: ContractLeafKey.Bytes(),
|
||||||
Value: valueBytes,
|
Value: valueBytes,
|
||||||
Storage: storage,
|
Storage: storage,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
DeletedAccountDiffs = statediff.AccountDiffsMap{ContractLeafKey: {
|
DeletedAccountDiffs = []statediff.AccountDiff{{
|
||||||
Key: ContractLeafKey.Bytes(),
|
Key: ContractLeafKey.Bytes(),
|
||||||
Value: valueBytes,
|
Value: valueBytes,
|
||||||
Storage: storage,
|
Storage: storage,
|
||||||
@ -97,7 +97,7 @@ var (
|
|||||||
DeletedAccounts: DeletedAccountDiffs,
|
DeletedAccounts: DeletedAccountDiffs,
|
||||||
UpdatedAccounts: UpdatedAccountDiffs,
|
UpdatedAccounts: UpdatedAccountDiffs,
|
||||||
}
|
}
|
||||||
MockStateDiffRlp, _ = rlp.EncodeToBytes(MockStateDiff)
|
MockStateDiffBytes, _ = rlp.EncodeToBytes(MockStateDiff)
|
||||||
|
|
||||||
mockTransaction1 = types.NewTransaction(0, common.HexToAddress("0x0"), big.NewInt(1000), 50, big.NewInt(100), nil)
|
mockTransaction1 = types.NewTransaction(0, common.HexToAddress("0x0"), big.NewInt(1000), 50, big.NewInt(100), nil)
|
||||||
mockTransaction2 = types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(2000), 100, big.NewInt(200), nil)
|
mockTransaction2 = types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(2000), 100, big.NewInt(200), nil)
|
||||||
@ -119,7 +119,7 @@ var (
|
|||||||
|
|
||||||
MockStatediffPayload = statediff.Payload{
|
MockStatediffPayload = statediff.Payload{
|
||||||
BlockRlp: MockBlockRlp,
|
BlockRlp: MockBlockRlp,
|
||||||
StateDiffRlp: MockStateDiffRlp,
|
StateDiffRlp: MockStateDiffBytes,
|
||||||
Err: nil,
|
Err: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ var (
|
|||||||
|
|
||||||
MockCIDPayload = ipfs.CIDPayload{
|
MockCIDPayload = ipfs.CIDPayload{
|
||||||
BlockNumber: "1",
|
BlockNumber: "1",
|
||||||
BlockHash: "0x0",
|
BlockHash: common.HexToHash("0x0"),
|
||||||
HeaderCID: "mockHeaderCID",
|
HeaderCID: "mockHeaderCID",
|
||||||
TransactionCIDs: map[common.Hash]*ipfs.TrxMetaData{
|
TransactionCIDs: map[common.Hash]*ipfs.TrxMetaData{
|
||||||
common.HexToHash("0x0"): {
|
common.HexToHash("0x0"): {
|
||||||
@ -163,16 +163,30 @@ var (
|
|||||||
Topic0s: []string{"mockTopic1", "mockTopic2"},
|
Topic0s: []string{"mockTopic1", "mockTopic2"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
StateLeafCIDs: map[common.Hash]string{
|
StateNodeCIDs: map[common.Hash]ipfs.StateNodeCID{
|
||||||
common.HexToHash("0x0"): "mockStateCID1",
|
|
||||||
common.HexToHash("0x1"): "mockStateCID2",
|
|
||||||
},
|
|
||||||
StorageLeafCIDs: map[common.Hash]map[common.Hash]string{
|
|
||||||
common.HexToHash("0x0"): {
|
common.HexToHash("0x0"): {
|
||||||
common.HexToHash("0x0"): "mockStorageCID1",
|
CID: "mockStateCID1",
|
||||||
|
Leaf: true,
|
||||||
},
|
},
|
||||||
common.HexToHash("0x1"): {
|
common.HexToHash("0x1"): {
|
||||||
common.HexToHash("0x1"): "mockStorageCID2",
|
CID: "mockStateCID2",
|
||||||
|
Leaf: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
StorageNodeCIDs: map[common.Hash][]ipfs.StorageNodeCID{
|
||||||
|
common.HexToHash("0x0"): {
|
||||||
|
{
|
||||||
|
CID: "mockStorageCID1",
|
||||||
|
Key: common.HexToHash("0x0"),
|
||||||
|
Leaf: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
common.HexToHash("0x1"): {
|
||||||
|
{
|
||||||
|
CID: "mockStorageCID2",
|
||||||
|
Key: common.HexToHash("0x1"),
|
||||||
|
Leaf: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,10 @@
|
|||||||
package ipfs
|
package ipfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"math/big"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IPLDPayload is a custom type which packages ETH data for the IPFS publisher
|
// IPLDPayload is a custom type which packages ETH data for the IPFS publisher
|
||||||
@ -31,20 +32,42 @@ type IPLDPayload struct {
|
|||||||
TrxMetaData []*TrxMetaData
|
TrxMetaData []*TrxMetaData
|
||||||
Receipts types.Receipts
|
Receipts types.Receipts
|
||||||
ReceiptMetaData []*ReceiptMetaData
|
ReceiptMetaData []*ReceiptMetaData
|
||||||
StateLeafs map[common.Hash][]byte
|
StateNodes map[common.Hash]StateNode
|
||||||
StorageLeafs map[common.Hash]map[common.Hash][]byte
|
StorageNodes map[common.Hash][]StorageNode
|
||||||
|
}
|
||||||
|
|
||||||
|
type StateNode struct {
|
||||||
|
Value []byte
|
||||||
|
Leaf bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type StorageNode struct {
|
||||||
|
Key common.Hash
|
||||||
|
Value []byte
|
||||||
|
Leaf bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CIDPayload is a struct to hold all the CIDs and their meta data
|
// CIDPayload is a struct to hold all the CIDs and their meta data
|
||||||
type CIDPayload struct {
|
type CIDPayload struct {
|
||||||
BlockNumber string
|
BlockNumber string
|
||||||
BlockHash string
|
BlockHash common.Hash
|
||||||
HeaderCID string
|
HeaderCID string
|
||||||
UncleCIDS map[common.Hash]string
|
UncleCIDS map[common.Hash]string
|
||||||
TransactionCIDs map[common.Hash]*TrxMetaData
|
TransactionCIDs map[common.Hash]*TrxMetaData
|
||||||
ReceiptCIDs map[common.Hash]*ReceiptMetaData
|
ReceiptCIDs map[common.Hash]*ReceiptMetaData
|
||||||
StateLeafCIDs map[common.Hash]string
|
StateNodeCIDs map[common.Hash]StateNodeCID
|
||||||
StorageLeafCIDs map[common.Hash]map[common.Hash]string
|
StorageNodeCIDs map[common.Hash][]StorageNodeCID
|
||||||
|
}
|
||||||
|
|
||||||
|
type StateNodeCID struct {
|
||||||
|
CID string
|
||||||
|
Leaf bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type StorageNodeCID struct {
|
||||||
|
Key common.Hash
|
||||||
|
CID string
|
||||||
|
Leaf bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReceiptMetaData wraps some additional data around our receipt CIDs for indexing
|
// ReceiptMetaData wraps some additional data around our receipt CIDs for indexing
|
||||||
|
17
vendor/github.com/ethereum/go-ethereum/statediff/api.go
generated
vendored
17
vendor/github.com/ethereum/go-ethereum/statediff/api.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2019 The go-ethereum Authors
|
||||||
// This file is part of the go-ethereum library.
|
// This file is part of the go-ethereum library.
|
||||||
//
|
//
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
@ -19,7 +19,6 @@ package statediff
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
@ -37,16 +36,14 @@ const APIVersion = "0.0.1"
|
|||||||
type PublicStateDiffAPI struct {
|
type PublicStateDiffAPI struct {
|
||||||
sds IService
|
sds IService
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
lastUsed map[string]time.Time // keeps track when a filter was polled for the last time.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPublicStateDiffAPI create a new state diff websocket streaming service.
|
// NewPublicStateDiffAPI create a new state diff websocket streaming service.
|
||||||
func NewPublicStateDiffAPI(sds IService) *PublicStateDiffAPI {
|
func NewPublicStateDiffAPI(sds IService) *PublicStateDiffAPI {
|
||||||
return &PublicStateDiffAPI{
|
return &PublicStateDiffAPI{
|
||||||
sds: sds,
|
sds: sds,
|
||||||
lastUsed: make(map[string]time.Time),
|
mu: sync.Mutex{},
|
||||||
mu: sync.Mutex{},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,12 +77,6 @@ func (api *PublicStateDiffAPI) Subscribe(ctx context.Context) (*rpc.Subscription
|
|||||||
log.Error("Failed to unsubscribe from the state diff service", err)
|
log.Error("Failed to unsubscribe from the state diff service", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
case <-notifier.Closed():
|
|
||||||
err := api.sds.Unsubscribe(rpcSub.ID)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Failed to unsubscribe from the state diff service", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
case <-quitChan:
|
case <-quitChan:
|
||||||
// don't need to unsubscribe, statediff service does so before sending the quit signal
|
// don't need to unsubscribe, statediff service does so before sending the quit signal
|
||||||
return
|
return
|
||||||
|
191
vendor/github.com/ethereum/go-ethereum/statediff/builder.go
generated
vendored
191
vendor/github.com/ethereum/go-ethereum/statediff/builder.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2019 The go-ethereum Authors
|
||||||
// This file is part of the go-ethereum library.
|
// This file is part of the go-ethereum library.
|
||||||
//
|
//
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
@ -20,47 +20,55 @@
|
|||||||
package statediff
|
package statediff
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"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/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var nullNode = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")
|
||||||
|
|
||||||
// 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
|
||||||
type Builder interface {
|
type Builder interface {
|
||||||
BuildStateDiff(oldStateRoot, newStateRoot common.Hash, blockNumber int64, blockHash common.Hash) (StateDiff, error)
|
BuildStateDiff(oldStateRoot, newStateRoot common.Hash, blockNumber *big.Int, blockHash common.Hash) (StateDiff, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type builder struct {
|
type builder struct {
|
||||||
chainDB ethdb.Database
|
chainDB ethdb.Database
|
||||||
|
config Config
|
||||||
blockChain *core.BlockChain
|
blockChain *core.BlockChain
|
||||||
|
stateCache state.Database
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBuilder is used to create a builder
|
// NewBuilder is used to create a state diff builder
|
||||||
func NewBuilder(db ethdb.Database, blockChain *core.BlockChain) Builder {
|
func NewBuilder(db ethdb.Database, blockChain *core.BlockChain, config Config) Builder {
|
||||||
return &builder{
|
return &builder{
|
||||||
chainDB: db,
|
chainDB: db,
|
||||||
|
config: config,
|
||||||
blockChain: blockChain,
|
blockChain: blockChain,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildStateDiff builds a StateDiff object from two blocks
|
// BuildStateDiff builds a StateDiff object from two blocks
|
||||||
func (sdb *builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, blockNumber int64, blockHash common.Hash) (StateDiff, error) {
|
func (sdb *builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, blockNumber *big.Int, blockHash common.Hash) (StateDiff, error) {
|
||||||
// Generate tries for old and new states
|
// Generate tries for old and new states
|
||||||
stateCache := sdb.blockChain.StateCache()
|
sdb.stateCache = sdb.blockChain.StateCache()
|
||||||
oldTrie, err := stateCache.OpenTrie(oldStateRoot)
|
oldTrie, err := sdb.stateCache.OpenTrie(oldStateRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error creating trie for oldStateRoot", "error", err)
|
return StateDiff{}, fmt.Errorf("error creating trie for oldStateRoot: %v", err)
|
||||||
return StateDiff{}, err
|
|
||||||
}
|
}
|
||||||
newTrie, err := stateCache.OpenTrie(newStateRoot)
|
newTrie, err := sdb.stateCache.OpenTrie(newStateRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error creating trie for newStateRoot", "error", err)
|
return StateDiff{}, fmt.Errorf("error creating trie for newStateRoot: %v", err)
|
||||||
return StateDiff{}, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find created accounts
|
// Find created accounts
|
||||||
@ -68,8 +76,7 @@ func (sdb *builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, block
|
|||||||
newIt := newTrie.NodeIterator([]byte{})
|
newIt := newTrie.NodeIterator([]byte{})
|
||||||
creations, err := sdb.collectDiffNodes(oldIt, newIt)
|
creations, err := sdb.collectDiffNodes(oldIt, newIt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error collecting creation diff nodes", "error", err)
|
return StateDiff{}, fmt.Errorf("error collecting creation diff nodes: %v", err)
|
||||||
return StateDiff{}, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find deleted accounts
|
// Find deleted accounts
|
||||||
@ -77,8 +84,7 @@ func (sdb *builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, block
|
|||||||
newIt = newTrie.NodeIterator([]byte{})
|
newIt = newTrie.NodeIterator([]byte{})
|
||||||
deletions, err := sdb.collectDiffNodes(newIt, oldIt)
|
deletions, err := sdb.collectDiffNodes(newIt, oldIt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error collecting deletion diff nodes", "error", err)
|
return StateDiff{}, fmt.Errorf("error collecting deletion diff nodes: %v", err)
|
||||||
return StateDiff{}, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all the diffed keys
|
// Find all the diffed keys
|
||||||
@ -89,18 +95,15 @@ func (sdb *builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, block
|
|||||||
// Build and return the statediff
|
// Build and return the statediff
|
||||||
updatedAccounts, err := sdb.buildDiffIncremental(creations, deletions, updatedKeys)
|
updatedAccounts, err := sdb.buildDiffIncremental(creations, deletions, updatedKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error building diff for updated accounts", "error", err)
|
return StateDiff{}, fmt.Errorf("error building diff for updated accounts: %v", err)
|
||||||
return StateDiff{}, err
|
|
||||||
}
|
}
|
||||||
createdAccounts, err := sdb.buildDiffEventual(creations)
|
createdAccounts, err := sdb.buildDiffEventual(creations)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error building diff for created accounts", "error", err)
|
return StateDiff{}, fmt.Errorf("error building diff for created accounts: %v", err)
|
||||||
return StateDiff{}, err
|
|
||||||
}
|
}
|
||||||
deletedAccounts, err := sdb.buildDiffEventual(deletions)
|
deletedAccounts, err := sdb.buildDiffEventual(deletions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error building diff for deleted accounts", "error", err)
|
return StateDiff{}, fmt.Errorf("error building diff for deleted accounts: %v", err)
|
||||||
return StateDiff{}, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return StateDiff{
|
return StateDiff{
|
||||||
@ -112,17 +115,27 @@ func (sdb *builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, block
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sdb *builder) isWatchedAddress(hashKey []byte) bool {
|
||||||
|
// If we aren't watching any addresses, we are watching everything
|
||||||
|
if len(sdb.config.WatchedAddresses) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, addrStr := range sdb.config.WatchedAddresses {
|
||||||
|
addr := common.HexToAddress(addrStr)
|
||||||
|
addrHashKey := crypto.Keccak256(addr[:])
|
||||||
|
if bytes.Equal(addrHashKey, hashKey) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (sdb *builder) collectDiffNodes(a, b trie.NodeIterator) (AccountsMap, error) {
|
func (sdb *builder) collectDiffNodes(a, b trie.NodeIterator) (AccountsMap, error) {
|
||||||
var diffAccounts = make(AccountsMap)
|
var diffAccounts = make(AccountsMap)
|
||||||
it, _ := trie.NewDifferenceIterator(a, b)
|
it, _ := trie.NewDifferenceIterator(a, b)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
log.Debug("Current Path and Hash", "path", pathToStr(it), "hashold", it.Hash())
|
log.Debug("Current Path and Hash", "path", pathToStr(it), "old hash", it.Hash())
|
||||||
if it.Leaf() {
|
if it.Leaf() && sdb.isWatchedAddress(it.LeafKey()) {
|
||||||
leafProof := make([][]byte, len(it.LeafProof()))
|
|
||||||
copy(leafProof, it.LeafProof())
|
|
||||||
leafPath := make([]byte, len(it.Path()))
|
|
||||||
copy(leafPath, it.Path())
|
|
||||||
leafKey := make([]byte, len(it.LeafKey()))
|
leafKey := make([]byte, len(it.LeafKey()))
|
||||||
copy(leafKey, it.LeafKey())
|
copy(leafKey, it.LeafKey())
|
||||||
leafKeyHash := common.BytesToHash(leafKey)
|
leafKeyHash := common.BytesToHash(leafKey)
|
||||||
@ -131,19 +144,38 @@ func (sdb *builder) collectDiffNodes(a, b trie.NodeIterator) (AccountsMap, error
|
|||||||
// lookup account state
|
// lookup account state
|
||||||
var account state.Account
|
var account state.Account
|
||||||
if err := rlp.DecodeBytes(leafValue, &account); err != nil {
|
if err := rlp.DecodeBytes(leafValue, &account); err != nil {
|
||||||
log.Error("Error looking up account via address", "address", leafKeyHash, "error", err)
|
return nil, fmt.Errorf("error looking up account via address %s\r\nerror: %v", leafKeyHash.Hex(), err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
aw := accountWrapper{
|
aw := accountWrapper{
|
||||||
Account: account,
|
Leaf: true,
|
||||||
|
Account: &account,
|
||||||
RawKey: leafKey,
|
RawKey: leafKey,
|
||||||
RawValue: leafValue,
|
RawValue: leafValue,
|
||||||
Proof: leafProof,
|
}
|
||||||
Path: leafPath,
|
if sdb.config.PathsAndProofs {
|
||||||
|
leafProof := make([][]byte, len(it.LeafProof()))
|
||||||
|
copy(leafProof, it.LeafProof())
|
||||||
|
leafPath := make([]byte, len(it.Path()))
|
||||||
|
copy(leafPath, it.Path())
|
||||||
|
aw.Proof = leafProof
|
||||||
|
aw.Path = leafPath
|
||||||
}
|
}
|
||||||
// record account to diffs (creation if we are looking at new - old; deletion if old - new)
|
// record account to diffs (creation if we are looking at new - old; deletion if old - new)
|
||||||
log.Debug("Account lookup successful", "address", leafKeyHash, "account", account)
|
log.Debug("Account lookup successful", "address", leafKeyHash, "account", account)
|
||||||
diffAccounts[leafKeyHash] = aw
|
diffAccounts[leafKeyHash] = aw
|
||||||
|
} else if sdb.config.AllNodes && !bytes.Equal(nullNode, it.Hash().Bytes()) {
|
||||||
|
nodeKey := it.Hash()
|
||||||
|
node, err := sdb.stateCache.TrieDB().Node(nodeKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error looking up intermediate state trie node %s\r\nerror: %v", nodeKey.Hex(), err)
|
||||||
|
}
|
||||||
|
aw := accountWrapper{
|
||||||
|
Leaf: false,
|
||||||
|
RawKey: nodeKey.Bytes(),
|
||||||
|
RawValue: node,
|
||||||
|
}
|
||||||
|
log.Debug("intermediate state trie node lookup successful", "key", nodeKey.Hex(), "value", node)
|
||||||
|
diffAccounts[nodeKey] = aw
|
||||||
}
|
}
|
||||||
cont := it.Next(true)
|
cont := it.Next(true)
|
||||||
if !cont {
|
if !cont {
|
||||||
@ -154,45 +186,55 @@ func (sdb *builder) collectDiffNodes(a, b trie.NodeIterator) (AccountsMap, error
|
|||||||
return diffAccounts, nil
|
return diffAccounts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sdb *builder) buildDiffEventual(accounts AccountsMap) (AccountDiffsMap, error) {
|
func (sdb *builder) buildDiffEventual(accounts AccountsMap) ([]AccountDiff, error) {
|
||||||
accountDiffs := make(AccountDiffsMap)
|
accountDiffs := make([]AccountDiff, 0)
|
||||||
|
var err error
|
||||||
for _, val := range accounts {
|
for _, val := range accounts {
|
||||||
storageDiffs, err := sdb.buildStorageDiffsEventual(val.Account.Root)
|
// If account is not nil, we need to process storage diffs
|
||||||
if err != nil {
|
var storageDiffs []StorageDiff
|
||||||
log.Error("Failed building eventual storage diffs", "Address", common.BytesToHash(val.RawKey), "error", err)
|
if val.Account != nil {
|
||||||
return nil, err
|
storageDiffs, err = sdb.buildStorageDiffsEventual(val.Account.Root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed building eventual storage diffs for %s\r\nerror: %v", common.BytesToHash(val.RawKey), err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
accountDiffs[common.BytesToHash(val.RawKey)] = AccountDiff{
|
accountDiffs = append(accountDiffs, AccountDiff{
|
||||||
|
Leaf: val.Leaf,
|
||||||
Key: val.RawKey,
|
Key: val.RawKey,
|
||||||
Value: val.RawValue,
|
Value: val.RawValue,
|
||||||
Proof: val.Proof,
|
Proof: val.Proof,
|
||||||
Path: val.Path,
|
Path: val.Path,
|
||||||
Storage: storageDiffs,
|
Storage: storageDiffs,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return accountDiffs, nil
|
return accountDiffs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sdb *builder) buildDiffIncremental(creations AccountsMap, deletions AccountsMap, updatedKeys []string) (AccountDiffsMap, error) {
|
func (sdb *builder) buildDiffIncremental(creations AccountsMap, deletions AccountsMap, updatedKeys []string) ([]AccountDiff, error) {
|
||||||
updatedAccounts := make(AccountDiffsMap)
|
updatedAccounts := make([]AccountDiff, 0)
|
||||||
|
var err error
|
||||||
for _, val := range updatedKeys {
|
for _, val := range updatedKeys {
|
||||||
createdAcc := creations[common.HexToHash(val)]
|
hashKey := common.HexToHash(val)
|
||||||
deletedAcc := deletions[common.HexToHash(val)]
|
createdAcc := creations[hashKey]
|
||||||
oldSR := deletedAcc.Account.Root
|
deletedAcc := deletions[hashKey]
|
||||||
newSR := createdAcc.Account.Root
|
var storageDiffs []StorageDiff
|
||||||
storageDiffs, err := sdb.buildStorageDiffsIncremental(oldSR, newSR)
|
if deletedAcc.Account != nil && createdAcc.Account != nil {
|
||||||
if err != nil {
|
oldSR := deletedAcc.Account.Root
|
||||||
log.Error("Failed building storage diffs", "Address", val, "error", err)
|
newSR := createdAcc.Account.Root
|
||||||
return nil, err
|
storageDiffs, err = sdb.buildStorageDiffsIncremental(oldSR, newSR)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed building incremental storage diffs for %s\r\nerror: %v", hashKey.Hex(), err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updatedAccounts[common.HexToHash(val)] = AccountDiff{
|
updatedAccounts = append(updatedAccounts, AccountDiff{
|
||||||
|
Leaf: createdAcc.Leaf,
|
||||||
Key: createdAcc.RawKey,
|
Key: createdAcc.RawKey,
|
||||||
Value: createdAcc.RawValue,
|
Value: createdAcc.RawValue,
|
||||||
Proof: createdAcc.Proof,
|
Proof: createdAcc.Proof,
|
||||||
Path: createdAcc.Path,
|
Path: createdAcc.Path,
|
||||||
Storage: storageDiffs,
|
Storage: storageDiffs,
|
||||||
}
|
})
|
||||||
delete(creations, common.HexToHash(val))
|
delete(creations, common.HexToHash(val))
|
||||||
delete(deletions, common.HexToHash(val))
|
delete(deletions, common.HexToHash(val))
|
||||||
}
|
}
|
||||||
@ -209,8 +251,7 @@ func (sdb *builder) buildStorageDiffsEventual(sr common.Hash) ([]StorageDiff, er
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
it := sTrie.NodeIterator(make([]byte, 0))
|
it := sTrie.NodeIterator(make([]byte, 0))
|
||||||
storageDiffs := buildStorageDiffsFromTrie(it)
|
return sdb.buildStorageDiffsFromTrie(it)
|
||||||
return storageDiffs, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sdb *builder) buildStorageDiffsIncremental(oldSR common.Hash, newSR common.Hash) ([]StorageDiff, error) {
|
func (sdb *builder) buildStorageDiffsIncremental(oldSR common.Hash, newSR common.Hash) ([]StorageDiff, error) {
|
||||||
@ -229,31 +270,45 @@ func (sdb *builder) buildStorageDiffsIncremental(oldSR common.Hash, newSR common
|
|||||||
oldIt := oldTrie.NodeIterator(make([]byte, 0))
|
oldIt := oldTrie.NodeIterator(make([]byte, 0))
|
||||||
newIt := newTrie.NodeIterator(make([]byte, 0))
|
newIt := newTrie.NodeIterator(make([]byte, 0))
|
||||||
it, _ := trie.NewDifferenceIterator(oldIt, newIt)
|
it, _ := trie.NewDifferenceIterator(oldIt, newIt)
|
||||||
storageDiffs := buildStorageDiffsFromTrie(it)
|
return sdb.buildStorageDiffsFromTrie(it)
|
||||||
|
|
||||||
return storageDiffs, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildStorageDiffsFromTrie(it trie.NodeIterator) []StorageDiff {
|
func (sdb *builder) buildStorageDiffsFromTrie(it trie.NodeIterator) ([]StorageDiff, error) {
|
||||||
storageDiffs := make([]StorageDiff, 0)
|
storageDiffs := make([]StorageDiff, 0)
|
||||||
for {
|
for {
|
||||||
log.Debug("Iterating over state at path ", "path", pathToStr(it))
|
log.Debug("Iterating over state at path ", "path", pathToStr(it))
|
||||||
if it.Leaf() {
|
if it.Leaf() {
|
||||||
log.Debug("Found leaf in storage", "path", pathToStr(it))
|
log.Debug("Found leaf in storage", "path", pathToStr(it))
|
||||||
leafProof := make([][]byte, len(it.LeafProof()))
|
|
||||||
copy(leafProof, it.LeafProof())
|
|
||||||
leafPath := make([]byte, len(it.Path()))
|
|
||||||
copy(leafPath, it.Path())
|
|
||||||
leafKey := make([]byte, len(it.LeafKey()))
|
leafKey := make([]byte, len(it.LeafKey()))
|
||||||
copy(leafKey, it.LeafKey())
|
copy(leafKey, it.LeafKey())
|
||||||
leafValue := make([]byte, len(it.LeafBlob()))
|
leafValue := make([]byte, len(it.LeafBlob()))
|
||||||
copy(leafValue, it.LeafBlob())
|
copy(leafValue, it.LeafBlob())
|
||||||
storageDiffs = append(storageDiffs, StorageDiff{
|
sd := StorageDiff{
|
||||||
|
Leaf: true,
|
||||||
Key: leafKey,
|
Key: leafKey,
|
||||||
Value: leafValue,
|
Value: leafValue,
|
||||||
Path: leafPath,
|
}
|
||||||
Proof: leafProof,
|
if sdb.config.PathsAndProofs {
|
||||||
|
leafProof := make([][]byte, len(it.LeafProof()))
|
||||||
|
copy(leafProof, it.LeafProof())
|
||||||
|
leafPath := make([]byte, len(it.Path()))
|
||||||
|
copy(leafPath, it.Path())
|
||||||
|
sd.Proof = leafProof
|
||||||
|
sd.Path = leafPath
|
||||||
|
}
|
||||||
|
storageDiffs = append(storageDiffs, sd)
|
||||||
|
} else if sdb.config.AllNodes && !bytes.Equal(nullNode, it.Hash().Bytes()) {
|
||||||
|
nodeKey := it.Hash()
|
||||||
|
node, err := sdb.stateCache.TrieDB().Node(nodeKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error looking up intermediate storage trie node %s\r\nerror: %v", nodeKey.Hex(), err)
|
||||||
|
}
|
||||||
|
storageDiffs = append(storageDiffs, StorageDiff{
|
||||||
|
Leaf: false,
|
||||||
|
Key: nodeKey.Bytes(),
|
||||||
|
Value: node,
|
||||||
})
|
})
|
||||||
|
log.Debug("intermediate storage trie node lookup successful", "key", nodeKey.Hex(), "value", node)
|
||||||
}
|
}
|
||||||
cont := it.Next(true)
|
cont := it.Next(true)
|
||||||
if !cont {
|
if !cont {
|
||||||
@ -261,7 +316,7 @@ func buildStorageDiffsFromTrie(it trie.NodeIterator) []StorageDiff {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return storageDiffs
|
return storageDiffs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sdb *builder) addressByPath(path []byte) (*common.Address, error) {
|
func (sdb *builder) addressByPath(path []byte) (*common.Address, error) {
|
||||||
|
564
vendor/github.com/ethereum/go-ethereum/statediff/builder_test.go
generated
vendored
Normal file
564
vendor/github.com/ethereum/go-ethereum/statediff/builder_test.go
generated
vendored
Normal file
@ -0,0 +1,564 @@
|
|||||||
|
// 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package statediff_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"math/big"
|
||||||
|
"sort"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff/testhelpers"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
contractLeafKey common.Hash
|
||||||
|
emptyAccountDiffEventualMap = make([]statediff.AccountDiff, 0)
|
||||||
|
emptyAccountDiffIncrementalMap = make([]statediff.AccountDiff, 0)
|
||||||
|
block0, block1, block2, block3 *types.Block
|
||||||
|
builder statediff.Builder
|
||||||
|
miningReward = int64(2000000000000000000)
|
||||||
|
burnAddress = common.HexToAddress("0x0")
|
||||||
|
burnLeafKey = testhelpers.AddressToLeafKey(burnAddress)
|
||||||
|
|
||||||
|
block0Hash = common.HexToHash("0xd1721cfd0b29c36fd7a68f25c128e86413fb666a6e1d68e89b875bd299262661")
|
||||||
|
block1Hash = common.HexToHash("0xbbe88de60ba33a3f18c0caa37d827bfb70252e19e40a07cd34041696c35ecb1a")
|
||||||
|
block2Hash = common.HexToHash("0x34ad0fd9bb2911986b75d518c822641079dea823bc6952343ebf05da1062b6f5")
|
||||||
|
block3Hash = common.HexToHash("0x9872058136c560a6ebed0c0522b8d3016fc21f4fb0fb6585ddd8fd4c54f9909a")
|
||||||
|
balanceChange10000 = int64(10000)
|
||||||
|
balanceChange1000 = int64(1000)
|
||||||
|
block1BankBalance = int64(99990000)
|
||||||
|
block1Account1Balance = int64(10000)
|
||||||
|
block2Account2Balance = int64(1000)
|
||||||
|
nonce0 = uint64(0)
|
||||||
|
nonce1 = uint64(1)
|
||||||
|
nonce2 = uint64(2)
|
||||||
|
nonce3 = uint64(3)
|
||||||
|
originalContractRoot = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
||||||
|
contractContractRoot = "0x821e2556a290c86405f8160a2d662042a431ba456b9db265c79bb837c04be5f0"
|
||||||
|
newContractRoot = "0x71e0d14b2b93e5c7f9748e69e1fe5f17498a1c3ac3cec29f96af13d7f8a4e070"
|
||||||
|
originalStorageLocation = common.HexToHash("0")
|
||||||
|
originalStorageKey = crypto.Keccak256Hash(originalStorageLocation[:]).Bytes()
|
||||||
|
updatedStorageLocation = common.HexToHash("2")
|
||||||
|
updatedStorageKey = crypto.Keccak256Hash(updatedStorageLocation[:]).Bytes()
|
||||||
|
originalStorageValue = common.Hex2Bytes("01")
|
||||||
|
updatedStorageValue = common.Hex2Bytes("03")
|
||||||
|
|
||||||
|
account1, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: nonce0,
|
||||||
|
Balance: big.NewInt(balanceChange10000),
|
||||||
|
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
|
||||||
|
Root: common.HexToHash(originalContractRoot),
|
||||||
|
})
|
||||||
|
burnAccount1, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: nonce0,
|
||||||
|
Balance: big.NewInt(miningReward),
|
||||||
|
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
|
||||||
|
Root: common.HexToHash(originalContractRoot),
|
||||||
|
})
|
||||||
|
bankAccount1, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: nonce1,
|
||||||
|
Balance: big.NewInt(testhelpers.TestBankFunds.Int64() - balanceChange10000),
|
||||||
|
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
|
||||||
|
Root: common.HexToHash(originalContractRoot),
|
||||||
|
})
|
||||||
|
account2, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: nonce0,
|
||||||
|
Balance: big.NewInt(balanceChange1000),
|
||||||
|
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
|
||||||
|
Root: common.HexToHash(originalContractRoot),
|
||||||
|
})
|
||||||
|
contractAccount, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: nonce1,
|
||||||
|
Balance: big.NewInt(0),
|
||||||
|
CodeHash: common.HexToHash("0x753f98a8d4328b15636e46f66f2cb4bc860100aa17967cc145fcd17d1d4710ea").Bytes(),
|
||||||
|
Root: common.HexToHash(contractContractRoot),
|
||||||
|
})
|
||||||
|
bankAccount2, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: nonce2,
|
||||||
|
Balance: big.NewInt(block1BankBalance - balanceChange1000),
|
||||||
|
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
|
||||||
|
Root: common.HexToHash(originalContractRoot),
|
||||||
|
})
|
||||||
|
account3, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: nonce2,
|
||||||
|
Balance: big.NewInt(block1Account1Balance - balanceChange1000 + balanceChange1000),
|
||||||
|
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
|
||||||
|
Root: common.HexToHash(originalContractRoot),
|
||||||
|
})
|
||||||
|
burnAccount2, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: nonce0,
|
||||||
|
Balance: big.NewInt(miningReward + miningReward),
|
||||||
|
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
|
||||||
|
Root: common.HexToHash(originalContractRoot),
|
||||||
|
})
|
||||||
|
account4, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: nonce0,
|
||||||
|
Balance: big.NewInt(block2Account2Balance + miningReward),
|
||||||
|
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
|
||||||
|
Root: common.HexToHash(originalContractRoot),
|
||||||
|
})
|
||||||
|
contractAccount2, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: nonce1,
|
||||||
|
Balance: big.NewInt(0),
|
||||||
|
CodeHash: common.HexToHash("0x753f98a8d4328b15636e46f66f2cb4bc860100aa17967cc145fcd17d1d4710ea").Bytes(),
|
||||||
|
Root: common.HexToHash(newContractRoot),
|
||||||
|
})
|
||||||
|
bankAccount3, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: nonce3,
|
||||||
|
Balance: big.NewInt(99989000),
|
||||||
|
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
|
||||||
|
Root: common.HexToHash(originalContractRoot),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
type arguments struct {
|
||||||
|
oldStateRoot common.Hash
|
||||||
|
newStateRoot common.Hash
|
||||||
|
blockNumber *big.Int
|
||||||
|
blockHash common.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuilder(t *testing.T) {
|
||||||
|
_, blockMap, chain := testhelpers.MakeChain(3, testhelpers.Genesis)
|
||||||
|
contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr)
|
||||||
|
defer chain.Stop()
|
||||||
|
block0 = blockMap[block0Hash]
|
||||||
|
block1 = blockMap[block1Hash]
|
||||||
|
block2 = blockMap[block2Hash]
|
||||||
|
block3 = blockMap[block3Hash]
|
||||||
|
config := statediff.Config{
|
||||||
|
PathsAndProofs: true,
|
||||||
|
AllNodes: false,
|
||||||
|
}
|
||||||
|
builder = statediff.NewBuilder(testhelpers.Testdb, chain, config)
|
||||||
|
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
startingArguments arguments
|
||||||
|
expected *statediff.StateDiff
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"testEmptyDiff",
|
||||||
|
arguments{
|
||||||
|
oldStateRoot: block0.Root(),
|
||||||
|
newStateRoot: block0.Root(),
|
||||||
|
blockNumber: block0.Number(),
|
||||||
|
blockHash: block0Hash,
|
||||||
|
},
|
||||||
|
&statediff.StateDiff{
|
||||||
|
BlockNumber: block0.Number(),
|
||||||
|
BlockHash: block0Hash,
|
||||||
|
CreatedAccounts: emptyAccountDiffEventualMap,
|
||||||
|
DeletedAccounts: emptyAccountDiffEventualMap,
|
||||||
|
UpdatedAccounts: emptyAccountDiffIncrementalMap,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testBlock1",
|
||||||
|
//10000 transferred from testBankAddress to account1Addr
|
||||||
|
arguments{
|
||||||
|
oldStateRoot: block0.Root(),
|
||||||
|
newStateRoot: block1.Root(),
|
||||||
|
blockNumber: block1.Number(),
|
||||||
|
blockHash: block1Hash,
|
||||||
|
},
|
||||||
|
&statediff.StateDiff{
|
||||||
|
BlockNumber: block1.Number(),
|
||||||
|
BlockHash: block1.Hash(),
|
||||||
|
CreatedAccounts: []statediff.AccountDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: burnLeafKey.Bytes(),
|
||||||
|
Value: burnAccount1,
|
||||||
|
Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128},
|
||||||
|
{248, 113, 160, 51, 128, 199, 183, 174, 129, 165, 142, 185, 141, 156, 120, 222, 74, 31, 215, 253, 149, 53, 252, 149, 62, 210, 190, 96, 45, 170, 164, 23, 103, 49, 42, 184, 78, 248, 76, 128, 136, 27, 193, 109, 103, 78, 200, 0, 0, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{5, 3, 8, 0, 12, 7, 11, 7, 10, 14, 8, 1, 10, 5, 8, 14, 11, 9, 8, 13, 9, 12, 7, 8, 13, 14, 4, 10, 1, 15, 13, 7, 15, 13, 9, 5, 3, 5, 15, 12, 9, 5, 3, 14, 13, 2, 11, 14, 6, 0, 2, 13, 10, 10, 10, 4, 1, 7, 6, 7, 3, 1, 2, 10, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: testhelpers.Account1LeafKey.Bytes(),
|
||||||
|
Value: account1,
|
||||||
|
Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128},
|
||||||
|
{248, 107, 160, 57, 38, 219, 105, 170, 206, 213, 24, 233, 185, 240, 244, 52, 164, 115, 231, 23, 65, 9, 201, 67, 84, 139, 184, 242, 59, 228, 28, 167, 109, 154, 210, 184, 72, 248, 70, 128, 130, 39, 16, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{14, 9, 2, 6, 13, 11, 6, 9, 10, 10, 12, 14, 13, 5, 1, 8, 14, 9, 11, 9, 15, 0, 15, 4, 3, 4, 10, 4, 7, 3, 14, 7, 1, 7, 4, 1, 0, 9, 12, 9, 4, 3, 5, 4, 8, 11, 11, 8, 15, 2, 3, 11, 14, 4, 1, 12, 10, 7, 6, 13, 9, 10, 13, 2, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DeletedAccounts: emptyAccountDiffEventualMap,
|
||||||
|
UpdatedAccounts: []statediff.AccountDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: testhelpers.BankLeafKey.Bytes(),
|
||||||
|
Value: bankAccount1,
|
||||||
|
Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128},
|
||||||
|
{248, 109, 160, 48, 191, 73, 244, 64, 161, 205, 5, 39, 228, 208, 110, 39, 101, 101, 76, 15, 86, 69, 34, 87, 81, 109, 121, 58, 155, 141, 96, 77, 207, 223, 42, 184, 74, 248, 72, 1, 132, 5, 245, 185, 240, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{0, 0, 11, 15, 4, 9, 15, 4, 4, 0, 10, 1, 12, 13, 0, 5, 2, 7, 14, 4, 13, 0, 6, 14, 2, 7, 6, 5, 6, 5, 4, 12, 0, 15, 5, 6, 4, 5, 2, 2, 5, 7, 5, 1, 6, 13, 7, 9, 3, 10, 9, 11, 8, 13, 6, 0, 4, 13, 12, 15, 13, 15, 2, 10, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testBlock2",
|
||||||
|
//1000 transferred from testBankAddress to account1Addr
|
||||||
|
//1000 transferred from account1Addr to account2Addr
|
||||||
|
arguments{
|
||||||
|
oldStateRoot: block1.Root(),
|
||||||
|
newStateRoot: block2.Root(),
|
||||||
|
blockNumber: block2.Number(),
|
||||||
|
blockHash: block2Hash,
|
||||||
|
},
|
||||||
|
&statediff.StateDiff{
|
||||||
|
BlockNumber: block2.Number(),
|
||||||
|
BlockHash: block2.Hash(),
|
||||||
|
CreatedAccounts: []statediff.AccountDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: contractLeafKey.Bytes(),
|
||||||
|
Value: contractAccount,
|
||||||
|
Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128},
|
||||||
|
{248, 105, 160, 49, 20, 101, 138, 116, 217, 204, 159, 122, 207, 44, 92, 214, 150, 195, 73, 77, 124, 52, 77, 120, 191, 236, 58, 221, 13, 145, 236, 78, 141, 28, 69, 184, 70, 248, 68, 1, 128, 160, 130, 30, 37, 86, 162, 144, 200, 100, 5, 248, 22, 10, 45, 102, 32, 66, 164, 49, 186, 69, 107, 157, 178, 101, 199, 155, 184, 55, 192, 75, 229, 240, 160, 117, 63, 152, 168, 212, 50, 139, 21, 99, 110, 70, 246, 111, 44, 180, 188, 134, 1, 0, 170, 23, 150, 124, 193, 69, 252, 209, 125, 29, 71, 16, 234}},
|
||||||
|
Path: []byte{6, 1, 1, 4, 6, 5, 8, 10, 7, 4, 13, 9, 12, 12, 9, 15, 7, 10, 12, 15, 2, 12, 5, 12, 13, 6, 9, 6, 12, 3, 4, 9, 4, 13, 7, 12, 3, 4, 4, 13, 7, 8, 11, 15, 14, 12, 3, 10, 13, 13, 0, 13, 9, 1, 14, 12, 4, 14, 8, 13, 1, 12, 4, 5, 16},
|
||||||
|
Storage: []statediff.StorageDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: originalStorageKey,
|
||||||
|
Value: originalStorageValue,
|
||||||
|
Proof: [][]byte{{227, 161, 32, 41, 13, 236, 217, 84, 139, 98, 168, 214, 3, 69, 169, 136, 56, 111, 200, 75, 166, 188, 149, 72, 64, 8, 246, 54, 47, 147, 22, 14, 243, 229, 99, 1}},
|
||||||
|
Path: []byte{2, 9, 0, 13, 14, 12, 13, 9, 5, 4, 8, 11, 6, 2, 10, 8, 13, 6, 0, 3, 4, 5, 10, 9, 8, 8, 3, 8, 6, 15, 12, 8, 4, 11, 10, 6, 11, 12, 9, 5, 4, 8, 4, 0, 0, 8, 15, 6, 3, 6, 2, 15, 9, 3, 1, 6, 0, 14, 15, 3, 14, 5, 6, 3, 16},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: testhelpers.Account2LeafKey.Bytes(),
|
||||||
|
Value: account2,
|
||||||
|
Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128},
|
||||||
|
{248, 107, 160, 57, 87, 243, 226, 240, 74, 7, 100, 195, 160, 73, 27, 23, 95, 105, 146, 109, 166, 30, 251, 204, 143, 97, 250, 20, 85, 253, 45, 43, 76, 221, 69, 184, 72, 248, 70, 128, 130, 3, 232, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{12, 9, 5, 7, 15, 3, 14, 2, 15, 0, 4, 10, 0, 7, 6, 4, 12, 3, 10, 0, 4, 9, 1, 11, 1, 7, 5, 15, 6, 9, 9, 2, 6, 13, 10, 6, 1, 14, 15, 11, 12, 12, 8, 15, 6, 1, 15, 10, 1, 4, 5, 5, 15, 13, 2, 13, 2, 11, 4, 12, 13, 13, 4, 5, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DeletedAccounts: emptyAccountDiffEventualMap,
|
||||||
|
UpdatedAccounts: []statediff.AccountDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: testhelpers.BankLeafKey.Bytes(),
|
||||||
|
Value: bankAccount2,
|
||||||
|
Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128},
|
||||||
|
{248, 109, 160, 48, 191, 73, 244, 64, 161, 205, 5, 39, 228, 208, 110, 39, 101, 101, 76, 15, 86, 69, 34, 87, 81, 109, 121, 58, 155, 141, 96, 77, 207, 223, 42, 184, 74, 248, 72, 2, 132, 5, 245, 182, 8, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{0, 0, 11, 15, 4, 9, 15, 4, 4, 0, 10, 1, 12, 13, 0, 5, 2, 7, 14, 4, 13, 0, 6, 14, 2, 7, 6, 5, 6, 5, 4, 12, 0, 15, 5, 6, 4, 5, 2, 2, 5, 7, 5, 1, 6, 13, 7, 9, 3, 10, 9, 11, 8, 13, 6, 0, 4, 13, 12, 15, 13, 15, 2, 10, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: burnLeafKey.Bytes(),
|
||||||
|
Value: burnAccount2,
|
||||||
|
Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128},
|
||||||
|
{248, 113, 160, 51, 128, 199, 183, 174, 129, 165, 142, 185, 141, 156, 120, 222, 74, 31, 215, 253, 149, 53, 252, 149, 62, 210, 190, 96, 45, 170, 164, 23, 103, 49, 42, 184, 78, 248, 76, 128, 136, 55, 130, 218, 206, 157, 144, 0, 0, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{5, 3, 8, 0, 12, 7, 11, 7, 10, 14, 8, 1, 10, 5, 8, 14, 11, 9, 8, 13, 9, 12, 7, 8, 13, 14, 4, 10, 1, 15, 13, 7, 15, 13, 9, 5, 3, 5, 15, 12, 9, 5, 3, 14, 13, 2, 11, 14, 6, 0, 2, 13, 10, 10, 10, 4, 1, 7, 6, 7, 3, 1, 2, 10, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: testhelpers.Account1LeafKey.Bytes(),
|
||||||
|
Value: account3,
|
||||||
|
Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128},
|
||||||
|
{248, 107, 160, 57, 38, 219, 105, 170, 206, 213, 24, 233, 185, 240, 244, 52, 164, 115, 231, 23, 65, 9, 201, 67, 84, 139, 184, 242, 59, 228, 28, 167, 109, 154, 210, 184, 72, 248, 70, 2, 130, 39, 16, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{14, 9, 2, 6, 13, 11, 6, 9, 10, 10, 12, 14, 13, 5, 1, 8, 14, 9, 11, 9, 15, 0, 15, 4, 3, 4, 10, 4, 7, 3, 14, 7, 1, 7, 4, 1, 0, 9, 12, 9, 4, 3, 5, 4, 8, 11, 11, 8, 15, 2, 3, 11, 14, 4, 1, 12, 10, 7, 6, 13, 9, 10, 13, 2, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testBlock3",
|
||||||
|
//the contract's storage is changed
|
||||||
|
//and the block is mined by account 2
|
||||||
|
arguments{
|
||||||
|
oldStateRoot: block2.Root(),
|
||||||
|
newStateRoot: block3.Root(),
|
||||||
|
blockNumber: block3.Number(),
|
||||||
|
blockHash: block3.Hash(),
|
||||||
|
},
|
||||||
|
&statediff.StateDiff{
|
||||||
|
BlockNumber: block3.Number(),
|
||||||
|
BlockHash: block3.Hash(),
|
||||||
|
CreatedAccounts: []statediff.AccountDiff{},
|
||||||
|
DeletedAccounts: emptyAccountDiffEventualMap,
|
||||||
|
UpdatedAccounts: []statediff.AccountDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: testhelpers.BankLeafKey.Bytes(),
|
||||||
|
Value: bankAccount3,
|
||||||
|
Proof: [][]byte{{248, 177, 160, 101, 223, 138, 81, 34, 40, 229, 170, 198, 188, 136, 99, 7, 55, 33, 112, 160, 111, 181, 131, 167, 201, 131, 24, 201, 211, 177, 30, 159, 229, 246, 6, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 32, 135, 108, 213, 150, 150, 110, 44, 170, 65, 75, 154, 74, 249, 94, 65, 74, 107, 100, 115, 39, 5, 3, 26, 22, 238, 138, 114, 254, 21, 6, 171, 128, 128, 128, 128, 128, 160, 4, 228, 121, 222, 255, 218, 60, 247, 15, 0, 34, 198, 28, 229, 180, 129, 109, 157, 68, 181, 248, 229, 200, 123, 29, 81, 145, 114, 90, 209, 205, 210, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128},
|
||||||
|
{248, 109, 160, 48, 191, 73, 244, 64, 161, 205, 5, 39, 228, 208, 110, 39, 101, 101, 76, 15, 86, 69, 34, 87, 81, 109, 121, 58, 155, 141, 96, 77, 207, 223, 42, 184, 74, 248, 72, 3, 132, 5, 245, 182, 8, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{0, 0, 11, 15, 4, 9, 15, 4, 4, 0, 10, 1, 12, 13, 0, 5, 2, 7, 14, 4, 13, 0, 6, 14, 2, 7, 6, 5, 6, 5, 4, 12, 0, 15, 5, 6, 4, 5, 2, 2, 5, 7, 5, 1, 6, 13, 7, 9, 3, 10, 9, 11, 8, 13, 6, 0, 4, 13, 12, 15, 13, 15, 2, 10, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: contractLeafKey.Bytes(),
|
||||||
|
Value: contractAccount2,
|
||||||
|
Proof: [][]byte{{248, 177, 160, 101, 223, 138, 81, 34, 40, 229, 170, 198, 188, 136, 99, 7, 55, 33, 112, 160, 111, 181, 131, 167, 201, 131, 24, 201, 211, 177, 30, 159, 229, 246, 6, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 32, 135, 108, 213, 150, 150, 110, 44, 170, 65, 75, 154, 74, 249, 94, 65, 74, 107, 100, 115, 39, 5, 3, 26, 22, 238, 138, 114, 254, 21, 6, 171, 128, 128, 128, 128, 128, 160, 4, 228, 121, 222, 255, 218, 60, 247, 15, 0, 34, 198, 28, 229, 180, 129, 109, 157, 68, 181, 248, 229, 200, 123, 29, 81, 145, 114, 90, 209, 205, 210, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128},
|
||||||
|
{248, 105, 160, 49, 20, 101, 138, 116, 217, 204, 159, 122, 207, 44, 92, 214, 150, 195, 73, 77, 124, 52, 77, 120, 191, 236, 58, 221, 13, 145, 236, 78, 141, 28, 69, 184, 70, 248, 68, 1, 128, 160, 113, 224, 209, 75, 43, 147, 229, 199, 249, 116, 142, 105, 225, 254, 95, 23, 73, 138, 28, 58, 195, 206, 194, 159, 150, 175, 19, 215, 248, 164, 224, 112, 160, 117, 63, 152, 168, 212, 50, 139, 21, 99, 110, 70, 246, 111, 44, 180, 188, 134, 1, 0, 170, 23, 150, 124, 193, 69, 252, 209, 125, 29, 71, 16, 234}},
|
||||||
|
Path: []byte{6, 1, 1, 4, 6, 5, 8, 10, 7, 4, 13, 9, 12, 12, 9, 15, 7, 10, 12, 15, 2, 12, 5, 12, 13, 6, 9, 6, 12, 3, 4, 9, 4, 13, 7, 12, 3, 4, 4, 13, 7, 8, 11, 15, 14, 12, 3, 10, 13, 13, 0, 13, 9, 1, 14, 12, 4, 14, 8, 13, 1, 12, 4, 5, 16},
|
||||||
|
Storage: []statediff.StorageDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: updatedStorageKey,
|
||||||
|
Value: updatedStorageValue,
|
||||||
|
Proof: [][]byte{{248, 81, 128, 128, 160, 79, 197, 241, 58, 178, 249, 186, 12, 45, 168, 139, 1, 81, 171, 14, 124, 244, 216, 93, 8, 204, 164, 92, 205, 146, 60, 106, 183, 99, 35, 235, 40, 128, 160, 205, 69, 114, 89, 105, 97, 21, 35, 94, 100, 199, 130, 35, 52, 214, 33, 41, 226, 241, 96, 68, 37, 167, 218, 100, 148, 243, 95, 196, 91, 229, 24, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128},
|
||||||
|
{226, 160, 48, 87, 135, 250, 18, 168, 35, 224, 242, 183, 99, 28, 196, 27, 59, 168, 130, 139, 51, 33, 202, 129, 17, 17, 250, 117, 205, 58, 163, 187, 90, 206, 3}},
|
||||||
|
Path: []byte{4, 0, 5, 7, 8, 7, 15, 10, 1, 2, 10, 8, 2, 3, 14, 0, 15, 2, 11, 7, 6, 3, 1, 12, 12, 4, 1, 11, 3, 11, 10, 8, 8, 2, 8, 11, 3, 3, 2, 1, 12, 10, 8, 1, 1, 1, 1, 1, 15, 10, 7, 5, 12, 13, 3, 10, 10, 3, 11, 11, 5, 10, 12, 14, 16},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: testhelpers.Account2LeafKey.Bytes(),
|
||||||
|
Value: account4,
|
||||||
|
Proof: [][]byte{{248, 177, 160, 101, 223, 138, 81, 34, 40, 229, 170, 198, 188, 136, 99, 7, 55, 33, 112, 160, 111, 181, 131, 167, 201, 131, 24, 201, 211, 177, 30, 159, 229, 246, 6, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 32, 135, 108, 213, 150, 150, 110, 44, 170, 65, 75, 154, 74, 249, 94, 65, 74, 107, 100, 115, 39, 5, 3, 26, 22, 238, 138, 114, 254, 21, 6, 171, 128, 128, 128, 128, 128, 160, 4, 228, 121, 222, 255, 218, 60, 247, 15, 0, 34, 198, 28, 229, 180, 129, 109, 157, 68, 181, 248, 229, 200, 123, 29, 81, 145, 114, 90, 209, 205, 210, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128},
|
||||||
|
{248, 113, 160, 57, 87, 243, 226, 240, 74, 7, 100, 195, 160, 73, 27, 23, 95, 105, 146, 109, 166, 30, 251, 204, 143, 97, 250, 20, 85, 253, 45, 43, 76, 221, 69, 184, 78, 248, 76, 128, 136, 27, 193, 109, 103, 78, 200, 3, 232, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{12, 9, 5, 7, 15, 3, 14, 2, 15, 0, 4, 10, 0, 7, 6, 4, 12, 3, 10, 0, 4, 9, 1, 11, 1, 7, 5, 15, 6, 9, 9, 2, 6, 13, 10, 6, 1, 14, 15, 11, 12, 12, 8, 15, 6, 1, 15, 10, 1, 4, 5, 5, 15, 13, 2, 13, 2, 11, 4, 12, 13, 13, 4, 5, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
arguments := test.startingArguments
|
||||||
|
diff, err := builder.BuildStateDiff(arguments.oldStateRoot, arguments.newStateRoot, arguments.blockNumber, arguments.blockHash)
|
||||||
|
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 rlp: %+v\nexpected state diff rlp: %+v", receivedStateDiffRlp, expectedStateDiffRlp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuilderWithWatchedAddressList(t *testing.T) {
|
||||||
|
_, blockMap, chain := testhelpers.MakeChain(3, testhelpers.Genesis)
|
||||||
|
contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr)
|
||||||
|
defer chain.Stop()
|
||||||
|
block0 = blockMap[block0Hash]
|
||||||
|
block1 = blockMap[block1Hash]
|
||||||
|
block2 = blockMap[block2Hash]
|
||||||
|
block3 = blockMap[block3Hash]
|
||||||
|
config := statediff.Config{
|
||||||
|
PathsAndProofs: true,
|
||||||
|
AllNodes: false,
|
||||||
|
WatchedAddresses: []string{testhelpers.Account1Addr.Hex(), testhelpers.ContractAddr.Hex()},
|
||||||
|
}
|
||||||
|
builder = statediff.NewBuilder(testhelpers.Testdb, chain, config)
|
||||||
|
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
startingArguments arguments
|
||||||
|
expected *statediff.StateDiff
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"testEmptyDiff",
|
||||||
|
arguments{
|
||||||
|
oldStateRoot: block0.Root(),
|
||||||
|
newStateRoot: block0.Root(),
|
||||||
|
blockNumber: block0.Number(),
|
||||||
|
blockHash: block0Hash,
|
||||||
|
},
|
||||||
|
&statediff.StateDiff{
|
||||||
|
BlockNumber: block0.Number(),
|
||||||
|
BlockHash: block0Hash,
|
||||||
|
CreatedAccounts: emptyAccountDiffEventualMap,
|
||||||
|
DeletedAccounts: emptyAccountDiffEventualMap,
|
||||||
|
UpdatedAccounts: emptyAccountDiffIncrementalMap,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testBlock1",
|
||||||
|
//10000 transferred from testBankAddress to account1Addr
|
||||||
|
arguments{
|
||||||
|
oldStateRoot: block0.Root(),
|
||||||
|
newStateRoot: block1.Root(),
|
||||||
|
blockNumber: block1.Number(),
|
||||||
|
blockHash: block1Hash,
|
||||||
|
},
|
||||||
|
&statediff.StateDiff{
|
||||||
|
BlockNumber: block1.Number(),
|
||||||
|
BlockHash: block1.Hash(),
|
||||||
|
CreatedAccounts: []statediff.AccountDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: testhelpers.Account1LeafKey.Bytes(),
|
||||||
|
Value: account1,
|
||||||
|
Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128},
|
||||||
|
{248, 107, 160, 57, 38, 219, 105, 170, 206, 213, 24, 233, 185, 240, 244, 52, 164, 115, 231, 23, 65, 9, 201, 67, 84, 139, 184, 242, 59, 228, 28, 167, 109, 154, 210, 184, 72, 248, 70, 128, 130, 39, 16, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{14, 9, 2, 6, 13, 11, 6, 9, 10, 10, 12, 14, 13, 5, 1, 8, 14, 9, 11, 9, 15, 0, 15, 4, 3, 4, 10, 4, 7, 3, 14, 7, 1, 7, 4, 1, 0, 9, 12, 9, 4, 3, 5, 4, 8, 11, 11, 8, 15, 2, 3, 11, 14, 4, 1, 12, 10, 7, 6, 13, 9, 10, 13, 2, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DeletedAccounts: emptyAccountDiffEventualMap,
|
||||||
|
UpdatedAccounts: []statediff.AccountDiff{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testBlock2",
|
||||||
|
//1000 transferred from testBankAddress to account1Addr
|
||||||
|
//1000 transferred from account1Addr to account2Addr
|
||||||
|
arguments{
|
||||||
|
oldStateRoot: block1.Root(),
|
||||||
|
newStateRoot: block2.Root(),
|
||||||
|
blockNumber: block2.Number(),
|
||||||
|
blockHash: block2Hash,
|
||||||
|
},
|
||||||
|
&statediff.StateDiff{
|
||||||
|
BlockNumber: block2.Number(),
|
||||||
|
BlockHash: block2.Hash(),
|
||||||
|
CreatedAccounts: []statediff.AccountDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: contractLeafKey.Bytes(),
|
||||||
|
Value: contractAccount,
|
||||||
|
Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128},
|
||||||
|
{248, 105, 160, 49, 20, 101, 138, 116, 217, 204, 159, 122, 207, 44, 92, 214, 150, 195, 73, 77, 124, 52, 77, 120, 191, 236, 58, 221, 13, 145, 236, 78, 141, 28, 69, 184, 70, 248, 68, 1, 128, 160, 130, 30, 37, 86, 162, 144, 200, 100, 5, 248, 22, 10, 45, 102, 32, 66, 164, 49, 186, 69, 107, 157, 178, 101, 199, 155, 184, 55, 192, 75, 229, 240, 160, 117, 63, 152, 168, 212, 50, 139, 21, 99, 110, 70, 246, 111, 44, 180, 188, 134, 1, 0, 170, 23, 150, 124, 193, 69, 252, 209, 125, 29, 71, 16, 234}},
|
||||||
|
Path: []byte{6, 1, 1, 4, 6, 5, 8, 10, 7, 4, 13, 9, 12, 12, 9, 15, 7, 10, 12, 15, 2, 12, 5, 12, 13, 6, 9, 6, 12, 3, 4, 9, 4, 13, 7, 12, 3, 4, 4, 13, 7, 8, 11, 15, 14, 12, 3, 10, 13, 13, 0, 13, 9, 1, 14, 12, 4, 14, 8, 13, 1, 12, 4, 5, 16},
|
||||||
|
Storage: []statediff.StorageDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: originalStorageKey,
|
||||||
|
Value: originalStorageValue,
|
||||||
|
Proof: [][]byte{{227, 161, 32, 41, 13, 236, 217, 84, 139, 98, 168, 214, 3, 69, 169, 136, 56, 111, 200, 75, 166, 188, 149, 72, 64, 8, 246, 54, 47, 147, 22, 14, 243, 229, 99, 1}},
|
||||||
|
Path: []byte{2, 9, 0, 13, 14, 12, 13, 9, 5, 4, 8, 11, 6, 2, 10, 8, 13, 6, 0, 3, 4, 5, 10, 9, 8, 8, 3, 8, 6, 15, 12, 8, 4, 11, 10, 6, 11, 12, 9, 5, 4, 8, 4, 0, 0, 8, 15, 6, 3, 6, 2, 15, 9, 3, 1, 6, 0, 14, 15, 3, 14, 5, 6, 3, 16},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DeletedAccounts: emptyAccountDiffEventualMap,
|
||||||
|
UpdatedAccounts: []statediff.AccountDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: testhelpers.Account1LeafKey.Bytes(),
|
||||||
|
Value: account3,
|
||||||
|
Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128},
|
||||||
|
{248, 107, 160, 57, 38, 219, 105, 170, 206, 213, 24, 233, 185, 240, 244, 52, 164, 115, 231, 23, 65, 9, 201, 67, 84, 139, 184, 242, 59, 228, 28, 167, 109, 154, 210, 184, 72, 248, 70, 2, 130, 39, 16, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{14, 9, 2, 6, 13, 11, 6, 9, 10, 10, 12, 14, 13, 5, 1, 8, 14, 9, 11, 9, 15, 0, 15, 4, 3, 4, 10, 4, 7, 3, 14, 7, 1, 7, 4, 1, 0, 9, 12, 9, 4, 3, 5, 4, 8, 11, 11, 8, 15, 2, 3, 11, 14, 4, 1, 12, 10, 7, 6, 13, 9, 10, 13, 2, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testBlock3",
|
||||||
|
//the contract's storage is changed
|
||||||
|
//and the block is mined by account 2
|
||||||
|
arguments{
|
||||||
|
oldStateRoot: block2.Root(),
|
||||||
|
newStateRoot: block3.Root(),
|
||||||
|
blockNumber: block3.Number(),
|
||||||
|
blockHash: block3.Hash(),
|
||||||
|
},
|
||||||
|
&statediff.StateDiff{
|
||||||
|
BlockNumber: block3.Number(),
|
||||||
|
BlockHash: block3.Hash(),
|
||||||
|
CreatedAccounts: []statediff.AccountDiff{},
|
||||||
|
DeletedAccounts: emptyAccountDiffEventualMap,
|
||||||
|
UpdatedAccounts: []statediff.AccountDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: contractLeafKey.Bytes(),
|
||||||
|
Value: contractAccount2,
|
||||||
|
Proof: [][]byte{{248, 177, 160, 101, 223, 138, 81, 34, 40, 229, 170, 198, 188, 136, 99, 7, 55, 33, 112, 160, 111, 181, 131, 167, 201, 131, 24, 201, 211, 177, 30, 159, 229, 246, 6, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 32, 135, 108, 213, 150, 150, 110, 44, 170, 65, 75, 154, 74, 249, 94, 65, 74, 107, 100, 115, 39, 5, 3, 26, 22, 238, 138, 114, 254, 21, 6, 171, 128, 128, 128, 128, 128, 160, 4, 228, 121, 222, 255, 218, 60, 247, 15, 0, 34, 198, 28, 229, 180, 129, 109, 157, 68, 181, 248, 229, 200, 123, 29, 81, 145, 114, 90, 209, 205, 210, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128},
|
||||||
|
{248, 105, 160, 49, 20, 101, 138, 116, 217, 204, 159, 122, 207, 44, 92, 214, 150, 195, 73, 77, 124, 52, 77, 120, 191, 236, 58, 221, 13, 145, 236, 78, 141, 28, 69, 184, 70, 248, 68, 1, 128, 160, 113, 224, 209, 75, 43, 147, 229, 199, 249, 116, 142, 105, 225, 254, 95, 23, 73, 138, 28, 58, 195, 206, 194, 159, 150, 175, 19, 215, 248, 164, 224, 112, 160, 117, 63, 152, 168, 212, 50, 139, 21, 99, 110, 70, 246, 111, 44, 180, 188, 134, 1, 0, 170, 23, 150, 124, 193, 69, 252, 209, 125, 29, 71, 16, 234}},
|
||||||
|
Path: []byte{6, 1, 1, 4, 6, 5, 8, 10, 7, 4, 13, 9, 12, 12, 9, 15, 7, 10, 12, 15, 2, 12, 5, 12, 13, 6, 9, 6, 12, 3, 4, 9, 4, 13, 7, 12, 3, 4, 4, 13, 7, 8, 11, 15, 14, 12, 3, 10, 13, 13, 0, 13, 9, 1, 14, 12, 4, 14, 8, 13, 1, 12, 4, 5, 16},
|
||||||
|
Storage: []statediff.StorageDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: updatedStorageKey,
|
||||||
|
Value: updatedStorageValue,
|
||||||
|
Proof: [][]byte{{248, 81, 128, 128, 160, 79, 197, 241, 58, 178, 249, 186, 12, 45, 168, 139, 1, 81, 171, 14, 124, 244, 216, 93, 8, 204, 164, 92, 205, 146, 60, 106, 183, 99, 35, 235, 40, 128, 160, 205, 69, 114, 89, 105, 97, 21, 35, 94, 100, 199, 130, 35, 52, 214, 33, 41, 226, 241, 96, 68, 37, 167, 218, 100, 148, 243, 95, 196, 91, 229, 24, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128},
|
||||||
|
{226, 160, 48, 87, 135, 250, 18, 168, 35, 224, 242, 183, 99, 28, 196, 27, 59, 168, 130, 139, 51, 33, 202, 129, 17, 17, 250, 117, 205, 58, 163, 187, 90, 206, 3}},
|
||||||
|
Path: []byte{4, 0, 5, 7, 8, 7, 15, 10, 1, 2, 10, 8, 2, 3, 14, 0, 15, 2, 11, 7, 6, 3, 1, 12, 12, 4, 1, 11, 3, 11, 10, 8, 8, 2, 8, 11, 3, 3, 2, 1, 12, 10, 8, 1, 1, 1, 1, 1, 15, 10, 7, 5, 12, 13, 3, 10, 10, 3, 11, 11, 5, 10, 12, 14, 16},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
arguments := test.startingArguments
|
||||||
|
diff, err := builder.BuildStateDiff(arguments.oldStateRoot, arguments.newStateRoot, arguments.blockNumber, arguments.blockHash)
|
||||||
|
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 rlp: %+v\nexpected state diff rlp: %+v", receivedStateDiffRlp, expectedStateDiffRlp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
contract test {
|
||||||
|
|
||||||
|
uint256[100] data;
|
||||||
|
|
||||||
|
constructor() public {
|
||||||
|
data = [1];
|
||||||
|
}
|
||||||
|
|
||||||
|
function Put(uint256 addr, uint256 value) {
|
||||||
|
data[addr] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get(uint256 addr) constant returns (uint256 value) {
|
||||||
|
return data[addr];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
25
vendor/github.com/ethereum/go-ethereum/statediff/config.go
generated
vendored
Normal file
25
vendor/github.com/ethereum/go-ethereum/statediff/config.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package statediff
|
||||||
|
|
||||||
|
// Config is used to carry in parameters from CLI configuration
|
||||||
|
type Config struct {
|
||||||
|
StreamBlock bool
|
||||||
|
PathsAndProofs bool
|
||||||
|
AllNodes bool
|
||||||
|
WatchedAddresses []string
|
||||||
|
}
|
2
vendor/github.com/ethereum/go-ethereum/statediff/helpers.go
generated
vendored
2
vendor/github.com/ethereum/go-ethereum/statediff/helpers.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2019 The go-ethereum Authors
|
||||||
// This file is part of the go-ethereum library.
|
// This file is part of the go-ethereum library.
|
||||||
//
|
//
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
114
vendor/github.com/ethereum/go-ethereum/statediff/service.go
generated
vendored
114
vendor/github.com/ethereum/go-ethereum/statediff/service.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2019 The go-ethereum Authors
|
||||||
// This file is part of the go-ethereum library.
|
// This file is part of the go-ethereum library.
|
||||||
//
|
//
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
@ -21,7 +21,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/node"
|
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
@ -30,6 +29,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/node"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
@ -64,29 +64,21 @@ type Service struct {
|
|||||||
QuitChan chan bool
|
QuitChan chan bool
|
||||||
// A mapping of rpc.IDs to their subscription channels
|
// A mapping of rpc.IDs to their subscription channels
|
||||||
Subscriptions map[rpc.ID]Subscription
|
Subscriptions map[rpc.ID]Subscription
|
||||||
}
|
// Cache the last block so that we can avoid having to lookup the next block's parent
|
||||||
|
lastBlock *types.Block
|
||||||
// Subscription struct holds our subscription channels
|
// Whether or not the block data is streamed alongside the state diff data in the subscription payload
|
||||||
type Subscription struct {
|
streamBlock bool
|
||||||
PayloadChan chan<- Payload
|
|
||||||
QuitChan chan<- bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Payload packages the data to send to StateDiffingService subscriptions
|
|
||||||
type Payload struct {
|
|
||||||
BlockRlp []byte `json:"blockRlp" gencodec:"required"`
|
|
||||||
StateDiffRlp []byte `json:"stateDiffRlp" gencodec:"required"`
|
|
||||||
Err error `json:"error"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStateDiffService creates a new StateDiffingService
|
// NewStateDiffService creates a new StateDiffingService
|
||||||
func NewStateDiffService(db ethdb.Database, blockChain *core.BlockChain) (*Service, error) {
|
func NewStateDiffService(db ethdb.Database, blockChain *core.BlockChain, config Config) (*Service, error) {
|
||||||
return &Service{
|
return &Service{
|
||||||
Mutex: sync.Mutex{},
|
Mutex: sync.Mutex{},
|
||||||
BlockChain: blockChain,
|
BlockChain: blockChain,
|
||||||
Builder: NewBuilder(db, blockChain),
|
Builder: NewBuilder(db, blockChain, config),
|
||||||
QuitChan: make(chan bool),
|
QuitChan: make(chan bool),
|
||||||
Subscriptions: make(map[rpc.ID]Subscription),
|
Subscriptions: make(map[rpc.ID]Subscription),
|
||||||
|
streamBlock: config.StreamBlock,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,70 +101,72 @@ func (sds *Service) APIs() []rpc.API {
|
|||||||
|
|
||||||
// Loop is the main processing method
|
// Loop is the main processing method
|
||||||
func (sds *Service) Loop(chainEventCh chan core.ChainEvent) {
|
func (sds *Service) Loop(chainEventCh chan core.ChainEvent) {
|
||||||
|
|
||||||
chainEventSub := sds.BlockChain.SubscribeChainEvent(chainEventCh)
|
chainEventSub := sds.BlockChain.SubscribeChainEvent(chainEventCh)
|
||||||
defer chainEventSub.Unsubscribe()
|
defer chainEventSub.Unsubscribe()
|
||||||
|
|
||||||
blocksCh := make(chan *types.Block, 10)
|
|
||||||
errCh := chainEventSub.Err()
|
errCh := chainEventSub.Err()
|
||||||
|
|
||||||
go func() {
|
|
||||||
HandleChainEventChLoop:
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
//Notify chain event channel of events
|
|
||||||
case chainEvent := <-chainEventCh:
|
|
||||||
log.Debug("Event received from chainEventCh", "event", chainEvent)
|
|
||||||
blocksCh <- chainEvent.Block
|
|
||||||
//if node stopped
|
|
||||||
case err := <-errCh:
|
|
||||||
log.Warn("Error from chain event subscription, breaking loop.", "error", err)
|
|
||||||
close(sds.QuitChan)
|
|
||||||
break HandleChainEventChLoop
|
|
||||||
case <-sds.QuitChan:
|
|
||||||
break HandleChainEventChLoop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
//loop through chain events until no more
|
|
||||||
HandleBlockChLoop:
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case block := <-blocksCh:
|
//Notify chain event channel of events
|
||||||
currentBlock := block
|
case chainEvent := <-chainEventCh:
|
||||||
|
log.Debug("Event received from chainEventCh", "event", chainEvent)
|
||||||
|
currentBlock := chainEvent.Block
|
||||||
parentHash := currentBlock.ParentHash()
|
parentHash := currentBlock.ParentHash()
|
||||||
parentBlock := sds.BlockChain.GetBlockByHash(parentHash)
|
var parentBlock *types.Block
|
||||||
|
if sds.lastBlock != nil && bytes.Equal(sds.lastBlock.Hash().Bytes(), currentBlock.ParentHash().Bytes()) {
|
||||||
|
parentBlock = sds.lastBlock
|
||||||
|
} else {
|
||||||
|
parentBlock = sds.BlockChain.GetBlockByHash(parentHash)
|
||||||
|
}
|
||||||
|
sds.lastBlock = currentBlock
|
||||||
if parentBlock == nil {
|
if parentBlock == nil {
|
||||||
log.Error("Parent block is nil, skipping this block",
|
log.Error("Parent block is nil, skipping this block",
|
||||||
"parent block hash", parentHash.String(),
|
"parent block hash", parentHash.String(),
|
||||||
"current block number", currentBlock.Number())
|
"current block number", currentBlock.Number())
|
||||||
break HandleBlockChLoop
|
continue
|
||||||
}
|
}
|
||||||
|
if err := sds.process(currentBlock, parentBlock); err != nil {
|
||||||
stateDiff, err := sds.Builder.BuildStateDiff(parentBlock.Root(), currentBlock.Root(), currentBlock.Number().Int64(), currentBlock.Hash())
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Error building statediff", "block number", currentBlock.Number(), "error", err)
|
log.Error("Error building statediff", "block number", currentBlock.Number(), "error", err)
|
||||||
}
|
}
|
||||||
rlpBuff := new(bytes.Buffer)
|
case err := <-errCh:
|
||||||
currentBlock.EncodeRLP(rlpBuff)
|
log.Warn("Error from chain event subscription, breaking loop.", "error", err)
|
||||||
blockRlp := rlpBuff.Bytes()
|
sds.close()
|
||||||
stateDiffRlp, _ := rlp.EncodeToBytes(stateDiff)
|
return
|
||||||
payload := Payload{
|
|
||||||
BlockRlp: blockRlp,
|
|
||||||
StateDiffRlp: stateDiffRlp,
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
// If we have any websocket subscription listening in, send the data to them
|
|
||||||
sds.send(payload)
|
|
||||||
case <-sds.QuitChan:
|
case <-sds.QuitChan:
|
||||||
log.Debug("Quitting the statediff block channel")
|
log.Info("Quitting the statediff block channel")
|
||||||
sds.close()
|
sds.close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// process method builds the state diff payload from the current and parent block and streams it to listening subscriptions
|
||||||
|
func (sds *Service) process(currentBlock, parentBlock *types.Block) error {
|
||||||
|
stateDiff, err := sds.Builder.BuildStateDiff(parentBlock.Root(), currentBlock.Root(), currentBlock.Number(), currentBlock.Hash())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
stateDiffRlp, err := rlp.EncodeToBytes(stateDiff)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
payload := Payload{
|
||||||
|
StateDiffRlp: stateDiffRlp,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
if sds.streamBlock {
|
||||||
|
rlpBuff := new(bytes.Buffer)
|
||||||
|
if err = currentBlock.EncodeRLP(rlpBuff); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
payload.BlockRlp = rlpBuff.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have any websocket subscriptions listening in, send the data to them
|
||||||
|
sds.send(payload)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Subscribe is used by the API to subscribe to the StateDiffingService loop
|
// Subscribe is used by the API to subscribe to the StateDiffingService loop
|
||||||
func (sds *Service) Subscribe(id rpc.ID, sub chan<- Payload, quitChan chan<- bool) {
|
func (sds *Service) Subscribe(id rpc.ID, sub chan<- Payload, quitChan chan<- bool) {
|
||||||
log.Info("Subscribing to the statediff service")
|
log.Info("Subscribing to the statediff service")
|
||||||
|
130
vendor/github.com/ethereum/go-ethereum/statediff/service_test.go
generated
vendored
Normal file
130
vendor/github.com/ethereum/go-ethereum/statediff/service_test.go
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
// 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package statediff_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"math/big"
|
||||||
|
"math/rand"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff/testhelpers/mocks"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestServiceLoop(t *testing.T) {
|
||||||
|
testErrorInChainEventLoop(t)
|
||||||
|
testErrorInBlockLoop(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
eventsChannel = make(chan core.ChainEvent, 1)
|
||||||
|
|
||||||
|
parentRoot1 = common.HexToHash("0x01")
|
||||||
|
parentRoot2 = common.HexToHash("0x02")
|
||||||
|
parentHeader1 = types.Header{Number: big.NewInt(rand.Int63()), Root: parentRoot1}
|
||||||
|
parentHeader2 = types.Header{Number: big.NewInt(rand.Int63()), Root: parentRoot2}
|
||||||
|
|
||||||
|
parentBlock1 = types.NewBlock(&parentHeader1, nil, nil, nil)
|
||||||
|
parentBlock2 = types.NewBlock(&parentHeader2, nil, nil, nil)
|
||||||
|
|
||||||
|
parentHash1 = parentBlock1.Hash()
|
||||||
|
parentHash2 = parentBlock2.Hash()
|
||||||
|
|
||||||
|
testRoot1 = common.HexToHash("0x03")
|
||||||
|
testRoot2 = common.HexToHash("0x04")
|
||||||
|
testRoot3 = common.HexToHash("0x04")
|
||||||
|
header1 = types.Header{ParentHash: parentHash1, Root: testRoot1}
|
||||||
|
header2 = types.Header{ParentHash: parentHash2, Root: testRoot2}
|
||||||
|
header3 = types.Header{ParentHash: common.HexToHash("parent hash"), Root: testRoot3}
|
||||||
|
|
||||||
|
testBlock1 = types.NewBlock(&header1, nil, nil, nil)
|
||||||
|
testBlock2 = types.NewBlock(&header2, nil, nil, nil)
|
||||||
|
testBlock3 = types.NewBlock(&header3, nil, nil, nil)
|
||||||
|
|
||||||
|
event1 = core.ChainEvent{Block: testBlock1}
|
||||||
|
event2 = core.ChainEvent{Block: testBlock2}
|
||||||
|
event3 = core.ChainEvent{Block: testBlock3}
|
||||||
|
)
|
||||||
|
|
||||||
|
func testErrorInChainEventLoop(t *testing.T) {
|
||||||
|
//the first chain event causes and error (in blockchain mock)
|
||||||
|
builder := mocks.Builder{}
|
||||||
|
blockChain := mocks.BlockChain{}
|
||||||
|
service := statediff.Service{
|
||||||
|
Builder: &builder,
|
||||||
|
BlockChain: &blockChain,
|
||||||
|
QuitChan: make(chan bool),
|
||||||
|
Subscriptions: make(map[rpc.ID]statediff.Subscription),
|
||||||
|
}
|
||||||
|
testRoot2 = common.HexToHash("0xTestRoot2")
|
||||||
|
blockChain.SetParentBlocksToReturn([]*types.Block{parentBlock1, parentBlock2})
|
||||||
|
blockChain.SetChainEvents([]core.ChainEvent{event1, event2, event3})
|
||||||
|
service.Loop(eventsChannel)
|
||||||
|
if !reflect.DeepEqual(builder.BlockHash, testBlock2.Hash()) {
|
||||||
|
t.Error("Test failure:", t.Name())
|
||||||
|
t.Logf("Actual does not equal expected.\nactual:%+v\nexpected: %+v", builder.BlockHash, testBlock2.Hash())
|
||||||
|
}
|
||||||
|
if !bytes.Equal(builder.OldStateRoot.Bytes(), parentBlock2.Root().Bytes()) {
|
||||||
|
t.Error("Test failure:", t.Name())
|
||||||
|
t.Logf("Actual does not equal expected.\nactual:%+v\nexpected: %+v", builder.OldStateRoot, parentBlock2.Root())
|
||||||
|
}
|
||||||
|
if !bytes.Equal(builder.NewStateRoot.Bytes(), testBlock2.Root().Bytes()) {
|
||||||
|
t.Error("Test failure:", t.Name())
|
||||||
|
t.Logf("Actual does not equal expected.\nactual:%+v\nexpected: %+v", builder.NewStateRoot, testBlock2.Root())
|
||||||
|
}
|
||||||
|
//look up the parent block from its hash
|
||||||
|
expectedHashes := []common.Hash{testBlock1.ParentHash(), testBlock2.ParentHash()}
|
||||||
|
if !reflect.DeepEqual(blockChain.ParentHashesLookedUp, expectedHashes) {
|
||||||
|
t.Error("Test failure:", t.Name())
|
||||||
|
t.Logf("Actual does not equal expected.\nactual:%+v\nexpected: %+v", blockChain.ParentHashesLookedUp, expectedHashes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testErrorInBlockLoop(t *testing.T) {
|
||||||
|
//second block's parent block can't be found
|
||||||
|
builder := mocks.Builder{}
|
||||||
|
blockChain := mocks.BlockChain{}
|
||||||
|
service := statediff.Service{
|
||||||
|
Builder: &builder,
|
||||||
|
BlockChain: &blockChain,
|
||||||
|
QuitChan: make(chan bool),
|
||||||
|
Subscriptions: make(map[rpc.ID]statediff.Subscription),
|
||||||
|
}
|
||||||
|
|
||||||
|
blockChain.SetParentBlocksToReturn([]*types.Block{parentBlock1, nil})
|
||||||
|
blockChain.SetChainEvents([]core.ChainEvent{event1, event2})
|
||||||
|
service.Loop(eventsChannel)
|
||||||
|
|
||||||
|
if !bytes.Equal(builder.BlockHash.Bytes(), testBlock1.Hash().Bytes()) {
|
||||||
|
t.Error("Test failure:", t.Name())
|
||||||
|
t.Logf("Actual does not equal expected.\nactual:%+v\nexpected: %+v", builder.BlockHash, testBlock1.Hash())
|
||||||
|
}
|
||||||
|
if !bytes.Equal(builder.OldStateRoot.Bytes(), parentBlock1.Root().Bytes()) {
|
||||||
|
t.Error("Test failure:", t.Name())
|
||||||
|
t.Logf("Actual does not equal expected.\nactual:%+v\nexpected: %+v", builder.OldStateRoot, parentBlock1.Root())
|
||||||
|
}
|
||||||
|
if !bytes.Equal(builder.NewStateRoot.Bytes(), testBlock1.Root().Bytes()) {
|
||||||
|
t.Error("Test failure:", t.Name())
|
||||||
|
t.Logf("Actual does not equal expected.\nactual:%+v\nexpected: %+v", builder.NewStateRoot, testBlock1.Root())
|
||||||
|
}
|
||||||
|
}
|
2
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/helpers.go
generated
vendored
2
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/helpers.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2019 The go-ethereum Authors
|
||||||
// This file is part of the go-ethereum library.
|
// This file is part of the go-ethereum library.
|
||||||
//
|
//
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
2
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/blockchain.go
generated
vendored
2
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/blockchain.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2019 The go-ethereum Authors
|
||||||
// This file is part of the go-ethereum library.
|
// This file is part of the go-ethereum library.
|
||||||
//
|
//
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
8
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/builder.go
generated
vendored
8
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/builder.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2019 The go-ethereum Authors
|
||||||
// This file is part of the go-ethereum library.
|
// This file is part of the go-ethereum library.
|
||||||
//
|
//
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
@ -17,6 +17,8 @@
|
|||||||
package mocks
|
package mocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/statediff"
|
"github.com/ethereum/go-ethereum/statediff"
|
||||||
)
|
)
|
||||||
@ -25,14 +27,14 @@ import (
|
|||||||
type Builder struct {
|
type Builder struct {
|
||||||
OldStateRoot common.Hash
|
OldStateRoot common.Hash
|
||||||
NewStateRoot common.Hash
|
NewStateRoot common.Hash
|
||||||
BlockNumber int64
|
BlockNumber *big.Int
|
||||||
BlockHash common.Hash
|
BlockHash common.Hash
|
||||||
stateDiff statediff.StateDiff
|
stateDiff statediff.StateDiff
|
||||||
builderError error
|
builderError error
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildStateDiff mock method
|
// BuildStateDiff mock method
|
||||||
func (builder *Builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, blockNumber int64, blockHash common.Hash) (statediff.StateDiff, error) {
|
func (builder *Builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, blockNumber *big.Int, blockHash common.Hash) (statediff.StateDiff, error) {
|
||||||
builder.OldStateRoot = oldStateRoot
|
builder.OldStateRoot = oldStateRoot
|
||||||
builder.NewStateRoot = newStateRoot
|
builder.NewStateRoot = newStateRoot
|
||||||
builder.BlockNumber = blockNumber
|
builder.BlockNumber = blockNumber
|
||||||
|
2
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/publisher.go
generated
vendored
2
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/publisher.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2019 The go-ethereum Authors
|
||||||
// This file is part of the go-ethereum library.
|
// This file is part of the go-ethereum library.
|
||||||
//
|
//
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
53
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/service.go
generated
vendored
53
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/service.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2019 The go-ethereum Authors
|
||||||
// This file is part of the go-ethereum library.
|
// This file is part of the go-ethereum library.
|
||||||
//
|
//
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
@ -22,11 +22,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/ethereum/go-ethereum/statediff"
|
"github.com/ethereum/go-ethereum/statediff"
|
||||||
)
|
)
|
||||||
@ -41,6 +42,7 @@ type MockStateDiffService struct {
|
|||||||
ParentBlockChan chan *types.Block
|
ParentBlockChan chan *types.Block
|
||||||
QuitChan chan bool
|
QuitChan chan bool
|
||||||
Subscriptions map[rpc.ID]statediff.Subscription
|
Subscriptions map[rpc.ID]statediff.Subscription
|
||||||
|
streamBlock bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protocols mock method
|
// Protocols mock method
|
||||||
@ -63,7 +65,6 @@ func (sds *MockStateDiffService) APIs() []rpc.API {
|
|||||||
// Loop mock method
|
// Loop mock method
|
||||||
func (sds *MockStateDiffService) Loop(chan core.ChainEvent) {
|
func (sds *MockStateDiffService) Loop(chan core.ChainEvent) {
|
||||||
//loop through chain events until no more
|
//loop through chain events until no more
|
||||||
HandleBlockChLoop:
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case block := <-sds.BlockChan:
|
case block := <-sds.BlockChan:
|
||||||
@ -74,24 +75,12 @@ HandleBlockChLoop:
|
|||||||
log.Error("Parent block is nil, skipping this block",
|
log.Error("Parent block is nil, skipping this block",
|
||||||
"parent block hash", parentHash.String(),
|
"parent block hash", parentHash.String(),
|
||||||
"current block number", currentBlock.Number())
|
"current block number", currentBlock.Number())
|
||||||
break HandleBlockChLoop
|
continue
|
||||||
}
|
}
|
||||||
|
if err := sds.process(currentBlock, parentBlock); err != nil {
|
||||||
stateDiff, err := sds.Builder.BuildStateDiff(parentBlock.Root(), currentBlock.Root(), currentBlock.Number().Int64(), currentBlock.Hash())
|
println(err.Error())
|
||||||
if err != nil {
|
|
||||||
log.Error("Error building statediff", "block number", currentBlock.Number(), "error", err)
|
log.Error("Error building statediff", "block number", currentBlock.Number(), "error", err)
|
||||||
}
|
}
|
||||||
rlpBuff := new(bytes.Buffer)
|
|
||||||
currentBlock.EncodeRLP(rlpBuff)
|
|
||||||
blockRlp := rlpBuff.Bytes()
|
|
||||||
stateDiffRlp, _ := rlp.EncodeToBytes(stateDiff)
|
|
||||||
payload := statediff.Payload{
|
|
||||||
BlockRlp: blockRlp,
|
|
||||||
StateDiffRlp: stateDiffRlp,
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
// If we have any websocket subscription listening in, send the data to them
|
|
||||||
sds.send(payload)
|
|
||||||
case <-sds.QuitChan:
|
case <-sds.QuitChan:
|
||||||
log.Debug("Quitting the statediff block channel")
|
log.Debug("Quitting the statediff block channel")
|
||||||
sds.close()
|
sds.close()
|
||||||
@ -100,6 +89,34 @@ HandleBlockChLoop:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// process method builds the state diff payload from the current and parent block and streams it to listening subscriptions
|
||||||
|
func (sds *MockStateDiffService) process(currentBlock, parentBlock *types.Block) error {
|
||||||
|
stateDiff, err := sds.Builder.BuildStateDiff(parentBlock.Root(), currentBlock.Root(), currentBlock.Number(), currentBlock.Hash())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
stateDiffRlp, err := rlp.EncodeToBytes(stateDiff)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
payload := statediff.Payload{
|
||||||
|
StateDiffRlp: stateDiffRlp,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
if sds.streamBlock {
|
||||||
|
rlpBuff := new(bytes.Buffer)
|
||||||
|
if err = currentBlock.EncodeRLP(rlpBuff); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
payload.BlockRlp = rlpBuff.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have any websocket subscription listening in, send the data to them
|
||||||
|
sds.send(payload)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Subscribe mock method
|
// Subscribe mock method
|
||||||
func (sds *MockStateDiffService) Subscribe(id rpc.ID, sub chan<- statediff.Payload, quitChan chan<- bool) {
|
func (sds *MockStateDiffService) Subscribe(id rpc.ID, sub chan<- statediff.Payload, quitChan chan<- bool) {
|
||||||
log.Info("Subscribing to the statediff service")
|
log.Info("Subscribing to the statediff service")
|
||||||
|
145
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/service_test.go
generated
vendored
Normal file
145
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/service_test.go
generated
vendored
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package mocks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"math/big"
|
||||||
|
"sort"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff/testhelpers"
|
||||||
|
)
|
||||||
|
|
||||||
|
var block0, block1 *types.Block
|
||||||
|
var burnLeafKey = testhelpers.AddressToLeafKey(common.HexToAddress("0x0"))
|
||||||
|
var emptyAccountDiffEventualMap = make([]statediff.AccountDiff, 0)
|
||||||
|
var account1, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: uint64(0),
|
||||||
|
Balance: big.NewInt(10000),
|
||||||
|
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
|
||||||
|
Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
|
||||||
|
})
|
||||||
|
var burnAccount1, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: uint64(0),
|
||||||
|
Balance: big.NewInt(2000000000000000000),
|
||||||
|
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
|
||||||
|
Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
|
||||||
|
})
|
||||||
|
var bankAccount1, _ = rlp.EncodeToBytes(state.Account{
|
||||||
|
Nonce: uint64(1),
|
||||||
|
Balance: big.NewInt(testhelpers.TestBankFunds.Int64() - 10000),
|
||||||
|
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
|
||||||
|
Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
|
||||||
|
})
|
||||||
|
|
||||||
|
func TestAPI(t *testing.T) {
|
||||||
|
_, blockMap, chain := testhelpers.MakeChain(3, testhelpers.Genesis)
|
||||||
|
defer chain.Stop()
|
||||||
|
block0Hash := common.HexToHash("0xd1721cfd0b29c36fd7a68f25c128e86413fb666a6e1d68e89b875bd299262661")
|
||||||
|
block1Hash := common.HexToHash("0xbbe88de60ba33a3f18c0caa37d827bfb70252e19e40a07cd34041696c35ecb1a")
|
||||||
|
block0 = blockMap[block0Hash]
|
||||||
|
block1 = blockMap[block1Hash]
|
||||||
|
blockChan := make(chan *types.Block)
|
||||||
|
parentBlockChain := make(chan *types.Block)
|
||||||
|
serviceQuitChan := make(chan bool)
|
||||||
|
config := statediff.Config{
|
||||||
|
PathsAndProofs: true,
|
||||||
|
AllNodes: false,
|
||||||
|
}
|
||||||
|
mockService := MockStateDiffService{
|
||||||
|
Mutex: sync.Mutex{},
|
||||||
|
Builder: statediff.NewBuilder(testhelpers.Testdb, chain, config),
|
||||||
|
BlockChan: blockChan,
|
||||||
|
ParentBlockChan: parentBlockChain,
|
||||||
|
QuitChan: serviceQuitChan,
|
||||||
|
Subscriptions: make(map[rpc.ID]statediff.Subscription),
|
||||||
|
streamBlock: true,
|
||||||
|
}
|
||||||
|
mockService.Start(nil)
|
||||||
|
id := rpc.NewID()
|
||||||
|
payloadChan := make(chan statediff.Payload)
|
||||||
|
quitChan := make(chan bool)
|
||||||
|
mockService.Subscribe(id, payloadChan, quitChan)
|
||||||
|
blockChan <- block1
|
||||||
|
parentBlockChain <- block0
|
||||||
|
expectedBlockRlp, _ := rlp.EncodeToBytes(block1)
|
||||||
|
expectedStateDiff := statediff.StateDiff{
|
||||||
|
BlockNumber: block1.Number(),
|
||||||
|
BlockHash: block1.Hash(),
|
||||||
|
CreatedAccounts: []statediff.AccountDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: burnLeafKey.Bytes(),
|
||||||
|
Value: burnAccount1,
|
||||||
|
Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128},
|
||||||
|
{248, 113, 160, 51, 128, 199, 183, 174, 129, 165, 142, 185, 141, 156, 120, 222, 74, 31, 215, 253, 149, 53, 252, 149, 62, 210, 190, 96, 45, 170, 164, 23, 103, 49, 42, 184, 78, 248, 76, 128, 136, 27, 193, 109, 103, 78, 200, 0, 0, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{5, 3, 8, 0, 12, 7, 11, 7, 10, 14, 8, 1, 10, 5, 8, 14, 11, 9, 8, 13, 9, 12, 7, 8, 13, 14, 4, 10, 1, 15, 13, 7, 15, 13, 9, 5, 3, 5, 15, 12, 9, 5, 3, 14, 13, 2, 11, 14, 6, 0, 2, 13, 10, 10, 10, 4, 1, 7, 6, 7, 3, 1, 2, 10, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: testhelpers.Account1LeafKey.Bytes(),
|
||||||
|
Value: account1,
|
||||||
|
Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128},
|
||||||
|
{248, 107, 160, 57, 38, 219, 105, 170, 206, 213, 24, 233, 185, 240, 244, 52, 164, 115, 231, 23, 65, 9, 201, 67, 84, 139, 184, 242, 59, 228, 28, 167, 109, 154, 210, 184, 72, 248, 70, 128, 130, 39, 16, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{14, 9, 2, 6, 13, 11, 6, 9, 10, 10, 12, 14, 13, 5, 1, 8, 14, 9, 11, 9, 15, 0, 15, 4, 3, 4, 10, 4, 7, 3, 14, 7, 1, 7, 4, 1, 0, 9, 12, 9, 4, 3, 5, 4, 8, 11, 11, 8, 15, 2, 3, 11, 14, 4, 1, 12, 10, 7, 6, 13, 9, 10, 13, 2, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DeletedAccounts: emptyAccountDiffEventualMap,
|
||||||
|
UpdatedAccounts: []statediff.AccountDiff{
|
||||||
|
{
|
||||||
|
Leaf: true,
|
||||||
|
Key: testhelpers.BankLeafKey.Bytes(),
|
||||||
|
Value: bankAccount1,
|
||||||
|
Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128},
|
||||||
|
{248, 109, 160, 48, 191, 73, 244, 64, 161, 205, 5, 39, 228, 208, 110, 39, 101, 101, 76, 15, 86, 69, 34, 87, 81, 109, 121, 58, 155, 141, 96, 77, 207, 223, 42, 184, 74, 248, 72, 1, 132, 5, 245, 185, 240, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}},
|
||||||
|
Path: []byte{0, 0, 11, 15, 4, 9, 15, 4, 4, 0, 10, 1, 12, 13, 0, 5, 2, 7, 14, 4, 13, 0, 6, 14, 2, 7, 6, 5, 6, 5, 4, 12, 0, 15, 5, 6, 4, 5, 2, 2, 5, 7, 5, 1, 6, 13, 7, 9, 3, 10, 9, 11, 8, 13, 6, 0, 4, 13, 12, 15, 13, 15, 2, 10, 16},
|
||||||
|
Storage: []statediff.StorageDiff{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
expectedStateDiffBytes, err := rlp.EncodeToBytes(expectedStateDiff)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
sort.Slice(expectedStateDiffBytes, func(i, j int) bool { return expectedStateDiffBytes[i] < expectedStateDiffBytes[j] })
|
||||||
|
|
||||||
|
select {
|
||||||
|
case payload := <-payloadChan:
|
||||||
|
if !bytes.Equal(payload.BlockRlp, expectedBlockRlp) {
|
||||||
|
t.Errorf("payload does not have expected block\r\actual block rlp: %v\r\nexpected block rlp: %v", payload.BlockRlp, expectedBlockRlp)
|
||||||
|
}
|
||||||
|
sort.Slice(payload.StateDiffRlp, func(i, j int) bool { return payload.StateDiffRlp[i] < payload.StateDiffRlp[j] })
|
||||||
|
if !bytes.Equal(payload.StateDiffRlp, expectedStateDiffBytes) {
|
||||||
|
t.Errorf("payload does not have expected state diff\r\actual state diff rlp: %v\r\nexpected state diff rlp: %v", payload.StateDiffRlp, expectedStateDiffBytes)
|
||||||
|
}
|
||||||
|
if payload.Err != nil {
|
||||||
|
t.Errorf("payload should not contain an error, but does: %v", payload.Err)
|
||||||
|
}
|
||||||
|
case <-quitChan:
|
||||||
|
t.Errorf("channel quit before delivering payload")
|
||||||
|
}
|
||||||
|
}
|
14
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/test_data.go
generated
vendored
14
vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/test_data.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2019 The go-ethereum Authors
|
||||||
// This file is part of the go-ethereum library.
|
// This file is part of the go-ethereum library.
|
||||||
//
|
//
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
@ -36,7 +36,7 @@ func AddressToLeafKey(address common.Address) common.Hash {
|
|||||||
|
|
||||||
// Test variables
|
// Test variables
|
||||||
var (
|
var (
|
||||||
BlockNumber = rand.Int63()
|
BlockNumber = big.NewInt(rand.Int63())
|
||||||
BlockHash = "0xfa40fbe2d98d98b3363a778d52f2bcd29d6790b9b3f3cab2b167fd12d3550f73"
|
BlockHash = "0xfa40fbe2d98d98b3363a778d52f2bcd29d6790b9b3f3cab2b167fd12d3550f73"
|
||||||
CodeHash = common.Hex2Bytes("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
|
CodeHash = common.Hex2Bytes("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
|
||||||
NewNonceValue = rand.Uint64()
|
NewNonceValue = rand.Uint64()
|
||||||
@ -63,26 +63,26 @@ var (
|
|||||||
CodeHash: CodeHash,
|
CodeHash: CodeHash,
|
||||||
}
|
}
|
||||||
valueBytes, _ = rlp.EncodeToBytes(testAccount)
|
valueBytes, _ = rlp.EncodeToBytes(testAccount)
|
||||||
CreatedAccountDiffs = statediff.AccountDiffsMap{
|
CreatedAccountDiffs = []statediff.AccountDiff{
|
||||||
ContractLeafKey: {
|
{
|
||||||
Key: ContractLeafKey.Bytes(),
|
Key: ContractLeafKey.Bytes(),
|
||||||
Value: valueBytes,
|
Value: valueBytes,
|
||||||
Storage: storage,
|
Storage: storage,
|
||||||
},
|
},
|
||||||
AnotherContractLeafKey: {
|
{
|
||||||
Key: AnotherContractLeafKey.Bytes(),
|
Key: AnotherContractLeafKey.Bytes(),
|
||||||
Value: valueBytes,
|
Value: valueBytes,
|
||||||
Storage: emptyStorage,
|
Storage: emptyStorage,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatedAccountDiffs = statediff.AccountDiffsMap{ContractLeafKey: {
|
UpdatedAccountDiffs = []statediff.AccountDiff{{
|
||||||
Key: ContractLeafKey.Bytes(),
|
Key: ContractLeafKey.Bytes(),
|
||||||
Value: valueBytes,
|
Value: valueBytes,
|
||||||
Storage: storage,
|
Storage: storage,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
DeletedAccountDiffs = statediff.AccountDiffsMap{ContractLeafKey: {
|
DeletedAccountDiffs = []statediff.AccountDiff{{
|
||||||
Key: ContractLeafKey.Bytes(),
|
Key: ContractLeafKey.Bytes(),
|
||||||
Value: valueBytes,
|
Value: valueBytes,
|
||||||
Storage: storage,
|
Storage: storage,
|
||||||
|
77
vendor/github.com/ethereum/go-ethereum/statediff/types.go
generated
vendored
77
vendor/github.com/ethereum/go-ethereum/statediff/types.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2019 The go-ethereum Authors
|
||||||
// This file is part of the go-ethereum library.
|
// This file is part of the go-ethereum library.
|
||||||
//
|
//
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
@ -21,30 +21,33 @@ package statediff
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountsMap is a mapping of keccak256(address) => accountWrapper
|
// Subscription struct holds our subscription channels
|
||||||
type AccountsMap map[common.Hash]accountWrapper
|
type Subscription struct {
|
||||||
|
PayloadChan chan<- Payload
|
||||||
|
QuitChan chan<- bool
|
||||||
|
}
|
||||||
|
|
||||||
// AccountWrapper is used to temporary associate the unpacked account with its raw values
|
// Payload packages the data to send to StateDiffingService subscriptions
|
||||||
type accountWrapper struct {
|
type Payload struct {
|
||||||
Account state.Account
|
BlockRlp []byte `json:"blockRlp" gencodec:"required"`
|
||||||
RawKey []byte
|
StateDiffRlp []byte `json:"stateDiff" gencodec:"required"`
|
||||||
RawValue []byte
|
Err error `json:"error"`
|
||||||
Proof [][]byte
|
|
||||||
Path []byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StateDiff is the final output structure from the builder
|
// StateDiff is the final output structure from the builder
|
||||||
type StateDiff struct {
|
type StateDiff struct {
|
||||||
BlockNumber int64 `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"`
|
||||||
CreatedAccounts AccountDiffsMap `json:"createdAccounts" gencodec:"required"`
|
CreatedAccounts []AccountDiff `json:"createdAccounts" gencodec:"required"`
|
||||||
DeletedAccounts AccountDiffsMap `json:"deletedAccounts" gencodec:"required"`
|
DeletedAccounts []AccountDiff `json:"deletedAccounts" gencodec:"required"`
|
||||||
UpdatedAccounts AccountDiffsMap `json:"updatedAccounts" gencodec:"required"`
|
UpdatedAccounts []AccountDiff `json:"updatedAccounts" gencodec:"required"`
|
||||||
|
|
||||||
encoded []byte
|
encoded []byte
|
||||||
err error
|
err error
|
||||||
@ -68,46 +71,34 @@ func (sd *StateDiff) Encode() ([]byte, error) {
|
|||||||
return sd.encoded, sd.err
|
return sd.encoded, sd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountDiffsMap is a mapping of keccak256(address) => AccountDiff
|
// AccountDiff holds the data for a single state diff node
|
||||||
type AccountDiffsMap map[common.Hash]AccountDiff
|
|
||||||
|
|
||||||
// AccountDiff holds the data for a single state diff leaf node
|
|
||||||
type AccountDiff struct {
|
type AccountDiff struct {
|
||||||
|
Leaf bool `json:"leaf" gencodec:"required"`
|
||||||
Key []byte `json:"key" gencodec:"required"`
|
Key []byte `json:"key" gencodec:"required"`
|
||||||
Value []byte `json:"value" gencodec:"required"`
|
Value []byte `json:"value" gencodec:"required"`
|
||||||
Proof [][]byte `json:"proof" gencodec:"required"`
|
Proof [][]byte `json:"proof" gencodec:"required"`
|
||||||
Storage []StorageDiff `json:"storage" gencodec:"required"`
|
|
||||||
Path []byte `json:"path" gencodec:"required"`
|
Path []byte `json:"path" gencodec:"required"`
|
||||||
|
Storage []StorageDiff `json:"storage" gencodec:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// StorageDiff holds the data for a single storage diff leaf node
|
// StorageDiff holds the data for a single storage diff node
|
||||||
type StorageDiff struct {
|
type StorageDiff struct {
|
||||||
|
Leaf bool `json:"leaf" gencodec:"required"`
|
||||||
Key []byte `json:"key" gencodec:"required"`
|
Key []byte `json:"key" gencodec:"required"`
|
||||||
Value []byte `json:"value" gencodec:"required"`
|
Value []byte `json:"value" gencodec:"required"`
|
||||||
Proof [][]byte `json:"proof" gencodec:"required"`
|
Proof [][]byte `json:"proof" gencodec:"required"`
|
||||||
Path []byte `json:"path" gencodec:"required"`
|
Path []byte `json:"path" gencodec:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// AccountsMap is a mapping of keccak256(address) => accountWrapper
|
||||||
// State trie leaf is just a short node, below
|
type AccountsMap map[common.Hash]accountWrapper
|
||||||
// that has an rlp encoded account as the value
|
|
||||||
|
|
||||||
|
// AccountWrapper is used to temporary associate the unpacked account with its raw values
|
||||||
// SO each account diffs map is reall a map of shortnode keys to values
|
type accountWrapper struct {
|
||||||
// Flatten to a slice of short nodes?
|
Account *state.Account
|
||||||
|
Leaf bool
|
||||||
// Need to coerce into:
|
RawKey []byte
|
||||||
|
RawValue []byte
|
||||||
type TrieNode struct {
|
Proof [][]byte
|
||||||
// leaf, extension or branch
|
Path []byte
|
||||||
nodeKind string
|
|
||||||
|
|
||||||
// If leaf or extension: [0] is key, [1] is val.
|
|
||||||
// If branch: [0] - [16] are children.
|
|
||||||
elements []interface{}
|
|
||||||
|
|
||||||
// IPLD block information
|
|
||||||
cid *cid.Cid
|
|
||||||
rawdata []byte
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
Loading…
Reference in New Issue
Block a user