diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index 7d2874090..d27c3b109 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -148,8 +148,6 @@ var (
utils.EWASMInterpreterFlag,
utils.EVMInterpreterFlag,
utils.StateDiffFlag,
- utils.StateDiffModeFlag,
- utils.StateDiffPathFlag,
configFileFlag,
}
diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go
index ce6eab279..77d816476 100644
--- a/cmd/geth/usage.go
+++ b/cmd/geth/usage.go
@@ -266,8 +266,6 @@ var AppHelpFlagGroups = []flagGroup{
Name: "STATE DIFF",
Flags: []cli.Flag{
utils.StateDiffFlag,
- utils.StateDiffModeFlag,
- utils.StateDiffPathFlag,
},
},
{
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 1ab05773d..b76c5dfe0 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -29,6 +29,8 @@ import (
"strings"
"time"
+ cli "gopkg.in/urfave/cli.v1"
+
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
@@ -59,11 +61,10 @@ import (
"github.com/ethereum/go-ethereum/p2p/netutil"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
- whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
- pcsclite "github.com/gballet/go-libpcsclite"
- cli "gopkg.in/urfave/cli.v1"
- "github.com/ethereum/go-ethereum/statediff/service"
"github.com/ethereum/go-ethereum/statediff"
+ whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
+
+ pcsclite "github.com/gballet/go-libpcsclite"
)
var (
@@ -744,18 +745,6 @@ var (
Name: "statediff",
Usage: "Enables the calculation of state diffs between each block, persists these state diffs the configured persistence mode.",
}
-
- StateDiffModeFlag = cli.StringFlag{
- Name: "statediff.mode",
- Usage: "Enables the user to determine which persistence mode they'd like to store the state diffs in.",
- Value: "csv",
- }
-
- StateDiffPathFlag = cli.StringFlag{
- Name: "statediff.path",
- Usage: "Enables the user to determine where to persist the state diffs.",
- Value: ".",
- }
)
// MakeDataDir retrieves the currently requested data directory, terminating
@@ -965,6 +954,9 @@ func setWS(ctx *cli.Context, cfg *node.Config) {
if ctx.GlobalIsSet(WSApiFlag.Name) {
cfg.WSModules = splitAndTrim(ctx.GlobalString(WSApiFlag.Name))
}
+ if ctx.GlobalBool(StateDiffFlag.Name) {
+ cfg.WSModules = append(cfg.WSModules, "statediff")
+ }
}
// setIPC creates an IPC path configuration from the set command line flags,
@@ -1606,29 +1598,14 @@ func RegisterGraphQLService(stack *node.Node, endpoint string, cors, vhosts []st
}
}
+// RegisterStateDiffService configures and registers a service to stream state diff data over RPC
func RegisterStateDiffService(stack *node.Node, ctx *cli.Context) {
- //based on the context, if path and mode are set, update the config here
- //otherwise pass in an empty config
-
- modeFlag := ctx.GlobalString(StateDiffModeFlag.Name)
- mode, err := statediff.NewMode(modeFlag)
- if err != nil {
- Fatalf("Failed to register State Diff Service", err)
- }
-
- path := ctx.GlobalString(StateDiffPathFlag.Name)
-
- config := statediff.Config{
- Mode: mode,
- Path: path,
- }
-
if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
var ethServ *eth.Ethereum
ctx.Service(ðServ)
chainDb := ethServ.ChainDb()
blockChain := ethServ.BlockChain()
- return service.NewStateDiffService(chainDb, blockChain, config)
+ return statediff.NewStateDiffService(chainDb, blockChain)
}); err != nil {
Fatalf("Failed to register State Diff Service", err)
}
diff --git a/core/blockchain.go b/core/blockchain.go
index 18bcd4113..cf1a65cd5 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -106,11 +106,11 @@ const (
// CacheConfig contains the configuration values for the trie caching/pruning
// that's resident in a blockchain.
type CacheConfig struct {
- TrieCleanLimit int // Memory allowance (MB) to use for caching trie nodes in memory
- TrieCleanNoPrefetch bool // Whether to disable heuristic state prefetching for followup blocks
- TrieDirtyLimit int // Memory limit (MB) at which to start flushing dirty trie nodes to disk
- TrieDirtyDisabled bool // Whether to disable trie write caching and GC altogether (archive node)
- TrieTimeLimit time.Duration // Time limit after which to flush the current in-memory trie to disk
+ TrieCleanLimit int // Memory allowance (MB) to use for caching trie nodes in memory
+ TrieCleanNoPrefetch bool // Whether to disable heuristic state prefetching for followup blocks
+ TrieDirtyLimit int // Memory limit (MB) at which to start flushing dirty trie nodes to disk
+ TrieDirtyDisabled bool // Whether to disable trie write caching and GC altogether (archive node)
+ TrieTimeLimit time.Duration // Time limit after which to flush the current in-memory trie to disk
ProcessingStateDiffs bool // Whether statediffs processing should be taken into a account before a trie is pruned
}
@@ -1336,16 +1336,19 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
bc.triegc.Push(root, number)
break
}
-
if bc.cacheConfig.ProcessingStateDiffs {
if !bc.allowedRootToBeDereferenced(root.(common.Hash)) {
bc.triegc.Push(root, number)
break
} else {
+ log.Debug("Current root found in stateDiffsProcessed collection with a count of 2, okay to dereference",
+ "root", root.(common.Hash).Hex(),
+ "blockNumber", uint64(-number),
+ "size of stateDiffsProcessed", len(bc.stateDiffsProcessed))
delete(bc.stateDiffsProcessed, root.(common.Hash))
}
}
-
+ log.Debug("Dereferencing", "root", root.(common.Hash).Hex())
triedb.Dereference(root.(common.Hash))
}
}
diff --git a/eth/backend.go b/eth/backend.go
index b3ca91373..f46fde656 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -179,11 +179,11 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
EVMInterpreter: config.EVMInterpreter,
}
cacheConfig = &core.CacheConfig{
- TrieCleanLimit: config.TrieCleanCache,
- TrieCleanNoPrefetch: config.NoPrefetch,
- TrieDirtyLimit: config.TrieDirtyCache,
- TrieDirtyDisabled: config.NoPruning,
- TrieTimeLimit: config.TrieTimeout,
+ TrieCleanLimit: config.TrieCleanCache,
+ TrieCleanNoPrefetch: config.NoPrefetch,
+ TrieDirtyLimit: config.TrieDirtyCache,
+ TrieDirtyDisabled: config.NoPruning,
+ TrieTimeLimit: config.TrieTimeout,
ProcessingStateDiffs: config.StateDiff,
}
)
diff --git a/statediff/config.go b/statediff/config.go
deleted file mode 100644
index 7f5ec3c35..000000000
--- a/statediff/config.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains a batch of utility type declarations used by the tests. As the node
-// operates on unique types, a lot of them are needed to check various features.
-
-package statediff
-
-import "fmt"
-
-type Config struct {
- Mode StateDiffMode // Mode for storing diffs
- Path string // Path for storing diffs
-}
-
-type StateDiffMode int
-
-const (
- CSV StateDiffMode = iota
- IPLD
- LDB
- SQL
-)
-
-func (mode StateDiffMode) IsValid() bool {
- return mode >= IPLD && mode <= SQL
-}
-
-// String implements the stringer interface.
-func (mode StateDiffMode) String() string {
- switch mode {
- case CSV:
- return "csv"
- case IPLD:
- return "ipfs"
- case LDB:
- return "ldb"
- case SQL:
- return "sql"
- default:
- return "unknown"
- }
-}
-
-func NewMode(mode string) (StateDiffMode, error) {
- stateDiffMode := StateDiffMode(0)
- err := stateDiffMode.UnmarshalText([]byte(mode))
- return stateDiffMode, err
-}
-
-func (mode StateDiffMode) MarshalText() ([]byte, error) {
- switch mode {
- case CSV:
- return []byte("ipfs"), nil
- case IPLD:
- return []byte("ipfs"), nil
- case LDB:
- return []byte("ldb"), nil
- case SQL:
- return []byte("sql"), nil
- default:
- return nil, fmt.Errorf("unknown state diff storage mode %d", mode)
- }
-}
-
-func (mode *StateDiffMode) UnmarshalText(text []byte) error {
- switch string(text) {
- case "csv":
- *mode = CSV
- case "ipfs":
- *mode = IPLD
- case "ldb":
- *mode = LDB
- case "sql":
- *mode = SQL
- default:
- return fmt.Errorf(`unknown state diff storage mode %q, want "ipfs", "ldb" or "sql"`, text)
- }
- return nil
-}
diff --git a/statediff/config_test.go b/statediff/config_test.go
deleted file mode 100644
index 5246d1cd1..000000000
--- a/statediff/config_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package statediff_test
-
-import (
- "testing"
-
- "github.com/ethereum/go-ethereum/statediff"
- "github.com/ethereum/go-ethereum/statediff/testhelpers"
-)
-
-func TestNewMode(t *testing.T) {
- mode, err := statediff.NewMode("csv")
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- if mode != statediff.CSV {
- t.Error()
- }
-
- _, err = statediff.NewMode("not a real mode")
- if err == nil {
- t.Error("Expected an error, and got nil.")
- }
-}
diff --git a/statediff/extractor/extractor.go b/statediff/extractor/extractor.go
deleted file mode 100644
index 770973c8d..000000000
--- a/statediff/extractor/extractor.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains a batch of utility type declarations used by the tests. As the node
-// operates on unique types, a lot of them are needed to check various features.
-
-package extractor
-
-import (
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/statediff/builder"
- "github.com/ethereum/go-ethereum/statediff/publisher"
-)
-
-type Extractor interface {
- ExtractStateDiff(parent, current types.Block) (string, error)
-}
-
-type extractor struct {
- Builder builder.Builder // Interface for building state diff objects from two blocks
- Publisher publisher.Publisher // Interface for publishing state diff objects to a datastore (e.g. IPFS)
-}
-
-func NewExtractor(builder builder.Builder, publisher publisher.Publisher) *extractor {
- return &extractor{
- Builder: builder,
- Publisher: publisher,
- }
-}
-
-func (e *extractor) ExtractStateDiff(parent, current types.Block) (string, error) {
- stateDiff, err := e.Builder.BuildStateDiff(parent.Root(), current.Root(), current.Number().Int64(), current.Hash())
- if err != nil {
- return "", err
- }
-
- return e.Publisher.PublishStateDiff(stateDiff)
-}
diff --git a/statediff/extractor/extractor_test.go b/statediff/extractor/extractor_test.go
deleted file mode 100644
index 0ed036c12..000000000
--- a/statediff/extractor/extractor_test.go
+++ /dev/null
@@ -1,123 +0,0 @@
-package extractor_test
-
-import (
- "bytes"
- "math/big"
- "math/rand"
- "reflect"
- "testing"
-
- "github.com/ethereum/go-ethereum/core/types"
- b "github.com/ethereum/go-ethereum/statediff/builder"
- e "github.com/ethereum/go-ethereum/statediff/extractor"
- "github.com/ethereum/go-ethereum/statediff/testhelpers/mocks"
-)
-
-var publisher mocks.Publisher
-var builder mocks.Builder
-var currentBlockNumber *big.Int
-var parentBlock, currentBlock *types.Block
-var expectedStateDiff b.StateDiff
-var extractor e.Extractor
-var err error
-
-func TestExtractor(t *testing.T) {
- publisher = mocks.Publisher{}
- builder = mocks.Builder{}
- extractor = e.NewExtractor(&builder, &publisher)
- if err != nil {
- t.Error(err)
- }
-
- blockNumber := rand.Int63()
- parentBlockNumber := big.NewInt(blockNumber - int64(1))
- currentBlockNumber = big.NewInt(blockNumber)
- parentBlock = types.NewBlock(&types.Header{Number: parentBlockNumber}, nil, nil, nil)
- currentBlock = types.NewBlock(&types.Header{Number: currentBlockNumber}, nil, nil, nil)
-
- expectedStateDiff = b.StateDiff{
- BlockNumber: blockNumber,
- BlockHash: currentBlock.Hash(),
- CreatedAccounts: nil,
- DeletedAccounts: nil,
- UpdatedAccounts: nil,
- }
-
- testBuildStateDiffStruct(t)
- testBuildStateDiffErrorHandling(t)
- testPublishingStateDiff(t)
- testPublisherErrorHandling(t)
-}
-
-func testBuildStateDiffStruct(t *testing.T) {
- builder.SetStateDiffToBuild(&expectedStateDiff)
-
- _, err = extractor.ExtractStateDiff(*parentBlock, *currentBlock)
- if err != nil {
- t.Error(err)
- }
-
- if !equals(builder.OldStateRoot, parentBlock.Root()) {
- t.Error()
- }
- if !equals(builder.NewStateRoot, currentBlock.Root()) {
- t.Error()
- }
- if !equals(builder.BlockNumber, currentBlockNumber.Int64()) {
- t.Error()
- }
- if !equals(builder.BlockHash, currentBlock.Hash()) {
- t.Error()
- }
-}
-
-func testBuildStateDiffErrorHandling(t *testing.T) {
- builder.SetBuilderError(mocks.Error)
-
- _, err = extractor.ExtractStateDiff(*parentBlock, *currentBlock)
- if err == nil {
- t.Error(err)
- }
-
- if !equals(err, mocks.Error) {
- t.Error()
- }
- builder.SetBuilderError(nil)
-}
-
-func testPublishingStateDiff(t *testing.T) {
- builder.SetStateDiffToBuild(&expectedStateDiff)
-
- _, err = extractor.ExtractStateDiff(*parentBlock, *currentBlock)
- if err != nil {
- t.Error(err)
- }
-
- if !equals(publisher.StateDiff, &expectedStateDiff) {
- t.Error()
- }
-}
-
-func testPublisherErrorHandling(t *testing.T) {
- publisher.SetPublisherError(mocks.Error)
-
- _, err = extractor.ExtractStateDiff(*parentBlock, *currentBlock)
- if err == nil {
- t.Error("Expected an error, but it didn't occur.")
- }
- if !equals(err, mocks.Error) {
- t.Error()
- }
-
- publisher.SetPublisherError(nil)
-}
-
-func equals(actual, expected interface{}) (success bool) {
- if actualByteSlice, ok := actual.([]byte); ok {
- if expectedByteSlice, ok := expected.([]byte); ok {
- return bytes.Equal(actualByteSlice, expectedByteSlice)
- }
- }
-
- return reflect.DeepEqual(actual, expected)
-}
diff --git a/statediff/helpers.go b/statediff/helpers.go
new file mode 100644
index 000000000..96f9ddf30
--- /dev/null
+++ b/statediff/helpers.go
@@ -0,0 +1,118 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// Contains a batch of utility type declarations used by the tests. As the node
+// operates on unique types, a lot of them are needed to check various features.
+
+package statediff
+
+import (
+ "sort"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/trie"
+)
+
+func sortKeys(data AccountsMap) []string {
+ var keys []string
+ for key := range data {
+ keys = append(keys, key.Hex())
+ }
+ sort.Strings(keys)
+
+ return keys
+}
+
+// BytesToNiblePath
+func bytesToNiblePath(path []byte) string {
+ if hasTerm(path) {
+ path = path[:len(path)-1]
+ }
+ nibblePath := ""
+ for i, v := range common.ToHex(path) {
+ if i%2 == 0 && i > 1 {
+ continue
+ }
+ nibblePath = nibblePath + string(v)
+ }
+
+ return nibblePath
+}
+
+func findIntersection(a, b []string) []string {
+ lenA := len(a)
+ lenB := len(b)
+ iOfA, iOfB := 0, 0
+ updates := make([]string, 0)
+ if iOfA >= lenA || iOfB >= lenB {
+ return updates
+ }
+ for {
+ switch strings.Compare(a[iOfA], b[iOfB]) {
+ // a[iOfA] < b[iOfB]
+ case -1:
+ iOfA++
+ if iOfA >= lenA {
+ return updates
+ }
+ // a[iOfA] == b[iOfB]
+ case 0:
+ updates = append(updates, a[iOfA])
+ iOfA++
+ iOfB++
+ if iOfA >= lenA || iOfB >= lenB {
+ return updates
+ }
+ // a[iOfA] > b[iOfB]
+ case 1:
+ iOfB++
+ if iOfB >= lenB {
+ return updates
+ }
+ }
+ }
+
+}
+
+func pathToStr(it trie.NodeIterator) string {
+ return bytesToNiblePath(it.Path())
+}
+
+// Duplicated from trie/encoding.go
+func hexToKeyBytes(hex []byte) []byte {
+ if hasTerm(hex) {
+ hex = hex[:len(hex)-1]
+ }
+ if len(hex)&1 != 0 {
+ panic("can't convert hex key of odd length")
+ }
+ key := make([]byte, (len(hex)+1)/2)
+ decodeNibbles(hex, key)
+
+ return key
+}
+
+func decodeNibbles(nibbles []byte, bytes []byte) {
+ for bi, ni := 0, 0; ni < len(nibbles); bi, ni = bi+1, ni+2 {
+ bytes[bi] = nibbles[ni]<<4 | nibbles[ni+1]
+ }
+}
+
+// hasTerm returns whether a hex key has the terminator flag.
+func hasTerm(s []byte) bool {
+ return len(s) > 0 && s[len(s)-1] == 16
+}
diff --git a/statediff/publisher/csv.go b/statediff/publisher/csv.go
deleted file mode 100644
index 13971a5c8..000000000
--- a/statediff/publisher/csv.go
+++ /dev/null
@@ -1,130 +0,0 @@
-package publisher
-
-import (
- "encoding/csv"
- "os"
- "path/filepath"
- "strconv"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/statediff/builder"
-)
-
-var (
- Headers = []string{
- "blockNumber", "blockHash", "accountAction", "codeHash",
- "nonceValue", "balanceValue", "contractRoot", "storageDiffPaths",
- "accountLeafKey", "storageKey", "storageValue",
- }
-
- timeStampFormat = "20060102150405.00000"
- deletedAccountAction = "deleted"
- createdAccountAction = "created"
- updatedAccountAction = "updated"
-)
-
-func createCSVFilePath(path, blockNumber string) string {
- now := time.Now()
- timeStamp := now.Format(timeStampFormat)
- suffix := timeStamp + "-" + blockNumber
- filePath := filepath.Join(path, suffix)
- filePath = filePath + ".csv"
- return filePath
-}
-
-func (p *publisher) publishStateDiffToCSV(sd builder.StateDiff) (string, error) {
- filePath := createCSVFilePath(p.Config.Path, strconv.FormatInt(sd.BlockNumber, 10))
-
- file, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
- if err != nil {
- return "", err
- }
- defer file.Close()
-
- writer := csv.NewWriter(file)
- defer writer.Flush()
-
- var data [][]string
- data = append(data, Headers)
- data = append(data, accumulateAccountRows(sd)...)
- for _, value := range data {
- err := writer.Write(value)
- if err != nil {
- return "", err
- }
- }
-
- return filePath, nil
-}
-
-func accumulateAccountRows(sd builder.StateDiff) [][]string {
- var accountRows [][]string
- for accountAddr, accountDiff := range sd.CreatedAccounts {
- formattedAccountData := formatAccountData(accountAddr, accountDiff, sd, createdAccountAction)
-
- accountRows = append(accountRows, formattedAccountData...)
- }
-
- for accountAddr, accountDiff := range sd.UpdatedAccounts {
- formattedAccountData := formatAccountData(accountAddr, accountDiff, sd, updatedAccountAction)
-
- accountRows = append(accountRows, formattedAccountData...)
- }
-
- for accountAddr, accountDiff := range sd.DeletedAccounts {
- formattedAccountData := formatAccountData(accountAddr, accountDiff, sd, deletedAccountAction)
-
- accountRows = append(accountRows, formattedAccountData...)
- }
-
- return accountRows
-}
-
-func formatAccountData(accountAddr common.Hash, accountDiff builder.AccountDiff, sd builder.StateDiff, accountAction string) [][]string {
- blockNumberString := strconv.FormatInt(sd.BlockNumber, 10)
- blockHash := sd.BlockHash.String()
- codeHash := accountDiff.CodeHash
- nonce := strconv.FormatUint(*accountDiff.Nonce.Value, 10)
- balance := accountDiff.Balance.Value.String()
- newContractRoot := accountDiff.ContractRoot.Value
- address := accountAddr.String()
- var result [][]string
-
- if len(accountDiff.Storage) > 0 {
- for storagePath, storage := range accountDiff.Storage {
- formattedAccountData := []string{
- blockNumberString,
- blockHash,
- accountAction,
- codeHash,
- nonce,
- balance,
- *newContractRoot,
- storagePath,
- address,
- *storage.Key,
- *storage.Value,
- }
-
- result = append(result, formattedAccountData)
- }
- } else {
- formattedAccountData := []string{
- blockNumberString,
- blockHash,
- accountAction,
- codeHash,
- nonce,
- balance,
- *newContractRoot,
- "",
- address,
- "",
- "",
- }
- result = append(result, formattedAccountData)
- }
-
- return result
-}
diff --git a/statediff/publisher/publisher.go b/statediff/publisher/publisher.go
deleted file mode 100644
index ff1925513..000000000
--- a/statediff/publisher/publisher.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains a batch of utility type declarations used by the tests. As the node
-// operates on unique types, a lot of them are needed to check various features.
-
-package publisher
-
-import (
- "github.com/ethereum/go-ethereum/statediff"
- "github.com/ethereum/go-ethereum/statediff/builder"
-)
-
-type Publisher interface {
- PublishStateDiff(sd *builder.StateDiff) (string, error)
-}
-
-type publisher struct {
- Config statediff.Config
-}
-
-func NewPublisher(config statediff.Config) (*publisher, error) {
- return &publisher{
- Config: config,
- }, nil
-}
-
-func (p *publisher) PublishStateDiff(sd *builder.StateDiff) (string, error) {
- switch p.Config.Mode {
- case statediff.CSV:
- return p.publishStateDiffToCSV(*sd)
- default:
- return p.publishStateDiffToCSV(*sd)
- }
-}
diff --git a/statediff/publisher/publisher_test.go b/statediff/publisher/publisher_test.go
deleted file mode 100644
index 76aaf961e..000000000
--- a/statediff/publisher/publisher_test.go
+++ /dev/null
@@ -1,316 +0,0 @@
-package publisher_test
-
-import (
- "bytes"
- "encoding/csv"
- "io/ioutil"
- "os"
- "path/filepath"
- "reflect"
- "strconv"
- "strings"
- "testing"
-
- "github.com/ethereum/go-ethereum/statediff"
- "github.com/ethereum/go-ethereum/statediff/builder"
- p "github.com/ethereum/go-ethereum/statediff/publisher"
- "github.com/ethereum/go-ethereum/statediff/testhelpers"
- "github.com/pkg/errors"
-)
-
-var (
- tempDir = os.TempDir()
- testFilePrefix = "test-statediff"
- publisher p.Publisher
- dir string
- err error
-)
-
-var expectedCreatedAccountRow = []string{
- strconv.FormatInt(testhelpers.BlockNumber, 10),
- testhelpers.BlockHash,
- "created",
- testhelpers.CodeHash,
- strconv.FormatUint(testhelpers.NewNonceValue, 10),
- strconv.FormatInt(testhelpers.NewBalanceValue, 10),
- testhelpers.ContractRoot,
- testhelpers.StoragePath,
- testhelpers.ContractLeafKey.Hex(),
- "0000000000000000000000000000000000000000000000000000000000000001",
- testhelpers.StorageValue,
-}
-
-var expectedCreatedAccountWithoutStorageUpdateRow = []string{
- strconv.FormatInt(testhelpers.BlockNumber, 10),
- testhelpers.BlockHash,
- "created",
- testhelpers.CodeHash,
- strconv.FormatUint(testhelpers.NewNonceValue, 10),
- strconv.FormatInt(testhelpers.NewBalanceValue, 10),
- testhelpers.ContractRoot,
- "",
- testhelpers.AnotherContractLeafKey.Hex(),
- "",
- "",
-}
-
-var expectedUpdatedAccountRow = []string{
- strconv.FormatInt(testhelpers.BlockNumber, 10),
- testhelpers.BlockHash,
- "updated",
- testhelpers.CodeHash,
- strconv.FormatUint(testhelpers.NewNonceValue, 10),
- strconv.FormatInt(testhelpers.NewBalanceValue, 10),
- testhelpers.ContractRoot,
- testhelpers.StoragePath,
- testhelpers.ContractLeafKey.Hex(),
- "0000000000000000000000000000000000000000000000000000000000000001",
- testhelpers.StorageValue,
-}
-
-var expectedDeletedAccountRow = []string{
- strconv.FormatInt(testhelpers.BlockNumber, 10),
- testhelpers.BlockHash,
- "deleted",
- testhelpers.CodeHash,
- strconv.FormatUint(testhelpers.NewNonceValue, 10),
- strconv.FormatInt(testhelpers.NewBalanceValue, 10),
- testhelpers.ContractRoot,
- testhelpers.StoragePath,
- testhelpers.ContractLeafKey.Hex(),
- "0000000000000000000000000000000000000000000000000000000000000001",
- testhelpers.StorageValue,
-}
-
-func TestPublisher(t *testing.T) {
- dir, err = ioutil.TempDir(tempDir, testFilePrefix)
- if err != nil {
- t.Error(err)
- }
- config := statediff.Config{
- Path: dir,
- Mode: statediff.CSV,
- }
- publisher, err = p.NewPublisher(config)
- if err != nil {
- t.Error(err)
- }
-
- type Test func(t *testing.T)
-
- var tests = []Test{
- testFileName,
- testColumnHeaders,
- testAccountDiffs,
- testWhenNoDiff,
- testDefaultPublisher,
- testDefaultDirectory,
- }
-
- for _, test := range tests {
- test(t)
- err := removeFilesFromDir(dir)
- if err != nil {
- t.Errorf("Error removing files from temp dir: %s", dir)
- }
- }
-}
-
-func removeFilesFromDir(dir string) error {
- files, err := filepath.Glob(filepath.Join(dir, "*"))
- if err != nil {
- return err
- }
-
- for _, file := range files {
- err = os.RemoveAll(file)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func testFileName(t *testing.T) {
- fileName, err := publisher.PublishStateDiff(&testhelpers.TestStateDiff)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- if !strings.HasPrefix(fileName, dir) {
- t.Errorf(testhelpers.TestFailureFormatString, t.Name(), dir, fileName)
- }
- blockNumberWithFileExt := strconv.FormatInt(testhelpers.BlockNumber, 10) + ".csv"
- if !strings.HasSuffix(fileName, blockNumberWithFileExt) {
- t.Errorf(testhelpers.TestFailureFormatString, t.Name(), blockNumberWithFileExt, fileName)
- }
-}
-
-func testColumnHeaders(t *testing.T) {
- _, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- file, err := getTestDiffFile(dir)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- lines, err := csv.NewReader(file).ReadAll()
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
- if len(lines) < 1 {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
- if !equals(lines[0], p.Headers) {
- t.Error()
- }
-}
-
-func testAccountDiffs(t *testing.T) {
- // it persists the created, updated and deleted account diffs to a CSV file
- _, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- file, err := getTestDiffFile(dir)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- lines, err := csv.NewReader(file).ReadAll()
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
- if len(lines) <= 3 {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
- if !equals(lines[1], expectedCreatedAccountRow) {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
- if !equals(lines[2], expectedCreatedAccountWithoutStorageUpdateRow) {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
- if !equals(lines[3], expectedUpdatedAccountRow) {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
- if !equals(lines[4], expectedDeletedAccountRow) {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-}
-
-func testWhenNoDiff(t *testing.T) {
- //it creates an empty CSV when there is no diff
- emptyDiff := builder.StateDiff{}
- _, err = publisher.PublishStateDiff(&emptyDiff)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- file, err := getTestDiffFile(dir)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- lines, err := csv.NewReader(file).ReadAll()
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- if !equals(len(lines), 1) {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-}
-
-func testDefaultPublisher(t *testing.T) {
- //it defaults to publishing state diffs to a CSV file when no mode is configured
- config := statediff.Config{Path: dir}
- publisher, err = p.NewPublisher(config)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- _, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- file, err := getTestDiffFile(dir)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- lines, err := csv.NewReader(file).ReadAll()
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
- if !equals(len(lines), 5) {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
- if !equals(lines[0], p.Headers) {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-}
-
-func testDefaultDirectory(t *testing.T) {
- //it defaults to publishing CSV files in the current directory when no path is configured
- config := statediff.Config{}
- publisher, err = p.NewPublisher(config)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- err := os.Chdir(dir)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- _, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- file, err := getTestDiffFile(dir)
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-
- lines, err := csv.NewReader(file).ReadAll()
- if err != nil {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
- if !equals(len(lines), 5) {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
- if !equals(lines[0], p.Headers) {
- t.Errorf(testhelpers.ErrorFormatString, t.Name(), err)
- }
-}
-
-func getTestDiffFile(dir string) (*os.File, error) {
- files, err := ioutil.ReadDir(dir)
- if err != nil {
- return nil, err
- }
- if len(files) == 0 {
- return nil, errors.New("There are 0 files.")
- }
-
- fileName := files[0].Name()
- filePath := filepath.Join(dir, fileName)
-
- return os.Open(filePath)
-}
-
-func equals(actual, expected interface{}) (success bool) {
- if actualByteSlice, ok := actual.([]byte); ok {
- if expectedByteSlice, ok := expected.([]byte); ok {
- return bytes.Equal(actualByteSlice, expectedByteSlice)
- }
- }
-
- return reflect.DeepEqual(actual, expected)
-}
diff --git a/statediff/testhelpers/helpers.go b/statediff/testhelpers/helpers.go
index 0bfc53e5e..5126c6556 100644
--- a/statediff/testhelpers/helpers.go
+++ b/statediff/testhelpers/helpers.go
@@ -1,4 +1,83 @@
+// Copyright 2015 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 .
+
package testhelpers
-var ErrorFormatString = "Error: %s, %+v"
-var TestFailureFormatString = "Test failed: %s\nexpected %+v, got %+v\n"
+import (
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus/ethash"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/params"
+)
+
+// MakeChain creates a chain of n blocks starting at and including parent.
+// the returned hash chain is ordered head->parent. In addition, every 3rd block
+// contains a transaction and every 5th an uncle to allow testing correct block
+// reassembly.
+func MakeChain(n int, parent *types.Block) ([]common.Hash, map[common.Hash]*types.Block, *core.BlockChain) {
+ blocks, _ := core.GenerateChain(params.TestChainConfig, parent, ethash.NewFaker(), Testdb, n, testChainGen)
+ headers := make([]*types.Header, len(blocks))
+ for i, block := range blocks {
+ headers[i] = block.Header()
+ }
+ chain, _ := core.NewBlockChain(Testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil)
+
+ hashes := make([]common.Hash, n+1)
+ hashes[len(hashes)-1] = parent.Hash()
+ blockm := make(map[common.Hash]*types.Block, n+1)
+ blockm[parent.Hash()] = parent
+ for i, b := range blocks {
+ hashes[len(hashes)-i-2] = b.Hash()
+ blockm[b.Hash()] = b
+ }
+ return hashes, blockm, chain
+}
+
+func testChainGen(i int, block *core.BlockGen) {
+ signer := types.HomesteadSigner{}
+ switch i {
+ case 0:
+ // In block 1, the test bank sends account #1 some ether.
+ tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), Account1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, TestBankKey)
+ block.AddTx(tx)
+ case 1:
+ // In block 2, the test bank sends some more ether to account #1.
+ // account1Addr passes it on to account #2.
+ // account1Addr creates a test contract.
+ tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), Account1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, TestBankKey)
+ nonce := block.TxNonce(Account1Addr)
+ tx2, _ := types.SignTx(types.NewTransaction(nonce, Account2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, Account1Key)
+ nonce++
+ tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 1000000, big.NewInt(0), ContractCode), signer, Account1Key)
+ ContractAddr = crypto.CreateAddress(Account1Addr, nonce) //0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592
+ block.AddTx(tx1)
+ block.AddTx(tx2)
+ block.AddTx(tx3)
+ case 2:
+ // Block 3 is empty but was mined by account #2.
+ block.SetCoinbase(Account2Addr)
+ //get function: 60cd2685
+ //put function: c16431b9
+ data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003")
+ tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), ContractAddr, big.NewInt(0), 100000, nil, data), signer, TestBankKey)
+ block.AddTx(tx)
+ }
+}
diff --git a/statediff/testhelpers/mocks/blockchain.go b/statediff/testhelpers/mocks/blockchain.go
index 7b0d74c59..cececde6f 100644
--- a/statediff/testhelpers/mocks/blockchain.go
+++ b/statediff/testhelpers/mocks/blockchain.go
@@ -1,3 +1,19 @@
+// Copyright 2015 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 .
+
package mocks
import (
@@ -11,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/event"
)
+// BlockChain is a mock blockchain for testing
type BlockChain struct {
ParentHashesLookedUp []common.Hash
parentBlocksToReturn []*types.Block
@@ -18,34 +35,39 @@ type BlockChain struct {
ChainEvents []core.ChainEvent
}
-func (mc *BlockChain) AddToStateDiffProcessedCollection(hash common.Hash) {}
+// AddToStateDiffProcessedCollection mock method
+func (blockChain *BlockChain) AddToStateDiffProcessedCollection(hash common.Hash) {}
-func (mc *BlockChain) SetParentBlocksToReturn(blocks []*types.Block) {
- mc.parentBlocksToReturn = blocks
+// SetParentBlocksToReturn mock method
+func (blockChain *BlockChain) SetParentBlocksToReturn(blocks []*types.Block) {
+ blockChain.parentBlocksToReturn = blocks
}
-func (mc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
- mc.ParentHashesLookedUp = append(mc.ParentHashesLookedUp, hash)
+// GetBlockByHash mock method
+func (blockChain *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
+ blockChain.ParentHashesLookedUp = append(blockChain.ParentHashesLookedUp, hash)
var parentBlock *types.Block
- if len(mc.parentBlocksToReturn) > 0 {
- parentBlock = mc.parentBlocksToReturn[mc.callCount]
+ if len(blockChain.parentBlocksToReturn) > 0 {
+ parentBlock = blockChain.parentBlocksToReturn[blockChain.callCount]
}
- mc.callCount++
+ blockChain.callCount++
return parentBlock
}
-func (bc *BlockChain) SetChainEvents(chainEvents []core.ChainEvent) {
- bc.ChainEvents = chainEvents
+// SetChainEvents mock method
+func (blockChain *BlockChain) SetChainEvents(chainEvents []core.ChainEvent) {
+ blockChain.ChainEvents = chainEvents
}
-func (bc *BlockChain) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
+// SubscribeChainEvent mock method
+func (blockChain *BlockChain) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
subErr := errors.New("Subscription Error")
var eventCounter int
subscription := event.NewSubscription(func(quit <-chan struct{}) error {
- for _, chainEvent := range bc.ChainEvents {
+ for _, chainEvent := range blockChain.ChainEvents {
if eventCounter > 1 {
time.Sleep(250 * time.Millisecond)
return subErr
diff --git a/statediff/testhelpers/mocks/builder.go b/statediff/testhelpers/mocks/builder.go
index ae9ff5ced..e9668629e 100644
--- a/statediff/testhelpers/mocks/builder.go
+++ b/statediff/testhelpers/mocks/builder.go
@@ -1,20 +1,38 @@
+// Copyright 2015 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 .
+
package mocks
import (
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/statediff/builder"
+ "github.com/ethereum/go-ethereum/statediff"
)
+// Builder is a mock state diff builder
type Builder struct {
OldStateRoot common.Hash
NewStateRoot common.Hash
BlockNumber int64
BlockHash common.Hash
- stateDiff *builder.StateDiff
+ stateDiff statediff.StateDiff
builderError error
}
-func (builder *Builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, blockNumber int64, blockHash common.Hash) (*builder.StateDiff, error) {
+// BuildStateDiff mock method
+func (builder *Builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, blockNumber int64, blockHash common.Hash) (statediff.StateDiff, error) {
builder.OldStateRoot = oldStateRoot
builder.NewStateRoot = newStateRoot
builder.BlockNumber = blockNumber
@@ -23,10 +41,12 @@ func (builder *Builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, b
return builder.stateDiff, builder.builderError
}
-func (builder *Builder) SetStateDiffToBuild(stateDiff *builder.StateDiff) {
+// SetStateDiffToBuild mock method
+func (builder *Builder) SetStateDiffToBuild(stateDiff statediff.StateDiff) {
builder.stateDiff = stateDiff
}
+// SetBuilderError mock method
func (builder *Builder) SetBuilderError(err error) {
builder.builderError = err
}
diff --git a/statediff/testhelpers/mocks/error.go b/statediff/testhelpers/mocks/error.go
deleted file mode 100644
index 7c40452ae..000000000
--- a/statediff/testhelpers/mocks/error.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package mocks
-
-import "errors"
-
-var Error = errors.New("mock error")
diff --git a/statediff/testhelpers/mocks/extractor.go b/statediff/testhelpers/mocks/extractor.go
deleted file mode 100644
index 067497646..000000000
--- a/statediff/testhelpers/mocks/extractor.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package mocks
-
-import "github.com/ethereum/go-ethereum/core/types"
-
-type Extractor struct {
- ParentBlocks []types.Block
- CurrentBlocks []types.Block
- extractError error
-}
-
-func (me *Extractor) ExtractStateDiff(parent, current types.Block) (string, error) {
- me.ParentBlocks = append(me.ParentBlocks, parent)
- me.CurrentBlocks = append(me.CurrentBlocks, current)
-
- return "", me.extractError
-}
-
-func (me *Extractor) SetExtractError(err error) {
- me.extractError = err
-}
diff --git a/statediff/testhelpers/mocks/publisher.go b/statediff/testhelpers/mocks/publisher.go
index efbe4e2ab..3ea18abf0 100644
--- a/statediff/testhelpers/mocks/publisher.go
+++ b/statediff/testhelpers/mocks/publisher.go
@@ -1,17 +1,36 @@
+// Copyright 2015 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 .
+
package mocks
-import "github.com/ethereum/go-ethereum/statediff/builder"
+import "github.com/ethereum/go-ethereum/statediff"
+// Publisher mock
type Publisher struct {
- StateDiff *builder.StateDiff
+ StateDiff *statediff.StateDiff
publisherError error
}
-func (publisher *Publisher) PublishStateDiff(sd *builder.StateDiff) (string, error) {
+// PublishStateDiff mock method
+func (publisher *Publisher) PublishStateDiff(sd *statediff.StateDiff) (string, error) {
publisher.StateDiff = sd
return "", publisher.publisherError
}
+// SetPublisherError mock method
func (publisher *Publisher) SetPublisherError(err error) {
publisher.publisherError = err
}
diff --git a/statediff/testhelpers/test_data.go b/statediff/testhelpers/test_data.go
index 831bed218..17dac8473 100644
--- a/statediff/testhelpers/test_data.go
+++ b/statediff/testhelpers/test_data.go
@@ -1,3 +1,19 @@
+// Copyright 2015 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 .
+
package testhelpers
import (
@@ -5,71 +21,94 @@ import (
"math/rand"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
+ "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/statediff/builder"
+ "github.com/ethereum/go-ethereum/rlp"
+ "github.com/ethereum/go-ethereum/statediff"
)
+// AddressToLeafKey hashes an returns an address
func AddressToLeafKey(address common.Address) common.Hash {
return common.BytesToHash(crypto.Keccak256(address[:]))
}
+// Test variables
var (
BlockNumber = rand.Int63()
BlockHash = "0xfa40fbe2d98d98b3363a778d52f2bcd29d6790b9b3f3cab2b167fd12d3550f73"
- CodeHash = "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
+ CodeHash = common.Hex2Bytes("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
NewNonceValue = rand.Uint64()
NewBalanceValue = rand.Int63()
- ContractRoot = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
- StoragePath = "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
- StorageKey = "0000000000000000000000000000000000000000000000000000000000000001"
- StorageValue = "0x03"
- storage = map[string]builder.DiffStorage{StoragePath: {
- Key: &StorageKey,
- Value: &StorageValue,
+ ContractRoot = common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
+ StoragePath = common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes()
+ StorageKey = common.HexToHash("0000000000000000000000000000000000000000000000000000000000000001").Bytes()
+ StorageValue = common.Hex2Bytes("0x03")
+ storage = []statediff.StorageDiff{{
+ Key: StorageKey,
+ Value: StorageValue,
+ Path: StoragePath,
+ Proof: [][]byte{},
}}
- emptyStorage = map[string]builder.DiffStorage{}
+ emptyStorage = make([]statediff.StorageDiff, 0)
address = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592")
ContractLeafKey = AddressToLeafKey(address)
anotherAddress = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476593")
AnotherContractLeafKey = AddressToLeafKey(anotherAddress)
- CreatedAccountDiffs = builder.AccountDiffsMap{
+ testAccount = state.Account{
+ Nonce: NewNonceValue,
+ Balance: big.NewInt(NewBalanceValue),
+ Root: ContractRoot,
+ CodeHash: CodeHash,
+ }
+ valueBytes, _ = rlp.EncodeToBytes(testAccount)
+ CreatedAccountDiffs = statediff.AccountDiffsMap{
ContractLeafKey: {
- Nonce: builder.DiffUint64{Value: &NewNonceValue},
- Balance: builder.DiffBigInt{Value: big.NewInt(NewBalanceValue)},
- ContractRoot: builder.DiffString{Value: &ContractRoot},
- CodeHash: CodeHash,
- Storage: storage,
+ Key: ContractLeafKey.Bytes(),
+ Value: valueBytes,
+ Storage: storage,
},
AnotherContractLeafKey: {
- Nonce: builder.DiffUint64{Value: &NewNonceValue},
- Balance: builder.DiffBigInt{Value: big.NewInt(NewBalanceValue)},
- CodeHash: CodeHash,
- ContractRoot: builder.DiffString{Value: &ContractRoot},
- Storage: emptyStorage,
+ Key: AnotherContractLeafKey.Bytes(),
+ Value: valueBytes,
+ Storage: emptyStorage,
},
}
- UpdatedAccountDiffs = builder.AccountDiffsMap{ContractLeafKey: {
- Nonce: builder.DiffUint64{Value: &NewNonceValue},
- Balance: builder.DiffBigInt{Value: big.NewInt(NewBalanceValue)},
- CodeHash: CodeHash,
- ContractRoot: builder.DiffString{Value: &ContractRoot},
- Storage: storage,
+ UpdatedAccountDiffs = statediff.AccountDiffsMap{ContractLeafKey: {
+ Key: ContractLeafKey.Bytes(),
+ Value: valueBytes,
+ Storage: storage,
}}
- DeletedAccountDiffs = builder.AccountDiffsMap{ContractLeafKey: {
- Nonce: builder.DiffUint64{Value: &NewNonceValue},
- Balance: builder.DiffBigInt{Value: big.NewInt(NewBalanceValue)},
- ContractRoot: builder.DiffString{Value: &ContractRoot},
- CodeHash: CodeHash,
- Storage: storage,
+ DeletedAccountDiffs = statediff.AccountDiffsMap{ContractLeafKey: {
+ Key: ContractLeafKey.Bytes(),
+ Value: valueBytes,
+ Storage: storage,
}}
- TestStateDiff = builder.StateDiff{
+ TestStateDiff = statediff.StateDiff{
BlockNumber: BlockNumber,
BlockHash: common.HexToHash(BlockHash),
CreatedAccounts: CreatedAccountDiffs,
DeletedAccounts: DeletedAccountDiffs,
UpdatedAccounts: UpdatedAccountDiffs,
}
+ Testdb = rawdb.NewMemoryDatabase()
+
+ TestBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ TestBankAddress = crypto.PubkeyToAddress(TestBankKey.PublicKey) //0x71562b71999873DB5b286dF957af199Ec94617F7
+ BankLeafKey = AddressToLeafKey(TestBankAddress)
+ TestBankFunds = big.NewInt(100000000)
+ Genesis = core.GenesisBlockForTesting(Testdb, TestBankAddress, TestBankFunds)
+
+ Account1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
+ Account2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
+ Account1Addr = crypto.PubkeyToAddress(Account1Key.PublicKey) //0x703c4b2bD70c169f5717101CaeE543299Fc946C7
+ Account2Addr = crypto.PubkeyToAddress(Account2Key.PublicKey) //0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e
+ Account1LeafKey = AddressToLeafKey(Account1Addr)
+ Account2LeafKey = AddressToLeafKey(Account2Addr)
+ ContractCode = common.Hex2Bytes("608060405234801561001057600080fd5b50602060405190810160405280600160ff16815250600090600161003592919061003b565b506100a5565b826064810192821561006f579160200282015b8281111561006e578251829060ff1690559160200191906001019061004e565b5b50905061007c9190610080565b5090565b6100a291905b8082111561009e576000816000905550600101610086565b5090565b90565b610124806100b46000396000f3fe6080604052348015600f57600080fd5b5060043610604f576000357c01000000000000000000000000000000000000000000000000000000009004806360cd2685146054578063c16431b9146093575b600080fd5b607d60048036036020811015606857600080fd5b810190808035906020019092919050505060c8565b6040518082815260200191505060405180910390f35b60c66004803603604081101560a757600080fd5b81019080803590602001909291908035906020019092919050505060e0565b005b6000808260648110151560d757fe5b01549050919050565b8060008360648110151560ef57fe5b0181905550505056fea165627a7a7230582064e918c3140a117bf3aa65865a9b9e83fae21ad1720506e7933b2a9f54bb40260029")
+ ContractAddr common.Address
)