Skip to content

Commit

Permalink
Cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
fasmat committed Aug 29, 2024
1 parent d6c161f commit 6b51e03
Show file tree
Hide file tree
Showing 20 changed files with 178 additions and 48 deletions.
3 changes: 2 additions & 1 deletion activation/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func NewHandler(
fetcher: fetcher,
beacon: beacon,
tortoise: tortoise,
malPublisher: &MalfeasancePublisher{},
malPublisher: &ATXMalfeasancePublisher{},
},
}

Expand Down Expand Up @@ -286,6 +286,7 @@ func (h *Handler) handleAtx(
case *wire.ActivationTxV1:
return h.v1.processATX(ctx, peer, atx, receivedTime)
case *wire.ActivationTxV2:
// TODO(mafa): change function signature to not return proofs any more
return (*mwire.MalfeasanceProof)(nil), h.v2.processATX(ctx, peer, atx, receivedTime)
default:
panic("unreachable")
Expand Down
4 changes: 2 additions & 2 deletions activation/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ type handlerMocks struct {
mValidator *MocknipostValidator
mbeacon *MockatxReceiver
mtortoise *mocks.MockTortoise
mMalPublish *MockmalfeasancePublisher
mMalPublish *MockatxMalfeasancePublisher
}

type testHandler struct {
Expand Down Expand Up @@ -190,7 +190,7 @@ func newTestHandlerMocks(tb testing.TB, golden types.ATXID) handlerMocks {
mValidator: NewMocknipostValidator(ctrl),
mbeacon: NewMockatxReceiver(ctrl),
mtortoise: mocks.NewMockTortoise(ctrl),
mMalPublish: NewMockmalfeasancePublisher(ctrl),
mMalPublish: NewMockatxmalfeasancePublisher(ctrl),
}
}

Expand Down
4 changes: 2 additions & 2 deletions activation/handler_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ type HandlerV2 struct {
tortoise system.Tortoise
logger *zap.Logger
fetcher system.Fetcher
malPublisher malfeasancePublisher
malPublisher atxMalfeasancePublisher
}

func (h *HandlerV2) processATX(
Expand Down Expand Up @@ -528,7 +528,7 @@ func (h *HandlerV2) syntacticallyValidateDeps(
return nil, fmt.Errorf("fetching previous atx: %w", err)
}
if prevAtx.PublishEpoch >= atx.PublishEpoch {
err := fmt.Errorf("previous atx is too new (%d >= %d) (%s) ", prevAtx.PublishEpoch, atx.PublishEpoch, prev)
err := fmt.Errorf("previous atx (%s) is too new (%d >= %d)", prev, prevAtx.PublishEpoch, atx.PublishEpoch)
return nil, err
}
previousAtxs[i] = prevAtx
Expand Down
6 changes: 2 additions & 4 deletions activation/handler_v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package activation
import (
"context"
"errors"
"fmt"
"math"
"slices"
"testing"
Expand All @@ -17,7 +18,6 @@ import (

"github.com/spacemeshos/go-spacemesh/activation/wire"
"github.com/spacemeshos/go-spacemesh/atxsdata"
"github.com/spacemeshos/go-spacemesh/codec"
"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/spacemeshos/go-spacemesh/datastore"
"github.com/spacemeshos/go-spacemesh/fetch"
Expand Down Expand Up @@ -1509,7 +1509,7 @@ func TestHandlerV2_SyntacticallyValidateDeps(t *testing.T) {
atx.Sign(sig)

_, err := atxHandler.syntacticallyValidateDeps(context.Background(), atx)
require.ErrorContains(t, err, "previous atx is too new")
require.ErrorContains(t, err, fmt.Sprintf("previous atx (%s) is too new", prev.ID()))
})
t.Run("previous ATX by different smesher", func(t *testing.T) {
atxHandler := newV2TestHandler(t, golden)
Expand Down Expand Up @@ -1719,8 +1719,6 @@ func Test_Marriages(t *testing.T) {
nId, err := malProof.Valid(atxHandler.edVerifier)
require.NoError(t, err)
require.Equal(t, sig.NodeID(), nId)
b := codec.MustEncode(malProof)
_ = b
return nil
})
err = atxHandler.processATX(context.Background(), "", atx2, time.Now())
Expand Down
8 changes: 6 additions & 2 deletions activation/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,22 @@ type syncer interface {
RegisterForATXSynced() <-chan struct{}
}

// malfeasancePublisher is an interface for publishing malfeasance proofs.
// atxMalfeasancePublisher is an interface for publishing malfeasance proofs.
// This interface is used to publish proofs in V2.
//
// The provider of that interface ensures that only valid proofs are published (invalid ones return an error).
// Proofs against an identity that is managed by the node will also return an error and will not be gossiped.
//
// Additionally the publisher will only gossip proofs when the node is in sync, otherwise it will only store them.
// and mark the associated identity as malfeasant.
type malfeasancePublisher interface {
type atxMalfeasancePublisher interface {
Publish(ctx context.Context, id types.NodeID, proof wire.Proof) error
}

type malfeasancePublisher interface {
Publish(ctx context.Context, id types.NodeID, proof []byte) error
}

type atxProvider interface {
GetAtx(id types.ATXID) (*types.ActivationTx, error)
}
Expand Down
121 changes: 121 additions & 0 deletions activation/malfeasance2_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package activation

import (
"context"
"fmt"

"github.com/spacemeshos/go-spacemesh/activation/wire"
"github.com/spacemeshos/go-spacemesh/codec"
"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/spacemeshos/go-spacemesh/datastore"
"github.com/spacemeshos/go-spacemesh/signing"
"github.com/spacemeshos/go-spacemesh/system"
)

type MalfeasanceHandlerV2 struct {
syncer syncer
clock layerClock
publisher malfeasancePublisher
cdb *datastore.CachedDB
tortoise system.Tortoise
edVerifier *signing.EdVerifier
}

func NewMalfeasanceHandlerV2(
syncer syncer,
layerClock layerClock,
malPublisher malfeasancePublisher,
cdb *datastore.CachedDB,
tortoise system.Tortoise,
edVerifier *signing.EdVerifier,
) *MalfeasanceHandlerV2 {
return &MalfeasanceHandlerV2{
syncer: syncer,
clock: layerClock,
publisher: malPublisher, // TODO(mafa): implement malfeasancePublisher in `malfeasance` package
cdb: cdb,
tortoise: tortoise,
edVerifier: edVerifier,
}
}

// TODO(mafa): call this validate in the handler for publish/gossip.
// TODO(mafa): extend this validate to return nil if `peer` == self.
func (mh *MalfeasanceHandlerV2) Validate(ctx context.Context, data []byte) ([]types.NodeID, error) {
var decoded wire.ATXProof
if err := codec.Decode(data, &decoded); err != nil {
return nil, fmt.Errorf("decoding ATX malfeasance proof: %w", err)
}

var proof wire.Proof
switch decoded.ProofType {
case wire.DoubleMarry:
p := &wire.ProofDoubleMarry{}
if err := codec.Decode(decoded.Proof, p); err != nil {
return nil, fmt.Errorf("decoding ATX double marry proof: %w", err)
}
proof = p
case wire.InvalidPost:
// TODO(mafa): implement this
default:
return nil, fmt.Errorf("unknown ATX malfeasance proof type: %d", decoded.ProofType)
}

id, err := proof.Valid(mh.edVerifier)
if err != nil {
return nil, fmt.Errorf("validating ATX malfeasance proof: %w", err)
}

// TODO(mafa): do this in the general handler
// validIDs := make([]types.NodeID, 0, len(decoded.Certificates)+1)
// validIDs = append(validIDs, id) // id has already been proven to be malfeasant

// // check certificates provided with the proof
// // TODO(mafa): only works if the main identity becomes malfeasant - try different approach with merkle proofs
// for _, cert := range decoded.Certificates {
// if id != cert.Target {
// continue
// }
// if !mh.edVerifier.Verify(signing.MARRIAGE, cert.Target, cert.ID.Bytes(), cert.Signature) {
// continue
// }
// validIDs = append(validIDs, cert.ID)
// }
// return validIDs, nil
return []types.NodeID{id}, nil
}

// TODO(mafa): this roughly how the general publisher looks like
//
// func Publish(ctx context.Context, smesherID types.NodeID, data []byte) error {
// // Combine IDs from the present equivocation set for atx.SmesherID and IDs in atx.Marriages.
// set, err := identities.EquivocationSet(mh.cdb, nodeID)
// if err != nil {
// return fmt.Errorf("getting equivocation set: %w", err)
// }
// for _, id := range set {
// if err := identities.SetMalicious(mh.cdb, id, encoded, time.Now()); err != nil {
// return fmt.Errorf("adding malfeasance proof: %w", err)
// }

// mh.cdb.CacheMalfeasanceProof(id, proof)
// mh.tortoise.OnMalfeasance(id)
// }

// if !mh.syncer.ListenToATXGossip() {
// // we are not gossiping proofs when we are not listening to ATX gossip
// return nil
// }

// gossip := mwire.MalfeasanceProofV2{
// Layer: mh.clock.CurrentLayer(),
// ProofType: mwire.InvalidActivation,
// Proof: data,
// }

// if err := mh.publisher.Publish(ctx, pubsub.MalfeasanceProof, codec.MustEncode(&gossip)); err != nil {
// mh.logger.Error("failed to broadcast malfeasance proof", zap.Error(err))
// return fmt.Errorf("broadcast atx malfeasance proof: %w", err)
// }
// return nil
// }
3 changes: 3 additions & 0 deletions activation/malfeasance2_handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package activation

// TODO(mafa): implement me
6 changes: 3 additions & 3 deletions activation/malfeasance2_publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import (
"github.com/spacemeshos/go-spacemesh/common/types"
)

// MalfeasancePublisher is the publisher for ATX proofs.
type MalfeasancePublisher struct{}
// ATXMalfeasancePublisher is the publisher for ATX proofs.
type ATXMalfeasancePublisher struct{}

func (p *MalfeasancePublisher) Publish(ctx context.Context, id types.NodeID, proof wire.Proof) error {
func (p *ATXMalfeasancePublisher) Publish(ctx context.Context, id types.NodeID, proof wire.Proof) error {
// TODO(mafa): implement me
return nil
}
3 changes: 3 additions & 0 deletions activation/malfeasance2_publisher_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package activation

// TODO(mafa): implement me
18 changes: 9 additions & 9 deletions activation/mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions activation/post_verifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,7 @@ func TestPostVerifierPrioritization(t *testing.T) {
verifier := NewMockPostVerifier(gomock.NewController(t))
v := newOffloadingPostVerifier(verifier, 2, zaptest.NewLogger(t), nodeID)

verifier.EXPECT().
Verify(gomock.Any(), gomock.Any(), &shared.ProofMetadata{NodeId: nodeID.Bytes()}, gomock.Any()).
Return(nil)
verifier.EXPECT().Verify(gomock.Any(), gomock.Any(), &shared.ProofMetadata{NodeId: nodeID.Bytes()}, gomock.Any())

err := v.Verify(context.Background(), &shared.Proof{}, &shared.ProofMetadata{NodeId: nodeID.Bytes()})
require.NoError(t, err)
Expand Down
9 changes: 4 additions & 5 deletions activation/wire/malfeasance.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,10 @@ const (
LegacyInvalidPost ProofType = 0x01
LegacyInvalidPrevATX ProofType = 0x02

DoublePublish ProofType = 0x10
DoubleMarry ProofType = 0x11
DoubleMerge ProofType = 0x12
InvalidPost ProofType = 0x13
InvalidPrevious ProofType = 0x14
DoubleMarry ProofType = 0x10
DoubleMerge ProofType = 0x11
InvalidPost ProofType = 0x12
InvalidPrevious ProofType = 0x13
)

// ProofVersion is an identifier for the version of the proof that is encoded in the ATXProof.
Expand Down
17 changes: 10 additions & 7 deletions activation/wire/wire_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ type MarriageCertificate struct {
// An ATX of the ID that marries. It proves that the ID exists.
// Note: the reference ATX does not need to be from the previous epoch.
// It only needs to prove the existence of the ID.
//
// In the case of a self signed certificate that is included in the Marriage ATX by the Smesher signing the ATX,
// this can be `types.EmptyATXID`.
ReferenceAtx types.ATXID
// Signature over the other ID that this ID marries with
// If Alice marries Bob, then Alice signs Bob's ID
Expand Down Expand Up @@ -227,7 +230,7 @@ type SubPostV2 struct {
// Can be used to extract the nodeID and verify if it is married with the smesher of the ATX.
// Must be 0 for non-merged ATXs.
MarriageIndex uint32
PrevATXIndex uint32 // Index of the previous ATX in the `InnerActivationTxV2.PreviousATXs` slice
PrevATXIndex uint32 // Index of the previous ATX in the `ActivationTxV2.PreviousATXs` slice
// Index of the leaf for this ID's challenge in the poet membership tree.
// IDs might shared the same index if their nipost challenges are equal.
// This happens when the IDs are continuously merged (they share the previous ATX).
Expand All @@ -243,9 +246,9 @@ func (sp *SubPostV2) Root(prevATXs []types.ATXID) []byte {
if err != nil {
panic(err)
}
marriageIndex := make([]byte, 4)
binary.LittleEndian.PutUint32(marriageIndex, sp.MarriageIndex)
tree.AddLeaf(marriageIndex)
var marriageIndex types.Hash32
binary.LittleEndian.PutUint32(marriageIndex[:], sp.MarriageIndex)
tree.AddLeaf(marriageIndex.Bytes())

if int(sp.PrevATXIndex) >= len(prevATXs) {
return nil // invalid index, root cannot be generated
Expand All @@ -258,9 +261,9 @@ func (sp *SubPostV2) Root(prevATXs []types.ATXID) []byte {

tree.AddLeaf(sp.Post.Root())

numUnits := make([]byte, 4)
binary.LittleEndian.PutUint32(numUnits, sp.NumUnits)
tree.AddLeaf(numUnits)
var numUnits types.Hash32
binary.LittleEndian.PutUint32(numUnits[:], sp.NumUnits)
tree.AddLeaf(numUnits.Bytes())
return tree.Root()
}

Expand Down
4 changes: 2 additions & 2 deletions api/grpcserver/globalstate_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func TestGlobalStateService(t *testing.T) {

_, err := c.AccountDataQuery(ctx, &pb.AccountDataQueryRequest{})
require.Error(t, err)
require.Contains(t, err.Error(), "`Filter` must be provided")
require.ErrorContains(t, err, "`Filter` must be provided")
})
t.Run("AccountDataQuery_MissingFlags", func(t *testing.T) {
t.Parallel()
Expand All @@ -91,7 +91,7 @@ func TestGlobalStateService(t *testing.T) {
},
})
require.Error(t, err)
require.Contains(t, err.Error(), "`Filter.AccountMeshDataFlags` must set at least one")
require.ErrorContains(t, err, "`Filter.AccountMeshDataFlags` must set at least one")
})
t.Run("AccountDataQuery_BadOffset", func(t *testing.T) {
t.Parallel()
Expand Down
Loading

0 comments on commit 6b51e03

Please sign in to comment.