mirror of https://github.com/status-im/op-geth.git
Changed prev_hash to block_hash, state transition now uses vm env
* PREVHASH => BLOCKHASH( N ) * State transition object uses VMEnv as it's query interface * Updated vm.Enviroment has GetHash( n ) for BLOCKHASH instruction * Added GetHash to xeth, core, utils & test environments
This commit is contained in:
parent
16f417f5af
commit
ca1b2a1a91
|
@ -151,7 +151,7 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
|
||||||
|
|
||||||
block := self.lib.eth.ChainManager().CurrentBlock()
|
block := self.lib.eth.ChainManager().CurrentBlock()
|
||||||
|
|
||||||
env := utils.NewEnv(statedb, block, account.Address(), value)
|
env := utils.NewEnv(self.lib.eth.ChainManager(), statedb, block, account.Address(), value)
|
||||||
|
|
||||||
self.Logf("callsize %d", len(script))
|
self.Logf("callsize %d", len(script))
|
||||||
go func() {
|
go func() {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type VMEnv struct {
|
type VMEnv struct {
|
||||||
|
chain *core.ChainManager
|
||||||
state *state.StateDB
|
state *state.StateDB
|
||||||
block *types.Block
|
block *types.Block
|
||||||
|
|
||||||
|
@ -20,8 +21,9 @@ type VMEnv struct {
|
||||||
Gas *big.Int
|
Gas *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEnv(state *state.StateDB, block *types.Block, transactor []byte, value *big.Int) *VMEnv {
|
func NewEnv(chain *core.ChainManager, state *state.StateDB, block *types.Block, transactor []byte, value *big.Int) *VMEnv {
|
||||||
return &VMEnv{
|
return &VMEnv{
|
||||||
|
chain: chain,
|
||||||
state: state,
|
state: state,
|
||||||
block: block,
|
block: block,
|
||||||
transactor: transactor,
|
transactor: transactor,
|
||||||
|
@ -35,12 +37,18 @@ func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
|
||||||
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
|
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
|
||||||
func (self *VMEnv) Time() int64 { return self.block.Time() }
|
func (self *VMEnv) Time() int64 { return self.block.Time() }
|
||||||
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
|
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
|
||||||
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
|
||||||
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
|
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
|
||||||
func (self *VMEnv) Value() *big.Int { return self.value }
|
func (self *VMEnv) Value() *big.Int { return self.value }
|
||||||
func (self *VMEnv) State() *state.StateDB { return self.state }
|
func (self *VMEnv) State() *state.StateDB { return self.state }
|
||||||
func (self *VMEnv) Depth() int { return self.depth }
|
func (self *VMEnv) Depth() int { return self.depth }
|
||||||
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
||||||
|
func (self *VMEnv) GetHash(n uint64) []byte {
|
||||||
|
if block := self.chain.GetBlockByNumber(n); block != nil {
|
||||||
|
return block.Hash()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
func (self *VMEnv) AddLog(log state.Log) {
|
func (self *VMEnv) AddLog(log state.Log) {
|
||||||
self.state.AddLog(log)
|
self.state.AddLog(log)
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ done:
|
||||||
txGas := new(big.Int).Set(tx.Gas())
|
txGas := new(big.Int).Set(tx.Gas())
|
||||||
|
|
||||||
cb := state.GetStateObject(coinbase.Address())
|
cb := state.GetStateObject(coinbase.Address())
|
||||||
st := NewStateTransition(cb, tx, state, block)
|
st := NewStateTransition(NewEnv(state, self.bc, tx, block), tx, cb)
|
||||||
_, err = st.TransitionState()
|
_, err = st.TransitionState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch {
|
switch {
|
||||||
|
@ -232,6 +232,8 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
|
||||||
// Sync the current block's state to the database and cancelling out the deferred Undo
|
// Sync the current block's state to the database and cancelling out the deferred Undo
|
||||||
state.Sync()
|
state.Sync()
|
||||||
|
|
||||||
|
state.Manifest().SetHash(block.Hash())
|
||||||
|
|
||||||
messages := state.Manifest().Messages
|
messages := state.Manifest().Messages
|
||||||
state.Manifest().Reset()
|
state.Manifest().Reset()
|
||||||
|
|
||||||
|
@ -342,7 +344,7 @@ func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent
|
||||||
To: block.Header().Coinbase,
|
To: block.Header().Coinbase,
|
||||||
Input: nil,
|
Input: nil,
|
||||||
Origin: nil,
|
Origin: nil,
|
||||||
Block: block.Hash(), Timestamp: int64(block.Header().Time), Coinbase: block.Header().Coinbase, Number: block.Header().Number,
|
Timestamp: int64(block.Header().Time), Coinbase: block.Header().Coinbase, Number: block.Header().Number,
|
||||||
Value: new(big.Int).Add(reward, block.Reward),
|
Value: new(big.Int).Add(reward, block.Reward),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -271,15 +271,15 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
|
||||||
self.mu.RLock()
|
self.mu.RLock()
|
||||||
defer self.mu.RUnlock()
|
defer self.mu.RUnlock()
|
||||||
|
|
||||||
block := self.currentBlock
|
var block *types.Block
|
||||||
|
|
||||||
|
if num <= self.currentBlock.Number().Uint64() {
|
||||||
|
block = self.currentBlock
|
||||||
for ; block != nil; block = self.GetBlock(block.Header().ParentHash) {
|
for ; block != nil; block = self.GetBlock(block.Header().ParentHash) {
|
||||||
if block.Header().Number.Uint64() == num {
|
if block.Header().Number.Uint64() == num {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if block != nil && block.Header().Number.Uint64() == 0 && num != 0 {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return block
|
return block
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethutil"
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
"github.com/ethereum/go-ethereum/state"
|
"github.com/ethereum/go-ethereum/state"
|
||||||
|
@ -28,18 +27,17 @@ import (
|
||||||
* 6) Derive new state root
|
* 6) Derive new state root
|
||||||
*/
|
*/
|
||||||
type StateTransition struct {
|
type StateTransition struct {
|
||||||
coinbase, receiver []byte
|
coinbase []byte
|
||||||
msg Message
|
msg Message
|
||||||
gas, gasPrice *big.Int
|
gas, gasPrice *big.Int
|
||||||
initialGas *big.Int
|
initialGas *big.Int
|
||||||
value *big.Int
|
value *big.Int
|
||||||
data []byte
|
data []byte
|
||||||
state *state.StateDB
|
state *state.StateDB
|
||||||
block *types.Block
|
|
||||||
|
|
||||||
cb, rec, sen *state.StateObject
|
cb, rec, sen *state.StateObject
|
||||||
|
|
||||||
Env vm.Environment
|
env vm.Environment
|
||||||
}
|
}
|
||||||
|
|
||||||
type Message interface {
|
type Message interface {
|
||||||
|
@ -69,16 +67,19 @@ func MessageGasValue(msg Message) *big.Int {
|
||||||
return new(big.Int).Mul(msg.Gas(), msg.GasPrice())
|
return new(big.Int).Mul(msg.Gas(), msg.GasPrice())
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStateTransition(coinbase *state.StateObject, msg Message, state *state.StateDB, block *types.Block) *StateTransition {
|
func NewStateTransition(env vm.Environment, msg Message, coinbase *state.StateObject) *StateTransition {
|
||||||
return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), new(big.Int), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil}
|
return &StateTransition{
|
||||||
}
|
coinbase: coinbase.Address(),
|
||||||
|
env: env,
|
||||||
func (self *StateTransition) VmEnv() vm.Environment {
|
msg: msg,
|
||||||
if self.Env == nil {
|
gas: new(big.Int),
|
||||||
self.Env = NewEnv(self.state, self.msg, self.block)
|
gasPrice: new(big.Int).Set(msg.GasPrice()),
|
||||||
|
initialGas: new(big.Int),
|
||||||
|
value: msg.Value(),
|
||||||
|
data: msg.Data(),
|
||||||
|
state: env.State(),
|
||||||
|
cb: coinbase,
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.Env
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) Coinbase() *state.StateObject {
|
func (self *StateTransition) Coinbase() *state.StateObject {
|
||||||
|
@ -183,7 +184,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
vmenv := self.VmEnv()
|
vmenv := self.env
|
||||||
var ref vm.ContextRef
|
var ref vm.ContextRef
|
||||||
if MessageCreatesContract(msg) {
|
if MessageCreatesContract(msg) {
|
||||||
contract := MakeContract(msg, self.state)
|
contract := MakeContract(msg, self.state)
|
||||||
|
|
|
@ -13,10 +13,12 @@ type VMEnv struct {
|
||||||
block *types.Block
|
block *types.Block
|
||||||
msg Message
|
msg Message
|
||||||
depth int
|
depth int
|
||||||
|
chain *ChainManager
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEnv(state *state.StateDB, msg Message, block *types.Block) *VMEnv {
|
func NewEnv(state *state.StateDB, chain *ChainManager, msg Message, block *types.Block) *VMEnv {
|
||||||
return &VMEnv{
|
return &VMEnv{
|
||||||
|
chain: chain,
|
||||||
state: state,
|
state: state,
|
||||||
block: block,
|
block: block,
|
||||||
msg: msg,
|
msg: msg,
|
||||||
|
@ -25,16 +27,21 @@ func NewEnv(state *state.StateDB, msg Message, block *types.Block) *VMEnv {
|
||||||
|
|
||||||
func (self *VMEnv) Origin() []byte { return self.msg.From() }
|
func (self *VMEnv) Origin() []byte { return self.msg.From() }
|
||||||
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
|
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
|
||||||
func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
|
|
||||||
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
|
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
|
||||||
func (self *VMEnv) Time() int64 { return self.block.Time() }
|
func (self *VMEnv) Time() int64 { return self.block.Time() }
|
||||||
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
|
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
|
||||||
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
|
||||||
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
|
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
|
||||||
func (self *VMEnv) Value() *big.Int { return self.msg.Value() }
|
func (self *VMEnv) Value() *big.Int { return self.msg.Value() }
|
||||||
func (self *VMEnv) State() *state.StateDB { return self.state }
|
func (self *VMEnv) State() *state.StateDB { return self.state }
|
||||||
func (self *VMEnv) Depth() int { return self.depth }
|
func (self *VMEnv) Depth() int { return self.depth }
|
||||||
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
||||||
|
func (self *VMEnv) GetHash(n uint64) []byte {
|
||||||
|
if block := self.chain.GetBlockByNumber(n); block != nil {
|
||||||
|
return block.Hash()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
func (self *VMEnv) AddLog(log state.Log) {
|
func (self *VMEnv) AddLog(log state.Log) {
|
||||||
self.state.AddLog(log)
|
self.state.AddLog(log)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,12 @@ func (self *Manifest) AddMessage(msg *Message) *Message {
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Manifest) SetHash(hash []byte) {
|
||||||
|
for _, message := range self.Messages {
|
||||||
|
message.Block = hash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Messages []*Message
|
type Messages []*Message
|
||||||
type Message struct {
|
type Message struct {
|
||||||
To, From []byte
|
To, From []byte
|
||||||
|
|
|
@ -55,9 +55,11 @@ func (self *Env) PrevHash() []byte { return self.parent }
|
||||||
func (self *Env) Coinbase() []byte { return self.coinbase }
|
func (self *Env) Coinbase() []byte { return self.coinbase }
|
||||||
func (self *Env) Time() int64 { return self.time }
|
func (self *Env) Time() int64 { return self.time }
|
||||||
func (self *Env) Difficulty() *big.Int { return self.difficulty }
|
func (self *Env) Difficulty() *big.Int { return self.difficulty }
|
||||||
func (self *Env) BlockHash() []byte { return nil }
|
|
||||||
func (self *Env) State() *state.StateDB { return self.state }
|
func (self *Env) State() *state.StateDB { return self.state }
|
||||||
func (self *Env) GasLimit() *big.Int { return self.gasLimit }
|
func (self *Env) GasLimit() *big.Int { return self.gasLimit }
|
||||||
|
func (self *Env) GetHash(n uint64) []byte {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
func (self *Env) AddLog(log state.Log) {
|
func (self *Env) AddLog(log state.Log) {
|
||||||
self.logs = append(self.logs, log)
|
self.logs = append(self.logs, log)
|
||||||
}
|
}
|
||||||
|
@ -126,10 +128,9 @@ func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.
|
||||||
|
|
||||||
message := NewMessage(keyPair.Address(), to, data, value, gas, price)
|
message := NewMessage(keyPair.Address(), to, data, value, gas, price)
|
||||||
Log.DebugDetailf("message{ to: %x, from %x, value: %v, gas: %v, price: %v }\n", message.to[:4], message.from[:4], message.value, message.gas, message.price)
|
Log.DebugDetailf("message{ to: %x, from %x, value: %v, gas: %v, price: %v }\n", message.to[:4], message.from[:4], message.value, message.gas, message.price)
|
||||||
st := core.NewStateTransition(coinbase, message, statedb, nil)
|
|
||||||
vmenv := NewEnvFromMap(statedb, env, tx)
|
vmenv := NewEnvFromMap(statedb, env, tx)
|
||||||
|
st := core.NewStateTransition(vmenv, message, coinbase)
|
||||||
vmenv.origin = keyPair.Address()
|
vmenv.origin = keyPair.Address()
|
||||||
st.Env = vmenv
|
|
||||||
ret, err := st.TransitionState()
|
ret, err := st.TransitionState()
|
||||||
statedb.Update(vmenv.Gas)
|
statedb.Update(vmenv.Gas)
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,10 @@ type Environment interface {
|
||||||
|
|
||||||
Origin() []byte
|
Origin() []byte
|
||||||
BlockNumber() *big.Int
|
BlockNumber() *big.Int
|
||||||
PrevHash() []byte
|
GetHash(n uint64) []byte
|
||||||
Coinbase() []byte
|
Coinbase() []byte
|
||||||
Time() int64
|
Time() int64
|
||||||
Difficulty() *big.Int
|
Difficulty() *big.Int
|
||||||
BlockHash() []byte
|
|
||||||
GasLimit() *big.Int
|
GasLimit() *big.Int
|
||||||
Transfer(from, to Account, amount *big.Int) error
|
Transfer(from, to Account, amount *big.Int) error
|
||||||
AddLog(state.Log)
|
AddLog(state.Log)
|
||||||
|
|
|
@ -59,7 +59,7 @@ const (
|
||||||
const (
|
const (
|
||||||
|
|
||||||
// 0x40 range - block operations
|
// 0x40 range - block operations
|
||||||
PREVHASH OpCode = 0x40 + iota
|
BLOCKHASH OpCode = 0x40 + iota
|
||||||
COINBASE
|
COINBASE
|
||||||
TIMESTAMP
|
TIMESTAMP
|
||||||
NUMBER
|
NUMBER
|
||||||
|
@ -216,7 +216,7 @@ var opCodeToString = map[OpCode]string{
|
||||||
GASPRICE: "TXGASPRICE",
|
GASPRICE: "TXGASPRICE",
|
||||||
|
|
||||||
// 0x40 range - block operations
|
// 0x40 range - block operations
|
||||||
PREVHASH: "PREVHASH",
|
BLOCKHASH: "BLOCKHASH",
|
||||||
COINBASE: "COINBASE",
|
COINBASE: "COINBASE",
|
||||||
TIMESTAMP: "TIMESTAMP",
|
TIMESTAMP: "TIMESTAMP",
|
||||||
NUMBER: "NUMBER",
|
NUMBER: "NUMBER",
|
||||||
|
|
|
@ -44,7 +44,7 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *
|
||||||
To: me.Address(), From: caller.Address(),
|
To: me.Address(), From: caller.Address(),
|
||||||
Input: callData,
|
Input: callData,
|
||||||
Origin: self.env.Origin(),
|
Origin: self.env.Origin(),
|
||||||
Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
|
Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
|
||||||
Value: value,
|
Value: value,
|
||||||
})
|
})
|
||||||
context := NewContext(msg, caller, me, code, gas, price)
|
context := NewContext(msg, caller, me, code, gas, price)
|
||||||
|
@ -516,12 +516,15 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *
|
||||||
self.Printf(" => %v", context.Price)
|
self.Printf(" => %v", context.Price)
|
||||||
|
|
||||||
// 0x40 range
|
// 0x40 range
|
||||||
case PREVHASH:
|
case BLOCKHASH:
|
||||||
prevHash := self.env.PrevHash()
|
num := stack.Pop()
|
||||||
|
if num.Cmp(new(big.Int).Sub(self.env.BlockNumber(), ethutil.Big256)) < 0 {
|
||||||
|
stack.Push(ethutil.Big0)
|
||||||
|
} else {
|
||||||
|
stack.Push(ethutil.BigD(self.env.GetHash(num.Uint64())))
|
||||||
|
}
|
||||||
|
|
||||||
stack.Push(ethutil.BigD(prevHash))
|
self.Printf(" => 0x%x", stack.Peek().Bytes())
|
||||||
|
|
||||||
self.Printf(" => 0x%x", prevHash)
|
|
||||||
case COINBASE:
|
case COINBASE:
|
||||||
coinbase := self.env.Coinbase()
|
coinbase := self.env.Coinbase()
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ func (self *XEth) ExecuteObject(object *Object, data []byte, value, gas, price *
|
||||||
|
|
||||||
self.Vm.State = self.World().State().Copy()
|
self.Vm.State = self.World().State().Copy()
|
||||||
|
|
||||||
vmenv := NewEnv(self.Vm.State, block, value.BigInt(), initiator.Address())
|
vmenv := NewEnv(self.chainManager, self.Vm.State, block, value.BigInt(), initiator.Address())
|
||||||
return vmenv.Call(initiator, object.Address(), data, gas.BigInt(), price.BigInt(), value.BigInt())
|
return vmenv.Call(initiator, object.Address(), data, gas.BigInt(), price.BigInt(), value.BigInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type VMEnv struct {
|
type VMEnv struct {
|
||||||
|
chain *core.ChainManager
|
||||||
state *state.StateDB
|
state *state.StateDB
|
||||||
block *types.Block
|
block *types.Block
|
||||||
value *big.Int
|
value *big.Int
|
||||||
|
@ -18,7 +19,7 @@ type VMEnv struct {
|
||||||
depth int
|
depth int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEnv(state *state.StateDB, block *types.Block, value *big.Int, sender []byte) *VMEnv {
|
func NewEnv(chain *core.ChainManager, state *state.StateDB, block *types.Block, value *big.Int, sender []byte) *VMEnv {
|
||||||
return &VMEnv{
|
return &VMEnv{
|
||||||
state: state,
|
state: state,
|
||||||
block: block,
|
block: block,
|
||||||
|
@ -33,12 +34,18 @@ func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
|
||||||
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
|
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
|
||||||
func (self *VMEnv) Time() int64 { return self.block.Time() }
|
func (self *VMEnv) Time() int64 { return self.block.Time() }
|
||||||
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
|
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
|
||||||
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
|
||||||
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
|
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
|
||||||
func (self *VMEnv) Value() *big.Int { return self.value }
|
func (self *VMEnv) Value() *big.Int { return self.value }
|
||||||
func (self *VMEnv) State() *state.StateDB { return self.state }
|
func (self *VMEnv) State() *state.StateDB { return self.state }
|
||||||
func (self *VMEnv) Depth() int { return self.depth }
|
func (self *VMEnv) Depth() int { return self.depth }
|
||||||
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
func (self *VMEnv) SetDepth(i int) { self.depth = i }
|
||||||
|
func (self *VMEnv) GetHash(n uint64) []byte {
|
||||||
|
if block := self.chain.GetBlockByNumber(n); block != nil {
|
||||||
|
return block.Hash()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
func (self *VMEnv) AddLog(log state.Log) {
|
func (self *VMEnv) AddLog(log state.Log) {
|
||||||
self.state.AddLog(log)
|
self.state.AddLog(log)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue