core: add policy check to mempool
After block was stored it's possible to have new FeePerByte constraint, so we should remove all transactions which do not meet this requirement. Also caching of FeePerByte was added in order not to re-verify transactions each time mempool needs to be updated.
This commit is contained in:
parent
ce402a70d2
commit
9f11a55bd6
1 changed files with 23 additions and 2 deletions
|
@ -46,7 +46,8 @@ type Pool struct {
|
|||
verifiedTxes items
|
||||
fees map[util.Uint160]utilityBalanceAndFees
|
||||
|
||||
capacity int
|
||||
capacity int
|
||||
feePerByte util.Fixed8
|
||||
}
|
||||
|
||||
func (p items) Len() int { return len(p) }
|
||||
|
@ -218,12 +219,13 @@ func (mp *Pool) Remove(hash util.Uint256) {
|
|||
// drop part of the mempool that is now invalid after the block acceptance.
|
||||
func (mp *Pool) RemoveStale(isOK func(*transaction.Transaction) bool, feer Feer) {
|
||||
mp.lock.Lock()
|
||||
policyChanged := mp.loadPolicy(feer)
|
||||
// We can reuse already allocated slice
|
||||
// because items are iterated one-by-one in increasing order.
|
||||
newVerifiedTxes := mp.verifiedTxes[:0]
|
||||
mp.fees = make(map[util.Uint160]utilityBalanceAndFees) // it'd be nice to reuse existing map, but we can't easily clear it
|
||||
for _, itm := range mp.verifiedTxes {
|
||||
if isOK(itm.txn) && mp.tryAddSendersFee(itm.txn, feer) {
|
||||
if isOK(itm.txn) && mp.checkPolicy(itm.txn, policyChanged) && mp.tryAddSendersFee(itm.txn, feer) {
|
||||
newVerifiedTxes = append(newVerifiedTxes, itm)
|
||||
} else {
|
||||
delete(mp.verifiedMap, itm.txn.Hash())
|
||||
|
@ -233,6 +235,25 @@ func (mp *Pool) RemoveStale(isOK func(*transaction.Transaction) bool, feer Feer)
|
|||
mp.lock.Unlock()
|
||||
}
|
||||
|
||||
// loadPolicy updates feePerByte field and returns whether policy has been
|
||||
// changed.
|
||||
func (mp *Pool) loadPolicy(feer Feer) bool {
|
||||
newFeePerByte := feer.FeePerByte()
|
||||
if newFeePerByte.GreaterThan(mp.feePerByte) {
|
||||
mp.feePerByte = newFeePerByte
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// checkPolicy checks whether transaction fits policy.
|
||||
func (mp *Pool) checkPolicy(tx *transaction.Transaction, policyChanged bool) bool {
|
||||
if !policyChanged || tx.FeePerByte() >= mp.feePerByte {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NewMemPool returns a new Pool struct.
|
||||
func NewMemPool(capacity int) Pool {
|
||||
return Pool{
|
||||
|
|
Loading…
Reference in a new issue