core: use maxBlockSize to apply policy to tx set

We should also take into account maxBlockSize in
(bc *Blockchain).ApplyPolicyToTxSet
This commit is contained in:
Anna Shaleva 2020-08-03 18:49:22 +03:00
parent c647f8e4ed
commit 4a1c8464f9
3 changed files with 21 additions and 5 deletions

View file

@ -1159,11 +1159,17 @@ func (bc *Blockchain) ApplyPolicyToTxSet(txes []*transaction.Transaction) []*tra
if maxTx != 0 && len(txes) > int(maxTx) { if maxTx != 0 && len(txes) > int(maxTx) {
txes = txes[:maxTx] txes = txes[:maxTx]
} }
maxBlockSize := bc.contracts.Policy.GetMaxBlockSizeInternal(bc.dao)
maxBlockSysFee := bc.contracts.Policy.GetMaxBlockSystemFeeInternal(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 { for i, tx := range txes {
blockSize += uint32(io.GetVarSize(tx))
sysFee += tx.SystemFee sysFee += tx.SystemFee
if sysFee > maxBlockSysFee { if blockSize > maxBlockSize || sysFee > maxBlockSysFee {
txes = txes[:i] txes = txes[:i]
break break
} }

View file

@ -225,12 +225,17 @@ func (p *Policy) GetMaxTransactionsPerBlockInternal(dao dao.DAO) uint32 {
// getMaxBlockSize is Policy contract method and returns maximum block size. // getMaxBlockSize is Policy contract method and returns maximum block size.
func (p *Policy) getMaxBlockSize(ic *interop.Context, _ []stackitem.Item) stackitem.Item { 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() p.lock.RLock()
defer p.lock.RUnlock() defer p.lock.RUnlock()
if p.isValid { 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 // getFeePerByte is Policy contract method and returns required transaction's fee

View file

@ -53,7 +53,12 @@ func TestMaxBlockSize(t *testing.T) {
chain := newTestChain(t) chain := newTestChain(t)
defer chain.Close() 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") res, err := invokeNativePolicyMethod(chain, "getMaxBlockSize")
require.NoError(t, err) require.NoError(t, err)
checkResult(t, res, smartcontract.Parameter{ checkResult(t, res, smartcontract.Parameter{