mempool: store feeSum as big.Int

Prevent (very) potential overflow.
This commit is contained in:
Roman Khimov 2020-08-20 19:06:59 +03:00
parent 95a80c6922
commit 0e086d61ac
2 changed files with 13 additions and 11 deletions

View file

@ -41,7 +41,7 @@ type items []*item
// sender's transactions which are currently in mempool // sender's transactions which are currently in mempool
type utilityBalanceAndFees struct { type utilityBalanceAndFees struct {
balance *big.Int balance *big.Int
feeSum int64 feeSum *big.Int
} }
// Pool stores the unconfirms transactions. // Pool stores the unconfirms transactions.
@ -116,12 +116,13 @@ func (mp *Pool) tryAddSendersFee(tx *transaction.Transaction, feer Feer, needChe
senderFee, ok := mp.fees[tx.Sender()] senderFee, ok := mp.fees[tx.Sender()]
if !ok { if !ok {
senderFee.balance = feer.GetUtilityTokenBalance(tx.Sender()) senderFee.balance = feer.GetUtilityTokenBalance(tx.Sender())
senderFee.feeSum = big.NewInt(0)
mp.fees[tx.Sender()] = senderFee mp.fees[tx.Sender()] = senderFee
} }
if needCheck && checkBalance(tx, senderFee) != nil { if needCheck && checkBalance(tx, senderFee) != nil {
return false return false
} }
senderFee.feeSum += tx.SystemFee + tx.NetworkFee senderFee.feeSum.Add(senderFee.feeSum, big.NewInt(tx.SystemFee+tx.NetworkFee))
mp.fees[tx.Sender()] = senderFee mp.fees[tx.Sender()] = senderFee
return true return true
} }
@ -129,12 +130,12 @@ func (mp *Pool) tryAddSendersFee(tx *transaction.Transaction, feer Feer, needChe
// checkBalance returns nil in case when sender has enough GAS to pay for the // checkBalance returns nil in case when sender has enough GAS to pay for the
// transaction // transaction
func checkBalance(tx *transaction.Transaction, balance utilityBalanceAndFees) error { func checkBalance(tx *transaction.Transaction, balance utilityBalanceAndFees) error {
txFee := tx.SystemFee + tx.NetworkFee txFee := big.NewInt(tx.SystemFee + tx.NetworkFee)
if balance.balance.Cmp(big.NewInt(txFee)) < 0 { if balance.balance.Cmp(txFee) < 0 {
return ErrInsufficientFunds return ErrInsufficientFunds
} }
needFee := balance.feeSum + txFee needFee := txFee.Add(txFee, balance.feeSum)
if balance.balance.Cmp(big.NewInt(needFee)) < 0 { if balance.balance.Cmp(needFee) < 0 {
return ErrConflict return ErrConflict
} }
return nil return nil
@ -212,7 +213,7 @@ func (mp *Pool) Remove(hash util.Uint256) {
mp.verifiedTxes = mp.verifiedTxes[:num] mp.verifiedTxes = mp.verifiedTxes[:num]
} }
senderFee := mp.fees[it.txn.Sender()] senderFee := mp.fees[it.txn.Sender()]
senderFee.feeSum -= it.txn.SystemFee + it.txn.NetworkFee senderFee.feeSum.Sub(senderFee.feeSum, big.NewInt(it.txn.SystemFee+it.txn.NetworkFee))
mp.fees[it.txn.Sender()] = senderFee mp.fees[it.txn.Sender()] = senderFee
} }
updateMempoolMetrics(len(mp.verifiedTxes)) updateMempoolMetrics(len(mp.verifiedTxes))
@ -299,6 +300,7 @@ func (mp *Pool) checkTxConflicts(tx *transaction.Transaction, fee Feer) error {
senderFee, ok := mp.fees[tx.Sender()] senderFee, ok := mp.fees[tx.Sender()]
if !ok { if !ok {
senderFee.balance = fee.GetUtilityTokenBalance(tx.Sender()) senderFee.balance = fee.GetUtilityTokenBalance(tx.Sender())
senderFee.feeSum = big.NewInt(0)
} }
return checkBalance(tx, senderFee) return checkBalance(tx, senderFee)
} }

View file

@ -205,7 +205,7 @@ func TestMemPoolFees(t *testing.T) {
require.Equal(t, 1, len(mp.fees)) require.Equal(t, 1, len(mp.fees))
require.Equal(t, utilityBalanceAndFees{ require.Equal(t, utilityBalanceAndFees{
balance: balance, balance: balance,
feeSum: tx1.NetworkFee, feeSum: big.NewInt(tx1.NetworkFee),
}, mp.fees[sender0]) }, mp.fees[sender0])
// balance shouldn't change after adding one more transaction // balance shouldn't change after adding one more transaction
@ -217,7 +217,7 @@ func TestMemPoolFees(t *testing.T) {
require.Equal(t, 1, len(mp.fees)) require.Equal(t, 1, len(mp.fees))
require.Equal(t, utilityBalanceAndFees{ require.Equal(t, utilityBalanceAndFees{
balance: balance, balance: balance,
feeSum: balance.Int64(), feeSum: balance,
}, mp.fees[sender0]) }, mp.fees[sender0])
// can't add more transactions as we don't have enough GAS // can't add more transactions as we don't have enough GAS
@ -229,7 +229,7 @@ func TestMemPoolFees(t *testing.T) {
require.Equal(t, 1, len(mp.fees)) require.Equal(t, 1, len(mp.fees))
require.Equal(t, utilityBalanceAndFees{ require.Equal(t, utilityBalanceAndFees{
balance: balance, balance: balance,
feeSum: balance.Int64(), feeSum: balance,
}, mp.fees[sender0]) }, mp.fees[sender0])
// check whether sender's fee updates correctly // check whether sender's fee updates correctly
@ -242,7 +242,7 @@ func TestMemPoolFees(t *testing.T) {
require.Equal(t, 1, len(mp.fees)) require.Equal(t, 1, len(mp.fees))
require.Equal(t, utilityBalanceAndFees{ require.Equal(t, utilityBalanceAndFees{
balance: balance, balance: balance,
feeSum: tx2.NetworkFee, feeSum: big.NewInt(tx2.NetworkFee),
}, mp.fees[sender0]) }, mp.fees[sender0])
// there should be nothing left // there should be nothing left