Merge pull request #1881 from Gustav-Simonsson/state_new_error
core/state, core, miner: handle missing root error from state.New
This commit is contained in:
commit
b747754009
@ -113,7 +113,7 @@ func run(ctx *cli.Context) {
|
|||||||
glog.SetV(ctx.GlobalInt(VerbosityFlag.Name))
|
glog.SetV(ctx.GlobalInt(VerbosityFlag.Name))
|
||||||
|
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb := state.New(common.Hash{}, db)
|
statedb, _ := state.New(common.Hash{}, db)
|
||||||
sender := statedb.CreateAccount(common.StringToAddress("sender"))
|
sender := statedb.CreateAccount(common.StringToAddress("sender"))
|
||||||
receiver := statedb.CreateAccount(common.StringToAddress("receiver"))
|
receiver := statedb.CreateAccount(common.StringToAddress("receiver"))
|
||||||
receiver.SetCode(common.Hex2Bytes(ctx.GlobalString(CodeFlag.Name)))
|
receiver.SetCode(common.Hex2Bytes(ctx.GlobalString(CodeFlag.Name)))
|
||||||
|
@ -101,7 +101,8 @@ func runBlockTest(ctx *cli.Context) {
|
|||||||
|
|
||||||
func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, error) {
|
func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, error) {
|
||||||
cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx)
|
cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx)
|
||||||
cfg.NewDB = func(path string) (ethdb.Database, error) { return ethdb.NewMemDatabase() }
|
db, _ := ethdb.NewMemDatabase()
|
||||||
|
cfg.NewDB = func(path string) (ethdb.Database, error) { return db, nil }
|
||||||
cfg.MaxPeers = 0 // disable network
|
cfg.MaxPeers = 0 // disable network
|
||||||
cfg.Shh = false // disable whisper
|
cfg.Shh = false // disable whisper
|
||||||
cfg.NAT = nil // disable port mapping
|
cfg.NAT = nil // disable port mapping
|
||||||
@ -113,7 +114,7 @@ func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, er
|
|||||||
// import the genesis block
|
// import the genesis block
|
||||||
ethereum.ResetWithGenesisBlock(test.Genesis)
|
ethereum.ResetWithGenesisBlock(test.Genesis)
|
||||||
// import pre accounts
|
// import pre accounts
|
||||||
_, err = test.InsertPreState(ethereum)
|
_, err = test.InsertPreState(db, cfg.AccountManager)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethereum, fmt.Errorf("InsertPreState: %v", err)
|
return ethereum, fmt.Errorf("InsertPreState: %v", err)
|
||||||
}
|
}
|
||||||
@ -123,7 +124,10 @@ func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, er
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return ethereum, fmt.Errorf("Block Test load error: %v", err)
|
return ethereum, fmt.Errorf("Block Test load error: %v", err)
|
||||||
}
|
}
|
||||||
newDB := cm.State()
|
newDB, err := cm.State()
|
||||||
|
if err != nil {
|
||||||
|
return ethereum, fmt.Errorf("Block Test get state error: %v", err)
|
||||||
|
}
|
||||||
if err := test.ValidatePostState(newDB); err != nil {
|
if err := test.ValidatePostState(newDB); err != nil {
|
||||||
return ethereum, fmt.Errorf("post state validation failed: %v", err)
|
return ethereum, fmt.Errorf("post state validation failed: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,11 @@ func dump(ctx *cli.Context) {
|
|||||||
fmt.Println("{}")
|
fmt.Println("{}")
|
||||||
utils.Fatalf("block not found")
|
utils.Fatalf("block not found")
|
||||||
} else {
|
} else {
|
||||||
state := state.New(block.Root(), chainDb)
|
state, err := state.New(block.Root(), chainDb)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("could not create new state: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
fmt.Printf("%s\n", state.Dump())
|
fmt.Printf("%s\n", state.Dump())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,10 @@ func (sm *BlockProcessor) Process(block *types.Block) (logs vm.Logs, receipts ty
|
|||||||
|
|
||||||
func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs vm.Logs, receipts types.Receipts, err error) {
|
func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs vm.Logs, receipts types.Receipts, err error) {
|
||||||
// Create a new state based on the parent's root (e.g., create copy)
|
// Create a new state based on the parent's root (e.g., create copy)
|
||||||
state := state.New(parent.Root(), sm.chainDb)
|
state, err := state.New(parent.Root(), sm.chainDb)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
header := block.Header()
|
header := block.Header()
|
||||||
uncles := block.Uncles()
|
uncles := block.Uncles()
|
||||||
txs := block.Transactions()
|
txs := block.Transactions()
|
||||||
|
@ -46,7 +46,7 @@ func TestNumber(t *testing.T) {
|
|||||||
pow := ezp.New()
|
pow := ezp.New()
|
||||||
_, chain := proc()
|
_, chain := proc()
|
||||||
|
|
||||||
statedb := state.New(chain.Genesis().Root(), chain.chainDb)
|
statedb, _ := state.New(chain.Genesis().Root(), chain.chainDb)
|
||||||
header := makeHeader(chain.Genesis(), statedb)
|
header := makeHeader(chain.Genesis(), statedb)
|
||||||
header.Number = big.NewInt(3)
|
header.Number = big.NewInt(3)
|
||||||
err := ValidateHeader(pow, header, chain.Genesis().Header(), false, false)
|
err := ValidateHeader(pow, header, chain.Genesis().Header(), false, false)
|
||||||
|
@ -199,7 +199,7 @@ func (self *BlockChain) SetProcessor(proc types.BlockProcessor) {
|
|||||||
self.processor = proc
|
self.processor = proc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *BlockChain) State() *state.StateDB {
|
func (self *BlockChain) State() (*state.StateDB, error) {
|
||||||
return state.New(self.CurrentBlock().Root(), self.chainDb)
|
return state.New(self.CurrentBlock().Root(), self.chainDb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,10 @@ func (b *BlockGen) OffsetTime(seconds int64) {
|
|||||||
// values. Inserting them into BlockChain requires use of FakePow or
|
// values. Inserting them into BlockChain requires use of FakePow or
|
||||||
// a similar non-validating proof of work implementation.
|
// a similar non-validating proof of work implementation.
|
||||||
func GenerateChain(parent *types.Block, db ethdb.Database, n int, gen func(int, *BlockGen)) []*types.Block {
|
func GenerateChain(parent *types.Block, db ethdb.Database, n int, gen func(int, *BlockGen)) []*types.Block {
|
||||||
statedb := state.New(parent.Root(), db)
|
statedb, err := state.New(parent.Root(), db)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
blocks := make(types.Blocks, n)
|
blocks := make(types.Blocks, n)
|
||||||
genblock := func(i int, h *types.Header) *types.Block {
|
genblock := func(i int, h *types.Header) *types.Block {
|
||||||
b := &BlockGen{parent: parent, i: i, chain: blocks, header: h, statedb: statedb}
|
b := &BlockGen{parent: parent, i: i, chain: blocks, header: h, statedb: statedb}
|
||||||
|
@ -84,7 +84,7 @@ func ExampleGenerateChain() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
state := chainman.State()
|
state, _ := chainman.State()
|
||||||
fmt.Printf("last block: #%d\n", chainman.CurrentBlock().Number())
|
fmt.Printf("last block: #%d\n", chainman.CurrentBlock().Number())
|
||||||
fmt.Println("balance of addr1:", state.GetBalance(addr1))
|
fmt.Println("balance of addr1:", state.GetBalance(addr1))
|
||||||
fmt.Println("balance of addr2:", state.GetBalance(addr2))
|
fmt.Println("balance of addr2:", state.GetBalance(addr2))
|
||||||
|
@ -60,7 +60,8 @@ func WriteGenesisBlock(chainDb ethdb.Database, reader io.Reader) (*types.Block,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
statedb := state.New(common.Hash{}, chainDb)
|
// creating with empty hash always works
|
||||||
|
statedb, _ := state.New(common.Hash{}, chainDb)
|
||||||
for addr, account := range genesis.Alloc {
|
for addr, account := range genesis.Alloc {
|
||||||
address := common.HexToAddress(addr)
|
address := common.HexToAddress(addr)
|
||||||
statedb.AddBalance(address, common.String2Big(account.Balance))
|
statedb.AddBalance(address, common.String2Big(account.Balance))
|
||||||
@ -115,9 +116,9 @@ func WriteGenesisBlock(chainDb ethdb.Database, reader io.Reader) (*types.Block,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GenesisBlockForTesting creates a block in which addr has the given wei balance.
|
// GenesisBlockForTesting creates a block in which addr has the given wei balance.
|
||||||
// The state trie of the block is written to db.
|
// The state trie of the block is written to db. the passed db needs to contain a state root
|
||||||
func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
|
func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
|
||||||
statedb := state.New(common.Hash{}, db)
|
statedb, _ := state.New(common.Hash{}, db)
|
||||||
obj := statedb.GetOrNewStateObject(addr)
|
obj := statedb.GetOrNewStateObject(addr)
|
||||||
obj.SetBalance(balance)
|
obj.SetBalance(balance)
|
||||||
root, err := statedb.Commit()
|
root, err := statedb.Commit()
|
||||||
|
@ -27,7 +27,7 @@ var addr = common.BytesToAddress([]byte("test"))
|
|||||||
|
|
||||||
func create() (*ManagedState, *account) {
|
func create() (*ManagedState, *account) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb := New(common.Hash{}, db)
|
statedb, _ := New(common.Hash{}, db)
|
||||||
ms := ManageState(statedb)
|
ms := ManageState(statedb)
|
||||||
so := &StateObject{address: addr, nonce: 100}
|
so := &StateObject{address: addr, nonce: 100}
|
||||||
ms.StateDB.stateObjects[addr.Str()] = so
|
ms.StateDB.stateObjects[addr.Str()] = so
|
||||||
|
@ -77,12 +77,12 @@ func (s *StateSuite) TestDump(c *checker.C) {
|
|||||||
|
|
||||||
func (s *StateSuite) SetUpTest(c *checker.C) {
|
func (s *StateSuite) SetUpTest(c *checker.C) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
s.state = New(common.Hash{}, db)
|
s.state, _ = New(common.Hash{}, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNull(t *testing.T) {
|
func TestNull(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
state := New(common.Hash{}, db)
|
state, _ := New(common.Hash{}, db)
|
||||||
|
|
||||||
address := common.HexToAddress("0x823140710bf13990e4500136726d8b55")
|
address := common.HexToAddress("0x823140710bf13990e4500136726d8b55")
|
||||||
state.CreateAccount(address)
|
state.CreateAccount(address)
|
||||||
@ -122,7 +122,7 @@ func (s *StateSuite) TestSnapshot(c *checker.C) {
|
|||||||
// printing/logging in tests (-check.vv does not work)
|
// printing/logging in tests (-check.vv does not work)
|
||||||
func TestSnapshot2(t *testing.T) {
|
func TestSnapshot2(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
state := New(common.Hash{}, db)
|
state, _ := New(common.Hash{}, db)
|
||||||
|
|
||||||
stateobjaddr0 := toAddr([]byte("so0"))
|
stateobjaddr0 := toAddr([]byte("so0"))
|
||||||
stateobjaddr1 := toAddr([]byte("so1"))
|
stateobjaddr1 := toAddr([]byte("so1"))
|
||||||
|
@ -52,12 +52,11 @@ type StateDB struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new state from a given trie
|
// Create a new state from a given trie
|
||||||
func New(root common.Hash, db ethdb.Database) *StateDB {
|
func New(root common.Hash, db ethdb.Database) (*StateDB, error) {
|
||||||
tr, err := trie.NewSecure(root, db)
|
tr, err := trie.NewSecure(root, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: bubble this up
|
|
||||||
tr, _ = trie.NewSecure(common.Hash{}, db)
|
|
||||||
glog.Errorf("can't create state trie with root %x: %v", root[:], err)
|
glog.Errorf("can't create state trie with root %x: %v", root[:], err)
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
return &StateDB{
|
return &StateDB{
|
||||||
db: db,
|
db: db,
|
||||||
@ -65,7 +64,7 @@ func New(root common.Hash, db ethdb.Database) *StateDB {
|
|||||||
stateObjects: make(map[string]*StateObject),
|
stateObjects: make(map[string]*StateObject),
|
||||||
refund: new(big.Int),
|
refund: new(big.Int),
|
||||||
logs: make(map[common.Hash]vm.Logs),
|
logs: make(map[common.Hash]vm.Logs),
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) StartRecord(thash, bhash common.Hash, ti int) {
|
func (self *StateDB) StartRecord(thash, bhash common.Hash, ti int) {
|
||||||
@ -297,7 +296,8 @@ func (self *StateDB) CreateAccount(addr common.Address) vm.Account {
|
|||||||
//
|
//
|
||||||
|
|
||||||
func (self *StateDB) Copy() *StateDB {
|
func (self *StateDB) Copy() *StateDB {
|
||||||
state := New(common.Hash{}, self.db)
|
// ignore error - we assume state-to-be-copied always exists
|
||||||
|
state, _ := New(common.Hash{}, self.db)
|
||||||
state.trie = self.trie
|
state.trie = self.trie
|
||||||
for k, stateObject := range self.stateObjects {
|
for k, stateObject := range self.stateObjects {
|
||||||
state.stateObjects[k] = stateObject.Copy()
|
state.stateObjects[k] = stateObject.Copy()
|
||||||
|
@ -48,7 +48,7 @@ const (
|
|||||||
maxQueued = 64 // max limit of queued txs per address
|
maxQueued = 64 // max limit of queued txs per address
|
||||||
)
|
)
|
||||||
|
|
||||||
type stateFn func() *state.StateDB
|
type stateFn func() (*state.StateDB, error)
|
||||||
|
|
||||||
// TxPool contains all currently known transactions. Transactions
|
// TxPool contains all currently known transactions. Transactions
|
||||||
// enter the pool when they are received from the network or submitted
|
// enter the pool when they are received from the network or submitted
|
||||||
@ -80,7 +80,7 @@ func NewTxPool(eventMux *event.TypeMux, currentStateFn stateFn, gasLimitFn func(
|
|||||||
currentState: currentStateFn,
|
currentState: currentStateFn,
|
||||||
gasLimit: gasLimitFn,
|
gasLimit: gasLimitFn,
|
||||||
minGasPrice: new(big.Int),
|
minGasPrice: new(big.Int),
|
||||||
pendingState: state.ManageState(currentStateFn()),
|
pendingState: nil,
|
||||||
events: eventMux.Subscribe(ChainHeadEvent{}, GasPriceChanged{}, RemovedTransactionEvent{}),
|
events: eventMux.Subscribe(ChainHeadEvent{}, GasPriceChanged{}, RemovedTransactionEvent{}),
|
||||||
}
|
}
|
||||||
go pool.eventLoop()
|
go pool.eventLoop()
|
||||||
@ -109,7 +109,17 @@ func (pool *TxPool) eventLoop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pool *TxPool) resetState() {
|
func (pool *TxPool) resetState() {
|
||||||
pool.pendingState = state.ManageState(pool.currentState())
|
currentState, err := pool.currentState()
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Info).Infoln("failed to get current state: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
managedState := state.ManageState(currentState)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Info).Infoln("failed to get managed state: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pool.pendingState = managedState
|
||||||
|
|
||||||
// validate the pool of pending transactions, this will remove
|
// validate the pool of pending transactions, this will remove
|
||||||
// any transactions that have been included in the block or
|
// any transactions that have been included in the block or
|
||||||
@ -180,12 +190,16 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error {
|
|||||||
|
|
||||||
// Make sure the account exist. Non existent accounts
|
// Make sure the account exist. Non existent accounts
|
||||||
// haven't got funds and well therefor never pass.
|
// haven't got funds and well therefor never pass.
|
||||||
if !pool.currentState().HasAccount(from) {
|
currentState, err := pool.currentState()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !currentState.HasAccount(from) {
|
||||||
return ErrNonExistentAccount
|
return ErrNonExistentAccount
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last but not least check for nonce errors
|
// Last but not least check for nonce errors
|
||||||
if pool.currentState().GetNonce(from) > tx.Nonce() {
|
if currentState.GetNonce(from) > tx.Nonce() {
|
||||||
return ErrNonce
|
return ErrNonce
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +218,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error {
|
|||||||
|
|
||||||
// Transactor should have enough funds to cover the costs
|
// Transactor should have enough funds to cover the costs
|
||||||
// cost == V + GP * GL
|
// cost == V + GP * GL
|
||||||
if pool.currentState().GetBalance(from).Cmp(tx.Cost()) < 0 {
|
if currentState.GetBalance(from).Cmp(tx.Cost()) < 0 {
|
||||||
return ErrInsufficientFunds
|
return ErrInsufficientFunds
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,6 +271,11 @@ func (self *TxPool) queueTx(hash common.Hash, tx *types.Transaction) {
|
|||||||
|
|
||||||
// addTx will add a transaction to the pending (processable queue) list of transactions
|
// addTx will add a transaction to the pending (processable queue) list of transactions
|
||||||
func (pool *TxPool) addTx(hash common.Hash, addr common.Address, tx *types.Transaction) {
|
func (pool *TxPool) addTx(hash common.Hash, addr common.Address, tx *types.Transaction) {
|
||||||
|
// init delayed since tx pool could have been started before any state sync
|
||||||
|
if pool.pendingState == nil {
|
||||||
|
pool.resetState()
|
||||||
|
}
|
||||||
|
|
||||||
if _, ok := pool.pending[hash]; !ok {
|
if _, ok := pool.pending[hash]; !ok {
|
||||||
pool.pending[hash] = tx
|
pool.pending[hash] = tx
|
||||||
|
|
||||||
@ -382,14 +401,22 @@ func (pool *TxPool) RemoveTx(hash common.Hash) {
|
|||||||
|
|
||||||
// checkQueue moves transactions that have become processable to main pool.
|
// checkQueue moves transactions that have become processable to main pool.
|
||||||
func (pool *TxPool) checkQueue() {
|
func (pool *TxPool) checkQueue() {
|
||||||
state := pool.pendingState
|
// init delayed since tx pool could have been started before any state sync
|
||||||
|
if pool.pendingState == nil {
|
||||||
|
pool.resetState()
|
||||||
|
}
|
||||||
|
|
||||||
var addq txQueue
|
var addq txQueue
|
||||||
for address, txs := range pool.queue {
|
for address, txs := range pool.queue {
|
||||||
// guessed nonce is the nonce currently kept by the tx pool (pending state)
|
// guessed nonce is the nonce currently kept by the tx pool (pending state)
|
||||||
guessedNonce := state.GetNonce(address)
|
guessedNonce := pool.pendingState.GetNonce(address)
|
||||||
// true nonce is the nonce known by the last state
|
// true nonce is the nonce known by the last state
|
||||||
trueNonce := pool.currentState().GetNonce(address)
|
currentState, err := pool.currentState()
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("could not get current state: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
trueNonce := currentState.GetNonce(address)
|
||||||
addq := addq[:0]
|
addq := addq[:0]
|
||||||
for hash, tx := range txs {
|
for hash, tx := range txs {
|
||||||
if tx.Nonce() < trueNonce {
|
if tx.Nonce() < trueNonce {
|
||||||
@ -434,7 +461,11 @@ func (pool *TxPool) checkQueue() {
|
|||||||
|
|
||||||
// validatePool removes invalid and processed transactions from the main pool.
|
// validatePool removes invalid and processed transactions from the main pool.
|
||||||
func (pool *TxPool) validatePool() {
|
func (pool *TxPool) validatePool() {
|
||||||
state := pool.currentState()
|
state, err := pool.currentState()
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Info).Infoln("failed to get current state: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
for hash, tx := range pool.pending {
|
for hash, tx := range pool.pending {
|
||||||
from, _ := tx.From() // err already checked
|
from, _ := tx.From() // err already checked
|
||||||
// perform light nonce validation
|
// perform light nonce validation
|
||||||
|
@ -36,11 +36,13 @@ func transaction(nonce uint64, gaslimit *big.Int, key *ecdsa.PrivateKey) *types.
|
|||||||
|
|
||||||
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
|
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb := state.New(common.Hash{}, db)
|
statedb, _ := state.New(common.Hash{}, db)
|
||||||
|
|
||||||
var m event.TypeMux
|
var m event.TypeMux
|
||||||
key, _ := crypto.GenerateKey()
|
key, _ := crypto.GenerateKey()
|
||||||
return NewTxPool(&m, func() *state.StateDB { return statedb }, func() *big.Int { return big.NewInt(1000000) }), key
|
newPool := NewTxPool(&m, func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
|
||||||
|
newPool.resetState()
|
||||||
|
return newPool, key
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInvalidTransactions(t *testing.T) {
|
func TestInvalidTransactions(t *testing.T) {
|
||||||
@ -52,19 +54,20 @@ func TestInvalidTransactions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
from, _ := tx.From()
|
from, _ := tx.From()
|
||||||
pool.currentState().AddBalance(from, big.NewInt(1))
|
currentState, _ := pool.currentState()
|
||||||
|
currentState.AddBalance(from, big.NewInt(1))
|
||||||
if err := pool.Add(tx); err != ErrInsufficientFunds {
|
if err := pool.Add(tx); err != ErrInsufficientFunds {
|
||||||
t.Error("expected", ErrInsufficientFunds)
|
t.Error("expected", ErrInsufficientFunds)
|
||||||
}
|
}
|
||||||
|
|
||||||
balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(tx.Gas(), tx.GasPrice()))
|
balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(tx.Gas(), tx.GasPrice()))
|
||||||
pool.currentState().AddBalance(from, balance)
|
currentState.AddBalance(from, balance)
|
||||||
if err := pool.Add(tx); err != ErrIntrinsicGas {
|
if err := pool.Add(tx); err != ErrIntrinsicGas {
|
||||||
t.Error("expected", ErrIntrinsicGas, "got", err)
|
t.Error("expected", ErrIntrinsicGas, "got", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pool.currentState().SetNonce(from, 1)
|
currentState.SetNonce(from, 1)
|
||||||
pool.currentState().AddBalance(from, big.NewInt(0xffffffffffffff))
|
currentState.AddBalance(from, big.NewInt(0xffffffffffffff))
|
||||||
tx = transaction(0, big.NewInt(100000), key)
|
tx = transaction(0, big.NewInt(100000), key)
|
||||||
if err := pool.Add(tx); err != ErrNonce {
|
if err := pool.Add(tx); err != ErrNonce {
|
||||||
t.Error("expected", ErrNonce)
|
t.Error("expected", ErrNonce)
|
||||||
@ -75,7 +78,8 @@ func TestTransactionQueue(t *testing.T) {
|
|||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
tx := transaction(0, big.NewInt(100), key)
|
tx := transaction(0, big.NewInt(100), key)
|
||||||
from, _ := tx.From()
|
from, _ := tx.From()
|
||||||
pool.currentState().AddBalance(from, big.NewInt(1))
|
currentState, _ := pool.currentState()
|
||||||
|
currentState.AddBalance(from, big.NewInt(1))
|
||||||
pool.queueTx(tx.Hash(), tx)
|
pool.queueTx(tx.Hash(), tx)
|
||||||
|
|
||||||
pool.checkQueue()
|
pool.checkQueue()
|
||||||
@ -85,7 +89,7 @@ func TestTransactionQueue(t *testing.T) {
|
|||||||
|
|
||||||
tx = transaction(1, big.NewInt(100), key)
|
tx = transaction(1, big.NewInt(100), key)
|
||||||
from, _ = tx.From()
|
from, _ = tx.From()
|
||||||
pool.currentState().SetNonce(from, 2)
|
currentState.SetNonce(from, 2)
|
||||||
pool.queueTx(tx.Hash(), tx)
|
pool.queueTx(tx.Hash(), tx)
|
||||||
pool.checkQueue()
|
pool.checkQueue()
|
||||||
if _, ok := pool.pending[tx.Hash()]; ok {
|
if _, ok := pool.pending[tx.Hash()]; ok {
|
||||||
@ -119,7 +123,8 @@ func TestRemoveTx(t *testing.T) {
|
|||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
tx := transaction(0, big.NewInt(100), key)
|
tx := transaction(0, big.NewInt(100), key)
|
||||||
from, _ := tx.From()
|
from, _ := tx.From()
|
||||||
pool.currentState().AddBalance(from, big.NewInt(1))
|
currentState, _ := pool.currentState()
|
||||||
|
currentState.AddBalance(from, big.NewInt(1))
|
||||||
pool.queueTx(tx.Hash(), tx)
|
pool.queueTx(tx.Hash(), tx)
|
||||||
pool.addTx(tx.Hash(), from, tx)
|
pool.addTx(tx.Hash(), from, tx)
|
||||||
if len(pool.queue) != 1 {
|
if len(pool.queue) != 1 {
|
||||||
@ -146,7 +151,8 @@ func TestNegativeValue(t *testing.T) {
|
|||||||
|
|
||||||
tx, _ := types.NewTransaction(0, common.Address{}, big.NewInt(-1), big.NewInt(100), big.NewInt(1), nil).SignECDSA(key)
|
tx, _ := types.NewTransaction(0, common.Address{}, big.NewInt(-1), big.NewInt(100), big.NewInt(1), nil).SignECDSA(key)
|
||||||
from, _ := tx.From()
|
from, _ := tx.From()
|
||||||
pool.currentState().AddBalance(from, big.NewInt(1))
|
currentState, _ := pool.currentState()
|
||||||
|
currentState.AddBalance(from, big.NewInt(1))
|
||||||
if err := pool.Add(tx); err != ErrNegativeValue {
|
if err := pool.Add(tx); err != ErrNegativeValue {
|
||||||
t.Error("expected", ErrNegativeValue, "got", err)
|
t.Error("expected", ErrNegativeValue, "got", err)
|
||||||
}
|
}
|
||||||
@ -157,9 +163,10 @@ func TestTransactionChainFork(t *testing.T) {
|
|||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
resetState := func() {
|
resetState := func() {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb := state.New(common.Hash{}, db)
|
statedb, _ := state.New(common.Hash{}, db)
|
||||||
pool.currentState = func() *state.StateDB { return statedb }
|
pool.currentState = func() (*state.StateDB, error) { return statedb, nil }
|
||||||
pool.currentState().AddBalance(addr, big.NewInt(100000000000000))
|
currentState, _ := pool.currentState()
|
||||||
|
currentState.AddBalance(addr, big.NewInt(100000000000000))
|
||||||
pool.resetState()
|
pool.resetState()
|
||||||
}
|
}
|
||||||
resetState()
|
resetState()
|
||||||
@ -182,9 +189,10 @@ func TestTransactionDoubleNonce(t *testing.T) {
|
|||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
resetState := func() {
|
resetState := func() {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb := state.New(common.Hash{}, db)
|
statedb, _ := state.New(common.Hash{}, db)
|
||||||
pool.currentState = func() *state.StateDB { return statedb }
|
pool.currentState = func() (*state.StateDB, error) { return statedb, nil }
|
||||||
pool.currentState().AddBalance(addr, big.NewInt(100000000000000))
|
currentState, _ := pool.currentState()
|
||||||
|
currentState.AddBalance(addr, big.NewInt(100000000000000))
|
||||||
pool.resetState()
|
pool.resetState()
|
||||||
}
|
}
|
||||||
resetState()
|
resetState()
|
||||||
@ -207,7 +215,8 @@ func TestTransactionDoubleNonce(t *testing.T) {
|
|||||||
func TestMissingNonce(t *testing.T) {
|
func TestMissingNonce(t *testing.T) {
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
pool.currentState().AddBalance(addr, big.NewInt(100000000000000))
|
currentState, _ := pool.currentState()
|
||||||
|
currentState.AddBalance(addr, big.NewInt(100000000000000))
|
||||||
tx := transaction(1, big.NewInt(100000), key)
|
tx := transaction(1, big.NewInt(100000), key)
|
||||||
if err := pool.add(tx); err != nil {
|
if err := pool.add(tx); err != nil {
|
||||||
t.Error("didn't expect error", err)
|
t.Error("didn't expect error", err)
|
||||||
@ -224,15 +233,16 @@ func TestNonceRecovery(t *testing.T) {
|
|||||||
const n = 10
|
const n = 10
|
||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
pool.currentState().SetNonce(addr, n)
|
currentState, _ := pool.currentState()
|
||||||
pool.currentState().AddBalance(addr, big.NewInt(100000000000000))
|
currentState.SetNonce(addr, n)
|
||||||
|
currentState.AddBalance(addr, big.NewInt(100000000000000))
|
||||||
pool.resetState()
|
pool.resetState()
|
||||||
tx := transaction(n, big.NewInt(100000), key)
|
tx := transaction(n, big.NewInt(100000), key)
|
||||||
if err := pool.Add(tx); err != nil {
|
if err := pool.Add(tx); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
// simulate some weird re-order of transactions and missing nonce(s)
|
// simulate some weird re-order of transactions and missing nonce(s)
|
||||||
pool.currentState().SetNonce(addr, n-1)
|
currentState.SetNonce(addr, n-1)
|
||||||
pool.resetState()
|
pool.resetState()
|
||||||
if fn := pool.pendingState.GetNonce(addr); fn != n+1 {
|
if fn := pool.pendingState.GetNonce(addr); fn != n+1 {
|
||||||
t.Errorf("expected nonce to be %d, got %d", n+1, fn)
|
t.Errorf("expected nonce to be %d, got %d", n+1, fn)
|
||||||
@ -243,7 +253,8 @@ func TestRemovedTxEvent(t *testing.T) {
|
|||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
tx := transaction(0, big.NewInt(1000000), key)
|
tx := transaction(0, big.NewInt(1000000), key)
|
||||||
from, _ := tx.From()
|
from, _ := tx.From()
|
||||||
pool.currentState().AddBalance(from, big.NewInt(1000000000000))
|
currentState, _ := pool.currentState()
|
||||||
|
currentState.AddBalance(from, big.NewInt(1000000000000))
|
||||||
pool.eventMux.Post(RemovedTransactionEvent{types.Transactions{tx}})
|
pool.eventMux.Post(RemovedTransactionEvent{types.Transactions{tx}})
|
||||||
pool.eventMux.Post(ChainHeadEvent{nil})
|
pool.eventMux.Post(ChainHeadEvent{nil})
|
||||||
if len(pool.pending) != 1 {
|
if len(pool.pending) != 1 {
|
||||||
|
@ -389,7 +389,8 @@ func New(config *Config) (*Ethereum, error) {
|
|||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
eth.txPool = core.NewTxPool(eth.EventMux(), eth.blockchain.State, eth.blockchain.GasLimit)
|
newPool := core.NewTxPool(eth.EventMux(), eth.blockchain.State, eth.blockchain.GasLimit)
|
||||||
|
eth.txPool = newPool
|
||||||
|
|
||||||
eth.blockProcessor = core.NewBlockProcessor(chainDb, eth.pow, eth.blockchain, eth.EventMux())
|
eth.blockProcessor = core.NewBlockProcessor(chainDb, eth.pow, eth.blockchain, eth.EventMux())
|
||||||
eth.blockchain.SetProcessor(eth.blockProcessor)
|
eth.blockchain.SetProcessor(eth.blockProcessor)
|
||||||
|
@ -443,10 +443,11 @@ func testGetNodeData(t *testing.T, protocol int) {
|
|||||||
}
|
}
|
||||||
accounts := []common.Address{testBankAddress, acc1Addr, acc2Addr}
|
accounts := []common.Address{testBankAddress, acc1Addr, acc2Addr}
|
||||||
for i := uint64(0); i <= pm.blockchain.CurrentBlock().NumberU64(); i++ {
|
for i := uint64(0); i <= pm.blockchain.CurrentBlock().NumberU64(); i++ {
|
||||||
trie := state.New(pm.blockchain.GetBlockByNumber(i).Root(), statedb)
|
trie, _ := state.New(pm.blockchain.GetBlockByNumber(i).Root(), statedb)
|
||||||
|
|
||||||
for j, acc := range accounts {
|
for j, acc := range accounts {
|
||||||
bw := pm.blockchain.State().GetBalance(acc)
|
state, _ := pm.blockchain.State()
|
||||||
|
bw := state.GetBalance(acc)
|
||||||
bh := trie.GetBalance(acc)
|
bh := trie.GetBalance(acc)
|
||||||
|
|
||||||
if (bw != nil && bh == nil) || (bw == nil && bh != nil) {
|
if (bw != nil && bh == nil) || (bw == nil && bh != nil) {
|
||||||
|
@ -38,7 +38,8 @@ func newTestProtocolManager(blocks int, generator func(int, *core.BlockGen), new
|
|||||||
blockproc = core.NewBlockProcessor(db, pow, blockchain, evmux)
|
blockproc = core.NewBlockProcessor(db, pow, blockchain, evmux)
|
||||||
)
|
)
|
||||||
blockchain.SetProcessor(blockproc)
|
blockchain.SetProcessor(blockproc)
|
||||||
if _, err := blockchain.InsertChain(core.GenerateChain(genesis, db, blocks, generator)); err != nil {
|
chain := core.GenerateChain(genesis, db, blocks, generator)
|
||||||
|
if _, err := blockchain.InsertChain(chain); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
pm := NewProtocolManager(NetworkId, evmux, &testTxPool{added: newtx}, pow, blockchain, db)
|
pm := NewProtocolManager(NetworkId, evmux, &testTxPool{added: newtx}, pow, blockchain, db)
|
||||||
|
@ -353,8 +353,11 @@ func (self *worker) push(work *Work) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// makeCurrent creates a new environment for the current cycle.
|
// makeCurrent creates a new environment for the current cycle.
|
||||||
func (self *worker) makeCurrent(parent *types.Block, header *types.Header) {
|
func (self *worker) makeCurrent(parent *types.Block, header *types.Header) error {
|
||||||
state := state.New(parent.Root(), self.eth.ChainDb())
|
state, err := state.New(parent.Root(), self.eth.ChainDb())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
work := &Work{
|
work := &Work{
|
||||||
state: state,
|
state: state,
|
||||||
ancestors: set.New(),
|
ancestors: set.New(),
|
||||||
@ -385,6 +388,7 @@ func (self *worker) makeCurrent(parent *types.Block, header *types.Header) {
|
|||||||
work.localMinedBlocks = self.current.localMinedBlocks
|
work.localMinedBlocks = self.current.localMinedBlocks
|
||||||
}
|
}
|
||||||
self.current = work
|
self.current = work
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worker) setGasPrice(p *big.Int) {
|
func (w *worker) setGasPrice(p *big.Int) {
|
||||||
@ -464,7 +468,12 @@ func (self *worker) commitNewWork() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
previous := self.current
|
previous := self.current
|
||||||
self.makeCurrent(parent, header)
|
// Could potentially happen if starting to mine in an odd state.
|
||||||
|
err := self.makeCurrent(parent, header)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Info).Infoln("Could not create new env for mining, retrying on next block.")
|
||||||
|
return
|
||||||
|
}
|
||||||
work := self.current
|
work := self.current
|
||||||
|
|
||||||
/* //approach 1
|
/* //approach 1
|
||||||
|
@ -119,9 +119,9 @@ func (self *debugApi) DumpBlock(req *shared.Request) (interface{}, error) {
|
|||||||
return nil, fmt.Errorf("block #%d not found", args.BlockNumber)
|
return nil, fmt.Errorf("block #%d not found", args.BlockNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
stateDb := state.New(block.Root(), self.ethereum.ChainDb())
|
stateDb, err := state.New(block.Root(), self.ethereum.ChainDb())
|
||||||
if stateDb == nil {
|
if err != nil {
|
||||||
return nil, nil
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return stateDb.RawDump(), nil
|
return stateDb.RawDump(), nil
|
||||||
|
@ -162,9 +162,25 @@ func runBlockTests(bt map[string]*BlockTest, skipTests []string) error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
func runBlockTest(test *BlockTest) error {
|
func runBlockTest(test *BlockTest) error {
|
||||||
cfg := test.makeEthConfig()
|
ks := crypto.NewKeyStorePassphrase(filepath.Join(common.DefaultDataDir(), "keystore"))
|
||||||
|
am := accounts.NewManager(ks)
|
||||||
|
db, _ := ethdb.NewMemDatabase()
|
||||||
|
cfg := ð.Config{
|
||||||
|
DataDir: common.DefaultDataDir(),
|
||||||
|
Verbosity: 5,
|
||||||
|
Etherbase: common.Address{},
|
||||||
|
AccountManager: am,
|
||||||
|
NewDB: func(path string) (ethdb.Database, error) { return db, nil },
|
||||||
|
}
|
||||||
|
|
||||||
cfg.GenesisBlock = test.Genesis
|
cfg.GenesisBlock = test.Genesis
|
||||||
|
|
||||||
|
// import pre accounts & construct test genesis block & state root
|
||||||
|
_, err := test.InsertPreState(db, am)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("InsertPreState: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
ethereum, err := eth.New(cfg)
|
ethereum, err := eth.New(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -175,12 +191,6 @@ func runBlockTest(test *BlockTest) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// import pre accounts
|
|
||||||
_, err = test.InsertPreState(ethereum)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("InsertPreState: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cm := ethereum.BlockChain()
|
cm := ethereum.BlockChain()
|
||||||
validBlocks, err := test.TryBlocksInsert(cm)
|
validBlocks, err := test.TryBlocksInsert(cm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -193,7 +203,10 @@ func runBlockTest(test *BlockTest) error {
|
|||||||
return fmt.Errorf("lastblockhash validation mismatch: want: %x, have: %x", lastblockhash, cmlast)
|
return fmt.Errorf("lastblockhash validation mismatch: want: %x, have: %x", lastblockhash, cmlast)
|
||||||
}
|
}
|
||||||
|
|
||||||
newDB := cm.State()
|
newDB, err := cm.State()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err = test.ValidatePostState(newDB); err != nil {
|
if err = test.ValidatePostState(newDB); err != nil {
|
||||||
return fmt.Errorf("post state validation failed: %v", err)
|
return fmt.Errorf("post state validation failed: %v", err)
|
||||||
}
|
}
|
||||||
@ -201,23 +214,13 @@ func runBlockTest(test *BlockTest) error {
|
|||||||
return test.ValidateImportedHeaders(cm, validBlocks)
|
return test.ValidateImportedHeaders(cm, validBlocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (test *BlockTest) makeEthConfig() *eth.Config {
|
|
||||||
ks := crypto.NewKeyStorePassphrase(filepath.Join(common.DefaultDataDir(), "keystore"))
|
|
||||||
|
|
||||||
return ð.Config{
|
|
||||||
DataDir: common.DefaultDataDir(),
|
|
||||||
Verbosity: 5,
|
|
||||||
Etherbase: common.Address{},
|
|
||||||
AccountManager: accounts.NewManager(ks),
|
|
||||||
NewDB: func(path string) (ethdb.Database, error) { return ethdb.NewMemDatabase() },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// InsertPreState populates the given database with the genesis
|
// InsertPreState populates the given database with the genesis
|
||||||
// accounts defined by the test.
|
// accounts defined by the test.
|
||||||
func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, error) {
|
func (t *BlockTest) InsertPreState(db ethdb.Database, am *accounts.Manager) (*state.StateDB, error) {
|
||||||
db := ethereum.ChainDb()
|
statedb, err := state.New(common.Hash{}, db)
|
||||||
statedb := state.New(common.Hash{}, db)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
for addrString, acct := range t.preAccounts {
|
for addrString, acct := range t.preAccounts {
|
||||||
addr, err := hex.DecodeString(addrString)
|
addr, err := hex.DecodeString(addrString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -239,7 +242,7 @@ func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, erro
|
|||||||
if acct.PrivateKey != "" {
|
if acct.PrivateKey != "" {
|
||||||
privkey, err := hex.DecodeString(strings.TrimPrefix(acct.PrivateKey, "0x"))
|
privkey, err := hex.DecodeString(strings.TrimPrefix(acct.PrivateKey, "0x"))
|
||||||
err = crypto.ImportBlockTestKey(privkey)
|
err = crypto.ImportBlockTestKey(privkey)
|
||||||
err = ethereum.AccountManager().TimedUnlock(common.BytesToAddress(addr), "", 999999*time.Second)
|
err = am.TimedUnlock(common.BytesToAddress(addr), "", 999999*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ func BenchStateTest(p string, conf bconf, b *testing.B) error {
|
|||||||
func benchStateTest(test VmTest, env map[string]string, b *testing.B) {
|
func benchStateTest(test VmTest, env map[string]string, b *testing.B) {
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb := state.New(common.Hash{}, db)
|
statedb, _ := state.New(common.Hash{}, db)
|
||||||
for addr, account := range test.Pre {
|
for addr, account := range test.Pre {
|
||||||
obj := StateObjectFromAccount(db, addr, account)
|
obj := StateObjectFromAccount(db, addr, account)
|
||||||
statedb.SetStateObject(obj)
|
statedb.SetStateObject(obj)
|
||||||
@ -142,7 +142,7 @@ func runStateTests(tests map[string]VmTest, skipTests []string) error {
|
|||||||
|
|
||||||
func runStateTest(test VmTest) error {
|
func runStateTest(test VmTest) error {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb := state.New(common.Hash{}, db)
|
statedb, _ := state.New(common.Hash{}, db)
|
||||||
for addr, account := range test.Pre {
|
for addr, account := range test.Pre {
|
||||||
obj := StateObjectFromAccount(db, addr, account)
|
obj := StateObjectFromAccount(db, addr, account)
|
||||||
statedb.SetStateObject(obj)
|
statedb.SetStateObject(obj)
|
||||||
|
@ -108,7 +108,7 @@ func BenchVmTest(p string, conf bconf, b *testing.B) error {
|
|||||||
func benchVmTest(test VmTest, env map[string]string, b *testing.B) {
|
func benchVmTest(test VmTest, env map[string]string, b *testing.B) {
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb := state.New(common.Hash{}, db)
|
statedb, _ := state.New(common.Hash{}, db)
|
||||||
for addr, account := range test.Pre {
|
for addr, account := range test.Pre {
|
||||||
obj := StateObjectFromAccount(db, addr, account)
|
obj := StateObjectFromAccount(db, addr, account)
|
||||||
statedb.SetStateObject(obj)
|
statedb.SetStateObject(obj)
|
||||||
@ -159,7 +159,7 @@ func runVmTests(tests map[string]VmTest, skipTests []string) error {
|
|||||||
|
|
||||||
func runVmTest(test VmTest) error {
|
func runVmTest(test VmTest) error {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb := state.New(common.Hash{}, db)
|
statedb, _ := state.New(common.Hash{}, db)
|
||||||
for addr, account := range test.Pre {
|
for addr, account := range test.Pre {
|
||||||
obj := StateObjectFromAccount(db, addr, account)
|
obj := StateObjectFromAccount(db, addr, account)
|
||||||
statedb.SetStateObject(obj)
|
statedb.SetStateObject(obj)
|
||||||
|
23
xeth/xeth.go
23
xeth/xeth.go
@ -126,7 +126,11 @@ func New(ethereum *eth.Ethereum, frontend Frontend) *XEth {
|
|||||||
if frontend == nil {
|
if frontend == nil {
|
||||||
xeth.frontend = dummyFrontend{}
|
xeth.frontend = dummyFrontend{}
|
||||||
}
|
}
|
||||||
xeth.state = NewState(xeth, xeth.backend.BlockChain().State())
|
state, err := xeth.backend.BlockChain().State()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
xeth.state = NewState(xeth, state)
|
||||||
|
|
||||||
go xeth.start()
|
go xeth.start()
|
||||||
|
|
||||||
@ -207,14 +211,21 @@ func (self *XEth) RemoteMining() *miner.RemoteAgent { return self.agent }
|
|||||||
|
|
||||||
func (self *XEth) AtStateNum(num int64) *XEth {
|
func (self *XEth) AtStateNum(num int64) *XEth {
|
||||||
var st *state.StateDB
|
var st *state.StateDB
|
||||||
|
var err error
|
||||||
switch num {
|
switch num {
|
||||||
case -2:
|
case -2:
|
||||||
st = self.backend.Miner().PendingState().Copy()
|
st = self.backend.Miner().PendingState().Copy()
|
||||||
default:
|
default:
|
||||||
if block := self.getBlockByHeight(num); block != nil {
|
if block := self.getBlockByHeight(num); block != nil {
|
||||||
st = state.New(block.Root(), self.backend.ChainDb())
|
st, err = state.New(block.Root(), self.backend.ChainDb())
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
st = state.New(self.backend.BlockChain().GetBlockByNumber(0).Root(), self.backend.ChainDb())
|
st, err = state.New(self.backend.BlockChain().GetBlockByNumber(0).Root(), self.backend.ChainDb())
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +277,11 @@ func (self *XEth) UpdateState() (wait chan *big.Int) {
|
|||||||
wait <- n
|
wait <- n
|
||||||
n = nil
|
n = nil
|
||||||
}
|
}
|
||||||
statedb := state.New(event.Block.Root(), self.backend.ChainDb())
|
statedb, err := state.New(event.Block.Root(), self.backend.ChainDb())
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infoln("Could not create new state: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
self.state = NewState(self, statedb)
|
self.state = NewState(self, statedb)
|
||||||
}
|
}
|
||||||
case n, ok = <-wait:
|
case n, ok = <-wait:
|
||||||
|
Loading…
Reference in New Issue
Block a user