mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
cmd, core, eth, internal, light: Add support for recording SHA3 preimages
This commit is contained in:
parent
3dab303826
commit
764162944a
17 changed files with 113 additions and 16 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@ var AppHelpFlagGroups = []flagGroup{
|
||||||
utils.VMEnableJitFlag,
|
utils.VMEnableJitFlag,
|
||||||
utils.VMForceJitFlag,
|
utils.VMForceJitFlag,
|
||||||
utils.VMJitCacheFlag,
|
utils.VMJitCacheFlag,
|
||||||
|
utils.VMEnableDebugFlag,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()))
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
@ -45,6 +46,7 @@ var (
|
||||||
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,31 @@ func GetMipmapBloom(db ethdb.Database, number, level uint64) types.Bloom {
|
||||||
return types.BytesToBloom(bloomDat)
|
return types.BytesToBloom(bloomDat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetPreimageTable(db ethdb.Database) ethdb.Database {
|
||||||
|
return ethdb.NewDatabaseTable(db, preimagePrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WritePreimages(db ethdb.Database, number uint64, preimages map[common.Hash][]byte) error {
|
||||||
|
table := GetPreimageTable(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.Error).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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,19 @@ func (self *StateDB) Logs() []*types.Log {
|
||||||
return logs
|
return logs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 +495,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 +506,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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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) {}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -560,3 +560,8 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, txHash common.
|
||||||
}
|
}
|
||||||
return nil, errors.New("database inconsistency")
|
return nil, errors.New("database inconsistency")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *PrivateDebugAPI) GetPreimage(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
|
||||||
|
db := core.GetPreimageTable(api.eth.ChainDb())
|
||||||
|
return db.Get(hash.Bytes())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
@ -99,6 +100,7 @@ type Config struct {
|
||||||
|
|
||||||
EnableJit bool
|
EnableJit bool
|
||||||
ForceJit bool
|
ForceJit bool
|
||||||
|
EnablePreimageRecording 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 +220,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.`)
|
||||||
|
|
|
||||||
|
|
@ -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: 'getPreimage',
|
||||||
|
call: 'debug_getPreimage',
|
||||||
|
params: 1,
|
||||||
|
inputFormatter: [null]
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
properties: []
|
properties: []
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue