diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index f2b27734d..eb80d4ee9 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -1159,11 +1159,17 @@ func (bc *Blockchain) ApplyPolicyToTxSet(txes []*transaction.Transaction) []*tra if maxTx != 0 && len(txes) > int(maxTx) { txes = txes[:maxTx] } + maxBlockSize := bc.contracts.Policy.GetMaxBlockSizeInternal(bc.dao) maxBlockSysFee := bc.contracts.Policy.GetMaxBlockSystemFeeInternal(bc.dao) - var sysFee int64 + var ( + blockSize uint32 + sysFee int64 + ) + blockSize = uint32(io.GetVarSize(new(block.Block)) + io.GetVarSize(len(txes)+1)) for i, tx := range txes { + blockSize += uint32(io.GetVarSize(tx)) sysFee += tx.SystemFee - if sysFee > maxBlockSysFee { + if blockSize > maxBlockSize || sysFee > maxBlockSysFee { txes = txes[:i] break } diff --git a/pkg/core/native/policy.go b/pkg/core/native/policy.go index c7258da0c..9d7c31cad 100644 --- a/pkg/core/native/policy.go +++ b/pkg/core/native/policy.go @@ -225,12 +225,17 @@ func (p *Policy) GetMaxTransactionsPerBlockInternal(dao dao.DAO) uint32 { // getMaxBlockSize is Policy contract method and returns maximum block size. func (p *Policy) getMaxBlockSize(ic *interop.Context, _ []stackitem.Item) stackitem.Item { + return stackitem.NewBigInteger(big.NewInt(int64(p.GetMaxBlockSizeInternal(ic.DAO)))) +} + +// GetMaxBlockSizeInternal returns maximum block size. +func (p *Policy) GetMaxBlockSizeInternal(dao dao.DAO) uint32 { p.lock.RLock() defer p.lock.RUnlock() if p.isValid { - return stackitem.NewBigInteger(big.NewInt(int64(p.maxBlockSize))) + return p.maxBlockSize } - return stackitem.NewBigInteger(big.NewInt(int64(p.getUint32WithKey(ic.DAO, maxBlockSizeKey)))) + return p.getUint32WithKey(dao, maxBlockSizeKey) } // getFeePerByte is Policy contract method and returns required transaction's fee diff --git a/pkg/core/native_policy_test.go b/pkg/core/native_policy_test.go index 58388dbb7..edf0b7b9e 100644 --- a/pkg/core/native_policy_test.go +++ b/pkg/core/native_policy_test.go @@ -53,7 +53,12 @@ func TestMaxBlockSize(t *testing.T) { chain := newTestChain(t) defer chain.Close() - t.Run("get", func(t *testing.T) { + t.Run("get, internal method", func(t *testing.T) { + n := chain.contracts.Policy.GetMaxBlockSizeInternal(chain.dao) + require.Equal(t, 1024*256, int(n)) + }) + + t.Run("get, contract method", func(t *testing.T) { res, err := invokeNativePolicyMethod(chain, "getMaxBlockSize") require.NoError(t, err) checkResult(t, res, smartcontract.Parameter{