From c0489c86dac14d65055de29f61b521e21c9f2430 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 22 Oct 2018 22:46:29 -0400 Subject: [PATCH] Remove old test importer --- test/importer/doc.go | 8 -- test/importer/importer.go | 247 -------------------------------------- test/importer/log.go | 66 ---------- test/importer/utils.go | 43 ------- test/run.go | 81 ------------- 5 files changed, 445 deletions(-) delete mode 100644 test/importer/doc.go delete mode 100644 test/importer/importer.go delete mode 100644 test/importer/log.go delete mode 100644 test/importer/utils.go delete mode 100644 test/run.go diff --git a/test/importer/doc.go b/test/importer/doc.go deleted file mode 100644 index 0993adc4..00000000 --- a/test/importer/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -// The implementation below is to be considered highly unstable and a continual -// WIP. It is a means to replicate and test replaying Ethereum transactions -// using the Cosmos SDK and the EVM. The ultimate result will be what is known -// as Ethermint. -// -// Note: Some code is directly copied from go-ethereum. - -package importer diff --git a/test/importer/importer.go b/test/importer/importer.go deleted file mode 100644 index 700d69eb..00000000 --- a/test/importer/importer.go +++ /dev/null @@ -1,247 +0,0 @@ -package importer - -import ( - "bytes" - "encoding/binary" - "encoding/json" - "fmt" - "io" - "os" - "path" - "time" - - "github.com/cosmos/ethermint/core" - "github.com/cosmos/ethermint/state" - - ethcommon "github.com/ethereum/go-ethereum/common" - ethmisc "github.com/ethereum/go-ethereum/consensus/misc" - ethcore "github.com/ethereum/go-ethereum/core" - ethstate "github.com/ethereum/go-ethereum/core/state" - ethtypes "github.com/ethereum/go-ethereum/core/types" - ethvm "github.com/ethereum/go-ethereum/core/vm" - ethparams "github.com/ethereum/go-ethereum/params" - ethrlp "github.com/ethereum/go-ethereum/rlp" -) - -var ( - miner501 = ethcommon.HexToAddress("0x35e8e5dC5FBd97c5b421A80B596C030a2Be2A04D") - genInvestor = ethcommon.HexToAddress("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0") -) - -// Importer implements a structure to facilitate testing of importing mainnet -// Ethereum blocks and transactions using the Cosmos SDK components and the -// EVM. -type Importer struct { - EthermintDB *state.Database - BlockchainFile string - Datadir string - InterruptCh <-chan bool -} - -// Import performs an import given an Importer that has a Geth stateDB -// implementation and a blockchain exported file. -// nolint -func (imp *Importer) Import() { - // only create genesis if it is a brand new database - if imp.EthermintDB.LatestVersion() == 0 { - // start with empty root hash (i.e. empty state) - gethStateDB, err := ethstate.New(ethcommon.Hash{}, imp.EthermintDB) - if err != nil { - panic(fmt.Sprintf("failed to instantiate geth state.StateDB: %v", err)) - } - - genBlock := ethcore.DefaultGenesisBlock() - for addr, account := range genBlock.Alloc { - gethStateDB.AddBalance(addr, account.Balance) - gethStateDB.SetCode(addr, account.Code) - gethStateDB.SetNonce(addr, account.Nonce) - - for key, value := range account.Storage { - gethStateDB.SetState(addr, key, value) - } - } - - // get balance of one of the genesis account having 200 ETH - b := gethStateDB.GetBalance(genInvestor) - fmt.Printf("balance of %s: %s\n", genInvestor.String(), b) - - // commit the geth stateDB with 'false' to delete empty objects - genRoot, err := gethStateDB.Commit(false) - if err != nil { - panic(err) - } - - commitID := imp.EthermintDB.Commit() - - fmt.Printf("commitID after genesis: %v\n", commitID) - fmt.Printf("genesis state root hash: %x\n", genRoot[:]) - } - - // file with blockchain data exported from geth by using "geth exportdb" - // command. - input, err := os.Open(imp.BlockchainFile) - if err != nil { - panic(err) - } - - defer input.Close() - - // ethereum mainnet config - chainConfig := ethparams.MainnetChainConfig - - // create RLP stream for exported blocks - stream := ethrlp.NewStream(input, 0) - - var ( - block ethtypes.Block - root500 ethcommon.Hash // root hash after block 500 - root501 ethcommon.Hash // root hash after block 501 - ) - - var prevRoot ethcommon.Hash - binary.BigEndian.PutUint64(prevRoot[:8], uint64(imp.EthermintDB.LatestVersion())) - - imp.EthermintDB.Tracing = true - chainContext := core.NewChainContext() - vmConfig := ethvm.Config{} - - n := 0 - startTime := time.Now() - interrupt := false - - var lastSkipped uint64 - for !interrupt { - if err = stream.Decode(&block); err == io.EOF { - err = nil - break - } else if err != nil { - panic(fmt.Errorf("failed to decode at block %d: %s", block.NumberU64(), err)) - } - - // don't import blocks already imported - if block.NumberU64() < uint64(imp.EthermintDB.LatestVersion()) { - lastSkipped = block.NumberU64() - continue - } - - if lastSkipped > 0 { - fmt.Printf("skipped blocks up to %d\n", lastSkipped) - lastSkipped = 0 - } - - header := block.Header() - chainContext.Coinbase = header.Coinbase - chainContext.SetHeader(block.NumberU64(), header) - - gethStateDB, err := ethstate.New(prevRoot, imp.EthermintDB) - if err != nil { - panic(fmt.Errorf("failed to instantiate geth state.StateDB at block %d: %v", block.NumberU64(), err)) - } - - var ( - receipts ethtypes.Receipts - usedGas = new(uint64) - allLogs []*ethtypes.Log - gp = new(ethcore.GasPool).AddGas(block.GasLimit()) - ) - - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { - ethmisc.ApplyDAOHardFork(gethStateDB) - } - - for i, tx := range block.Transactions() { - gethStateDB.Prepare(tx.Hash(), block.Hash(), i) - - txHash := tx.Hash() - if bytes.Equal(txHash[:], ethcommon.FromHex("0xc438cfcc3b74a28741bda361032f1c6362c34aa0e1cedff693f31ec7d6a12717")) { - vmConfig.Tracer = ethvm.NewStructLogger(ðvm.LogConfig{}) - vmConfig.Debug = true - } - - receipt, _, err := ethcore.ApplyTransaction(chainConfig, chainContext, nil, gp, gethStateDB, header, tx, usedGas, vmConfig) - if vmConfig.Tracer != nil { - w, err := os.Create(path.Join(imp.Datadir, "structlogs.txt")) - if err != nil { - panic(fmt.Sprintf("failed to create file for VM tracing: %v", err)) - } - - encoder := json.NewEncoder(w) - logs := FormatLogs(vmConfig.Tracer.(*ethvm.StructLogger).StructLogs()) - - if err := encoder.Encode(logs); err != nil { - panic(err) - } - - if err := w.Close(); err != nil { - panic(err) - } - - vmConfig.Debug = false - vmConfig.Tracer = nil - } - - if err != nil { - panic(fmt.Errorf("at block %d, tx %x: %v", block.NumberU64(), tx.Hash(), err)) - } - - receipts = append(receipts, receipt) - allLogs = append(allLogs, receipt.Logs...) - } - - // apply mining rewards to the geth stateDB - accumulateRewards(chainConfig, gethStateDB, header, block.Uncles()) - - // commit block in geth - prevRoot, err = gethStateDB.Commit(chainConfig.IsEIP158(block.Number())) - if err != nil { - panic(fmt.Errorf("at block %d: %v", block.NumberU64(), err)) - } - - // commit block in Ethermint - imp.EthermintDB.Commit() - - switch block.NumberU64() { - case 500: - root500 = prevRoot - case 501: - root501 = prevRoot - } - - n++ - if (n % 10000) == 0 { - fmt.Printf("processed %d blocks, time so far: %v\n", n, time.Since(startTime)) - } - - // Check for interrupts - select { - case interrupt = <-imp.InterruptCh: - fmt.Println("interrupted, please wait for cleanup...") - default: - } - } - - fmt.Printf("processed %d blocks\n", n) - - imp.EthermintDB.Tracing = true - - // try to create a new geth stateDB from root of the block 500 - fmt.Printf("root at block 500: %x\n", root500[:]) - - state500, err := ethstate.New(root500, imp.EthermintDB) - if err != nil { - panic(err) - } - - miner501BalanceAt500 := state500.GetBalance(miner501) - - state501, err := ethstate.New(root501, imp.EthermintDB) - if err != nil { - panic(err) - } - - miner501BalanceAt501 := state501.GetBalance(miner501) - - fmt.Printf("investor's balance after block 500: %d\n", state500.GetBalance(genInvestor)) - fmt.Printf("miner of block 501's balance after block 500: %d\n", miner501BalanceAt500) - fmt.Printf("miner of block 501's balance after block 501: %d\n", miner501BalanceAt501) -} diff --git a/test/importer/log.go b/test/importer/log.go deleted file mode 100644 index d8f6c137..00000000 --- a/test/importer/log.go +++ /dev/null @@ -1,66 +0,0 @@ -package importer - -import ( - "fmt" - - ethmath "github.com/ethereum/go-ethereum/common/math" - ethvm "github.com/ethereum/go-ethereum/core/vm" -) - -// StructLogRes stores a structured log emitted by the EVM while replaying a -// transaction in debug mode. -type StructLogRes struct { - Pc uint64 `json:"pc"` - Op string `json:"op"` - Gas uint64 `json:"gas"` - GasCost uint64 `json:"gasCost"` - Depth int `json:"depth"` - Error error `json:"error,omitempty"` - Stack *[]string `json:"stack,omitempty"` - Memory *[]string `json:"memory,omitempty"` - Storage *map[string]string `json:"storage,omitempty"` -} - -// FormatLogs formats EVM returned structured logs for json output. -func FormatLogs(logs []ethvm.StructLog) []StructLogRes { - formatted := make([]StructLogRes, len(logs)) - for index, trace := range logs { - formatted[index] = StructLogRes{ - Pc: trace.Pc, - Op: trace.Op.String(), - Gas: trace.Gas, - GasCost: trace.GasCost, - Depth: trace.Depth, - Error: trace.Err, - } - - if trace.Stack != nil { - stack := make([]string, len(trace.Stack)) - for i, stackValue := range trace.Stack { - stack[i] = fmt.Sprintf("%x", ethmath.PaddedBigBytes(stackValue, 32)) - } - - formatted[index].Stack = &stack - } - - if trace.Memory != nil { - memory := make([]string, 0, (len(trace.Memory)+31)/32) - for i := 0; i+32 <= len(trace.Memory); i += 32 { - memory = append(memory, fmt.Sprintf("%x", trace.Memory[i:i+32])) - } - - formatted[index].Memory = &memory - } - - if trace.Storage != nil { - storage := make(map[string]string) - for i, storageValue := range trace.Storage { - storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue) - } - - formatted[index].Storage = &storage - } - } - - return formatted -} diff --git a/test/importer/utils.go b/test/importer/utils.go deleted file mode 100644 index a70e783d..00000000 --- a/test/importer/utils.go +++ /dev/null @@ -1,43 +0,0 @@ -package importer - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/consensus/ethash" - ethstate "github.com/ethereum/go-ethereum/core/state" - ethtypes "github.com/ethereum/go-ethereum/core/types" - ethparams "github.com/ethereum/go-ethereum/params" -) - -// Some weird constants to avoid constant memory allocs for them. -var ( - big8 = big.NewInt(8) - big32 = big.NewInt(32) -) - -// accumulateRewards credits the coinbase of the given block with the mining -// reward. The total reward consists of the static block reward and rewards for -// included uncles. The coinbase of each uncle block is also rewarded. -func accumulateRewards(config *ethparams.ChainConfig, state ethstate.StateDB, header *ethtypes.Header, uncles []*ethtypes.Header) { - // select the correct block reward based on chain progression - blockReward := ethash.FrontierBlockReward - if config.IsByzantium(header.Number) { - blockReward = ethash.ByzantiumBlockReward - } - - // accumulate the rewards for the miner and any included uncles - reward := new(big.Int).Set(blockReward) - r := new(big.Int) - - for _, uncle := range uncles { - r.Add(uncle.Number, big8) - r.Sub(r, header.Number) - r.Mul(r, blockReward) - r.Div(r, big8) - state.AddBalance(uncle.Coinbase, r) - r.Div(blockReward, big32) - reward.Add(reward, r) - } - - state.AddBalance(header.Coinbase, reward) -} diff --git a/test/run.go b/test/run.go deleted file mode 100644 index 06518011..00000000 --- a/test/run.go +++ /dev/null @@ -1,81 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - "os/signal" - "path" - "runtime/pprof" - "syscall" - - "github.com/cosmos/cosmos-sdk/store" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/cosmos/ethermint/state" - "github.com/cosmos/ethermint/test/importer" - "github.com/cosmos/ethermint/types" - - dbm "github.com/tendermint/tendermint/libs/db" -) - -var ( - cpuprofile = flag.String("cpu-profile", "", "write cpu profile `file`") - blockchain = flag.String("blockchain", "data/blockchain", "file containing blocks to load") - datadir = flag.String("datadir", path.Join(os.Getenv("HOME"), ".ethermint"), "directory for ethermint data") - cachesize = flag.Int("cachesize", 1024*1024, "number of key-value pairs for the state stored in memory") -) - -func main() { - flag.Parse() - - if *cpuprofile != "" { - f, err := os.Create(*cpuprofile) - if err != nil { - fmt.Printf("could not create CPU profile: %v\n", err) - return - } - - if err := pprof.StartCPUProfile(f); err != nil { - fmt.Printf("could not start CPU profile: %v\n", err) - return - } - - defer pprof.StopCPUProfile() - } - - sigs := make(chan os.Signal, 1) - interruptCh := make(chan bool, 1) - signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) - - go func() { - <-sigs - interruptCh <- true - }() - - stateDB := dbm.NewDB("state", dbm.LevelDBBackend, *datadir) - codeDB := dbm.NewDB("code", dbm.LevelDBBackend, *datadir) - - cms := store.NewCommitMultiStore(stateDB) - cms.SetPruning(sdk.PruneNothing) - cms.MountStoreWithDB(types.StoreKeyAccount, sdk.StoreTypeIAVL, nil) - cms.MountStoreWithDB(types.StoreKeyStorage, sdk.StoreTypeIAVL, nil) - - if err := cms.LoadLatestVersion(); err != nil { - panic(fmt.Sprintf("failed to load state store: %v", err)) - } - - ethermintDB, err := state.NewDatabase(cms, codeDB, *cachesize) - if err != nil { - panic(fmt.Sprintf("failed to initialize geth Database: %v", err)) - } - - importer := importer.Importer{ - EthermintDB: ethermintDB, - BlockchainFile: *blockchain, - Datadir: *datadir, - InterruptCh: interruptCh, - } - - importer.Import() -}