diff --git a/config/protocol.mainnet.yml b/config/protocol.mainnet.yml index 14f163821..65eae8412 100644 --- a/config/protocol.mainnet.yml +++ b/config/protocol.mainnet.yml @@ -36,6 +36,7 @@ ProtocolConfiguration: MaxTransactionsPerBlock: 500 MaxFreeTransactionsPerBlock: 20 MaxFreeTransactionSize: 1024 + MinimumNetworkFee: 0 FeePerExtraByte: 0.00001 ApplicationConfiguration: diff --git a/config/protocol.testnet.yml b/config/protocol.testnet.yml index ccfe6a689..fa04b58ec 100644 --- a/config/protocol.testnet.yml +++ b/config/protocol.testnet.yml @@ -36,6 +36,7 @@ ProtocolConfiguration: MaxTransactionsPerBlock: 500 MaxFreeTransactionsPerBlock: 20 MaxFreeTransactionSize: 1024 + MinimumNetworkFee: 0 FeePerExtraByte: 0.00001 ApplicationConfiguration: diff --git a/pkg/config/protocol_config.go b/pkg/config/protocol_config.go index acd2bb203..13c2deba5 100644 --- a/pkg/config/protocol_config.go +++ b/pkg/config/protocol_config.go @@ -36,7 +36,9 @@ type ( MaxFreeTransactionSize int `yaml:"MaxFreeTransactionSize"` // Maximum number of low priority transactions accepted into block. MaxFreeTransactionsPerBlock int `yaml:"MaxFreeTransactionsPerBlock"` - MemPoolSize int `yaml:"MemPoolSize"` + // MinimumNetworkFee sets the minimum required network fee for transaction to pass validation. + MinimumNetworkFee util.Fixed8 `yaml:"MinimumNetworkFee"` + MemPoolSize int `yaml:"MemPoolSize"` // SaveStorageBatch enables storage batch saving before every persist. SaveStorageBatch bool `yaml:"SaveStorageBatch"` SecondsPerBlock int `yaml:"SecondsPerBlock"` diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 1481302b1..2bcf7c777 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -168,6 +168,10 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L cfg.MaxFreeTransactionSize = 0 log.Info("MaxFreeTransactionSize is not set or wrong, setting default value (unlimited)", zap.Int("MaxFreeTransactionSize", cfg.MaxFreeTransactionSize)) } + if cfg.MinimumNetworkFee < 0 { + cfg.MinimumNetworkFee = 0 + log.Info("MinimumNetworkFee is not set or wrong, setting default value (0)", zap.String("MinimumNetworkFee", cfg.MinimumNetworkFee.String())) + } if cfg.FeePerExtraByte <= 0 { cfg.FeePerExtraByte = 0 log.Info("FeePerExtraByte is not set or wrong, setting default value", zap.Float64("FeePerExtraByte", cfg.FeePerExtraByte)) @@ -1996,13 +2000,16 @@ func (bc *Blockchain) PoolTx(t *transaction.Transaction) error { if t.Type != transaction.ClaimType { txSize := io.GetVarSize(t) maxFree := bc.config.MaxFreeTransactionSize + netFee := bc.NetworkFee(t) if maxFree != 0 && txSize > maxFree { - netFee := bc.NetworkFee(t) if bc.IsLowPriority(netFee) || netFee < util.Fixed8FromFloat(bc.config.FeePerExtraByte)*util.Fixed8(txSize-maxFree) { return ErrPolicy } } + if t.Type == transaction.InvocationType && netFee < bc.config.MinimumNetworkFee { + return ErrPolicy + } } if err := bc.memPool.Add(t, bc); err != nil { switch err { diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 216f6d3be..e05671399 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -89,6 +89,7 @@ var rpcHandlers = map[string]func(*Server, request.Params) (interface{}, *respon "getclaimable": (*Server).getClaimable, "getconnectioncount": (*Server).getConnectionCount, "getcontractstate": (*Server).getContractState, + "getminimumnetworkfee": (*Server).getMinimumNetworkFee, "getnep5balances": (*Server).getNEP5Balances, "getnep5transfers": (*Server).getNEP5Transfers, "getpeers": (*Server).getPeers, @@ -798,6 +799,10 @@ func (s *Server) getNEP5Transfers(ps request.Params) (interface{}, *response.Err return bs, nil } +func (s *Server) getMinimumNetworkFee(ps request.Params) (interface{}, *response.Error) { + return s.chain.GetConfig().MinimumNetworkFee, nil +} + func (s *Server) getProof(ps request.Params) (interface{}, *response.Error) { root, err := ps.Value(0).GetUint256() if err != nil {