forked from cerc-io/plugeth
core/types, miner: avoid tx sender miscaching (#14773)
This commit is contained in:
parent
e3db1236de
commit
c1740e4540
@ -381,28 +381,32 @@ func (s *TxByPrice) Pop() interface{} {
|
|||||||
// transactions in a profit-maximising sorted order, while supporting removing
|
// transactions in a profit-maximising sorted order, while supporting removing
|
||||||
// entire batches of transactions for non-executable accounts.
|
// entire batches of transactions for non-executable accounts.
|
||||||
type TransactionsByPriceAndNonce struct {
|
type TransactionsByPriceAndNonce struct {
|
||||||
txs map[common.Address]Transactions // Per account nonce-sorted list of transactions
|
txs map[common.Address]Transactions // Per account nonce-sorted list of transactions
|
||||||
heads TxByPrice // Next transaction for each unique account (price heap)
|
heads TxByPrice // Next transaction for each unique account (price heap)
|
||||||
|
signer Signer // Signer for the set of transactions
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTransactionsByPriceAndNonce creates a transaction set that can retrieve
|
// NewTransactionsByPriceAndNonce creates a transaction set that can retrieve
|
||||||
// price sorted transactions in a nonce-honouring way.
|
// price sorted transactions in a nonce-honouring way.
|
||||||
//
|
//
|
||||||
// Note, the input map is reowned so the caller should not interact any more with
|
// Note, the input map is reowned so the caller should not interact any more with
|
||||||
// if after providng it to the constructor.
|
// if after providing it to the constructor.
|
||||||
func NewTransactionsByPriceAndNonce(txs map[common.Address]Transactions) *TransactionsByPriceAndNonce {
|
func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transactions) *TransactionsByPriceAndNonce {
|
||||||
// Initialize a price based heap with the head transactions
|
// Initialize a price based heap with the head transactions
|
||||||
heads := make(TxByPrice, 0, len(txs))
|
heads := make(TxByPrice, 0, len(txs))
|
||||||
for acc, accTxs := range txs {
|
for _, accTxs := range txs {
|
||||||
heads = append(heads, accTxs[0])
|
heads = append(heads, accTxs[0])
|
||||||
|
// Ensure the sender address is from the signer
|
||||||
|
acc, _ := Sender(signer, accTxs[0])
|
||||||
txs[acc] = accTxs[1:]
|
txs[acc] = accTxs[1:]
|
||||||
}
|
}
|
||||||
heap.Init(&heads)
|
heap.Init(&heads)
|
||||||
|
|
||||||
// Assemble and return the transaction set
|
// Assemble and return the transaction set
|
||||||
return &TransactionsByPriceAndNonce{
|
return &TransactionsByPriceAndNonce{
|
||||||
txs: txs,
|
txs: txs,
|
||||||
heads: heads,
|
heads: heads,
|
||||||
|
signer: signer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,9 +420,7 @@ func (t *TransactionsByPriceAndNonce) Peek() *Transaction {
|
|||||||
|
|
||||||
// Shift replaces the current best head with the next one from the same account.
|
// Shift replaces the current best head with the next one from the same account.
|
||||||
func (t *TransactionsByPriceAndNonce) Shift() {
|
func (t *TransactionsByPriceAndNonce) Shift() {
|
||||||
signer := deriveSigner(t.heads[0].data.V)
|
acc, _ := Sender(t.signer, t.heads[0])
|
||||||
// derive signer but don't cache.
|
|
||||||
acc, _ := Sender(signer, t.heads[0]) // we only sort valid txs so this cannot fail
|
|
||||||
if txs, ok := t.txs[acc]; ok && len(txs) > 0 {
|
if txs, ok := t.txs[acc]; ok && len(txs) > 0 {
|
||||||
t.heads[0], t.txs[acc] = txs[0], txs[1:]
|
t.heads[0], t.txs[acc] = txs[0], txs[1:]
|
||||||
heap.Fix(&t.heads, 0)
|
heap.Fix(&t.heads, 0)
|
||||||
|
@ -143,7 +143,7 @@ func TestTransactionPriceNonceSort(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Sort the transactions and cross check the nonce ordering
|
// Sort the transactions and cross check the nonce ordering
|
||||||
txset := NewTransactionsByPriceAndNonce(groups)
|
txset := NewTransactionsByPriceAndNonce(signer, groups)
|
||||||
|
|
||||||
txs := Transactions{}
|
txs := Transactions{}
|
||||||
for {
|
for {
|
||||||
|
@ -268,7 +268,7 @@ func (self *worker) update() {
|
|||||||
self.currentMu.Lock()
|
self.currentMu.Lock()
|
||||||
acc, _ := types.Sender(self.current.signer, ev.Tx)
|
acc, _ := types.Sender(self.current.signer, ev.Tx)
|
||||||
txs := map[common.Address]types.Transactions{acc: {ev.Tx}}
|
txs := map[common.Address]types.Transactions{acc: {ev.Tx}}
|
||||||
txset := types.NewTransactionsByPriceAndNonce(txs)
|
txset := types.NewTransactionsByPriceAndNonce(self.current.signer, txs)
|
||||||
|
|
||||||
self.current.commitTransactions(self.mux, txset, self.chain, self.coinbase)
|
self.current.commitTransactions(self.mux, txset, self.chain, self.coinbase)
|
||||||
self.currentMu.Unlock()
|
self.currentMu.Unlock()
|
||||||
@ -471,7 +471,7 @@ func (self *worker) commitNewWork() {
|
|||||||
log.Error("Failed to fetch pending transactions", "err", err)
|
log.Error("Failed to fetch pending transactions", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
txs := types.NewTransactionsByPriceAndNonce(pending)
|
txs := types.NewTransactionsByPriceAndNonce(self.current.signer, pending)
|
||||||
work.commitTransactions(self.mux, txs, self.chain, self.coinbase)
|
work.commitTransactions(self.mux, txs, self.chain, self.coinbase)
|
||||||
|
|
||||||
// compute uncles for the new block.
|
// compute uncles for the new block.
|
||||||
|
Loading…
Reference in New Issue
Block a user