Pull CSV publishing methods into their own file
This commit is contained in:
parent
5b63446b6e
commit
8578fc20a3
152
statediff/publisher/csv.go
Normal file
152
statediff/publisher/csv.go
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
package publisher
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/statediff/builder"
|
||||||
|
"time"
|
||||||
|
"os"
|
||||||
|
"encoding/csv"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Headers = []string{
|
||||||
|
"blockNumber", "blockHash", "accountAction",
|
||||||
|
"code", "codeHash",
|
||||||
|
"oldNonceValue", "newNonceValue",
|
||||||
|
"oldBalanceValue", "newBalanceValue",
|
||||||
|
"oldContractRoot", "newContractRoot",
|
||||||
|
"storageDiffPaths",
|
||||||
|
}
|
||||||
|
|
||||||
|
timeStampFormat = "20060102150405.00000"
|
||||||
|
deletedAccountAction = "deleted"
|
||||||
|
createdAccountAction = "created"
|
||||||
|
updatedAccountAction = "updated"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createCSVFilePath(path string) string {
|
||||||
|
now := time.Now()
|
||||||
|
timeStamp := now.Format(timeStampFormat)
|
||||||
|
filePath := filepath.Join(path, timeStamp)
|
||||||
|
filePath = filePath + ".csv"
|
||||||
|
return filePath
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *publisher) publishStateDiffToCSV(sd builder.StateDiff) error {
|
||||||
|
filePath := createCSVFilePath(p.Config.Path)
|
||||||
|
|
||||||
|
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)
|
||||||
|
for _, row := range accumulateCreatedAccountRows(sd) {
|
||||||
|
data = append(data, row)
|
||||||
|
}
|
||||||
|
for _, row := range accumulateUpdatedAccountRows(sd) {
|
||||||
|
data = append(data, row)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, row := range accumulateDeletedAccountRows(sd) {
|
||||||
|
data = append(data, row)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, value := range data{
|
||||||
|
err := writer.Write(value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func accumulateUpdatedAccountRows(sd builder.StateDiff) [][]string {
|
||||||
|
var updatedAccountRows [][]string
|
||||||
|
for _, accountDiff := range sd.UpdatedAccounts {
|
||||||
|
formattedAccountData := formatAccountDiffIncremental(accountDiff, sd, updatedAccountAction)
|
||||||
|
|
||||||
|
updatedAccountRows = append(updatedAccountRows, formattedAccountData)
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedAccountRows
|
||||||
|
}
|
||||||
|
|
||||||
|
func accumulateDeletedAccountRows(sd builder.StateDiff) [][]string {
|
||||||
|
var deletedAccountRows [][]string
|
||||||
|
for _, accountDiff := range sd.DeletedAccounts {
|
||||||
|
formattedAccountData := formatAccountDiffEventual(accountDiff, sd, deletedAccountAction)
|
||||||
|
|
||||||
|
deletedAccountRows = append(deletedAccountRows, formattedAccountData)
|
||||||
|
}
|
||||||
|
|
||||||
|
return deletedAccountRows
|
||||||
|
}
|
||||||
|
|
||||||
|
func accumulateCreatedAccountRows(sd builder.StateDiff) [][]string {
|
||||||
|
var createdAccountRows [][]string
|
||||||
|
for _, accountDiff := range sd.CreatedAccounts {
|
||||||
|
formattedAccountData := formatAccountDiffEventual(accountDiff, sd, createdAccountAction)
|
||||||
|
|
||||||
|
createdAccountRows = append(createdAccountRows, formattedAccountData)
|
||||||
|
}
|
||||||
|
|
||||||
|
return createdAccountRows
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatAccountDiffEventual(accountDiff builder.AccountDiffEventual, sd builder.StateDiff, accountAction string) []string {
|
||||||
|
oldContractRoot := accountDiff.ContractRoot.OldValue
|
||||||
|
newContractRoot := accountDiff.ContractRoot.NewValue
|
||||||
|
var storageDiffPaths []string
|
||||||
|
for k := range accountDiff.Storage {
|
||||||
|
storageDiffPaths = append(storageDiffPaths, k)
|
||||||
|
}
|
||||||
|
formattedAccountData := []string{
|
||||||
|
strconv.FormatInt(sd.BlockNumber, 10),
|
||||||
|
sd.BlockHash.String(),
|
||||||
|
accountAction,
|
||||||
|
string(accountDiff.Code),
|
||||||
|
accountDiff.CodeHash,
|
||||||
|
strconv.FormatUint(*accountDiff.Nonce.OldValue, 10),
|
||||||
|
strconv.FormatUint(*accountDiff.Nonce.NewValue, 10),
|
||||||
|
accountDiff.Balance.OldValue.String(),
|
||||||
|
accountDiff.Balance.NewValue.String(),
|
||||||
|
*oldContractRoot,
|
||||||
|
*newContractRoot,
|
||||||
|
strings.Join(storageDiffPaths, ","),
|
||||||
|
}
|
||||||
|
return formattedAccountData
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatAccountDiffIncremental(accountDiff builder.AccountDiffIncremental, sd builder.StateDiff, accountAction string) []string {
|
||||||
|
oldContractRoot := accountDiff.ContractRoot.OldValue
|
||||||
|
newContractRoot := accountDiff.ContractRoot.NewValue
|
||||||
|
var storageDiffPaths []string
|
||||||
|
for k := range accountDiff.Storage {
|
||||||
|
storageDiffPaths = append(storageDiffPaths, k)
|
||||||
|
}
|
||||||
|
formattedAccountData := []string{
|
||||||
|
strconv.FormatInt(sd.BlockNumber, 10),
|
||||||
|
sd.BlockHash.String(),
|
||||||
|
accountAction,
|
||||||
|
"",
|
||||||
|
accountDiff.CodeHash,
|
||||||
|
strconv.FormatUint(*accountDiff.Nonce.OldValue, 10),
|
||||||
|
strconv.FormatUint(*accountDiff.Nonce.NewValue, 10),
|
||||||
|
accountDiff.Balance.OldValue.String(),
|
||||||
|
accountDiff.Balance.NewValue.String(),
|
||||||
|
*oldContractRoot,
|
||||||
|
*newContractRoot,
|
||||||
|
strings.Join(storageDiffPaths, ","),
|
||||||
|
}
|
||||||
|
return formattedAccountData
|
||||||
|
}
|
||||||
|
|
@ -20,11 +20,6 @@
|
|||||||
package publisher
|
package publisher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"encoding/csv"
|
|
||||||
"time"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"github.com/ethereum/go-ethereum/statediff/builder"
|
"github.com/ethereum/go-ethereum/statediff/builder"
|
||||||
"github.com/ethereum/go-ethereum/statediff"
|
"github.com/ethereum/go-ethereum/statediff"
|
||||||
)
|
)
|
||||||
@ -37,22 +32,6 @@ type publisher struct {
|
|||||||
Config statediff.Config
|
Config statediff.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
Headers = []string{
|
|
||||||
"blockNumber", "blockHash", "accountAction",
|
|
||||||
"code", "codeHash",
|
|
||||||
"oldNonceValue", "newNonceValue",
|
|
||||||
"oldBalanceValue", "newBalanceValue",
|
|
||||||
"oldContractRoot", "newContractRoot",
|
|
||||||
"storageDiffPaths",
|
|
||||||
}
|
|
||||||
|
|
||||||
timeStampFormat = "20060102150405.00000"
|
|
||||||
deletedAccountAction = "deleted"
|
|
||||||
createdAccountAction = "created"
|
|
||||||
updatedAccountAction = "updated"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewPublisher(config statediff.Config) (*publisher, error) {
|
func NewPublisher(config statediff.Config) (*publisher, error) {
|
||||||
return &publisher{
|
return &publisher{
|
||||||
Config: config,
|
Config: config,
|
||||||
@ -67,121 +46,3 @@ func (p *publisher) PublishStateDiff(sd *builder.StateDiff) (string, error) {
|
|||||||
return "", p.publishStateDiffToCSV(*sd)
|
return "", p.publishStateDiffToCSV(*sd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *publisher) publishStateDiffToCSV(sd builder.StateDiff) error {
|
|
||||||
now := time.Now()
|
|
||||||
timeStamp := now.Format(timeStampFormat)
|
|
||||||
filePath := p.Config.Path + timeStamp + ".csv"
|
|
||||||
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)
|
|
||||||
for _, row := range accumulateCreatedAccountRows(sd) {
|
|
||||||
data = append(data, row)
|
|
||||||
}
|
|
||||||
for _, row := range accumulateUpdatedAccountRows(sd) {
|
|
||||||
data = append(data, row)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, row := range accumulateDeletedAccountRows(sd) {
|
|
||||||
data = append(data, row)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, value := range data{
|
|
||||||
err := writer.Write(value)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func accumulateUpdatedAccountRows(sd builder.StateDiff) [][]string {
|
|
||||||
var updatedAccountRows [][]string
|
|
||||||
for _, accountDiff := range sd.UpdatedAccounts {
|
|
||||||
formattedAccountData := formatAccountDiffIncremental(accountDiff, sd, updatedAccountAction)
|
|
||||||
|
|
||||||
updatedAccountRows = append(updatedAccountRows, formattedAccountData)
|
|
||||||
}
|
|
||||||
|
|
||||||
return updatedAccountRows
|
|
||||||
}
|
|
||||||
|
|
||||||
func accumulateDeletedAccountRows(sd builder.StateDiff) [][]string {
|
|
||||||
var deletedAccountRows [][]string
|
|
||||||
for _, accountDiff := range sd.DeletedAccounts {
|
|
||||||
formattedAccountData := formatAccountDiffEventual(accountDiff, sd, deletedAccountAction)
|
|
||||||
|
|
||||||
deletedAccountRows = append(deletedAccountRows, formattedAccountData)
|
|
||||||
}
|
|
||||||
|
|
||||||
return deletedAccountRows
|
|
||||||
}
|
|
||||||
|
|
||||||
func accumulateCreatedAccountRows(sd builder.StateDiff) [][]string {
|
|
||||||
var createdAccountRows [][]string
|
|
||||||
for _, accountDiff := range sd.CreatedAccounts {
|
|
||||||
formattedAccountData := formatAccountDiffEventual(accountDiff, sd, createdAccountAction)
|
|
||||||
|
|
||||||
createdAccountRows = append(createdAccountRows, formattedAccountData)
|
|
||||||
}
|
|
||||||
|
|
||||||
return createdAccountRows
|
|
||||||
}
|
|
||||||
|
|
||||||
func formatAccountDiffEventual(accountDiff builder.AccountDiffEventual, sd builder.StateDiff, accountAction string) []string {
|
|
||||||
oldContractRoot := accountDiff.ContractRoot.OldValue
|
|
||||||
newContractRoot := accountDiff.ContractRoot.NewValue
|
|
||||||
var storageDiffPaths []string
|
|
||||||
for k := range accountDiff.Storage {
|
|
||||||
storageDiffPaths = append(storageDiffPaths, k)
|
|
||||||
}
|
|
||||||
formattedAccountData := []string{
|
|
||||||
strconv.FormatInt(sd.BlockNumber, 10),
|
|
||||||
sd.BlockHash.String(),
|
|
||||||
accountAction,
|
|
||||||
string(accountDiff.Code),
|
|
||||||
accountDiff.CodeHash,
|
|
||||||
strconv.FormatUint(*accountDiff.Nonce.OldValue, 10),
|
|
||||||
strconv.FormatUint(*accountDiff.Nonce.NewValue, 10),
|
|
||||||
accountDiff.Balance.OldValue.String(),
|
|
||||||
accountDiff.Balance.NewValue.String(),
|
|
||||||
*oldContractRoot,
|
|
||||||
*newContractRoot,
|
|
||||||
strings.Join(storageDiffPaths, ","),
|
|
||||||
}
|
|
||||||
return formattedAccountData
|
|
||||||
}
|
|
||||||
|
|
||||||
func formatAccountDiffIncremental(accountDiff builder.AccountDiffIncremental, sd builder.StateDiff, accountAction string) []string {
|
|
||||||
oldContractRoot := accountDiff.ContractRoot.OldValue
|
|
||||||
newContractRoot := accountDiff.ContractRoot.NewValue
|
|
||||||
var storageDiffPaths []string
|
|
||||||
for k := range accountDiff.Storage {
|
|
||||||
storageDiffPaths = append(storageDiffPaths, k)
|
|
||||||
}
|
|
||||||
formattedAccountData := []string{
|
|
||||||
strconv.FormatInt(sd.BlockNumber, 10),
|
|
||||||
sd.BlockHash.String(),
|
|
||||||
accountAction,
|
|
||||||
"",
|
|
||||||
accountDiff.CodeHash,
|
|
||||||
strconv.FormatUint(*accountDiff.Nonce.OldValue, 10),
|
|
||||||
strconv.FormatUint(*accountDiff.Nonce.NewValue, 10),
|
|
||||||
accountDiff.Balance.OldValue.String(),
|
|
||||||
accountDiff.Balance.NewValue.String(),
|
|
||||||
*oldContractRoot,
|
|
||||||
*newContractRoot,
|
|
||||||
strings.Join(storageDiffPaths, ","),
|
|
||||||
}
|
|
||||||
return formattedAccountData
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -2,206 +2,168 @@ package publisher_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/onsi/ginkgo"
|
"github.com/onsi/ginkgo"
|
||||||
"github.com/ethereum/go-ethereum/statediff"
|
|
||||||
"github.com/onsi/gomega"
|
"github.com/onsi/gomega"
|
||||||
"os"
|
"os"
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"math/rand"
|
|
||||||
"math/big"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
p "github.com/ethereum/go-ethereum/statediff/publisher"
|
p "github.com/ethereum/go-ethereum/statediff/publisher"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff/testhelpers"
|
||||||
|
"io/ioutil"
|
||||||
"github.com/ethereum/go-ethereum/statediff/builder"
|
"github.com/ethereum/go-ethereum/statediff/builder"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = ginkgo.Describe("Publisher", func() {
|
var _ = ginkgo.Describe("Publisher", func() {
|
||||||
ginkgo.Context("default CSV publisher", func() {
|
var (
|
||||||
var (
|
tempDir = os.TempDir()
|
||||||
publisher p.Publisher
|
testFilePrefix = "test-statediff"
|
||||||
err error
|
publisher p.Publisher
|
||||||
config = statediff.Config{
|
dir string
|
||||||
Path: "./test-",
|
err error
|
||||||
}
|
)
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var expectedCreatedAccountRow = []string{
|
||||||
blockNumber = rand.Int63()
|
strconv.FormatInt(testhelpers.BlockNumber, 10),
|
||||||
blockHash = "0xfa40fbe2d98d98b3363a778d52f2bcd29d6790b9b3f3cab2b167fd12d3550f73"
|
testhelpers.BlockHash,
|
||||||
codeHash = "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
|
"created",
|
||||||
oldNonceValue = rand.Uint64()
|
"created account code",
|
||||||
newNonceValue = oldNonceValue + 1
|
testhelpers.CodeHash,
|
||||||
oldBalanceValue = rand.Int63()
|
strconv.FormatUint(testhelpers.OldNonceValue, 10),
|
||||||
newBalanceValue = oldBalanceValue - 1
|
strconv.FormatUint(testhelpers.NewNonceValue, 10),
|
||||||
contractRoot = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
strconv.FormatInt(testhelpers.OldBalanceValue, 10),
|
||||||
storagePath = "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
|
strconv.FormatInt(testhelpers.NewBalanceValue, 10),
|
||||||
oldStorage = "0x0"
|
testhelpers.ContractRoot,
|
||||||
newStorage = "0x03"
|
testhelpers.ContractRoot,
|
||||||
storage = map[string]builder.DiffString{storagePath: {
|
testhelpers.StoragePath,
|
||||||
NewValue: &newStorage,
|
}
|
||||||
OldValue: &oldStorage,
|
|
||||||
}}
|
|
||||||
address = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592")
|
|
||||||
createdAccounts = map[common.Address]builder.AccountDiffEventual{address: {
|
|
||||||
Nonce: builder.DiffUint64{
|
|
||||||
NewValue: &newNonceValue,
|
|
||||||
OldValue: &oldNonceValue,
|
|
||||||
},
|
|
||||||
Balance: builder.DiffBigInt{
|
|
||||||
NewValue: big.NewInt(newBalanceValue),
|
|
||||||
OldValue: big.NewInt(oldBalanceValue),
|
|
||||||
},
|
|
||||||
ContractRoot: builder.DiffString{
|
|
||||||
NewValue: &contractRoot,
|
|
||||||
OldValue: &contractRoot,
|
|
||||||
},
|
|
||||||
Code: []byte("created account code"),
|
|
||||||
CodeHash: codeHash,
|
|
||||||
Storage: storage,
|
|
||||||
}}
|
|
||||||
|
|
||||||
updatedAccounts = map[common.Address]builder.AccountDiffIncremental{address: {
|
var expectedUpdatedAccountRow = []string{
|
||||||
Nonce: builder.DiffUint64{
|
strconv.FormatInt(testhelpers.BlockNumber, 10),
|
||||||
NewValue: &newNonceValue,
|
testhelpers.BlockHash,
|
||||||
OldValue: &oldNonceValue,
|
"updated",
|
||||||
},
|
"",
|
||||||
Balance: builder.DiffBigInt{
|
testhelpers.CodeHash,
|
||||||
NewValue: big.NewInt(newBalanceValue),
|
strconv.FormatUint(testhelpers.OldNonceValue, 10),
|
||||||
OldValue: big.NewInt(oldBalanceValue),
|
strconv.FormatUint(testhelpers.NewNonceValue, 10),
|
||||||
},
|
strconv.FormatInt(testhelpers.OldBalanceValue, 10),
|
||||||
CodeHash: codeHash,
|
strconv.FormatInt(testhelpers.NewBalanceValue, 10),
|
||||||
ContractRoot: builder.DiffString{
|
testhelpers.ContractRoot,
|
||||||
NewValue: &contractRoot,
|
testhelpers.ContractRoot,
|
||||||
OldValue: &contractRoot,
|
testhelpers.StoragePath,
|
||||||
},
|
}
|
||||||
Storage: storage,
|
|
||||||
}}
|
|
||||||
|
|
||||||
deletedAccounts = map[common.Address]builder.AccountDiffEventual{address: {
|
var expectedDeletedAccountRow = []string{
|
||||||
Nonce: builder.DiffUint64{
|
strconv.FormatInt(testhelpers.BlockNumber, 10),
|
||||||
NewValue: &newNonceValue,
|
testhelpers.BlockHash,
|
||||||
OldValue: &oldNonceValue,
|
"deleted",
|
||||||
},
|
"deleted account code",
|
||||||
Balance: builder.DiffBigInt{
|
testhelpers.CodeHash,
|
||||||
NewValue: big.NewInt(newBalanceValue),
|
strconv.FormatUint(testhelpers.OldNonceValue, 10),
|
||||||
OldValue: big.NewInt(oldBalanceValue),
|
strconv.FormatUint(testhelpers.NewNonceValue, 10),
|
||||||
},
|
strconv.FormatInt(testhelpers.OldBalanceValue, 10),
|
||||||
ContractRoot: builder.DiffString{
|
strconv.FormatInt(testhelpers.NewBalanceValue, 10),
|
||||||
NewValue: &contractRoot,
|
testhelpers.ContractRoot,
|
||||||
OldValue: &contractRoot,
|
testhelpers.ContractRoot,
|
||||||
},
|
testhelpers.StoragePath,
|
||||||
Code: []byte("deleted account code"),
|
}
|
||||||
CodeHash: codeHash,
|
|
||||||
Storage: storage,
|
|
||||||
}}
|
|
||||||
|
|
||||||
testStateDiff = builder.StateDiff{
|
ginkgo.BeforeEach(func() {
|
||||||
BlockNumber: blockNumber,
|
dir, err = ioutil.TempDir(tempDir, testFilePrefix)
|
||||||
BlockHash: common.HexToHash(blockHash),
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
CreatedAccounts: createdAccounts,
|
config := statediff.Config{
|
||||||
DeletedAccounts: deletedAccounts,
|
Path: dir,
|
||||||
UpdatedAccounts: updatedAccounts,
|
Mode: statediff.CSV,
|
||||||
}
|
}
|
||||||
)
|
publisher, err = p.NewPublisher(config)
|
||||||
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
var lines [][]string
|
ginkgo.AfterEach(func() {
|
||||||
var file *os.File
|
os.RemoveAll(dir)
|
||||||
ginkgo.BeforeEach(func() {
|
})
|
||||||
publisher, err = p.NewPublisher(config)
|
|
||||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
|
||||||
|
|
||||||
_, err := publisher.PublishStateDiff(&testStateDiff)
|
ginkgo.It("persists the column headers to a CSV file", func() {
|
||||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
_, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
|
||||||
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
|
|
||||||
filePaths := getTestCSVFiles(".")
|
file, err := getTestDiffFile(dir)
|
||||||
file, err = os.Open(filePaths[0])
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
|
||||||
|
|
||||||
defer file.Close()
|
lines, err := csv.NewReader(file).ReadAll()
|
||||||
|
gomega.Expect(len(lines) > 1).To(gomega.BeTrue())
|
||||||
|
gomega.Expect(lines[0]).To(gomega.Equal(p.Headers))
|
||||||
|
})
|
||||||
|
|
||||||
lines, err = csv.NewReader(file).ReadAll()
|
ginkgo.It("persists the created, upated and deleted account diffs to a CSV file", func() {
|
||||||
})
|
_, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
|
||||||
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
|
|
||||||
ginkgo.AfterEach(func() {
|
file, err := getTestDiffFile(dir)
|
||||||
os.Remove(file.Name())
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
})
|
|
||||||
|
|
||||||
ginkgo.It("persists the column headers to a CSV file", func() {
|
lines, err := csv.NewReader(file).ReadAll()
|
||||||
gomega.Expect(len(lines) > 1).To(gomega.BeTrue())
|
gomega.Expect(len(lines) > 3).To(gomega.BeTrue())
|
||||||
gomega.Expect(lines[0]).To(gomega.Equal(p.Headers))
|
gomega.Expect(lines[1]).To(gomega.Equal(expectedCreatedAccountRow))
|
||||||
})
|
gomega.Expect(lines[2]).To(gomega.Equal(expectedUpdatedAccountRow))
|
||||||
|
gomega.Expect(lines[3]).To(gomega.Equal(expectedDeletedAccountRow))
|
||||||
|
})
|
||||||
|
|
||||||
ginkgo.It("persists the created account diffs to a CSV file", func() {
|
ginkgo.It("creates an empty CSV when there is no diff", func() {
|
||||||
expectedCreatedAccountRow := []string{
|
emptyDiff := builder.StateDiff{}
|
||||||
strconv.FormatInt(blockNumber, 10),
|
_, err = publisher.PublishStateDiff(&emptyDiff)
|
||||||
blockHash,
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
"created",
|
|
||||||
"created account code",
|
|
||||||
codeHash,
|
|
||||||
strconv.FormatUint(oldNonceValue, 10),
|
|
||||||
strconv.FormatUint(newNonceValue, 10),
|
|
||||||
strconv.FormatInt(oldBalanceValue, 10),
|
|
||||||
strconv.FormatInt(newBalanceValue, 10),
|
|
||||||
contractRoot,
|
|
||||||
contractRoot,
|
|
||||||
storagePath,
|
|
||||||
}
|
|
||||||
|
|
||||||
gomega.Expect(len(lines) > 1).To(gomega.BeTrue())
|
file, err := getTestDiffFile(dir)
|
||||||
gomega.Expect(lines[1]).To(gomega.Equal(expectedCreatedAccountRow))
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
})
|
|
||||||
|
|
||||||
ginkgo.It("persists the updated account diffs to a CSV file", func() {
|
lines, err := csv.NewReader(file).ReadAll()
|
||||||
expectedUpdatedAccountRow := []string{
|
gomega.Expect(len(lines)).To(gomega.Equal(1))
|
||||||
strconv.FormatInt(blockNumber, 10),
|
})
|
||||||
blockHash,
|
|
||||||
"updated",
|
|
||||||
"",
|
|
||||||
codeHash,
|
|
||||||
strconv.FormatUint(oldNonceValue, 10),
|
|
||||||
strconv.FormatUint(newNonceValue, 10),
|
|
||||||
strconv.FormatInt(oldBalanceValue, 10),
|
|
||||||
strconv.FormatInt(newBalanceValue, 10),
|
|
||||||
contractRoot,
|
|
||||||
contractRoot,
|
|
||||||
storagePath,
|
|
||||||
}
|
|
||||||
|
|
||||||
gomega.Expect(len(lines) > 2).To(gomega.BeTrue())
|
ginkgo.It("defaults to publishing state diffs to a CSV file when no mode is configured", func() {
|
||||||
gomega.Expect(lines[2]).To(gomega.Equal(expectedUpdatedAccountRow))
|
config := statediff.Config{Path: dir}
|
||||||
})
|
publisher, err = p.NewPublisher(config)
|
||||||
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
|
|
||||||
ginkgo.It("persists the deleted account diffs to a CSV file", func() {
|
_, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
|
||||||
expectedDeletedAccountRow := []string{
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
strconv.FormatInt(blockNumber, 10),
|
|
||||||
blockHash,
|
|
||||||
"deleted",
|
|
||||||
"deleted account code",
|
|
||||||
codeHash,
|
|
||||||
strconv.FormatUint(oldNonceValue, 10),
|
|
||||||
strconv.FormatUint(newNonceValue, 10),
|
|
||||||
strconv.FormatInt(oldBalanceValue, 10),
|
|
||||||
strconv.FormatInt(newBalanceValue, 10),
|
|
||||||
contractRoot,
|
|
||||||
contractRoot,
|
|
||||||
storagePath,
|
|
||||||
}
|
|
||||||
|
|
||||||
gomega.Expect(len(lines) > 3).To(gomega.BeTrue())
|
file, err := getTestDiffFile(dir)
|
||||||
gomega.Expect(lines[3]).To(gomega.Equal(expectedDeletedAccountRow))
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
})
|
|
||||||
|
lines, err := csv.NewReader(file).ReadAll()
|
||||||
|
gomega.Expect(len(lines)).To(gomega.Equal(4))
|
||||||
|
gomega.Expect(lines[0]).To(gomega.Equal(p.Headers))
|
||||||
|
})
|
||||||
|
|
||||||
|
ginkgo.FIt("defaults to publishing CSV files in the current directory when no path is configured", func() {
|
||||||
|
config := statediff.Config{}
|
||||||
|
publisher, err = p.NewPublisher(config)
|
||||||
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
|
|
||||||
|
err := os.Chdir(dir)
|
||||||
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
|
|
||||||
|
_, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
|
||||||
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
|
|
||||||
|
file, err := getTestDiffFile(dir)
|
||||||
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
|
|
||||||
|
lines, err := csv.NewReader(file).ReadAll()
|
||||||
|
gomega.Expect(len(lines)).To(gomega.Equal(4))
|
||||||
|
gomega.Expect(lines[0]).To(gomega.Equal(p.Headers))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
func getTestCSVFiles(rootPath string) []string{
|
func getTestDiffFile(dir string) (*os.File, error) {
|
||||||
var files []string
|
files, err := ioutil.ReadDir(dir)
|
||||||
err := filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error {
|
|
||||||
if strings.HasPrefix(path, "test-") {
|
|
||||||
files = append(files, path)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||||
return files
|
gomega.Expect(len(files) > 0).To(gomega.BeTrue())
|
||||||
|
|
||||||
|
fileName := files[0].Name()
|
||||||
|
filePath := filepath.Join(dir, fileName)
|
||||||
|
|
||||||
|
return os.Open(filePath)
|
||||||
}
|
}
|
||||||
|
87
statediff/testhelpers/test_data.go
Normal file
87
statediff/testhelpers/test_data.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package testhelpers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/statediff/builder"
|
||||||
|
"math/big"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"math/rand"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
BlockNumber = rand.Int63()
|
||||||
|
BlockHash = "0xfa40fbe2d98d98b3363a778d52f2bcd29d6790b9b3f3cab2b167fd12d3550f73"
|
||||||
|
CodeHash = "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
|
||||||
|
OldNonceValue = rand.Uint64()
|
||||||
|
NewNonceValue = OldNonceValue + 1
|
||||||
|
OldBalanceValue = rand.Int63()
|
||||||
|
NewBalanceValue = OldBalanceValue - 1
|
||||||
|
ContractRoot = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
||||||
|
StoragePath = "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
|
||||||
|
oldStorage = "0x0"
|
||||||
|
newStorage = "0x03"
|
||||||
|
storage = map[string]builder.DiffString{StoragePath: {
|
||||||
|
NewValue: &newStorage,
|
||||||
|
OldValue: &oldStorage,
|
||||||
|
}}
|
||||||
|
address = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592")
|
||||||
|
CreatedAccountDiffs = map[common.Address]builder.AccountDiffEventual{address: {
|
||||||
|
Nonce: builder.DiffUint64{
|
||||||
|
NewValue: &NewNonceValue,
|
||||||
|
OldValue: &OldNonceValue,
|
||||||
|
},
|
||||||
|
Balance: builder.DiffBigInt{
|
||||||
|
NewValue: big.NewInt(NewBalanceValue),
|
||||||
|
OldValue: big.NewInt(OldBalanceValue),
|
||||||
|
},
|
||||||
|
ContractRoot: builder.DiffString{
|
||||||
|
NewValue: &ContractRoot,
|
||||||
|
OldValue: &ContractRoot,
|
||||||
|
},
|
||||||
|
Code: []byte("created account code"),
|
||||||
|
CodeHash: CodeHash,
|
||||||
|
Storage: storage,
|
||||||
|
}}
|
||||||
|
|
||||||
|
UpdatedAccountDiffs = map[common.Address]builder.AccountDiffIncremental{address: {
|
||||||
|
Nonce: builder.DiffUint64{
|
||||||
|
NewValue: &NewNonceValue,
|
||||||
|
OldValue: &OldNonceValue,
|
||||||
|
},
|
||||||
|
Balance: builder.DiffBigInt{
|
||||||
|
NewValue: big.NewInt(NewBalanceValue),
|
||||||
|
OldValue: big.NewInt(OldBalanceValue),
|
||||||
|
},
|
||||||
|
CodeHash: CodeHash,
|
||||||
|
ContractRoot: builder.DiffString{
|
||||||
|
NewValue: &ContractRoot,
|
||||||
|
OldValue: &ContractRoot,
|
||||||
|
},
|
||||||
|
Storage: storage,
|
||||||
|
}}
|
||||||
|
|
||||||
|
DeletedAccountDiffs = map[common.Address]builder.AccountDiffEventual{address: {
|
||||||
|
Nonce: builder.DiffUint64{
|
||||||
|
NewValue: &NewNonceValue,
|
||||||
|
OldValue: &OldNonceValue,
|
||||||
|
},
|
||||||
|
Balance: builder.DiffBigInt{
|
||||||
|
NewValue: big.NewInt(NewBalanceValue),
|
||||||
|
OldValue: big.NewInt(OldBalanceValue),
|
||||||
|
},
|
||||||
|
ContractRoot: builder.DiffString{
|
||||||
|
NewValue: &ContractRoot,
|
||||||
|
OldValue: &ContractRoot,
|
||||||
|
},
|
||||||
|
Code: []byte("deleted account code"),
|
||||||
|
CodeHash: CodeHash,
|
||||||
|
Storage: storage,
|
||||||
|
}}
|
||||||
|
|
||||||
|
TestStateDiff = builder.StateDiff{
|
||||||
|
BlockNumber: BlockNumber,
|
||||||
|
BlockHash: common.HexToHash(BlockHash),
|
||||||
|
CreatedAccounts: CreatedAccountDiffs,
|
||||||
|
DeletedAccounts: DeletedAccountDiffs,
|
||||||
|
UpdatedAccounts: UpdatedAccountDiffs,
|
||||||
|
}
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user