Merge branch 'release/0.9.28' into develop
This commit is contained in:
		| @@ -44,7 +44,7 @@ import ( | |||||||
|  |  | ||||||
| const ( | const ( | ||||||
| 	ClientIdentifier = "Geth" | 	ClientIdentifier = "Geth" | ||||||
| 	Version          = "0.9.27" | 	Version          = "0.9.28" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ type ManagedState struct { | |||||||
| // ManagedState returns a new managed state with the statedb as it's backing layer | // ManagedState returns a new managed state with the statedb as it's backing layer | ||||||
| func ManageState(statedb *StateDB) *ManagedState { | func ManageState(statedb *StateDB) *ManagedState { | ||||||
| 	return &ManagedState{ | 	return &ManagedState{ | ||||||
| 		StateDB:  statedb, | 		StateDB:  statedb.Copy(), | ||||||
| 		accounts: make(map[string]*account), | 		accounts: make(map[string]*account), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ type stateFn func() *state.StateDB | |||||||
| type TxPool struct { | type TxPool struct { | ||||||
| 	quit         chan bool // Quiting channel | 	quit         chan bool // Quiting channel | ||||||
| 	currentState stateFn   // The state function which will allow us to do some pre checkes | 	currentState stateFn   // The state function which will allow us to do some pre checkes | ||||||
| 	state        *state.ManagedState | 	pendingState *state.ManagedState | ||||||
| 	gasLimit     func() *big.Int // The current gas limit function callback | 	gasLimit     func() *big.Int // The current gas limit function callback | ||||||
| 	eventMux     *event.TypeMux | 	eventMux     *event.TypeMux | ||||||
| 	events       event.Subscription | 	events       event.Subscription | ||||||
| @@ -57,7 +57,7 @@ func NewTxPool(eventMux *event.TypeMux, currentStateFn stateFn, gasLimitFn func( | |||||||
| 		eventMux:     eventMux, | 		eventMux:     eventMux, | ||||||
| 		currentState: currentStateFn, | 		currentState: currentStateFn, | ||||||
| 		gasLimit:     gasLimitFn, | 		gasLimit:     gasLimitFn, | ||||||
| 		state:        state.ManageState(currentStateFn()), | 		pendingState: state.ManageState(currentStateFn()), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -76,7 +76,7 @@ func (pool *TxPool) Start() { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (pool *TxPool) resetState() { | func (pool *TxPool) resetState() { | ||||||
| 	pool.state = state.ManageState(pool.currentState()) | 	pool.pendingState = state.ManageState(pool.currentState()) | ||||||
|  |  | ||||||
| 	// 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 | ||||||
| @@ -90,7 +90,7 @@ func (pool *TxPool) resetState() { | |||||||
| 		if addr, err := tx.From(); err == nil { | 		if addr, err := tx.From(); err == nil { | ||||||
| 			// Set the nonce. Transaction nonce can never be lower | 			// Set the nonce. Transaction nonce can never be lower | ||||||
| 			// than the state nonce; validatePool took care of that. | 			// than the state nonce; validatePool took care of that. | ||||||
| 			pool.state.SetNonce(addr, tx.Nonce()) | 			pool.pendingState.SetNonce(addr, tx.Nonce()) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -110,7 +110,7 @@ func (pool *TxPool) State() *state.ManagedState { | |||||||
| 	pool.mu.RLock() | 	pool.mu.RLock() | ||||||
| 	defer pool.mu.RUnlock() | 	defer pool.mu.RUnlock() | ||||||
|  |  | ||||||
| 	return pool.state | 	return pool.pendingState | ||||||
| } | } | ||||||
|  |  | ||||||
| // validateTx checks whether a transaction is valid according | // validateTx checks whether a transaction is valid according | ||||||
| @@ -302,7 +302,9 @@ func (pool *TxPool) addTx(hash common.Hash, addr common.Address, tx *types.Trans | |||||||
| 	if _, ok := pool.pending[hash]; !ok { | 	if _, ok := pool.pending[hash]; !ok { | ||||||
| 		pool.pending[hash] = tx | 		pool.pending[hash] = tx | ||||||
|  |  | ||||||
| 		pool.state.SetNonce(addr, tx.AccountNonce) | 		// Increment the nonce on the pending state. This can only happen if | ||||||
|  | 		// the nonce is +1 to the previous one. | ||||||
|  | 		pool.pendingState.SetNonce(addr, tx.AccountNonce+1) | ||||||
| 		// Notify the subscribers. This event is posted in a goroutine | 		// Notify the subscribers. This event is posted in a goroutine | ||||||
| 		// because it's possible that somewhere during the post "Remove transaction" | 		// because it's possible that somewhere during the post "Remove transaction" | ||||||
| 		// gets called which will then wait for the global tx pool lock and deadlock. | 		// gets called which will then wait for the global tx pool lock and deadlock. | ||||||
| @@ -312,14 +314,17 @@ func (pool *TxPool) addTx(hash common.Hash, addr common.Address, tx *types.Trans | |||||||
|  |  | ||||||
| // 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.state | 	state := pool.pendingState | ||||||
|  |  | ||||||
| 	var addq txQueue | 	var addq txQueue | ||||||
| 	for address, txs := range pool.queue { | 	for address, txs := range pool.queue { | ||||||
| 		curnonce := state.GetNonce(address) | 		// guessed nonce is the nonce currently kept by the tx pool (pending state) | ||||||
|  | 		guessedNonce := state.GetNonce(address) | ||||||
|  | 		// true nonce is the nonce known by the last state | ||||||
|  | 		trueNonce := pool.currentState().GetNonce(address) | ||||||
| 		addq := addq[:0] | 		addq := addq[:0] | ||||||
| 		for hash, tx := range txs { | 		for hash, tx := range txs { | ||||||
| 			if tx.AccountNonce < curnonce { | 			if tx.AccountNonce < trueNonce { | ||||||
| 				// Drop queued transactions whose nonce is lower than | 				// Drop queued transactions whose nonce is lower than | ||||||
| 				// the account nonce because they have been processed. | 				// the account nonce because they have been processed. | ||||||
| 				delete(txs, hash) | 				delete(txs, hash) | ||||||
| @@ -332,7 +337,7 @@ func (pool *TxPool) checkQueue() { | |||||||
| 		// current account nonce. | 		// current account nonce. | ||||||
| 		sort.Sort(addq) | 		sort.Sort(addq) | ||||||
| 		for _, e := range addq { | 		for _, e := range addq { | ||||||
| 			if e.AccountNonce > curnonce { | 			if e.AccountNonce > guessedNonce { | ||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| 			delete(txs, e.hash) | 			delete(txs, e.hash) | ||||||
|   | |||||||
| @@ -37,21 +37,21 @@ func TestInvalidTransactions(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	from, _ := tx.From() | 	from, _ := tx.From() | ||||||
| 	pool.state.AddBalance(from, big.NewInt(1)) | 	pool.currentState().AddBalance(from, big.NewInt(1)) | ||||||
| 	err = pool.Add(tx) | 	err = pool.Add(tx) | ||||||
| 	if err != ErrInsufficientFunds { | 	if 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.state.AddBalance(from, balance) | 	pool.currentState().AddBalance(from, balance) | ||||||
| 	err = pool.Add(tx) | 	err = pool.Add(tx) | ||||||
| 	if err != ErrIntrinsicGas { | 	if err != ErrIntrinsicGas { | ||||||
| 		t.Error("expected", ErrIntrinsicGas, "got", err) | 		t.Error("expected", ErrIntrinsicGas, "got", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	pool.state.SetNonce(from, 1) | 	pool.currentState().SetNonce(from, 1) | ||||||
| 	pool.state.AddBalance(from, big.NewInt(0xffffffffffffff)) | 	pool.currentState().AddBalance(from, big.NewInt(0xffffffffffffff)) | ||||||
| 	tx.GasLimit = big.NewInt(100000) | 	tx.GasLimit = big.NewInt(100000) | ||||||
| 	tx.Price = big.NewInt(1) | 	tx.Price = big.NewInt(1) | ||||||
| 	tx.SignECDSA(key) | 	tx.SignECDSA(key) | ||||||
| @@ -67,7 +67,7 @@ func TestTransactionQueue(t *testing.T) { | |||||||
| 	tx := transaction() | 	tx := transaction() | ||||||
| 	tx.SignECDSA(key) | 	tx.SignECDSA(key) | ||||||
| 	from, _ := tx.From() | 	from, _ := tx.From() | ||||||
| 	pool.state.AddBalance(from, big.NewInt(1)) | 	pool.currentState().AddBalance(from, big.NewInt(1)) | ||||||
| 	pool.queueTx(tx.Hash(), tx) | 	pool.queueTx(tx.Hash(), tx) | ||||||
|  |  | ||||||
| 	pool.checkQueue() | 	pool.checkQueue() | ||||||
| @@ -79,7 +79,7 @@ func TestTransactionQueue(t *testing.T) { | |||||||
| 	tx.SetNonce(1) | 	tx.SetNonce(1) | ||||||
| 	tx.SignECDSA(key) | 	tx.SignECDSA(key) | ||||||
| 	from, _ = tx.From() | 	from, _ = tx.From() | ||||||
| 	pool.state.SetNonce(from, 2) | 	pool.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 { | ||||||
| @@ -117,7 +117,7 @@ func TestRemoveTx(t *testing.T) { | |||||||
| 	tx := transaction() | 	tx := transaction() | ||||||
| 	tx.SignECDSA(key) | 	tx.SignECDSA(key) | ||||||
| 	from, _ := tx.From() | 	from, _ := tx.From() | ||||||
| 	pool.state.AddBalance(from, big.NewInt(1)) | 	pool.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 +146,7 @@ func TestNegativeValue(t *testing.T) { | |||||||
| 	tx.Value().Set(big.NewInt(-1)) | 	tx.Value().Set(big.NewInt(-1)) | ||||||
| 	tx.SignECDSA(key) | 	tx.SignECDSA(key) | ||||||
| 	from, _ := tx.From() | 	from, _ := tx.From() | ||||||
| 	pool.state.AddBalance(from, big.NewInt(1)) | 	pool.currentState().AddBalance(from, big.NewInt(1)) | ||||||
| 	err := pool.Add(tx) | 	err := pool.Add(tx) | ||||||
| 	if err != ErrNegativeValue { | 	if err != ErrNegativeValue { | ||||||
| 		t.Error("expected", ErrNegativeValue, "got", err) | 		t.Error("expected", ErrNegativeValue, "got", err) | ||||||
| @@ -156,7 +156,15 @@ func TestNegativeValue(t *testing.T) { | |||||||
| func TestTransactionChainFork(t *testing.T) { | func TestTransactionChainFork(t *testing.T) { | ||||||
| 	pool, key := setupTxPool() | 	pool, key := setupTxPool() | ||||||
| 	addr := crypto.PubkeyToAddress(key.PublicKey) | 	addr := crypto.PubkeyToAddress(key.PublicKey) | ||||||
|  | 	resetState := func() { | ||||||
|  | 		db, _ := ethdb.NewMemDatabase() | ||||||
|  | 		statedb := state.New(common.Hash{}, db) | ||||||
|  | 		pool.currentState = func() *state.StateDB { return statedb } | ||||||
| 		pool.currentState().AddBalance(addr, big.NewInt(100000000000000)) | 		pool.currentState().AddBalance(addr, big.NewInt(100000000000000)) | ||||||
|  | 		pool.resetState() | ||||||
|  | 	} | ||||||
|  | 	resetState() | ||||||
|  |  | ||||||
| 	tx := transaction() | 	tx := transaction() | ||||||
| 	tx.GasLimit = big.NewInt(100000) | 	tx.GasLimit = big.NewInt(100000) | ||||||
| 	tx.SignECDSA(key) | 	tx.SignECDSA(key) | ||||||
| @@ -168,7 +176,7 @@ func TestTransactionChainFork(t *testing.T) { | |||||||
| 	pool.RemoveTransactions([]*types.Transaction{tx}) | 	pool.RemoveTransactions([]*types.Transaction{tx}) | ||||||
|  |  | ||||||
| 	// reset the pool's internal state | 	// reset the pool's internal state | ||||||
| 	pool.resetState() | 	resetState() | ||||||
| 	err = pool.add(tx) | 	err = pool.add(tx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Error("didn't expect error", err) | 		t.Error("didn't expect error", err) | ||||||
| @@ -178,7 +186,15 @@ func TestTransactionChainFork(t *testing.T) { | |||||||
| func TestTransactionDoubleNonce(t *testing.T) { | func TestTransactionDoubleNonce(t *testing.T) { | ||||||
| 	pool, key := setupTxPool() | 	pool, key := setupTxPool() | ||||||
| 	addr := crypto.PubkeyToAddress(key.PublicKey) | 	addr := crypto.PubkeyToAddress(key.PublicKey) | ||||||
|  | 	resetState := func() { | ||||||
|  | 		db, _ := ethdb.NewMemDatabase() | ||||||
|  | 		statedb := state.New(common.Hash{}, db) | ||||||
|  | 		pool.currentState = func() *state.StateDB { return statedb } | ||||||
| 		pool.currentState().AddBalance(addr, big.NewInt(100000000000000)) | 		pool.currentState().AddBalance(addr, big.NewInt(100000000000000)) | ||||||
|  | 		pool.resetState() | ||||||
|  | 	} | ||||||
|  | 	resetState() | ||||||
|  |  | ||||||
| 	tx := transaction() | 	tx := transaction() | ||||||
| 	tx.GasLimit = big.NewInt(100000) | 	tx.GasLimit = big.NewInt(100000) | ||||||
| 	tx.SignECDSA(key) | 	tx.SignECDSA(key) | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ func TestCompileSolidity(t *testing.T) { | |||||||
| 	if solc == nil { | 	if solc == nil { | ||||||
| 		t.Skip("no solc found: skip") | 		t.Skip("no solc found: skip") | ||||||
| 	} else if solc.Version() != solcVersion { | 	} else if solc.Version() != solcVersion { | ||||||
| 		t.Logf("WARNING: solc different version found (%v, test written for %v, may need to update)", solc.Version(), solcVersion) | 		t.Skip("WARNING: skipping test because of solc different version (%v, test written for %v, may need to update)", solc.Version(), solcVersion) | ||||||
| 	} | 	} | ||||||
| 	source := `contract test {\n` + | 	source := `contract test {\n` + | ||||||
| 		"   /// @notice Will multiply `a` by 7." + `\n` + | 		"   /// @notice Will multiply `a` by 7." + `\n` + | ||||||
|   | |||||||
| @@ -957,7 +957,7 @@ func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceS | |||||||
| 	if err := self.backend.TxPool().Add(tx); err != nil { | 	if err := self.backend.TxPool().Add(tx); err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| 	state.SetNonce(from, nonce+1) | 	//state.SetNonce(from, nonce+1) | ||||||
|  |  | ||||||
| 	if contractCreation { | 	if contractCreation { | ||||||
| 		addr := core.AddressFromMessage(tx) | 		addr := core.AddressFromMessage(tx) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user