[NOD-1259] Do not panic on non-protocol errors from RPC (#863)

* [NOD-1259] All rule-errors should be protocol-errors

* [NOD-1259] Handle submitting of coinbase transactions properly

* Revert "[NOD-1259] All rule-errors should be protocol-errors"

This reverts commit 2fd30c185640fcee62030f72ed14654570a1d7c7.

* [NOD-1259] Don't panic on non-protocol errors in ProtocolManager.AddTransaction/AddBlock

* [NOD-1259] Implement subnetworkid.IsBuiltInOrNative and use where appropriate
This commit is contained in:
Svarog 2020-08-12 12:29:58 +03:00 committed by GitHub
parent aa9556aa59
commit 91f4ed9825
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 19 additions and 36 deletions

View File

@ -881,7 +881,7 @@ func (dag *BlockDAG) validateGasLimit(block *util.Block) error {
// In native and Built-In subnetworks all txs must have Gas = 0, and that was already validated in checkTransactionSanity // In native and Built-In subnetworks all txs must have Gas = 0, and that was already validated in checkTransactionSanity
// Therefore - no need to check them here. // Therefore - no need to check them here.
if msgTx.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) || msgTx.SubnetworkID.IsBuiltIn() { if msgTx.SubnetworkID.IsBuiltInOrNative() {
continue continue
} }

View File

@ -6,11 +6,12 @@ package blockdag
import ( import (
"fmt" "fmt"
"github.com/kaspanet/kaspad/util/mstime"
"math" "math"
"sort" "sort"
"time" "time"
"github.com/kaspanet/kaspad/util/mstime"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/kaspanet/kaspad/dagconfig" "github.com/kaspanet/kaspad/dagconfig"
@ -212,10 +213,7 @@ func CheckTransactionSanity(tx *util.Tx, subnetworkID *subnetworkid.SubnetworkID
} }
// Transactions in native, registry and coinbase subnetworks must have Gas = 0 // Transactions in native, registry and coinbase subnetworks must have Gas = 0
if (msgTx.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) || if msgTx.SubnetworkID.IsBuiltInOrNative() && msgTx.Gas > 0 {
msgTx.SubnetworkID.IsBuiltIn()) &&
msgTx.Gas > 0 {
return ruleError(ErrInvalidGas, "transaction in the native or "+ return ruleError(ErrInvalidGas, "transaction in the native or "+
"registry subnetworks has gas > 0 ") "registry subnetworks has gas > 0 ")
} }

View File

@ -851,7 +851,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *util.Tx, rejectDupOrphans bool) ([]
// Check that transaction does not overuse GAS // Check that transaction does not overuse GAS
msgTx := tx.MsgTx() msgTx := tx.MsgTx()
if !msgTx.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) && !msgTx.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDRegistry) { if !msgTx.SubnetworkID.IsBuiltInOrNative() {
gasLimit, err := mp.cfg.DAG.GasLimit(&msgTx.SubnetworkID) gasLimit, err := mp.cfg.DAG.GasLimit(&msgTx.SubnetworkID)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err

View File

@ -156,7 +156,7 @@ func (g *BlkTmplGenerator) collectCandidatesTxs(sourceTxs []*TxDesc) []*candidat
} }
gasLimit := uint64(0) gasLimit := uint64(0)
if !tx.MsgTx().SubnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) && !tx.MsgTx().SubnetworkID.IsBuiltIn() { if !tx.MsgTx().SubnetworkID.IsBuiltInOrNative() {
subnetworkID := tx.MsgTx().SubnetworkID subnetworkID := tx.MsgTx().SubnetworkID
gasLimit, err = g.dag.GasLimit(&subnetworkID) gasLimit, err = g.dag.GasLimit(&subnetworkID)
if err != nil { if err != nil {
@ -202,8 +202,7 @@ func (g *BlkTmplGenerator) calcTxValue(tx *util.Tx, fee uint64) (float64, error)
massLimit := g.policy.BlockMaxMass massLimit := g.policy.BlockMaxMass
msgTx := tx.MsgTx() msgTx := tx.MsgTx()
if msgTx.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) || if msgTx.SubnetworkID.IsBuiltInOrNative() {
msgTx.SubnetworkID.IsBuiltIn() {
return float64(fee) / (float64(mass) / float64(massLimit)), nil return float64(fee) / (float64(mass) / float64(massLimit)), nil
} }
@ -266,7 +265,7 @@ func (g *BlkTmplGenerator) populateTemplateFromCandidates(candidateTxs []*candid
// Enforce maximum gas per subnetwork per block. Also check // Enforce maximum gas per subnetwork per block. Also check
// for overflow. // for overflow.
if !tx.MsgTx().SubnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) && !tx.MsgTx().SubnetworkID.IsBuiltIn() { if !tx.MsgTx().SubnetworkID.IsBuiltInOrNative() {
subnetworkID := tx.MsgTx().SubnetworkID subnetworkID := tx.MsgTx().SubnetworkID
gasUsage, ok := gasUsageMap[subnetworkID] gasUsage, ok := gasUsageMap[subnetworkID]
if !ok { if !ok {

View File

@ -11,9 +11,7 @@ import (
"github.com/kaspanet/kaspad/netadapter" "github.com/kaspanet/kaspad/netadapter"
"github.com/kaspanet/kaspad/protocol/flowcontext" "github.com/kaspanet/kaspad/protocol/flowcontext"
peerpkg "github.com/kaspanet/kaspad/protocol/peer" peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/protocol/protocolerrors"
"github.com/kaspanet/kaspad/util" "github.com/kaspanet/kaspad/util"
"github.com/pkg/errors"
) )
// Manager manages the p2p protocol // Manager manages the p2p protocol
@ -56,30 +54,12 @@ func (m *Manager) IBDPeer() *peerpkg.Peer {
// AddTransaction adds transaction to the mempool and propagates it. // AddTransaction adds transaction to the mempool and propagates it.
func (m *Manager) AddTransaction(tx *util.Tx) error { func (m *Manager) AddTransaction(tx *util.Tx) error {
err := m.context.AddTransaction(tx) return m.context.AddTransaction(tx)
if err != nil {
if protocolErr := &(protocolerrors.ProtocolError{}); errors.As(err, &protocolErr) {
return err
}
// TODO(libp2p): Remove panic once RPC is integrated into protocol architecture
panic(err)
}
return nil
} }
// AddBlock adds the given block to the DAG and propagates it. // AddBlock adds the given block to the DAG and propagates it.
func (m *Manager) AddBlock(block *util.Block, flags blockdag.BehaviorFlags) error { func (m *Manager) AddBlock(block *util.Block, flags blockdag.BehaviorFlags) error {
err := m.context.AddBlock(block, flags) return m.context.AddBlock(block, flags)
if err != nil {
if protocolErr := &(protocolerrors.ProtocolError{}); errors.As(err, &protocolErr) {
return err
}
// TODO(libp2p): Remove panic once RPC is integrated into protocol architecture
panic(err)
}
return nil
} }
func (m *Manager) runFlows(flows []*flow, peer *peerpkg.Peer, errChan <-chan error) error { func (m *Manager) runFlows(flows []*flow, peer *peerpkg.Peer, errChan <-chan error) error {

View File

@ -15,8 +15,7 @@ func handleGetSubnetwork(s *Server, cmd interface{}, closeChan <-chan struct{})
} }
var gasLimit *uint64 var gasLimit *uint64
if !subnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) && if !subnetworkID.IsBuiltInOrNative() {
!subnetworkID.IsBuiltIn() {
limit, err := s.dag.GasLimit(subnetworkID) limit, err := s.dag.GasLimit(subnetworkID)
if err != nil { if err != nil {
return nil, &model.RPCError{ return nil, &model.RPCError{

View File

@ -7,8 +7,9 @@ package subnetworkid
import ( import (
"encoding/hex" "encoding/hex"
"github.com/pkg/errors"
"math/big" "math/big"
"github.com/pkg/errors"
) )
// IDLength of array used to store the subnetwork ID. See SubnetworkID. // IDLength of array used to store the subnetwork ID. See SubnetworkID.
@ -196,6 +197,12 @@ func (id *SubnetworkID) IsBuiltIn() bool {
return id.IsEqual(SubnetworkIDCoinbase) || id.IsEqual(SubnetworkIDRegistry) return id.IsEqual(SubnetworkIDCoinbase) || id.IsEqual(SubnetworkIDRegistry)
} }
// IsBuiltInOrNative returns true if the subnetwork is the native or a built in subnetwork,
// see IsBuiltIn for further details
func (id *SubnetworkID) IsBuiltInOrNative() bool {
return id.IsEqual(SubnetworkIDNative) || id.IsBuiltIn()
}
// Less returns true iff id a is less than id b // Less returns true iff id a is less than id b
func Less(a *SubnetworkID, b *SubnetworkID) bool { func Less(a *SubnetworkID, b *SubnetworkID) bool {
return a.Cmp(b) < 0 return a.Cmp(b) < 0