Skip to content

Commit

Permalink
Fix recovery for multi-smeshing
Browse files Browse the repository at this point in the history
  • Loading branch information
fasmat committed Feb 22, 2024
1 parent 80c1796 commit 456359f
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 33 deletions.
35 changes: 23 additions & 12 deletions checkpoint/recovery.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package checkpoint

import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"net/url"
"path/filepath"
"slices"

"github.com/spf13/afero"

Expand Down Expand Up @@ -198,18 +200,27 @@ func recoverFromLocalFile(
allDeps = append(allDeps, deps...)
allProofs = append(allProofs, proofs...)

// // deduplicate allDeps and allProofs by sorting and compacting
// // TODO: for some reason this causes existing tests to fail - need to investigate
// slices.SortFunc(allDeps, func(i, j *types.VerifiedActivationTx) int {
// return bytes.Compare(i.ID().Bytes(), j.ID().Bytes())
// })
// allDeps = slices.Compact(allDeps)
// slices.SortFunc(allProofs, func(i, j *types.PoetProofMessage) int {
// iRef, _ := i.Ref()
// jRef, _ := j.Ref()
// return bytes.Compare(iRef[:], jRef[:])
// })
// allProofs = slices.Compact(allProofs)
// deduplicate allDeps and allProofs by sorting and compacting
// then sort them by publishEpoch
slices.SortFunc(allDeps, func(i, j *types.VerifiedActivationTx) int {
return bytes.Compare(i.ID().Bytes(), j.ID().Bytes())
})
allDeps = slices.CompactFunc(allDeps, func(i, j *types.VerifiedActivationTx) bool {
return i.ID() == j.ID()
})
slices.SortFunc(allDeps, func(i, j *types.VerifiedActivationTx) int {
return int(i.PublishEpoch) - int(j.PublishEpoch)
})
slices.SortFunc(allProofs, func(i, j *types.PoetProofMessage) int {
iRef, _ := i.Ref()
jRef, _ := j.Ref()
return bytes.Compare(iRef[:], jRef[:])
})
allProofs = slices.CompactFunc(allProofs, func(i, j *types.PoetProofMessage) bool {
iRef, _ := i.Ref()
jRef, _ := j.Ref()
return iRef == jRef
})
}
}
if err := db.Close(); err != nil {
Expand Down
53 changes: 32 additions & 21 deletions checkpoint/recovery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,6 @@ func validateAndPreserveData(
lg,
)
mfetch.EXPECT().GetAtxs(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
for _, vatx := range deps {
fmt.Println("deps", vatx.ID())
}
for i, vatx := range deps {
encoded, err := codec.Encode(vatx)
require.NoError(tb, err)
Expand All @@ -281,9 +278,14 @@ func validateAndPreserveData(
mvalidator.EXPECT().IsVerifyingFullPost().AnyTimes().Return(true)
mreceiver.EXPECT().OnAtx(gomock.Any())
mtrtl.EXPECT().OnAtx(gomock.Any())
require.NoError(tb, atxHandler.HandleSyncedAtx(context.Background(), vatx.ID().Hash32(), "self", encoded))

err = atxHandler.HandleSyncedAtx(context.Background(), vatx.ID().Hash32(), "self", encoded)
require.NoError(tb, err)

err = poetDb.ValidateAndStore(context.Background(), proofs[i])
require.ErrorContains(tb, err, "failed to validate poet proof for poetID 706f65745f round 1337")
require.ErrorContains(tb, err, fmt.Sprintf("failed to validate poet proof for poetID %s round 1337",
hex.EncodeToString(proofs[i].PoetServiceID[:5])),
)
}
}

Expand Down Expand Up @@ -368,13 +370,13 @@ func createAtxChain(tb testing.TB, sig *signing.EdSigner) ([]*types.VerifiedActi
proofMessage := &types.PoetProofMessage{
PoetProof: types.PoetProof{
MerkleProof: shared.MerkleProof{
Root: []byte{1, 2, 3},
Root: types.RandomBytes(32),
ProvenLeaves: [][]byte{{1}, {2}},
ProofNodes: [][]byte{{1}, {2}},
},
LeafCount: 1234,
},
PoetServiceID: []byte("poet_id_123456"),
PoetServiceID: types.RandomBytes(32),
RoundID: "1337",
}
proofs = append(proofs, proofMessage)
Expand Down Expand Up @@ -419,6 +421,15 @@ func atxIDs(atxs []*types.VerifiedActivationTx) []types.ATXID {
return ids
}

func proofRefs(proofs []*types.PoetProofMessage) []types.PoetProofRef {
refs := make([]types.PoetProofRef, 0, len(proofs))
for _, proof := range proofs {
ref, _ := proof.Ref()
refs = append(refs, ref)
}
return refs
}

func TestRecover_OwnAtxNotInCheckpoint_Preserve(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodGet, r.Method)
Expand All @@ -443,35 +454,35 @@ func TestRecover_OwnAtxNotInCheckpoint_Preserve(t *testing.T) {
Restore: types.LayerID(recoverLayer),
}

olddb, err := sql.Open("file:" + filepath.Join(cfg.DataDir, cfg.DbFile))
oldDB, err := sql.Open("file:" + filepath.Join(cfg.DataDir, cfg.DbFile))
require.NoError(t, err)
require.NotNil(t, olddb)
require.NotNil(t, oldDB)

vatxs, proofs := createAtxChain(t, sig)
validateAndPreserveData(t, olddb, vatxs, proofs)
validateAndPreserveData(t, oldDB, vatxs, proofs)
// the proofs are not valid, but save them anyway for the purpose of testing
for i, vatx := range vatxs {
encoded, err := codec.Encode(proofs[i])
require.NoError(t, err)
require.NoError(
t,
poets.Add(
olddb,
types.PoetProofRef(vatx.GetPoetProofRef()),
encoded,
proofs[i].PoetServiceID,
proofs[i].RoundID,
),

err = poets.Add(
oldDB,
types.PoetProofRef(vatx.GetPoetProofRef()),
encoded,
proofs[i].PoetServiceID,
proofs[i].RoundID,
)
require.NoError(t, err)
}
require.NoError(t, olddb.Close())
require.NoError(t, oldDB.Close())

preserve, err := checkpoint.Recover(ctx, logtest.New(t), afero.NewOsFs(), cfg)
require.NoError(t, err)
require.NotNil(t, preserve)

// the two set of atxs have different received time. just compare IDs
require.ElementsMatch(t, atxIDs(vatxs[:len(vatxs)-1]), atxIDs(preserve.Deps))
require.ElementsMatch(t, proofs[:len(proofs)-1], preserve.Proofs)
require.ElementsMatch(t, proofRefs(proofs[:len(vatxs)-1]), proofRefs(preserve.Proofs))

newdb, err := sql.Open("file:" + filepath.Join(cfg.DataDir, cfg.DbFile))
require.NoError(t, err)
Expand Down

0 comments on commit 456359f

Please sign in to comment.