Skip to content

Commit

Permalink
Fix DB migration failing
Browse files Browse the repository at this point in the history
  • Loading branch information
fasmat committed Oct 16, 2024
1 parent e78b3a9 commit 386eb40
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 197 deletions.
2 changes: 1 addition & 1 deletion activation/wire/wire_v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type ActivationTxV1 struct {
blob []byte
}

// InnerActivationTxV1 is a set of all of an ATX's fields, except the signature. To generate the ATX signature, this
// InnerActivationTxV1 is a set of all of an ATXs fields, except the signature. To generate the ATX signature, this
// structure is serialized and signed.
type InnerActivationTxV1 struct {
NIPostChallengeV1
Expand Down
2 changes: 1 addition & 1 deletion node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -1954,7 +1954,7 @@ func (app *App) setupDBs(ctx context.Context, lg log.Log) error {
return fmt.Errorf("failed to create %s: %w", dbPath, err)
}
dbLog := app.addLogger(StateDbLogger, lg).Zap()
schema, err := statemigrations.SchemaWithInCodeMigrations(app.malfeasanceHandler)
schema, err := statemigrations.SchemaWithInCodeMigrations(*app.Config)
if err != nil {
return fmt.Errorf("error loading db schema: %w", err)
}
Expand Down
14 changes: 0 additions & 14 deletions sql/statesql/migrations/interfaces.go

This file was deleted.

81 changes: 0 additions & 81 deletions sql/statesql/migrations/mocks.go

This file was deleted.

5 changes: 3 additions & 2 deletions sql/statesql/migrations/schema.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package migrations

import (
"github.com/spacemeshos/go-spacemesh/config"
"github.com/spacemeshos/go-spacemesh/sql"
"github.com/spacemeshos/go-spacemesh/sql/statesql"
)

func SchemaWithInCodeMigrations(malHandler malfeasanceValidator) (*sql.Schema, error) {
func SchemaWithInCodeMigrations(config config.Config) (*sql.Schema, error) {
return statesql.Schema(
New0021Migration(1_000_000),
New0025Migration(malHandler),
New0025Migration(config),
)
}
3 changes: 2 additions & 1 deletion sql/statesql/migrations/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import (
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"

"github.com/spacemeshos/go-spacemesh/config"
"github.com/spacemeshos/go-spacemesh/sql"
)

func TestCodedMigrations(t *testing.T) {
schema, err := SchemaWithInCodeMigrations(nil)
schema, err := SchemaWithInCodeMigrations(config.DefaultConfig())
require.NoError(t, err)

db := sql.InMemory(
Expand Down
58 changes: 43 additions & 15 deletions sql/statesql/migrations/state_0025_migration.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
package migrations

import (
"context"
"encoding/hex"
"errors"
"time"

"go.uber.org/zap"

"github.com/spacemeshos/go-spacemesh/codec"
"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/spacemeshos/go-spacemesh/config"
"github.com/spacemeshos/go-spacemesh/log"
"github.com/spacemeshos/go-spacemesh/malfeasance/wire"
"github.com/spacemeshos/go-spacemesh/signing"
"github.com/spacemeshos/go-spacemesh/sql"
"github.com/spacemeshos/go-spacemesh/sql/builder"
"github.com/spacemeshos/go-spacemesh/sql/identities"
)

type migration0025 struct {
handler malfeasanceValidator
edVerifier *signing.EdVerifier
}

var _ sql.Migration = &migration0025{}

func New0025Migration(handler malfeasanceValidator) *migration0025 {
func New0025Migration(config config.Config) *migration0025 {
return &migration0025{
handler: handler,
edVerifier: signing.NewEdVerifier(
signing.WithVerifierPrefix(config.Genesis.GenesisID().Bytes()),
),
}
}

Expand All @@ -47,23 +51,18 @@ func (m *migration0025) Apply(db sql.Executor, logger *zap.Logger) error {
proof := &wire.MalfeasanceProof{}
codec.MustDecode(bytes, proof)

id, err := m.handler.Validate(context.Background(), proof)
if err == nil && id == nodeID {
logger.Debug("Proof is valid", log.ZShortStringer("smesherID", nodeID))
if proof.Proof.Type != wire.InvalidPrevATX {
// we only care about invalid prev ATX proofs
return true
}

if proof.Proof.Type != wire.InvalidPrevATX {
logger.Warn("Found invalid proof during migration that cannot be fixed",
log.ZShortStringer("smesherID", nodeID),
zap.String("proof", hex.EncodeToString(bytes)),
zap.Error(err),
)
id, err := m.Validate(proof.Proof.Data)
if err == nil && id == nodeID {
logger.Debug("Proof is valid", log.ZShortStringer("smesherID", nodeID))
return true
}

proof.Proof.Data.(*wire.InvalidPrevATXProof).Atx1.VRFNonce = nil
id, err = m.handler.Validate(context.Background(), proof)
id, err = m.Validate(proof.Proof.Data)
if err == nil && id == nodeID {
updates[nodeID] = codec.MustEncode(proof)
return true
Expand Down Expand Up @@ -98,3 +97,32 @@ func (m *migration0025) Apply(db sql.Executor, logger *zap.Logger) error {
}
return nil
}

func (m *migration0025) Validate(data wire.ProofData) (types.NodeID, error) {
proof, ok := data.(*wire.InvalidPrevATXProof)
if !ok {
return types.EmptyNodeID, errors.New("wrong message type for invalid previous ATX")
}

atx1 := proof.Atx1
if !m.edVerifier.Verify(signing.ATX, atx1.SmesherID, atx1.SignedBytes(), atx1.Signature) {
return types.EmptyNodeID, errors.New("atx1: invalid signature")
}

atx2 := proof.Atx2
if atx1.SmesherID != atx2.SmesherID {
return types.EmptyNodeID, errors.New("invalid old prev ATX malfeasance proof: smesher IDs are different")
}

if !m.edVerifier.Verify(signing.ATX, atx2.SmesherID, atx2.SignedBytes(), atx2.Signature) {
return types.EmptyNodeID, errors.New("atx2: invalid signature")
}

if atx1.ID() == atx2.ID() {
return types.EmptyNodeID, errors.New("invalid old prev ATX malfeasance proof: ATX IDs are the same")
}
if atx1.PrevATXID != atx2.PrevATXID {
return types.EmptyNodeID, errors.New("invalid old prev ATX malfeasance proof: prev ATX IDs are different")
}
return atx1.SmesherID, nil
}
Loading

0 comments on commit 386eb40

Please sign in to comment.