Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Add double marry malfeasance proof #6219

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions activation/builder_v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func TestBuilder_BuildsInitialAtxV2(t *testing.T) {
require.Empty(t, atx.Marriages)
require.Equal(t, posEpoch+1, atx.PublishEpoch)
require.Equal(t, sig.NodeID(), atx.SmesherID)
require.True(t, signing.NewEdVerifier().Verify(signing.ATX, atx.SmesherID, atx.SignedBytes(), atx.Signature))
require.True(t, signing.NewEdVerifier().Verify(signing.ATX, atx.SmesherID, atx.ID().Bytes(), atx.Signature))
}

func TestBuilder_SwitchesToBuildV2(t *testing.T) {
Expand Down Expand Up @@ -106,5 +106,5 @@ func TestBuilder_SwitchesToBuildV2(t *testing.T) {
require.Empty(t, atx2.Marriages)
require.Equal(t, atx1.PublishEpoch+1, atx2.PublishEpoch)
require.Equal(t, sig.NodeID(), atx2.SmesherID)
require.True(t, signing.NewEdVerifier().Verify(signing.ATX, atx2.SmesherID, atx2.SignedBytes(), atx2.Signature))
require.True(t, signing.NewEdVerifier().Verify(signing.ATX, atx2.SmesherID, atx2.ID().Bytes(), atx2.Signature))
}
45 changes: 32 additions & 13 deletions activation/handler_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

"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/events"
Expand Down Expand Up @@ -626,9 +627,7 @@
zap.Int("index", invalidIdx.Index),
)
// TODO(mafa): finish proof
proof := &wire.ATXProof{
ProofType: wire.InvalidPost,
}
var proof wire.Proof
if err := h.malPublisher.Publish(ctx, id, proof); err != nil {
return nil, fmt.Errorf("publishing malfeasance proof for invalid post: %w", err)
}
Expand Down Expand Up @@ -713,9 +712,34 @@
return false, fmt.Errorf("checking if ID is married: %w", err)
}
if mATX != atxID {
// TODO(mafa): finish proof
proof := &wire.ATXProof{
ProofType: wire.DoubleMarry,
var blob sql.Blob
v, err := atxs.LoadBlob(ctx, tx, atxID.Bytes(), &blob)
fasmat marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return true, fmt.Errorf("creating double marry proof: %w", err)

Check warning on line 718 in activation/handler_v2.go

View check run for this annotation

Codecov / codecov/patch

activation/handler_v2.go#L718

Added line #L718 was not covered by tests
}
if v != types.AtxV2 {
h.logger.Fatal("Failed to create double marry malfeasance proof: ATX is not v2",
zap.Stringer("atx_id", atxID),
)

Check warning on line 723 in activation/handler_v2.go

View check run for this annotation

Codecov / codecov/patch

activation/handler_v2.go#L721-L723

Added lines #L721 - L723 were not covered by tests
}
var atx1 wire.ActivationTxV2
codec.MustDecode(blob.Bytes, &atx1)

v, err = atxs.LoadBlob(ctx, tx, mATX.Bytes(), &blob)
if err != nil {
return true, fmt.Errorf("creating double marry proof: %w", err)

Check warning on line 730 in activation/handler_v2.go

View check run for this annotation

Codecov / codecov/patch

activation/handler_v2.go#L730

Added line #L730 was not covered by tests
}
if v != types.AtxV2 {
h.logger.Fatal("Failed to create double marry malfeasance proof: ATX is not v2",
zap.Stringer("atx_id", mATX),
)

Check warning on line 735 in activation/handler_v2.go

View check run for this annotation

Codecov / codecov/patch

activation/handler_v2.go#L733-L735

Added lines #L733 - L735 were not covered by tests
}
var atx2 wire.ActivationTxV2
codec.MustDecode(blob.Bytes, &atx2)

proof, err := wire.NewDoubleMarryProof(tx, &atx1, &atx2, m.id)
if err != nil {
return true, fmt.Errorf("creating double marry proof: %w", err)

Check warning on line 742 in activation/handler_v2.go

View check run for this annotation

Codecov / codecov/patch

activation/handler_v2.go#L742

Added line #L742 was not covered by tests
}
return true, h.malPublisher.Publish(ctx, m.id, proof)
}
Expand Down Expand Up @@ -747,9 +771,7 @@
zap.Uint32("epoch", atx.PublishEpoch.Uint32()),
)
// TODO(mafa): finish proof
proof := &wire.ATXProof{
ProofType: wire.DoublePublish,
}
var proof wire.Proof
return true, h.malPublisher.Publish(ctx, id, proof)
}
return false, nil
Expand All @@ -776,10 +798,7 @@
zap.Stringer("smesher_id", watx.SmesherID),
)

// TODO(mafa): finish proof
proof := &wire.ATXProof{
ProofType: wire.DoubleMerge,
}
var proof wire.Proof
return true, h.malPublisher.Publish(ctx, watx.SmesherID, proof)
}

Expand Down
30 changes: 13 additions & 17 deletions activation/handler_v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ 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 @@ -1561,17 +1562,7 @@ func TestHandlerV2_SyntacticallyValidateDeps(t *testing.T) {
gomock.Any(),
).
Return(verifying.ErrInvalidIndex{Index: 7})
atxHandler.mMalPublish.EXPECT().Publish(
gomock.Any(),
sig.NodeID(),
gomock.Cond(func(data any) bool {
proof, ok := data.(*wire.ATXProof)
if !ok {
return false
}
return proof.ProofType == wire.InvalidPost
}),
)
atxHandler.mMalPublish.EXPECT().Publish(gomock.Any(), sig.NodeID(), gomock.Any())
_, err := atxHandler.syntacticallyValidateDeps(context.Background(), atx)
vErr := &verifying.ErrInvalidIndex{}
require.ErrorAs(t, err, vErr)
Expand Down Expand Up @@ -1719,13 +1710,18 @@ func Test_Marriages(t *testing.T) {
gomock.Any(),
sig.NodeID(),
gomock.Cond(func(data any) bool {
proof, ok := data.(*wire.ATXProof)
if !ok {
return false
}
return proof.ProofType == wire.DoubleMarry
_, ok := data.(*wire.ProofDoubleMarry)
return ok
}),
)
).DoAndReturn(func(ctx context.Context, id types.NodeID, proof wire.Proof) error {
malProof := proof.(*wire.ProofDoubleMarry)
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())
require.NoError(t, err)

Expand Down
2 changes: 1 addition & 1 deletion activation/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ type syncer interface {
// 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 {
Publish(ctx context.Context, id types.NodeID, proof *wire.ATXProof) error
Publish(ctx context.Context, id types.NodeID, proof wire.Proof) error
}

type atxProvider interface {
Expand Down
2 changes: 1 addition & 1 deletion activation/malfeasance2.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// MalfeasancePublisher is the publisher for ATX proofs.
type MalfeasancePublisher struct{}

func (p *MalfeasancePublisher) Publish(ctx context.Context, id types.NodeID, proof *wire.ATXProof) error {
func (p *MalfeasancePublisher) Publish(ctx context.Context, id types.NodeID, proof wire.Proof) error {

Check warning on line 13 in activation/malfeasance2.go

View check run for this annotation

Codecov / codecov/patch

activation/malfeasance2.go#L13

Added line #L13 was not covered by tests
// TODO(mafa): implement me
return nil
}
6 changes: 3 additions & 3 deletions activation/mocks.go

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

47 changes: 40 additions & 7 deletions activation/wire/malfeasance.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,60 @@
package wire

import (
"github.com/spacemeshos/go-scale"

"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/spacemeshos/go-spacemesh/signing"
)

//go:generate scalegen

// MerkleTreeIndex is the index of the leaf containing the given field in the merkle tree.
type MerkleTreeIndex uint16

const (
PublishEpochIndex MerkleTreeIndex = iota
PositioningATXIndex
CoinbaseIndex
InitialPostIndex
PreviousATXsRootIndex
NIPostsRootIndex
VRFNonceIndex
MarriagesRootIndex
MarriageATXIndex
)

// ProofType is an identifier for the type of proof that is encoded in the ATXProof.
type ProofType byte

const (
DoublePublish ProofType = iota + 1
DoubleMarry
DoubleMerge
InvalidPost
// TODO(mafa): legacy types for future migration to new malfeasance proofs.
LegacyDoublePublish ProofType = 0x00
LegacyInvalidPost ProofType = 0x01
LegacyInvalidPrevATX ProofType = 0x02

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

// ProofVersion is an identifier for the version of the proof that is encoded in the ATXProof.
type ProofVersion byte

type ATXProof struct {
// LayerID is the layer in which the proof was created. This can be used to implement different versions of the ATX
// proof in the future.
Layer types.LayerID
// Version is the version identifier of the proof. This can be used to extend the ATX proof in the future.
Version ProofVersion
// ProofType is the type of proof that is being provided.
ProofType ProofType
// Proof is the actual proof. Its type depends on the ProofType.
Proof []byte `scale:"max=1048576"` // max size of proof is 1MiB
}

// Proof is an interface for all types of proofs that can be provided in an ATXProof.
// Generally the proof should be able to validate itself and be scale encoded.
type Proof interface {
scale.Encodable

Valid(edVerifier *signing.EdVerifier) (types.NodeID, error)
}
Loading
Loading