From db65ed04d9ac203d3cbf3ab248971a3ea73bcc81 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Mon, 3 Aug 2020 19:27:32 +0300 Subject: [PATCH] consensus: apply policy during verifyBlock To follow C# implementation we should also check proposed block on policy matching. --- pkg/consensus/consensus.go | 20 ++++++++++++++++++++ pkg/core/blockchain.go | 10 ++++++++++ pkg/core/blockchainer/blockchainer.go | 2 ++ pkg/network/helper_test.go | 8 ++++++++ 4 files changed, 40 insertions(+) diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index 921da8659..d41373af4 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -341,7 +341,19 @@ func (s *service) getTx(h util.Uint256) block.Transaction { func (s *service) verifyBlock(b block.Block) bool { 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 { + fee += tx.SystemFee if err := s.Chain.VerifyTx(tx, coreb); err != nil { s.log.Warn("invalid transaction in proposed block", 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 } diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index eb80d4ee9..8b571e8a5 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -1147,6 +1147,16 @@ func (bc *Blockchain) FeePerByte() int64 { 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. func (bc *Blockchain) GetMemPool() *mempool.Pool { return &bc.memPool diff --git a/pkg/core/blockchainer/blockchainer.go b/pkg/core/blockchainer/blockchainer.go index fc9ca0110..b1ff94f12 100644 --- a/pkg/core/blockchainer/blockchainer.go +++ b/pkg/core/blockchainer/blockchainer.go @@ -50,6 +50,8 @@ type Blockchainer interface { GetTestVM(tx *transaction.Transaction) *vm.VM GetTransaction(util.Uint256) (*transaction.Transaction, uint32, error) mempool.Feer // fee interface + GetMaxBlockSize() uint32 + GetMaxBlockSystemFee() int64 PoolTx(*transaction.Transaction) error SubscribeForBlocks(ch chan<- *block.Block) SubscribeForExecutions(ch chan<- *state.AppExecResult) diff --git a/pkg/network/helper_test.go b/pkg/network/helper_test.go index 2e7d336e6..45ccc3615 100644 --- a/pkg/network/helper_test.go +++ b/pkg/network/helper_test.go @@ -40,6 +40,14 @@ func (chain testChain) FeePerByte() int64 { panic("TODO") } +func (chain testChain) GetMaxBlockSystemFee() int64 { + panic("TODO") +} + +func (chain testChain) GetMaxBlockSize() uint32 { + panic("TODO") +} + func (chain testChain) AddHeaders(...*block.Header) error { panic("TODO") }