cmd/geth, core: add support for recording SHA3 preimages (#3543)

This commit is contained in:
Nick Johnson 2017-01-17 11:19:50 +00:00 committed by Felix Lange
parent 26d385c18b
commit 17d92233d9
29 changed files with 156 additions and 46 deletions

View File

@ -61,7 +61,7 @@ type SimulatedBackend struct {
func NewSimulatedBackend(accounts ...core.GenesisAccount) *SimulatedBackend { func NewSimulatedBackend(accounts ...core.GenesisAccount) *SimulatedBackend {
database, _ := ethdb.NewMemDatabase() database, _ := ethdb.NewMemDatabase()
core.WriteGenesisBlockForTesting(database, accounts...) core.WriteGenesisBlockForTesting(database, accounts...)
blockchain, _ := core.NewBlockChain(database, chainConfig, new(core.FakePow), new(event.TypeMux)) blockchain, _ := core.NewBlockChain(database, chainConfig, new(core.FakePow), new(event.TypeMux), vm.Config{})
backend := &SimulatedBackend{database: database, blockchain: blockchain} backend := &SimulatedBackend{database: database, blockchain: blockchain}
backend.rollback() backend.rollback()
return backend return backend

View File

@ -132,6 +132,7 @@ func init() {
utils.VMForceJitFlag, utils.VMForceJitFlag,
utils.VMJitCacheFlag, utils.VMJitCacheFlag,
utils.VMEnableJitFlag, utils.VMEnableJitFlag,
utils.VMEnableDebugFlag,
utils.NetworkIdFlag, utils.NetworkIdFlag,
utils.RPCCORSDomainFlag, utils.RPCCORSDomainFlag,
utils.EthStatsURLFlag, utils.EthStatsURLFlag,

View File

@ -155,6 +155,7 @@ var AppHelpFlagGroups = []flagGroup{
utils.VMEnableJitFlag, utils.VMEnableJitFlag,
utils.VMForceJitFlag, utils.VMForceJitFlag,
utils.VMJitCacheFlag, utils.VMJitCacheFlag,
utils.VMEnableDebugFlag,
}, },
}, },
{ {

View File

@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
@ -230,6 +231,10 @@ var (
Name: "jitvm", Name: "jitvm",
Usage: "Enable the JIT VM", Usage: "Enable the JIT VM",
} }
VMEnableDebugFlag = cli.BoolFlag{
Name: "vmdebug",
Usage: "Record information useful for VM and contract debugging",
}
// Logging and debug settings // Logging and debug settings
EthStatsURLFlag = cli.StringFlag{ EthStatsURLFlag = cli.StringFlag{
Name: "ethstats", Name: "ethstats",
@ -741,6 +746,7 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) {
GpobaseCorrectionFactor: ctx.GlobalInt(GpobaseCorrectionFactorFlag.Name), GpobaseCorrectionFactor: ctx.GlobalInt(GpobaseCorrectionFactorFlag.Name),
SolcPath: ctx.GlobalString(SolcPathFlag.Name), SolcPath: ctx.GlobalString(SolcPathFlag.Name),
AutoDAG: ctx.GlobalBool(AutoDAGFlag.Name) || ctx.GlobalBool(MiningEnabledFlag.Name), AutoDAG: ctx.GlobalBool(AutoDAGFlag.Name) || ctx.GlobalBool(MiningEnabledFlag.Name),
EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name),
} }
// Override any default configs in dev mode or the test net // Override any default configs in dev mode or the test net
@ -912,7 +918,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
if !ctx.GlobalBool(FakePoWFlag.Name) { if !ctx.GlobalBool(FakePoWFlag.Name) {
pow = ethash.New() pow = ethash.New()
} }
chain, err = core.NewBlockChain(chainDb, chainConfig, pow, new(event.TypeMux)) chain, err = core.NewBlockChain(chainDb, chainConfig, pow, new(event.TypeMux), vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)})
if err != nil { if err != nil {
Fatalf("Could not start chainmanager: %v", err) Fatalf("Could not start chainmanager: %v", err)
} }

View File

@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
@ -168,7 +169,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
// Time the insertion of the new chain. // Time the insertion of the new chain.
// State and blocks are stored in the same DB. // State and blocks are stored in the same DB.
evmux := new(event.TypeMux) evmux := new(event.TypeMux)
chainman, _ := NewBlockChain(db, &params.ChainConfig{HomesteadBlock: new(big.Int)}, FakePow{}, evmux) chainman, _ := NewBlockChain(db, &params.ChainConfig{HomesteadBlock: new(big.Int)}, FakePow{}, evmux, vm.Config{})
defer chainman.Stop() defer chainman.Stop()
b.ReportAllocs() b.ReportAllocs()
b.ResetTimer() b.ResetTimer()
@ -278,7 +279,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) {
if err != nil { if err != nil {
b.Fatalf("error opening database at %v: %v", dir, err) b.Fatalf("error opening database at %v: %v", dir, err)
} }
chain, err := NewBlockChain(db, testChainConfig(), FakePow{}, new(event.TypeMux)) chain, err := NewBlockChain(db, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
if err != nil { if err != nil {
b.Fatalf("error creating chain: %v", err) b.Fatalf("error creating chain: %v", err)
} }

View File

@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -39,7 +40,7 @@ func proc() (Validator, *BlockChain) {
var mux event.TypeMux var mux event.TypeMux
WriteTestNetGenesisBlock(db) WriteTestNetGenesisBlock(db)
blockchain, err := NewBlockChain(db, testChainConfig(), thePow(), &mux) blockchain, err := NewBlockChain(db, testChainConfig(), thePow(), &mux, vm.Config{})
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }

View File

@ -107,12 +107,13 @@ type BlockChain struct {
pow pow.PoW pow pow.PoW
processor Processor // block processor interface processor Processor // block processor interface
validator Validator // block and state validator interface validator Validator // block and state validator interface
vmConfig vm.Config
} }
// NewBlockChain returns a fully initialised block chain using information // NewBlockChain returns a fully initialised block chain using information
// available in the database. It initialiser the default Ethereum Validator and // available in the database. It initialiser the default Ethereum Validator and
// Processor. // Processor.
func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, pow pow.PoW, mux *event.TypeMux) (*BlockChain, error) { func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, pow pow.PoW, mux *event.TypeMux, vmConfig vm.Config) (*BlockChain, error) {
bodyCache, _ := lru.New(bodyCacheLimit) bodyCache, _ := lru.New(bodyCacheLimit)
bodyRLPCache, _ := lru.New(bodyCacheLimit) bodyRLPCache, _ := lru.New(bodyCacheLimit)
blockCache, _ := lru.New(blockCacheLimit) blockCache, _ := lru.New(blockCacheLimit)
@ -128,6 +129,7 @@ func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, pow pow.P
blockCache: blockCache, blockCache: blockCache,
futureBlocks: futureBlocks, futureBlocks: futureBlocks,
pow: pow, pow: pow,
vmConfig: vmConfig,
} }
bc.SetValidator(NewBlockValidator(config, bc, pow)) bc.SetValidator(NewBlockValidator(config, bc, pow))
bc.SetProcessor(NewStateProcessor(config, bc)) bc.SetProcessor(NewStateProcessor(config, bc))
@ -954,7 +956,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
return i, err return i, err
} }
// Process block using the parent state as reference point. // Process block using the parent state as reference point.
receipts, logs, usedGas, err := self.processor.Process(block, self.stateCache, vm.Config{}) receipts, logs, usedGas, err := self.processor.Process(block, self.stateCache, self.vmConfig)
if err != nil { if err != nil {
self.reportBlock(block, receipts, err) self.reportBlock(block, receipts, err)
return i, err return i, err
@ -1004,6 +1006,10 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil { if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil {
return i, err return i, err
} }
// Write hash preimages
if err := WritePreimages(self.chainDb, block.NumberU64(), self.stateCache.Preimages()); err != nil {
return i, err
}
case SideStatTy: case SideStatTy:
if glog.V(logger.Detail) { if glog.V(logger.Detail) {
glog.Infof("inserted forked block #%d [%x…] (TD=%v) in %9v: %3d txs %d uncles.", block.Number(), block.Hash().Bytes()[0:4], block.Difficulty(), common.PrettyDuration(time.Since(bstart)), len(block.Transactions()), len(block.Uncles())) glog.Infof("inserted forked block #%d [%x…] (TD=%v) in %9v: %3d txs %d uncles.", block.Number(), block.Hash().Bytes()[0:4], block.Difficulty(), common.PrettyDuration(time.Since(bstart)), len(block.Transactions()), len(block.Uncles()))

View File

@ -53,7 +53,7 @@ func thePow() pow.PoW {
func theBlockChain(db ethdb.Database, t *testing.T) *BlockChain { func theBlockChain(db ethdb.Database, t *testing.T) *BlockChain {
var eventMux event.TypeMux var eventMux event.TypeMux
WriteTestNetGenesisBlock(db) WriteTestNetGenesisBlock(db)
blockchain, err := NewBlockChain(db, testChainConfig(), thePow(), &eventMux) blockchain, err := NewBlockChain(db, testChainConfig(), thePow(), &eventMux, vm.Config{})
if err != nil { if err != nil {
t.Error("failed creating blockchain:", err) t.Error("failed creating blockchain:", err)
t.FailNow() t.FailNow()
@ -614,7 +614,7 @@ func testReorgBadHashes(t *testing.T, full bool) {
defer func() { delete(BadHashes, headers[3].Hash()) }() defer func() { delete(BadHashes, headers[3].Hash()) }()
} }
// Create a new chain manager and check it rolled back the state // Create a new chain manager and check it rolled back the state
ncm, err := NewBlockChain(db, testChainConfig(), FakePow{}, new(event.TypeMux)) ncm, err := NewBlockChain(db, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
if err != nil { if err != nil {
t.Fatalf("failed to create new chain manager: %v", err) t.Fatalf("failed to create new chain manager: %v", err)
} }
@ -735,7 +735,7 @@ func TestFastVsFullChains(t *testing.T) {
archiveDb, _ := ethdb.NewMemDatabase() archiveDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds}) WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
archive, _ := NewBlockChain(archiveDb, testChainConfig(), FakePow{}, new(event.TypeMux)) archive, _ := NewBlockChain(archiveDb, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
if n, err := archive.InsertChain(blocks); err != nil { if n, err := archive.InsertChain(blocks); err != nil {
t.Fatalf("failed to process block %d: %v", n, err) t.Fatalf("failed to process block %d: %v", n, err)
@ -743,7 +743,7 @@ func TestFastVsFullChains(t *testing.T) {
// Fast import the chain as a non-archive node to test // Fast import the chain as a non-archive node to test
fastDb, _ := ethdb.NewMemDatabase() fastDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds}) WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
fast, _ := NewBlockChain(fastDb, testChainConfig(), FakePow{}, new(event.TypeMux)) fast, _ := NewBlockChain(fastDb, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
headers := make([]*types.Header, len(blocks)) headers := make([]*types.Header, len(blocks))
for i, block := range blocks { for i, block := range blocks {
@ -819,7 +819,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
archiveDb, _ := ethdb.NewMemDatabase() archiveDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds}) WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
archive, _ := NewBlockChain(archiveDb, testChainConfig(), FakePow{}, new(event.TypeMux)) archive, _ := NewBlockChain(archiveDb, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
if n, err := archive.InsertChain(blocks); err != nil { if n, err := archive.InsertChain(blocks); err != nil {
t.Fatalf("failed to process block %d: %v", n, err) t.Fatalf("failed to process block %d: %v", n, err)
@ -831,7 +831,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
// Import the chain as a non-archive node and ensure all pointers are updated // Import the chain as a non-archive node and ensure all pointers are updated
fastDb, _ := ethdb.NewMemDatabase() fastDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds}) WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
fast, _ := NewBlockChain(fastDb, testChainConfig(), FakePow{}, new(event.TypeMux)) fast, _ := NewBlockChain(fastDb, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
headers := make([]*types.Header, len(blocks)) headers := make([]*types.Header, len(blocks))
for i, block := range blocks { for i, block := range blocks {
@ -850,7 +850,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
// Import the chain as a light node and ensure all pointers are updated // Import the chain as a light node and ensure all pointers are updated
lightDb, _ := ethdb.NewMemDatabase() lightDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(lightDb, GenesisAccount{address, funds}) WriteGenesisBlockForTesting(lightDb, GenesisAccount{address, funds})
light, _ := NewBlockChain(lightDb, testChainConfig(), FakePow{}, new(event.TypeMux)) light, _ := NewBlockChain(lightDb, testChainConfig(), FakePow{}, new(event.TypeMux), vm.Config{})
if n, err := light.InsertHeaderChain(headers, 1); err != nil { if n, err := light.InsertHeaderChain(headers, 1); err != nil {
t.Fatalf("failed to insert header %d: %v", n, err) t.Fatalf("failed to insert header %d: %v", n, err)
@ -916,7 +916,7 @@ func TestChainTxReorgs(t *testing.T) {
}) })
// Import the chain. This runs all block validation rules. // Import the chain. This runs all block validation rules.
evmux := &event.TypeMux{} evmux := &event.TypeMux{}
blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux) blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux, vm.Config{})
if i, err := blockchain.InsertChain(chain); err != nil { if i, err := blockchain.InsertChain(chain); err != nil {
t.Fatalf("failed to insert original chain[%d]: %v", i, err) t.Fatalf("failed to insert original chain[%d]: %v", i, err)
} }
@ -990,7 +990,7 @@ func TestLogReorgs(t *testing.T) {
) )
evmux := &event.TypeMux{} evmux := &event.TypeMux{}
blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux) blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux, vm.Config{})
subs := evmux.Subscribe(RemovedLogsEvent{}) subs := evmux.Subscribe(RemovedLogsEvent{})
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 2, func(i int, gen *BlockGen) { chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 2, func(i int, gen *BlockGen) {
@ -1027,7 +1027,7 @@ func TestReorgSideEvent(t *testing.T) {
) )
evmux := &event.TypeMux{} evmux := &event.TypeMux{}
blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux) blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux, vm.Config{})
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 3, func(i int, gen *BlockGen) {}) chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 3, func(i int, gen *BlockGen) {})
if _, err := blockchain.InsertChain(chain); err != nil { if _, err := blockchain.InsertChain(chain); err != nil {
@ -1103,7 +1103,7 @@ func TestCanonicalBlockRetrieval(t *testing.T) {
) )
evmux := &event.TypeMux{} evmux := &event.TypeMux{}
blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux) blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux, vm.Config{})
chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *BlockGen) {}) chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *BlockGen) {})
@ -1146,7 +1146,7 @@ func TestEIP155Transition(t *testing.T) {
mux event.TypeMux mux event.TypeMux
) )
blockchain, _ := NewBlockChain(db, config, FakePow{}, &mux) blockchain, _ := NewBlockChain(db, config, FakePow{}, &mux, vm.Config{})
blocks, _ := GenerateChain(config, genesis, db, 4, func(i int, block *BlockGen) { blocks, _ := GenerateChain(config, genesis, db, 4, func(i int, block *BlockGen) {
var ( var (
tx *types.Transaction tx *types.Transaction
@ -1250,7 +1250,7 @@ func TestEIP161AccountRemoval(t *testing.T) {
} }
mux event.TypeMux mux event.TypeMux
blockchain, _ = NewBlockChain(db, config, FakePow{}, &mux) blockchain, _ = NewBlockChain(db, config, FakePow{}, &mux, vm.Config{})
) )
blocks, _ := GenerateChain(config, genesis, db, 3, func(i int, block *BlockGen) { blocks, _ := GenerateChain(config, genesis, db, 3, func(i int, block *BlockGen) {
var ( var (

View File

@ -256,7 +256,7 @@ func newCanonical(n int, full bool) (ethdb.Database, *BlockChain, error) {
// Initialize a fresh chain with only a genesis block // Initialize a fresh chain with only a genesis block
genesis, _ := WriteTestNetGenesisBlock(db) genesis, _ := WriteTestNetGenesisBlock(db)
blockchain, _ := NewBlockChain(db, MakeChainConfig(), FakePow{}, evmux) blockchain, _ := NewBlockChain(db, MakeChainConfig(), FakePow{}, evmux, vm.Config{})
// Create and inject the requested chain // Create and inject the requested chain
if n == 0 { if n == 0 {
return db, blockchain, nil return db, blockchain, nil

View File

@ -21,6 +21,7 @@ import (
"math/big" "math/big"
"github.com/ethereum/go-ethereum/core/types" "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/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
@ -81,7 +82,7 @@ func ExampleGenerateChain() {
// Import the chain. This runs all block validation rules. // Import the chain. This runs all block validation rules.
evmux := &event.TypeMux{} evmux := &event.TypeMux{}
blockchain, _ := NewBlockChain(db, chainConfig, FakePow{}, evmux) blockchain, _ := NewBlockChain(db, chainConfig, FakePow{}, evmux, vm.Config{})
if i, err := blockchain.InsertChain(chain); err != nil { if i, err := blockchain.InsertChain(chain); err != nil {
fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err) fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err)
return return

View File

@ -20,6 +20,7 @@ import (
"math/big" "math/big"
"testing" "testing"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -39,12 +40,12 @@ func TestDAOForkRangeExtradata(t *testing.T) {
proDb, _ := ethdb.NewMemDatabase() proDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(proDb) WriteGenesisBlockForTesting(proDb)
proConf := &params.ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: true} proConf := &params.ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: true}
proBc, _ := NewBlockChain(proDb, proConf, new(FakePow), new(event.TypeMux)) proBc, _ := NewBlockChain(proDb, proConf, new(FakePow), new(event.TypeMux), vm.Config{})
conDb, _ := ethdb.NewMemDatabase() conDb, _ := ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(conDb) WriteGenesisBlockForTesting(conDb)
conConf := &params.ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: false} conConf := &params.ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: false}
conBc, _ := NewBlockChain(conDb, conConf, new(FakePow), new(event.TypeMux)) conBc, _ := NewBlockChain(conDb, conConf, new(FakePow), new(event.TypeMux), vm.Config{})
if _, err := proBc.InsertChain(prefix); err != nil { if _, err := proBc.InsertChain(prefix); err != nil {
t.Fatalf("pro-fork: failed to import chain prefix: %v", err) t.Fatalf("pro-fork: failed to import chain prefix: %v", err)
@ -57,7 +58,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
// Create a pro-fork block, and try to feed into the no-fork chain // Create a pro-fork block, and try to feed into the no-fork chain
db, _ = ethdb.NewMemDatabase() db, _ = ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(db) WriteGenesisBlockForTesting(db)
bc, _ := NewBlockChain(db, conConf, new(FakePow), new(event.TypeMux)) bc, _ := NewBlockChain(db, conConf, new(FakePow), new(event.TypeMux), vm.Config{})
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()+1)) blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()+1))
for j := 0; j < len(blocks)/2; j++ { for j := 0; j < len(blocks)/2; j++ {
@ -78,7 +79,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
// Create a no-fork block, and try to feed into the pro-fork chain // Create a no-fork block, and try to feed into the pro-fork chain
db, _ = ethdb.NewMemDatabase() db, _ = ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(db) WriteGenesisBlockForTesting(db)
bc, _ = NewBlockChain(db, proConf, new(FakePow), new(event.TypeMux)) bc, _ = NewBlockChain(db, proConf, new(FakePow), new(event.TypeMux), vm.Config{})
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()+1)) blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()+1))
for j := 0; j < len(blocks)/2; j++ { for j := 0; j < len(blocks)/2; j++ {
@ -100,7 +101,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
// Verify that contra-forkers accept pro-fork extra-datas after forking finishes // Verify that contra-forkers accept pro-fork extra-datas after forking finishes
db, _ = ethdb.NewMemDatabase() db, _ = ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(db) WriteGenesisBlockForTesting(db)
bc, _ := NewBlockChain(db, conConf, new(FakePow), new(event.TypeMux)) bc, _ := NewBlockChain(db, conConf, new(FakePow), new(event.TypeMux), vm.Config{})
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()+1)) blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()+1))
for j := 0; j < len(blocks)/2; j++ { for j := 0; j < len(blocks)/2; j++ {
@ -116,7 +117,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
// Verify that pro-forkers accept contra-fork extra-datas after forking finishes // Verify that pro-forkers accept contra-fork extra-datas after forking finishes
db, _ = ethdb.NewMemDatabase() db, _ = ethdb.NewMemDatabase()
WriteGenesisBlockForTesting(db) WriteGenesisBlockForTesting(db)
bc, _ = NewBlockChain(db, proConf, new(FakePow), new(event.TypeMux)) bc, _ = NewBlockChain(db, proConf, new(FakePow), new(event.TypeMux), vm.Config{})
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()+1)) blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()+1))
for j := 0; j < len(blocks)/2; j++ { for j := 0; j < len(blocks)/2; j++ {

View File

@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
@ -39,12 +40,13 @@ var (
headBlockKey = []byte("LastBlock") headBlockKey = []byte("LastBlock")
headFastKey = []byte("LastFast") headFastKey = []byte("LastFast")
headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header
tdSuffix = []byte("t") // headerPrefix + num (uint64 big endian) + hash + tdSuffix -> td tdSuffix = []byte("t") // headerPrefix + num (uint64 big endian) + hash + tdSuffix -> td
numSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + numSuffix -> hash numSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + numSuffix -> hash
blockHashPrefix = []byte("H") // blockHashPrefix + hash -> num (uint64 big endian) blockHashPrefix = []byte("H") // blockHashPrefix + hash -> num (uint64 big endian)
bodyPrefix = []byte("b") // bodyPrefix + num (uint64 big endian) + hash -> block body bodyPrefix = []byte("b") // bodyPrefix + num (uint64 big endian) + hash -> block body
blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts
preimagePrefix = "secure-key-" // preimagePrefix + hash -> preimage
txMetaSuffix = []byte{0x01} txMetaSuffix = []byte{0x01}
receiptsPrefix = []byte("receipts-") receiptsPrefix = []byte("receipts-")
@ -66,6 +68,9 @@ var (
ChainConfigNotFoundErr = errors.New("ChainConfig not found") // general config not found error ChainConfigNotFoundErr = errors.New("ChainConfig not found") // general config not found error
mipmapBloomMu sync.Mutex // protect against race condition when updating mipmap blooms mipmapBloomMu sync.Mutex // protect against race condition when updating mipmap blooms
preimageCounter = metrics.NewCounter("db/preimage/total")
preimageHitCounter = metrics.NewCounter("db/preimage/hits")
) )
// encodeBlockNumber encodes a block number as big endian uint64 // encodeBlockNumber encodes a block number as big endian uint64
@ -595,6 +600,34 @@ func GetMipmapBloom(db ethdb.Database, number, level uint64) types.Bloom {
return types.BytesToBloom(bloomDat) return types.BytesToBloom(bloomDat)
} }
// PreimageTable returns a Database instance with the key prefix for preimage entries.
func PreimageTable(db ethdb.Database) ethdb.Database {
return ethdb.NewTable(db, preimagePrefix)
}
// WritePreimages writes the provided set of preimages to the database. `number` is the
// current block number, and is used for debug messages only.
func WritePreimages(db ethdb.Database, number uint64, preimages map[common.Hash][]byte) error {
table := PreimageTable(db)
batch := table.NewBatch()
hitCount := 0
for hash, preimage := range preimages {
if _, err := table.Get(hash.Bytes()); err != nil {
batch.Put(hash.Bytes(), preimage)
hitCount += 1
}
}
preimageCounter.Inc(int64(len(preimages)))
preimageHitCounter.Inc(int64(hitCount))
if hitCount > 0 {
if err := batch.Write(); err != nil {
return fmt.Errorf("preimage write fail for block %d: %v", number, err)
}
glog.V(logger.Debug).Infof("%d preimages in block %d, including %d new", len(preimages), number, hitCount)
}
return nil
}
// GetBlockChainVersion reads the version number from db. // GetBlockChainVersion reads the version number from db.
func GetBlockChainVersion(db ethdb.Database) int { func GetBlockChainVersion(db ethdb.Database) int {
var vsn uint var vsn uint

View File

@ -67,6 +67,9 @@ type (
addLogChange struct { addLogChange struct {
txhash common.Hash txhash common.Hash
} }
addPreimageChange struct {
hash common.Hash
}
touchChange struct { touchChange struct {
account *common.Address account *common.Address
prev bool prev bool
@ -127,3 +130,7 @@ func (ch addLogChange) undo(s *StateDB) {
s.logs[ch.txhash] = logs[:len(logs)-1] s.logs[ch.txhash] = logs[:len(logs)-1]
} }
} }
func (ch addPreimageChange) undo(s *StateDB) {
delete(s.preimages, ch.hash)
}

View File

@ -75,6 +75,8 @@ type StateDB struct {
logs map[common.Hash][]*types.Log logs map[common.Hash][]*types.Log
logSize uint logSize uint
preimages map[common.Hash][]byte
// Journal of state modifications. This is the backbone of // Journal of state modifications. This is the backbone of
// Snapshot and RevertToSnapshot. // Snapshot and RevertToSnapshot.
journal journal journal journal
@ -99,6 +101,7 @@ func New(root common.Hash, db ethdb.Database) (*StateDB, error) {
stateObjectsDirty: make(map[common.Address]struct{}), stateObjectsDirty: make(map[common.Address]struct{}),
refund: new(big.Int), refund: new(big.Int),
logs: make(map[common.Hash][]*types.Log), logs: make(map[common.Hash][]*types.Log),
preimages: make(map[common.Hash][]byte),
}, nil }, nil
} }
@ -120,6 +123,7 @@ func (self *StateDB) New(root common.Hash) (*StateDB, error) {
stateObjectsDirty: make(map[common.Address]struct{}), stateObjectsDirty: make(map[common.Address]struct{}),
refund: new(big.Int), refund: new(big.Int),
logs: make(map[common.Hash][]*types.Log), logs: make(map[common.Hash][]*types.Log),
preimages: make(map[common.Hash][]byte),
}, nil }, nil
} }
@ -141,6 +145,7 @@ func (self *StateDB) Reset(root common.Hash) error {
self.txIndex = 0 self.txIndex = 0
self.logs = make(map[common.Hash][]*types.Log) self.logs = make(map[common.Hash][]*types.Log)
self.logSize = 0 self.logSize = 0
self.preimages = make(map[common.Hash][]byte)
self.clearJournalAndRefund() self.clearJournalAndRefund()
return nil return nil
@ -199,6 +204,21 @@ func (self *StateDB) Logs() []*types.Log {
return logs return logs
} }
// AddPreimage records a SHA3 preimage seen by the VM.
func (self *StateDB) AddPreimage(hash common.Hash, preimage []byte) {
if _, ok := self.preimages[hash]; !ok {
self.journal = append(self.journal, addPreimageChange{hash: hash})
pi := make([]byte, len(preimage))
copy(pi, preimage)
self.preimages[hash] = pi
}
}
// Preimages returns a list of SHA3 preimages that have been submitted.
func (self *StateDB) Preimages() map[common.Hash][]byte {
return self.preimages
}
func (self *StateDB) AddRefund(gas *big.Int) { func (self *StateDB) AddRefund(gas *big.Int) {
self.journal = append(self.journal, refundChange{prev: new(big.Int).Set(self.refund)}) self.journal = append(self.journal, refundChange{prev: new(big.Int).Set(self.refund)})
self.refund.Add(self.refund, gas) self.refund.Add(self.refund, gas)
@ -477,8 +497,9 @@ func (self *StateDB) Copy() *StateDB {
refund: new(big.Int).Set(self.refund), refund: new(big.Int).Set(self.refund),
logs: make(map[common.Hash][]*types.Log, len(self.logs)), logs: make(map[common.Hash][]*types.Log, len(self.logs)),
logSize: self.logSize, logSize: self.logSize,
preimages: make(map[common.Hash][]byte),
} }
// Copy the dirty states and logs // Copy the dirty states, logs, and preimages
for addr := range self.stateObjectsDirty { for addr := range self.stateObjectsDirty {
state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state, state.MarkStateObjectDirty) state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state, state.MarkStateObjectDirty)
state.stateObjectsDirty[addr] = struct{}{} state.stateObjectsDirty[addr] = struct{}{}
@ -487,6 +508,9 @@ func (self *StateDB) Copy() *StateDB {
state.logs[hash] = make([]*types.Log, len(logs)) state.logs[hash] = make([]*types.Log, len(logs))
copy(state.logs[hash], logs) copy(state.logs[hash], logs)
} }
for hash, preimage := range self.preimages {
state.preimages[hash] = preimage
}
return state return state
} }

View File

@ -99,7 +99,7 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, gp *GasPool, s
context := NewEVMContext(msg, header, bc) context := NewEVMContext(msg, header, bc)
// Create a new environment which holds all relevant information // Create a new environment which holds all relevant information
// about the transaction and calling mechanisms. // about the transaction and calling mechanisms.
vmenv := vm.NewEVM(context, statedb, config, vm.Config{}) vmenv := vm.NewEVM(context, statedb, config, cfg)
// Apply the transaction to the current state (included in the env) // Apply the transaction to the current state (included in the env)
_, gas, err := ApplyMessage(vmenv, msg, gp) _, gas, err := ApplyMessage(vmenv, msg, gp)
if err != nil { if err != nil {

View File

@ -247,7 +247,12 @@ func opMulmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *S
func opSha3(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { func opSha3(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
offset, size := stack.pop(), stack.pop() offset, size := stack.pop(), stack.pop()
hash := crypto.Keccak256(memory.Get(offset.Int64(), size.Int64())) data := memory.Get(offset.Int64(), size.Int64())
hash := crypto.Keccak256(data)
if env.vmConfig.EnablePreimageRecording {
env.StateDB.AddPreimage(common.BytesToHash(hash), data)
}
stack.push(common.BytesToBig(hash)) stack.push(common.BytesToBig(hash))
return nil, nil return nil, nil

View File

@ -60,6 +60,7 @@ type StateDB interface {
Snapshot() int Snapshot() int
AddLog(*types.Log) AddLog(*types.Log)
AddPreimage(common.Hash, []byte)
} }
// Account represents a contract or basic ethereum account. // Account represents a contract or basic ethereum account.

View File

@ -67,3 +67,4 @@ func (NoopStateDB) Empty(common.Address) bool { return f
func (NoopStateDB) RevertToSnapshot(int) {} func (NoopStateDB) RevertToSnapshot(int) {}
func (NoopStateDB) Snapshot() int { return 0 } func (NoopStateDB) Snapshot() int { return 0 }
func (NoopStateDB) AddLog(*types.Log) {} func (NoopStateDB) AddLog(*types.Log) {}
func (NoopStateDB) AddPreimage(common.Hash, []byte) {}

View File

@ -44,6 +44,8 @@ type Config struct {
NoRecursion bool NoRecursion bool
// Disable gas metering // Disable gas metering
DisableGasMetering bool DisableGasMetering bool
// Enable recording of SHA3/keccak preimages
EnablePreimageRecording bool
// JumpTable contains the EVM instruction table. This // JumpTable contains the EVM instruction table. This
// may me left uninitialised and will be set the default // may me left uninitialised and will be set the default
// table. // table.

View File

@ -560,3 +560,9 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, txHash common.
} }
return nil, errors.New("database inconsistency") return nil, errors.New("database inconsistency")
} }
// Preimage is a debug API function that returns the preimage for a sha3 hash, if known.
func (api *PrivateDebugAPI) Preimage(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
db := core.PreimageTable(api.eth.ChainDb())
return db.Get(hash.Bytes())
}

View File

@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/eth/filters"
"github.com/ethereum/go-ethereum/eth/gasprice" "github.com/ethereum/go-ethereum/eth/gasprice"
@ -97,8 +98,7 @@ type Config struct {
GpobaseStepUp int GpobaseStepUp int
GpobaseCorrectionFactor int GpobaseCorrectionFactor int
EnableJit bool EnablePreimageRecording bool
ForceJit bool
TestGenesisBlock *types.Block // Genesis block to seed the chain database with (testing only!) TestGenesisBlock *types.Block // Genesis block to seed the chain database with (testing only!)
TestGenesisState ethdb.Database // Genesis state to seed the database with (testing only!) TestGenesisState ethdb.Database // Genesis state to seed the database with (testing only!)
@ -218,7 +218,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
glog.V(logger.Info).Infoln("Chain config:", eth.chainConfig) glog.V(logger.Info).Infoln("Chain config:", eth.chainConfig)
eth.blockchain, err = core.NewBlockChain(chainDb, eth.chainConfig, eth.pow, eth.EventMux()) eth.blockchain, err = core.NewBlockChain(chainDb, eth.chainConfig, eth.pow, eth.EventMux(), vm.Config{EnablePreimageRecording: config.EnablePreimageRecording})
if err != nil { if err != nil {
if err == core.ErrNoGenesis { if err == core.ErrNoGenesis {
return nil, fmt.Errorf(`No chain found. Please initialise a new chain using the "init" subcommand.`) return nil, fmt.Errorf(`No chain found. Please initialise a new chain using the "init" subcommand.`)

View File

@ -27,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "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/crypto"
"github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
@ -469,7 +470,7 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool
db, _ = ethdb.NewMemDatabase() db, _ = ethdb.NewMemDatabase()
genesis = core.WriteGenesisBlockForTesting(db) genesis = core.WriteGenesisBlockForTesting(db)
config = &params.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked} config = &params.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked}
blockchain, _ = core.NewBlockChain(db, config, pow, evmux) blockchain, _ = core.NewBlockChain(db, config, pow, evmux, vm.Config{})
) )
pm, err := NewProtocolManager(config, false, NetworkId, 1000, evmux, new(testTxPool), pow, blockchain, db) pm, err := NewProtocolManager(config, false, NetworkId, 1000, evmux, new(testTxPool), pow, blockchain, db)
if err != nil { if err != nil {

View File

@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
@ -56,7 +57,7 @@ func newTestProtocolManager(fastSync bool, blocks int, generator func(int, *core
db, _ = ethdb.NewMemDatabase() db, _ = ethdb.NewMemDatabase()
genesis = core.WriteGenesisBlockForTesting(db, testBank) genesis = core.WriteGenesisBlockForTesting(db, testBank)
chainConfig = &params.ChainConfig{HomesteadBlock: big.NewInt(0)} // homestead set to 0 because of chain maker chainConfig = &params.ChainConfig{HomesteadBlock: big.NewInt(0)} // homestead set to 0 because of chain maker
blockchain, _ = core.NewBlockChain(db, chainConfig, pow, evmux) blockchain, _ = core.NewBlockChain(db, chainConfig, pow, evmux, vm.Config{})
) )
chain, _ := core.GenerateChain(chainConfig, genesis, db, blocks, generator) chain, _ := core.GenerateChain(chainConfig, genesis, db, blocks, generator)
if _, err := blockchain.InsertChain(chain); err != nil { if _, err := blockchain.InsertChain(chain); err != nil {

View File

@ -385,6 +385,12 @@ web3._extend({
call: 'debug_traceTransaction', call: 'debug_traceTransaction',
params: 2, params: 2,
inputFormatter: [null, null] inputFormatter: [null, null]
}),
new web3._extend.Method({
name: 'preimage',
call: 'debug_preimage',
params: 1,
inputFormatter: [null]
}) })
], ],
properties: [] properties: []

View File

@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
@ -143,7 +144,7 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor
odr = NewLesOdr(db) odr = NewLesOdr(db)
chain, _ = light.NewLightChain(odr, chainConfig, pow, evmux) chain, _ = light.NewLightChain(odr, chainConfig, pow, evmux)
} else { } else {
blockchain, _ := core.NewBlockChain(db, chainConfig, pow, evmux) blockchain, _ := core.NewBlockChain(db, chainConfig, pow, evmux, vm.Config{})
gchain, _ := core.GenerateChain(chainConfig, genesis, db, blocks, generator) gchain, _ := core.GenerateChain(chainConfig, genesis, db, blocks, generator)
if _, err := blockchain.InsertChain(gchain); err != nil { if _, err := blockchain.InsertChain(gchain); err != nil {
panic(err) panic(err)

View File

@ -251,7 +251,7 @@ func testChainOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
) )
core.WriteGenesisBlockForTesting(ldb, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds}) core.WriteGenesisBlockForTesting(ldb, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
// Assemble the test environment // Assemble the test environment
blockchain, _ := core.NewBlockChain(sdb, testChainConfig(), pow, evmux) blockchain, _ := core.NewBlockChain(sdb, testChainConfig(), pow, evmux, vm.Config{})
chainConfig := &params.ChainConfig{HomesteadBlock: new(big.Int)} chainConfig := &params.ChainConfig{HomesteadBlock: new(big.Int)}
gchain, _ := core.GenerateChain(chainConfig, genesis, sdb, 4, testChainGen) gchain, _ := core.GenerateChain(chainConfig, genesis, sdb, 4, testChainGen)
if _, err := blockchain.InsertChain(gchain); err != nil { if _, err := blockchain.InsertChain(gchain); err != nil {

View File

@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -88,7 +89,7 @@ func TestTxPool(t *testing.T) {
) )
core.WriteGenesisBlockForTesting(ldb, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds}) core.WriteGenesisBlockForTesting(ldb, core.GenesisAccount{Address: testBankAddress, Balance: testBankFunds})
// Assemble the test environment // Assemble the test environment
blockchain, _ := core.NewBlockChain(sdb, testChainConfig(), pow, evmux) blockchain, _ := core.NewBlockChain(sdb, testChainConfig(), pow, evmux, vm.Config{})
chainConfig := &params.ChainConfig{HomesteadBlock: new(big.Int)} chainConfig := &params.ChainConfig{HomesteadBlock: new(big.Int)}
gchain, _ := core.GenerateChain(chainConfig, genesis, sdb, poolTestBlocks, txPoolTestChainGen) gchain, _ := core.GenerateChain(chainConfig, genesis, sdb, poolTestBlocks, txPoolTestChainGen)
if _, err := blockchain.InsertChain(gchain); err != nil { if _, err := blockchain.InsertChain(gchain); err != nil {

View File

@ -45,6 +45,8 @@ func (s *VMState) Error() error {
func (s *VMState) AddLog(log *types.Log) {} func (s *VMState) AddLog(log *types.Log) {}
func (s *VMState) AddPreimage(hash common.Hash, preimage []byte) {}
// errHandler handles and stores any state error that happens during execution. // errHandler handles and stores any state error that happens during execution.
func (s *VMState) errHandler(err error) { func (s *VMState) errHandler(err error) {
if err != nil && s.err == nil { if err != nil && s.err == nil {

View File

@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "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/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
@ -172,7 +173,7 @@ func runBlockTest(homesteadBlock, daoForkBlock, gasPriceFork *big.Int, test *Blo
core.WriteHeadBlockHash(db, test.Genesis.Hash()) core.WriteHeadBlockHash(db, test.Genesis.Hash())
evmux := new(event.TypeMux) evmux := new(event.TypeMux)
config := &params.ChainConfig{HomesteadBlock: homesteadBlock, DAOForkBlock: daoForkBlock, DAOForkSupport: true, EIP150Block: gasPriceFork} config := &params.ChainConfig{HomesteadBlock: homesteadBlock, DAOForkBlock: daoForkBlock, DAOForkSupport: true, EIP150Block: gasPriceFork}
chain, err := core.NewBlockChain(db, config, ethash.NewShared(), evmux) chain, err := core.NewBlockChain(db, config, ethash.NewShared(), evmux, vm.Config{})
if err != nil { if err != nil {
return err return err
} }