diff --git a/node/consensus/data/consensus_frames.go b/node/consensus/data/consensus_frames.go index b5466a8..579a855 100644 --- a/node/consensus/data/consensus_frames.go +++ b/node/consensus/data/consensus_frames.go @@ -71,6 +71,7 @@ func (e *DataClockConsensusEngine) prove( tries, e.coinStore, e.clockStore, + e.pubSub, e.logger, ) if err != nil { diff --git a/node/consensus/data/message_handler.go b/node/consensus/data/message_handler.go index d0fac86..03f6dc8 100644 --- a/node/consensus/data/message_handler.go +++ b/node/consensus/data/message_handler.go @@ -66,8 +66,7 @@ func (e *DataClockConsensusEngine) runTxMessageHandler() { continue } - if e.frameProverTries[0].Contains(e.provingKeyAddress) && - e.syncingStatus == SyncStatusNotSyncing { + if e.frameProverTries[0].Contains(e.provingKeyAddress) { for name := range e.executionEngines { name := name go func() error { diff --git a/node/execution/intrinsics/token/application/token_application.go b/node/execution/intrinsics/token/application/token_application.go index bf681cf..0f8f7b0 100644 --- a/node/execution/intrinsics/token/application/token_application.go +++ b/node/execution/intrinsics/token/application/token_application.go @@ -29,6 +29,7 @@ type TokenApplication struct { Tries []*tries.RollingFrecencyCritbitTrie CoinStore store.CoinStore ClockStore store.ClockStore + PubSub p2p.PubSub Logger *zap.Logger Difficulty uint32 } @@ -78,6 +79,7 @@ func MaterializeApplicationFromFrame( tries []*tries.RollingFrecencyCritbitTrie, coinStore store.CoinStore, clockStore store.ClockStore, + pubSub p2p.PubSub, logger *zap.Logger, ) (*TokenApplication, error) { _, tokenOutputs, err := GetOutputsFromClockFrame(frame) @@ -94,6 +96,7 @@ func MaterializeApplicationFromFrame( CoinStore: coinStore, ClockStore: clockStore, Logger: logger, + PubSub: pubSub, Difficulty: frame.Difficulty, }, nil } @@ -124,7 +127,19 @@ func (a *TokenApplication) ApplyTransitions( "apply transitions") } - for _, transition := range transitions.Requests { + requests := []*protobufs.TokenRequest{} + if skipFailures { + mints := tries.NewMinHeap[*protobufs.TokenRequest]() + for _, req := range transitions.Requests { + mints.Push(req) + } + + requests = mints.All() + } else { + requests = transitions.Requests + } + + for _, transition := range requests { req: switch t := transition.Request.(type) { case *protobufs.TokenRequest_Announce: diff --git a/node/execution/intrinsics/token/application/token_handle_mint.go b/node/execution/intrinsics/token/application/token_handle_mint.go index 3700571..8cb6541 100644 --- a/node/execution/intrinsics/token/application/token_handle_mint.go +++ b/node/execution/intrinsics/token/application/token_handle_mint.go @@ -202,6 +202,23 @@ func (a *TokenApplication) handleMint( ) } + if (previousFrame != nil && newFrame <= previousFrame.FrameNumber) || + newFrame < currentFrameNumber-10 { + previousFrameNumber := uint64(0) + if previousFrame != nil { + previousFrameNumber = previousFrame.FrameNumber + } + a.Logger.Debug( + "received out of order proofs, ignoring", + zap.Error(err), + zap.String("peer_id", base58.Encode([]byte(peerId))), + zap.Uint64("previous_frame", previousFrameNumber), + zap.Uint64("new_frame", newFrame), + zap.Uint64("frame_number", currentFrameNumber), + ) + return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint") + } + if verified && delete != nil && len(t.Proofs) > 3 { hash := sha3.Sum256(previousFrame.Output) pick := tries.BytesToUnbiasedMod(hash, uint64(parallelism)) @@ -240,7 +257,8 @@ func (a *TokenApplication) handleMint( zap.String("peer_id", base58.Encode([]byte(peerId))), zap.Uint64("frame_number", currentFrameNumber), ) - return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint") + // we want this to still apply the next commit even if this proof failed + verified = false } } diff --git a/node/execution/intrinsics/token/application/token_handle_prover_join.go b/node/execution/intrinsics/token/application/token_handle_prover_join.go index 05fdc23..c723ef5 100644 --- a/node/execution/intrinsics/token/application/token_handle_prover_join.go +++ b/node/execution/intrinsics/token/application/token_handle_prover_join.go @@ -57,8 +57,7 @@ func (a *TokenApplication) handleDataAnnounceProverJoin( if t.PublicKeySignatureEd448.PublicKey == nil || t.PublicKeySignatureEd448.Signature == nil || t.PublicKeySignatureEd448.PublicKey.KeyValue == nil || - t.Filter == nil || len(t.Filter) != 32 || - t.FrameNumber > currentFrameNumber { + t.Filter == nil || len(t.Filter) != 32 { a.Logger.Debug( "bad payload", zap.Uint64("given_frame_number", t.FrameNumber), @@ -68,6 +67,7 @@ func (a *TokenApplication) handleDataAnnounceProverJoin( return nil, errors.Wrap(ErrInvalidStateTransition, "handle join") } + if _, touched := lockMap[string( t.PublicKeySignatureEd448.PublicKey.KeyValue, )]; touched { @@ -89,6 +89,30 @@ func (a *TokenApplication) handleDataAnnounceProverJoin( return nil, errors.Wrap(err, "handle join") } + if t.FrameNumber > currentFrameNumber { + a.Logger.Debug( + "bad payload", + zap.Uint64("given_frame_number", t.FrameNumber), + zap.Uint64("current_frame_number", currentFrameNumber), + zap.Int("filter_length", len(t.Filter)), + ) + + pk, err := pcrypto.UnmarshalEd448PublicKey( + t.PublicKeySignatureEd448.PublicKey.KeyValue, + ) + if err != nil { + return nil, errors.Wrap(err, "get address from signature") + } + + peerId, err := peer.IDFromPublicKey(pk) + if err != nil { + return nil, errors.Wrap(err, "get address from signature") + } + + a.PubSub.AddPeerScore([]byte(peerId), -100000) + return nil, errors.Wrap(ErrInvalidStateTransition, "handle join") + } + lockMap[string(t.PublicKeySignatureEd448.PublicKey.KeyValue)] = struct{}{} for _, t := range a.Tries { if t.Contains(address) { diff --git a/node/execution/intrinsics/token/token_execution_engine.go b/node/execution/intrinsics/token/token_execution_engine.go index d246f84..b078650 100644 --- a/node/execution/intrinsics/token/token_execution_engine.go +++ b/node/execution/intrinsics/token/token_execution_engine.go @@ -502,6 +502,7 @@ func (e *TokenExecutionEngine) ProcessFrame( triesAtFrame, e.coinStore, e.clockStore, + e.pubSub, e.logger, ) if err != nil { @@ -751,6 +752,7 @@ func (e *TokenExecutionEngine) VerifyExecution( tries, e.coinStore, e.clockStore, + e.pubSub, e.logger, ) if err != nil { @@ -772,6 +774,7 @@ func (e *TokenExecutionEngine) VerifyExecution( triesAtFrame, e.coinStore, e.clockStore, + e.pubSub, e.logger, ) if err != nil { diff --git a/node/protobufs/node.go b/node/protobufs/node.go new file mode 100644 index 0000000..1742958 --- /dev/null +++ b/node/protobufs/node.go @@ -0,0 +1,13 @@ +package protobufs + +import "math/big" + +func (t *TokenRequest) Priority() *big.Int { + switch p := t.Request.(type) { + case *TokenRequest_Mint: + if len(p.Mint.Proofs) >= 3 { + return new(big.Int).SetBytes(p.Mint.Proofs[2]) + } + } + return big.NewInt(0) +}