diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 26d8207b6..4c9d721c6 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "math/big" - "sort" "sync" "sync/atomic" "time" @@ -1206,21 +1205,10 @@ func (bc *Blockchain) verifyTx(t *transaction.Transaction, block *block.Block) e if t.ValidUntilBlock <= height || t.ValidUntilBlock > height+transaction.MaxValidUntilBlockIncrement { return fmt.Errorf("transaction has expired. ValidUntilBlock = %d, current height = %d", t.ValidUntilBlock, height) } - blockedAccounts, err := bc.contracts.Policy.GetBlockedAccountsInternal(bc.dao) - if err != nil { - return err - } - for _, signer := range t.Signers { - i := sort.Search(len(blockedAccounts), func(i int) bool { - return !blockedAccounts[i].Less(signer.Account) - }) - if i != len(blockedAccounts) && blockedAccounts[i].Equals(signer.Account) { - return fmt.Errorf("policy check failed: account %s is blocked", signer.Account.StringLE()) - } - } - maxBlockSystemFee := bc.contracts.Policy.GetMaxBlockSystemFeeInternal(bc.dao) - if maxBlockSystemFee < t.SystemFee { - return fmt.Errorf("policy check failed: transaction's fee shouldn't exceed maximum block system fee %d", maxBlockSystemFee) + // Policying. + if err := bc.contracts.Policy.CheckPolicy(bc.dao, t); err != nil { + // Only one %w can be used. + return fmt.Errorf("%w: %v", ErrPolicy, err) } balance := bc.GetUtilityTokenBalance(t.Sender()) need := t.SystemFee + t.NetworkFee @@ -1368,11 +1356,6 @@ func (bc *Blockchain) PoolTx(t *transaction.Transaction) error { if err := bc.verifyTx(t, nil); err != nil { return err } - // Policying. - if err := bc.contracts.Policy.CheckPolicy(bc.dao, t); err != nil { - // Only one %w can be used. - return fmt.Errorf("%w: %v", ErrPolicy, err) - } if err := bc.memPool.Add(t, bc); err != nil { switch { case errors.Is(err, mempool.ErrOOM): diff --git a/pkg/core/native/policy.go b/pkg/core/native/policy.go index 874e24293..6b661e4c9 100644 --- a/pkg/core/native/policy.go +++ b/pkg/core/native/policy.go @@ -509,19 +509,27 @@ func (p *Policy) checkValidators(ic *interop.Context) (bool, error) { return runtime.CheckHashedWitness(ic, prevBlock.NextConsensus) } -// CheckPolicy checks whether transaction's script hashes for verifying are -// included into blocked accounts list. +// CheckPolicy checks whether transaction conforms to current policy restrictions +// like not being signed by blocked account or not exceeding block-level system +// fee limit. func (p *Policy) CheckPolicy(d dao.DAO, tx *transaction.Transaction) error { ba, err := p.GetBlockedAccountsInternal(d) if err != nil { return fmt.Errorf("unable to get blocked accounts list: %w", err) } - for _, acc := range ba { + if len(ba) > 0 { for _, signer := range tx.Signers { - if acc.Equals(signer.Account) { - return fmt.Errorf("account %s is blocked", acc.StringLE()) + i := sort.Search(len(ba), func(i int) bool { + return !ba[i].Less(signer.Account) + }) + if i != len(ba) && ba[i].Equals(signer.Account) { + return fmt.Errorf("account %s is blocked", signer.Account.StringLE()) } } } + maxBlockSystemFee := p.GetMaxBlockSystemFeeInternal(d) + if maxBlockSystemFee < tx.SystemFee { + return fmt.Errorf("transaction's fee can't exceed maximum block system fee %d", maxBlockSystemFee) + } return nil }