Merge pull request #1254 from nspcc-dev/native/policy/maxblocksystemfee
core, consensus: add maxBlockSystemFee to native Policy
This commit is contained in:
commit
62f5aa8eb4
6 changed files with 193 additions and 14 deletions
|
@ -341,7 +341,19 @@ func (s *service) getTx(h util.Uint256) block.Transaction {
|
||||||
|
|
||||||
func (s *service) verifyBlock(b block.Block) bool {
|
func (s *service) verifyBlock(b block.Block) bool {
|
||||||
coreb := &b.(*neoBlock).Block
|
coreb := &b.(*neoBlock).Block
|
||||||
|
|
||||||
|
maxBlockSize := int(s.Chain.GetMaxBlockSize())
|
||||||
|
size := io.GetVarSize(coreb)
|
||||||
|
if size > maxBlockSize {
|
||||||
|
s.log.Warn("proposed block size exceeds policy max block size",
|
||||||
|
zap.Int("max size allowed", maxBlockSize),
|
||||||
|
zap.Int("block size", size))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var fee int64
|
||||||
for _, tx := range coreb.Transactions {
|
for _, tx := range coreb.Transactions {
|
||||||
|
fee += tx.SystemFee
|
||||||
if err := s.Chain.VerifyTx(tx, coreb); err != nil {
|
if err := s.Chain.VerifyTx(tx, coreb); err != nil {
|
||||||
s.log.Warn("invalid transaction in proposed block",
|
s.log.Warn("invalid transaction in proposed block",
|
||||||
zap.Stringer("hash", tx.Hash()),
|
zap.Stringer("hash", tx.Hash()),
|
||||||
|
@ -350,6 +362,14 @@ func (s *service) verifyBlock(b block.Block) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maxBlockSysFee := s.Chain.GetMaxBlockSystemFee()
|
||||||
|
if fee > maxBlockSysFee {
|
||||||
|
s.log.Warn("proposed block system fee exceeds policy max block system fee",
|
||||||
|
zap.Int("max system fee allowed", int(maxBlockSysFee)),
|
||||||
|
zap.Int("block system fee", int(fee)))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1147,6 +1147,16 @@ func (bc *Blockchain) FeePerByte() int64 {
|
||||||
return bc.contracts.Policy.GetFeePerByteInternal(bc.dao)
|
return bc.contracts.Policy.GetFeePerByteInternal(bc.dao)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMaxBlockSize returns maximum allowed block size from native Policy contract.
|
||||||
|
func (bc *Blockchain) GetMaxBlockSize() uint32 {
|
||||||
|
return bc.contracts.Policy.GetMaxBlockSizeInternal(bc.dao)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMaxBlockSystemFee returns maximum block system fee from native Policy contract.
|
||||||
|
func (bc *Blockchain) GetMaxBlockSystemFee() int64 {
|
||||||
|
return bc.contracts.Policy.GetMaxBlockSystemFeeInternal(bc.dao)
|
||||||
|
}
|
||||||
|
|
||||||
// GetMemPool returns the memory pool of the blockchain.
|
// GetMemPool returns the memory pool of the blockchain.
|
||||||
func (bc *Blockchain) GetMemPool() *mempool.Pool {
|
func (bc *Blockchain) GetMemPool() *mempool.Pool {
|
||||||
return &bc.memPool
|
return &bc.memPool
|
||||||
|
@ -1159,6 +1169,21 @@ 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)
|
||||||
|
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 blockSize > maxBlockSize || sysFee > maxBlockSysFee {
|
||||||
|
txes = txes[:i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
return txes
|
return txes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1194,9 +1219,13 @@ func (bc *Blockchain) verifyTx(t *transaction.Transaction, block *block.Block) e
|
||||||
return !blockedAccounts[i].Less(h)
|
return !blockedAccounts[i].Less(h)
|
||||||
})
|
})
|
||||||
if i != len(blockedAccounts) && blockedAccounts[i].Equals(h) {
|
if i != len(blockedAccounts) && blockedAccounts[i].Equals(h) {
|
||||||
return errors.Errorf("policy check failed")
|
return errors.Errorf("policy check failed: account %s is blocked", h.StringLE())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
maxBlockSystemFee := bc.contracts.Policy.GetMaxBlockSystemFeeInternal(bc.dao)
|
||||||
|
if maxBlockSystemFee < t.SystemFee {
|
||||||
|
return errors.Errorf("policy check failed: transaction's fee shouldn't exceed maximum block system fee %d", maxBlockSystemFee)
|
||||||
|
}
|
||||||
balance := bc.GetUtilityTokenBalance(t.Sender)
|
balance := bc.GetUtilityTokenBalance(t.Sender)
|
||||||
need := t.SystemFee + t.NetworkFee
|
need := t.SystemFee + t.NetworkFee
|
||||||
if balance.Cmp(big.NewInt(need)) < 0 {
|
if balance.Cmp(big.NewInt(need)) < 0 {
|
||||||
|
|
|
@ -50,6 +50,8 @@ type Blockchainer interface {
|
||||||
GetTestVM(tx *transaction.Transaction) *vm.VM
|
GetTestVM(tx *transaction.Transaction) *vm.VM
|
||||||
GetTransaction(util.Uint256) (*transaction.Transaction, uint32, error)
|
GetTransaction(util.Uint256) (*transaction.Transaction, uint32, error)
|
||||||
mempool.Feer // fee interface
|
mempool.Feer // fee interface
|
||||||
|
GetMaxBlockSize() uint32
|
||||||
|
GetMaxBlockSystemFee() int64
|
||||||
PoolTx(*transaction.Transaction) error
|
PoolTx(*transaction.Transaction) error
|
||||||
SubscribeForBlocks(ch chan<- *block.Block)
|
SubscribeForBlocks(ch chan<- *block.Block)
|
||||||
SubscribeForExecutions(ch chan<- *state.AppExecResult)
|
SubscribeForExecutions(ch chan<- *state.AppExecResult)
|
||||||
|
|
|
@ -26,6 +26,9 @@ const (
|
||||||
defaultMaxTransactionsPerBlock = 512
|
defaultMaxTransactionsPerBlock = 512
|
||||||
defaultFeePerByte = 1000
|
defaultFeePerByte = 1000
|
||||||
defaultMaxVerificationGas = 50000000
|
defaultMaxVerificationGas = 50000000
|
||||||
|
defaultMaxBlockSystemFee = 9000 * GASFactor
|
||||||
|
// minBlockSystemFee is the minimum allowed system fee per block.
|
||||||
|
minBlockSystemFee = 4007600
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -38,7 +41,9 @@ var (
|
||||||
// blockedAccountsKey is a key used to store the list of blocked accounts.
|
// blockedAccountsKey is a key used to store the list of blocked accounts.
|
||||||
blockedAccountsKey = []byte{15}
|
blockedAccountsKey = []byte{15}
|
||||||
// maxBlockSizeKey is a key used to store the maximum block size value.
|
// maxBlockSizeKey is a key used to store the maximum block size value.
|
||||||
maxBlockSizeKey = []byte{16}
|
maxBlockSizeKey = []byte{12}
|
||||||
|
// maxBlockSystemFeeKey is a key used to store the maximum block system fee value.
|
||||||
|
maxBlockSystemFeeKey = []byte{17}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Policy represents Policy native contract.
|
// Policy represents Policy native contract.
|
||||||
|
@ -52,6 +57,7 @@ type Policy struct {
|
||||||
maxTransactionsPerBlock uint32
|
maxTransactionsPerBlock uint32
|
||||||
maxBlockSize uint32
|
maxBlockSize uint32
|
||||||
feePerByte int64
|
feePerByte int64
|
||||||
|
maxBlockSystemFee int64
|
||||||
maxVerificationGas int64
|
maxVerificationGas int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,44 +71,53 @@ func newPolicy() *Policy {
|
||||||
p.Manifest.Features |= smartcontract.HasStorage
|
p.Manifest.Features |= smartcontract.HasStorage
|
||||||
|
|
||||||
desc := newDescriptor("getMaxTransactionsPerBlock", smartcontract.IntegerType)
|
desc := newDescriptor("getMaxTransactionsPerBlock", smartcontract.IntegerType)
|
||||||
md := newMethodAndPrice(p.getMaxTransactionsPerBlock, 1000000, smartcontract.NoneFlag)
|
md := newMethodAndPrice(p.getMaxTransactionsPerBlock, 1000000, smartcontract.AllowStates)
|
||||||
p.AddMethod(md, desc, true)
|
p.AddMethod(md, desc, true)
|
||||||
|
|
||||||
desc = newDescriptor("getMaxBlockSize", smartcontract.IntegerType)
|
desc = newDescriptor("getMaxBlockSize", smartcontract.IntegerType)
|
||||||
md = newMethodAndPrice(p.getMaxBlockSize, 1000000, smartcontract.NoneFlag)
|
md = newMethodAndPrice(p.getMaxBlockSize, 1000000, smartcontract.AllowStates)
|
||||||
p.AddMethod(md, desc, true)
|
p.AddMethod(md, desc, true)
|
||||||
|
|
||||||
desc = newDescriptor("getFeePerByte", smartcontract.IntegerType)
|
desc = newDescriptor("getFeePerByte", smartcontract.IntegerType)
|
||||||
md = newMethodAndPrice(p.getFeePerByte, 1000000, smartcontract.NoneFlag)
|
md = newMethodAndPrice(p.getFeePerByte, 1000000, smartcontract.AllowStates)
|
||||||
p.AddMethod(md, desc, true)
|
p.AddMethod(md, desc, true)
|
||||||
|
|
||||||
desc = newDescriptor("getBlockedAccounts", smartcontract.ArrayType)
|
desc = newDescriptor("getBlockedAccounts", smartcontract.ArrayType)
|
||||||
md = newMethodAndPrice(p.getBlockedAccounts, 1000000, smartcontract.NoneFlag)
|
md = newMethodAndPrice(p.getBlockedAccounts, 1000000, smartcontract.AllowStates)
|
||||||
|
p.AddMethod(md, desc, true)
|
||||||
|
|
||||||
|
desc = newDescriptor("getMaxBlockSystemFee", smartcontract.IntegerType)
|
||||||
|
md = newMethodAndPrice(p.getMaxBlockSystemFee, 1000000, smartcontract.AllowStates)
|
||||||
p.AddMethod(md, desc, true)
|
p.AddMethod(md, desc, true)
|
||||||
|
|
||||||
desc = newDescriptor("setMaxBlockSize", smartcontract.BoolType,
|
desc = newDescriptor("setMaxBlockSize", smartcontract.BoolType,
|
||||||
manifest.NewParameter("value", smartcontract.IntegerType))
|
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||||
md = newMethodAndPrice(p.setMaxBlockSize, 3000000, smartcontract.NoneFlag)
|
md = newMethodAndPrice(p.setMaxBlockSize, 3000000, smartcontract.AllowModifyStates)
|
||||||
p.AddMethod(md, desc, false)
|
p.AddMethod(md, desc, false)
|
||||||
|
|
||||||
desc = newDescriptor("setMaxTransactionsPerBlock", smartcontract.BoolType,
|
desc = newDescriptor("setMaxTransactionsPerBlock", smartcontract.BoolType,
|
||||||
manifest.NewParameter("value", smartcontract.IntegerType))
|
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||||
md = newMethodAndPrice(p.setMaxTransactionsPerBlock, 3000000, smartcontract.NoneFlag)
|
md = newMethodAndPrice(p.setMaxTransactionsPerBlock, 3000000, smartcontract.AllowModifyStates)
|
||||||
p.AddMethod(md, desc, false)
|
p.AddMethod(md, desc, false)
|
||||||
|
|
||||||
desc = newDescriptor("setFeePerByte", smartcontract.BoolType,
|
desc = newDescriptor("setFeePerByte", smartcontract.BoolType,
|
||||||
manifest.NewParameter("value", smartcontract.IntegerType))
|
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||||
md = newMethodAndPrice(p.setFeePerByte, 3000000, smartcontract.NoneFlag)
|
md = newMethodAndPrice(p.setFeePerByte, 3000000, smartcontract.AllowModifyStates)
|
||||||
|
p.AddMethod(md, desc, false)
|
||||||
|
|
||||||
|
desc = newDescriptor("setMaxBlockSystemFee", smartcontract.BoolType,
|
||||||
|
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||||
|
md = newMethodAndPrice(p.setMaxBlockSystemFee, 3000000, smartcontract.AllowModifyStates)
|
||||||
p.AddMethod(md, desc, false)
|
p.AddMethod(md, desc, false)
|
||||||
|
|
||||||
desc = newDescriptor("blockAccount", smartcontract.BoolType,
|
desc = newDescriptor("blockAccount", smartcontract.BoolType,
|
||||||
manifest.NewParameter("account", smartcontract.Hash160Type))
|
manifest.NewParameter("account", smartcontract.Hash160Type))
|
||||||
md = newMethodAndPrice(p.blockAccount, 3000000, smartcontract.NoneFlag)
|
md = newMethodAndPrice(p.blockAccount, 3000000, smartcontract.AllowModifyStates)
|
||||||
p.AddMethod(md, desc, false)
|
p.AddMethod(md, desc, false)
|
||||||
|
|
||||||
desc = newDescriptor("unblockAccount", smartcontract.BoolType,
|
desc = newDescriptor("unblockAccount", smartcontract.BoolType,
|
||||||
manifest.NewParameter("account", smartcontract.Hash160Type))
|
manifest.NewParameter("account", smartcontract.Hash160Type))
|
||||||
md = newMethodAndPrice(p.unblockAccount, 3000000, smartcontract.NoneFlag)
|
md = newMethodAndPrice(p.unblockAccount, 3000000, smartcontract.AllowModifyStates)
|
||||||
p.AddMethod(md, desc, false)
|
p.AddMethod(md, desc, false)
|
||||||
|
|
||||||
desc = newDescriptor("onPersist", smartcontract.VoidType)
|
desc = newDescriptor("onPersist", smartcontract.VoidType)
|
||||||
|
@ -140,6 +155,12 @@ func (p *Policy) Initialize(ic *interop.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binary.LittleEndian.PutUint64(si.Value, defaultMaxBlockSystemFee)
|
||||||
|
err = ic.DAO.PutStorageItem(p.ContractID, maxBlockSystemFeeKey, si)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ba := new(BlockedAccounts)
|
ba := new(BlockedAccounts)
|
||||||
si.Value = ba.Bytes()
|
si.Value = ba.Bytes()
|
||||||
err = ic.DAO.PutStorageItem(p.ContractID, blockedAccountsKey, si)
|
err = ic.DAO.PutStorageItem(p.ContractID, blockedAccountsKey, si)
|
||||||
|
@ -151,6 +172,7 @@ func (p *Policy) Initialize(ic *interop.Context) error {
|
||||||
p.maxTransactionsPerBlock = defaultMaxTransactionsPerBlock
|
p.maxTransactionsPerBlock = defaultMaxTransactionsPerBlock
|
||||||
p.maxBlockSize = defaultMaxBlockSize
|
p.maxBlockSize = defaultMaxBlockSize
|
||||||
p.feePerByte = defaultFeePerByte
|
p.feePerByte = defaultFeePerByte
|
||||||
|
p.maxBlockSystemFee = defaultMaxBlockSystemFee
|
||||||
p.maxVerificationGas = defaultMaxVerificationGas
|
p.maxVerificationGas = defaultMaxVerificationGas
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -178,6 +200,9 @@ func (p *Policy) OnPersistEnd(dao dao.DAO) {
|
||||||
feePerByte := p.getInt64WithKey(dao, feePerByteKey)
|
feePerByte := p.getInt64WithKey(dao, feePerByteKey)
|
||||||
p.feePerByte = feePerByte
|
p.feePerByte = feePerByte
|
||||||
|
|
||||||
|
maxBlockSystemFee := p.getInt64WithKey(dao, maxBlockSystemFeeKey)
|
||||||
|
p.maxBlockSystemFee = maxBlockSystemFee
|
||||||
|
|
||||||
p.isValid = true
|
p.isValid = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,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
|
||||||
|
@ -229,6 +259,22 @@ func (p *Policy) GetMaxVerificationGas(_ dao.DAO) int64 {
|
||||||
return p.maxVerificationGas
|
return p.maxVerificationGas
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getMaxBlockSystemFee is Policy contract method and returns the maximum overall
|
||||||
|
// system fee per block.
|
||||||
|
func (p *Policy) getMaxBlockSystemFee(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
|
||||||
|
return stackitem.NewBigInteger(big.NewInt(p.GetMaxBlockSystemFeeInternal(ic.DAO)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMaxBlockSystemFeeInternal the maximum overall system fee per block.
|
||||||
|
func (p *Policy) GetMaxBlockSystemFeeInternal(dao dao.DAO) int64 {
|
||||||
|
p.lock.RLock()
|
||||||
|
defer p.lock.RUnlock()
|
||||||
|
if p.isValid {
|
||||||
|
return p.maxBlockSystemFee
|
||||||
|
}
|
||||||
|
return p.getInt64WithKey(dao, maxBlockSystemFeeKey)
|
||||||
|
}
|
||||||
|
|
||||||
// getBlockedAccounts is Policy contract method and returns list of blocked
|
// getBlockedAccounts is Policy contract method and returns list of blocked
|
||||||
// accounts hashes.
|
// accounts hashes.
|
||||||
func (p *Policy) getBlockedAccounts(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
|
func (p *Policy) getBlockedAccounts(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
|
||||||
|
@ -316,6 +362,29 @@ func (p *Policy) setFeePerByte(ic *interop.Context, args []stackitem.Item) stack
|
||||||
return stackitem.NewBool(true)
|
return stackitem.NewBool(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setMaxBlockSystemFee is Policy contract method and sets the maximum system fee per block.
|
||||||
|
func (p *Policy) setMaxBlockSystemFee(ic *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
|
ok, err := p.checkValidators(ic)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return stackitem.NewBool(false)
|
||||||
|
}
|
||||||
|
value := toBigInt(args[0]).Int64()
|
||||||
|
if value <= minBlockSystemFee {
|
||||||
|
return stackitem.NewBool(false)
|
||||||
|
}
|
||||||
|
p.lock.Lock()
|
||||||
|
defer p.lock.Unlock()
|
||||||
|
err = p.setInt64WithKey(ic.DAO, maxBlockSystemFeeKey, value)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
p.isValid = false
|
||||||
|
return stackitem.NewBool(true)
|
||||||
|
}
|
||||||
|
|
||||||
// blockAccount is Policy contract method and adds given account hash to the list
|
// blockAccount is Policy contract method and adds given account hash to the list
|
||||||
// of blocked accounts.
|
// of blocked accounts.
|
||||||
func (p *Policy) blockAccount(ic *interop.Context, args []stackitem.Item) stackitem.Item {
|
func (p *Policy) blockAccount(ic *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
|
|
|
@ -47,7 +47,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, stackitem.NewBigInteger(big.NewInt(1024*256)))
|
checkResult(t, res, stackitem.NewBigInteger(big.NewInt(1024*256)))
|
||||||
|
@ -92,6 +97,52 @@ func TestFeePerByte(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBlockSystemFee(t *testing.T) {
|
||||||
|
chain := newTestChain(t)
|
||||||
|
defer chain.Close()
|
||||||
|
|
||||||
|
t.Run("get, internal method", func(t *testing.T) {
|
||||||
|
n := chain.contracts.Policy.GetMaxBlockSystemFeeInternal(chain.dao)
|
||||||
|
require.Equal(t, 9000*native.GASFactor, int(n))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("get", func(t *testing.T) {
|
||||||
|
res, err := invokeNativePolicyMethod(chain, "getMaxBlockSystemFee")
|
||||||
|
require.NoError(t, err)
|
||||||
|
checkResult(t, res, smartcontract.Parameter{
|
||||||
|
Type: smartcontract.IntegerType,
|
||||||
|
Value: 9000 * native.GASFactor,
|
||||||
|
})
|
||||||
|
require.NoError(t, chain.persist())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("set, too low fee", func(t *testing.T) {
|
||||||
|
res, err := invokeNativePolicyMethod(chain, "setMaxBlockSystemFee", bigint.ToBytes(big.NewInt(4007600)))
|
||||||
|
require.NoError(t, err)
|
||||||
|
checkResult(t, res, smartcontract.Parameter{
|
||||||
|
Type: smartcontract.BoolType,
|
||||||
|
Value: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("set, success", func(t *testing.T) {
|
||||||
|
res, err := invokeNativePolicyMethod(chain, "setMaxBlockSystemFee", bigint.ToBytes(big.NewInt(100000000)))
|
||||||
|
require.NoError(t, err)
|
||||||
|
checkResult(t, res, smartcontract.Parameter{
|
||||||
|
Type: smartcontract.BoolType,
|
||||||
|
Value: true,
|
||||||
|
})
|
||||||
|
require.NoError(t, chain.persist())
|
||||||
|
res, err = invokeNativePolicyMethod(chain, "getMaxBlockSystemFee")
|
||||||
|
require.NoError(t, err)
|
||||||
|
checkResult(t, res, smartcontract.Parameter{
|
||||||
|
Type: smartcontract.IntegerType,
|
||||||
|
Value: 100000000,
|
||||||
|
})
|
||||||
|
require.NoError(t, chain.persist())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestBlockedAccounts(t *testing.T) {
|
func TestBlockedAccounts(t *testing.T) {
|
||||||
chain := newTestChain(t)
|
chain := newTestChain(t)
|
||||||
defer chain.Close()
|
defer chain.Close()
|
||||||
|
|
|
@ -40,6 +40,14 @@ func (chain testChain) FeePerByte() int64 {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (chain testChain) GetMaxBlockSystemFee() int64 {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (chain testChain) GetMaxBlockSize() uint32 {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
func (chain testChain) AddHeaders(...*block.Header) error {
|
func (chain testChain) AddHeaders(...*block.Header) error {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue