Skip to content

Commit

Permalink
Merge pull request #288 from koinos/287-no-nonce-error-score
Browse files Browse the repository at this point in the history
No error score on invalid nonce
  • Loading branch information
sgerbino committed Mar 28, 2024
2 parents 1ce4c26 + 9f0e346 commit 4569bc2
Show file tree
Hide file tree
Showing 24 changed files with 1,232 additions and 84 deletions.
2 changes: 1 addition & 1 deletion cmd/koinos-p2p/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"github.com/koinos/koinos-p2p/internal/node"
"github.com/koinos/koinos-p2p/internal/options"
"github.com/koinos/koinos-p2p/internal/rpc"
util "github.com/koinos/koinos-util-golang"
util "github.com/koinos/koinos-util-golang/v2"
flag "github.com/spf13/pflag"
)

Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ go 1.20
require (
filippo.io/keygen v0.0.0-20230306160926-5201437acf8e
github.com/ipfs/go-log v1.0.5
github.com/koinos/koinos-log-golang v1.0.0
github.com/koinos/koinos-log-golang/v2 v2.0.0
github.com/koinos/koinos-mq-golang v1.0.0
github.com/koinos/koinos-proto-golang v1.0.0
github.com/koinos/koinos-util-golang v1.0.0
github.com/koinos/koinos-proto-golang/v2 v2.0.1
github.com/koinos/koinos-util-golang/v2 v2.0.0
github.com/libp2p/go-libp2p v0.30.0
github.com/libp2p/go-libp2p-gorpc v0.5.0
github.com/libp2p/go-libp2p-kad-dht v0.25.0
Expand Down Expand Up @@ -63,7 +63,7 @@ require (
github.com/jbenet/goprocess v0.1.4 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/koinos/koinos-log-golang/v2 v2.0.0 // indirect
github.com/koinos/koinos-log-golang v1.0.0 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-cidranger v1.1.0 // indirect
Expand Down
1,110 changes: 1,097 additions & 13 deletions go.sum

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions internal/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ import (

"filippo.io/keygen"

log "github.com/koinos/koinos-log-golang"
log "github.com/koinos/koinos-log-golang/v2"
koinosmq "github.com/koinos/koinos-mq-golang"
"github.com/koinos/koinos-p2p/internal/options"
"github.com/koinos/koinos-p2p/internal/p2p"
"github.com/koinos/koinos-p2p/internal/rpc"
"github.com/koinos/koinos-proto-golang/koinos"
"github.com/koinos/koinos-proto-golang/koinos/broadcast"
prpc "github.com/koinos/koinos-proto-golang/koinos/rpc"
rpcp2p "github.com/koinos/koinos-proto-golang/koinos/rpc/p2p"
util "github.com/koinos/koinos-util-golang"
"github.com/koinos/koinos-proto-golang/v2/koinos"
"github.com/koinos/koinos-proto-golang/v2/koinos/broadcast"
prpc "github.com/koinos/koinos-proto-golang/v2/koinos/rpc"
rpcp2p "github.com/koinos/koinos-proto-golang/v2/koinos/rpc/p2p"
util "github.com/koinos/koinos-util-golang/v2"

libp2p "github.com/libp2p/go-libp2p"
dht "github.com/libp2p/go-libp2p-kad-dht"
Expand Down Expand Up @@ -274,7 +274,7 @@ func (n *KoinosP2PNode) handleRPC(rpcType string, data []byte) ([]byte, error) {
err := proto.Unmarshal(data, req)
if err != nil {
log.Warnf("Received malformed request: 0x%v", hex.EncodeToString(data))
eResp := prpc.ErrorResponse{Message: err.Error()}
eResp := prpc.ErrorStatus{Message: err.Error()}
rErr := rpcp2p.P2PResponse_Error{Error: &eResp}
resp.Response = &rErr
} else {
Expand Down Expand Up @@ -306,7 +306,7 @@ func (n *KoinosP2PNode) handleRequest(req *rpcp2p.P2PRequest) *rpcp2p.P2PRespons
}

if err != nil {
result := prpc.ErrorResponse{Message: err.Error()}
result := prpc.ErrorStatus{Message: err.Error()}
respVal := rpcp2p.P2PResponse_Error{Error: &result}
response.Response = &respVal
}
Expand Down
8 changes: 4 additions & 4 deletions internal/node/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import (
"testing"

"github.com/koinos/koinos-p2p/internal/options"
"github.com/koinos/koinos-proto-golang/koinos"
"github.com/koinos/koinos-proto-golang/koinos/protocol"
"github.com/koinos/koinos-proto-golang/koinos/rpc/block_store"
"github.com/koinos/koinos-proto-golang/koinos/rpc/chain"
"github.com/koinos/koinos-proto-golang/v2/koinos"
"github.com/koinos/koinos-proto-golang/v2/koinos/protocol"
"github.com/koinos/koinos-proto-golang/v2/koinos/rpc/block_store"
"github.com/koinos/koinos-proto-golang/v2/koinos/rpc/chain"
"github.com/multiformats/go-multihash"
)

Expand Down
3 changes: 3 additions & 0 deletions internal/options/error_handler_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const (
blockApplicationTimeoutErrorScoreDefault = 2500
maxPendingBlocksErrorScoreDefault = 1000
transactionApplicationErrorScoreDefault = 100
invalidNonceErrorScoreDefault = 0
chainIDMismatchErrorScoreDefault = errorScoreThresholdDefault * 2
chainNotConnectedErrorScoreDefault = errorScoreThresholdDefault * 2
checkpointMismatchErrorScoreDefault = errorScoreThresholdDefault * 2
Expand Down Expand Up @@ -44,6 +45,7 @@ type PeerErrorHandlerOptions struct {
BlockApplicationTimeoutErrorScore uint64
MaxPendingBlocksErrorScore uint64
TransactionApplicationErrorScore uint64
InvalidNonceErrorScore uint64
ChainIDMismatchErrorScore uint64
ChainNotConnectedErrorScore uint64
CheckpointMismatchErrorScore uint64
Expand Down Expand Up @@ -71,6 +73,7 @@ func NewPeerErrorHandlerOptions() *PeerErrorHandlerOptions {
BlockApplicationTimeoutErrorScore: blockApplicationTimeoutErrorScoreDefault,
MaxPendingBlocksErrorScore: maxPendingBlocksErrorScoreDefault,
TransactionApplicationErrorScore: transactionApplicationErrorScoreDefault,
InvalidNonceErrorScore: invalidNonceErrorScoreDefault,
ChainIDMismatchErrorScore: chainIDMismatchErrorScoreDefault,
ChainNotConnectedErrorScore: chainNotConnectedErrorScoreDefault,
CheckpointMismatchErrorScore: checkpointMismatchErrorScoreDefault,
Expand Down
4 changes: 2 additions & 2 deletions internal/p2p/applicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"github.com/koinos/koinos-p2p/internal/options"
"github.com/koinos/koinos-p2p/internal/p2perrors"
"github.com/koinos/koinos-p2p/internal/rpc"
"github.com/koinos/koinos-proto-golang/koinos/broadcast"
"github.com/koinos/koinos-proto-golang/koinos/protocol"
"github.com/koinos/koinos-proto-golang/v2/koinos/broadcast"
"github.com/koinos/koinos-proto-golang/v2/koinos/protocol"
)

type blockEntry struct {
Expand Down
57 changes: 51 additions & 6 deletions internal/p2p/applicator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@ import (

"github.com/koinos/koinos-p2p/internal/options"
"github.com/koinos/koinos-p2p/internal/p2perrors"
"github.com/koinos/koinos-proto-golang/koinos"
"github.com/koinos/koinos-proto-golang/koinos/broadcast"
"github.com/koinos/koinos-proto-golang/koinos/protocol"
"github.com/koinos/koinos-proto-golang/koinos/rpc/block_store"
"github.com/koinos/koinos-proto-golang/koinos/rpc/chain"
"github.com/koinos/koinos-proto-golang/v2/koinos"
"github.com/koinos/koinos-proto-golang/v2/koinos/broadcast"
"github.com/koinos/koinos-proto-golang/v2/koinos/protocol"
"github.com/koinos/koinos-proto-golang/v2/koinos/rpc/block_store"
"github.com/koinos/koinos-proto-golang/v2/koinos/rpc/chain"
"github.com/multiformats/go-multihash"
)

type applicatorTestRPC struct {
blocksToFail map[string]void
unlinkableBlocks map[string]void
head []byte
invalidNonceTrxs map[string]void
}

func (b *applicatorTestRPC) GetHeadBlock(ctx context.Context) (*chain.GetHeadInfoResponse, error) {
Expand All @@ -43,7 +44,11 @@ func (b *applicatorTestRPC) ApplyBlock(ctx context.Context, block *protocol.Bloc
return &chain.SubmitBlockResponse{}, nil
}

func (b *applicatorTestRPC) ApplyTransaction(ctx context.Context, block *protocol.Transaction) (*chain.SubmitTransactionResponse, error) {
func (b *applicatorTestRPC) ApplyTransaction(ctx context.Context, trx *protocol.Transaction) (*chain.SubmitTransactionResponse, error) {
if _, ok := b.invalidNonceTrxs[string(trx.Id)]; ok {
return nil, p2perrors.ErrInvalidNonce
}

return &chain.SubmitTransactionResponse{}, nil
}

Expand Down Expand Up @@ -81,6 +86,7 @@ func TestApplicator(t *testing.T) {
blocksToFail: make(map[string]void),
unlinkableBlocks: make(map[string]void),
head: []byte{0x00},
invalidNonceTrxs: make(map[string]void),
}

applicator, err := NewApplicator(ctx, &rpc, NewTransactionCache(time.Minute), *options.NewApplicatorOptions())
Expand Down Expand Up @@ -243,6 +249,7 @@ func TestApplicatorLimits(t *testing.T) {
blocksToFail: make(map[string]void),
unlinkableBlocks: make(map[string]void),
head: []byte{0x00},
invalidNonceTrxs: make(map[string]void),
}

applicator, err := NewApplicator(ctx, &rpc, NewTransactionCache(10*time.Minute), options.ApplicatorOptions{MaxPendingBlocks: 5, MaxHeightDelta: 5})
Expand Down Expand Up @@ -320,3 +327,41 @@ func TestApplicatorLimits(t *testing.T) {
}
<-testChan
}

func TestInvalidNonce(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
rpc := applicatorTestRPC{
blocksToFail: make(map[string]void),
unlinkableBlocks: make(map[string]void),
head: []byte{0x00},
invalidNonceTrxs: make(map[string]void),
}

applicator, err := NewApplicator(ctx, &rpc, NewTransactionCache(time.Minute), *options.NewApplicatorOptions())
if err != nil {
t.Error(err)
}

goodTrx := &protocol.Transaction{
Id: []byte{0},
}

badTrx := &protocol.Transaction{
Id: []byte{1},
}

rpc.invalidNonceTrxs[string(badTrx.Id)] = void{}

applicator.Start(ctx)

err = applicator.ApplyTransaction(ctx, goodTrx)
if err != nil {
t.Error(err)
}

err = applicator.ApplyTransaction(ctx, badTrx)
if err != p2perrors.ErrInvalidNonce {
t.Errorf("badTrx - ErrInvalidNonce expected but was not returned, was: %v", err)
}
}
4 changes: 2 additions & 2 deletions internal/p2p/connection_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"fmt"
"time"

log "github.com/koinos/koinos-log-golang"
log "github.com/koinos/koinos-log-golang/v2"
"github.com/koinos/koinos-p2p/internal/options"
"github.com/koinos/koinos-p2p/internal/rpc"
util "github.com/koinos/koinos-util-golang"
util "github.com/koinos/koinos-util-golang/v2"

gorpc "github.com/libp2p/go-libp2p-gorpc"
"github.com/libp2p/go-libp2p/core/host"
Expand Down
4 changes: 3 additions & 1 deletion internal/p2p/error_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"math"
"time"

log "github.com/koinos/koinos-log-golang"
log "github.com/koinos/koinos-log-golang/v2"
"github.com/koinos/koinos-p2p/internal/options"
"github.com/koinos/koinos-p2p/internal/p2perrors"
"github.com/libp2p/go-libp2p/core/control"
Expand Down Expand Up @@ -150,6 +150,8 @@ func (p *PeerErrorHandler) getScoreForError(err error) uint64 {
// Errors that are commonly expected during normal use or potential attack vectors
case errors.Is(err, p2perrors.ErrTransactionApplication):
return p.opts.TransactionApplicationErrorScore
case errors.Is(err, p2perrors.ErrInvalidNonce):
return p.opts.InvalidNonceErrorScore
case errors.Is(err, p2perrors.ErrBlockApplication):
return p.opts.BlockApplicationErrorScore
case errors.Is(err, p2perrors.ErrUnknownPreviousBlock):
Expand Down
2 changes: 1 addition & 1 deletion internal/p2p/fork_watchdog.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"sync"

"github.com/koinos/koinos-p2p/internal/p2perrors"
"github.com/koinos/koinos-proto-golang/koinos/protocol"
"github.com/koinos/koinos-proto-golang/v2/koinos/protocol"
)

type pairKey struct {
Expand Down
2 changes: 1 addition & 1 deletion internal/p2p/fork_watchdog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"testing"

"github.com/koinos/koinos-p2p/internal/p2perrors"
"github.com/koinos/koinos-proto-golang/koinos/protocol"
"github.com/koinos/koinos-proto-golang/v2/koinos/protocol"
)

func TestForkWatchdog(t *testing.T) {
Expand Down
11 changes: 7 additions & 4 deletions internal/p2p/gossip.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import (
"sync/atomic"
"time"

log "github.com/koinos/koinos-log-golang"
log "github.com/koinos/koinos-log-golang/v2"
"github.com/koinos/koinos-p2p/internal/p2perrors"
"github.com/koinos/koinos-p2p/internal/rpc"
"github.com/koinos/koinos-proto-golang/koinos/canonical"
"github.com/koinos/koinos-proto-golang/koinos/protocol"
util "github.com/koinos/koinos-util-golang"
"github.com/koinos/koinos-proto-golang/v2/koinos/canonical"
"github.com/koinos/koinos-proto-golang/v2/koinos/protocol"
util "github.com/koinos/koinos-util-golang/v2"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
Expand Down Expand Up @@ -427,6 +427,9 @@ func (kg *KoinosGossip) applyTransaction(ctx context.Context, pid peer.ID, msg *
}

if err := kg.applicator.ApplyTransaction(ctx, transaction); err != nil {
if errors.Is(err, p2perrors.ErrInvalidNonce) {
return fmt.Errorf("%w - %s, %v", p2perrors.ErrInvalidNonce, util.TransactionString(transaction), err.Error())
}
return fmt.Errorf("%w - %s, %v", p2perrors.ErrTransactionApplication, util.TransactionString(transaction), err.Error())
}

Expand Down
2 changes: 1 addition & 1 deletion internal/p2p/gossip_toggle.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"sync"
"time"

log "github.com/koinos/koinos-log-golang"
log "github.com/koinos/koinos-log-golang/v2"
"github.com/koinos/koinos-p2p/internal/options"
)

Expand Down
2 changes: 1 addition & 1 deletion internal/p2p/lib_provider.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package p2p

import "github.com/koinos/koinos-proto-golang/koinos"
import "github.com/koinos/koinos-proto-golang/v2/koinos"

// LastIrreversibleBlockProvider is an interface for providing the last irreversible block to PeerConnection
type LastIrreversibleBlockProvider interface {
Expand Down
2 changes: 1 addition & 1 deletion internal/p2p/peer_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"fmt"
"time"

log "github.com/koinos/koinos-log-golang"
log "github.com/koinos/koinos-log-golang/v2"
"github.com/koinos/koinos-p2p/internal/options"
"github.com/koinos/koinos-p2p/internal/p2perrors"
"github.com/koinos/koinos-p2p/internal/rpc"
Expand Down
4 changes: 2 additions & 2 deletions internal/p2p/transaction_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"sync"
"time"

log "github.com/koinos/koinos-log-golang"
"github.com/koinos/koinos-proto-golang/koinos/protocol"
log "github.com/koinos/koinos-log-golang/v2"
"github.com/koinos/koinos-proto-golang/v2/koinos/protocol"
)

type void struct{}
Expand Down
2 changes: 1 addition & 1 deletion internal/p2p/transaction_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"testing"
"time"

"github.com/koinos/koinos-proto-golang/koinos/protocol"
"github.com/koinos/koinos-proto-golang/v2/koinos/protocol"
"github.com/stretchr/testify/assert"
)

Expand Down
10 changes: 5 additions & 5 deletions internal/p2p_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
"github.com/koinos/koinos-p2p/internal/node"
"github.com/koinos/koinos-p2p/internal/options"
"github.com/koinos/koinos-p2p/internal/p2p"
"github.com/koinos/koinos-proto-golang/koinos"
"github.com/koinos/koinos-proto-golang/koinos/broadcast"
"github.com/koinos/koinos-proto-golang/koinos/protocol"
"github.com/koinos/koinos-proto-golang/koinos/rpc/block_store"
"github.com/koinos/koinos-proto-golang/koinos/rpc/chain"
"github.com/koinos/koinos-proto-golang/v2/koinos"
"github.com/koinos/koinos-proto-golang/v2/koinos/broadcast"
"github.com/koinos/koinos-proto-golang/v2/koinos/protocol"
"github.com/koinos/koinos-proto-golang/v2/koinos/rpc/block_store"
"github.com/koinos/koinos-proto-golang/v2/koinos/rpc/chain"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/multiformats/go-multiaddr"
"github.com/multiformats/go-multihash"
Expand Down
3 changes: 3 additions & 0 deletions internal/p2perrors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ var (
// ErrTransactionApplication represents any error applying a transaction to the mem pool
ErrTransactionApplication = errors.New("transaction application failed")

// ErrInvalidNonce represents when a transaction cannot be applied because of an invalid nonce
ErrInvalidNonce = errors.New("invalid nonce")

// ErrChainIDMismatch represents the peer has a different chain id
ErrChainIDMismatch = errors.New("chain id does not match peer's")

Expand Down
Loading

0 comments on commit 4569bc2

Please sign in to comment.