diff --git a/core/proof_keeper.go b/core/proof_keeper.go index 4ecff48f61..1bbad5224b 100644 --- a/core/proof_keeper.go +++ b/core/proof_keeper.go @@ -114,11 +114,13 @@ func (keeper *proofKeeper) queryProposedProof(kRecord *pathdb.KeepRecord) (*proo func (keeper *proofKeeper) eventLoop() { var ( - putKeeperMetaRecordOnce bool + putKeeperMetaRecordOnce bool // default = false + ancientInitSequenceID uint64 // default = 0 ) for { select { case r := <-keeper.opts.watchStartKeepCh: + log.Info("keep proof", "record", r) var ( hasTruncatedMeta bool curProofID uint64 @@ -127,18 +129,17 @@ func (keeper *proofKeeper) eventLoop() { metaList := keeper.getKeeperMetaRecordList() if len(metaList) == 0 { keeper.proofDataDB.Reset() - curProofID = 1 + curProofID = ancientInitSequenceID } else { keeper.truncateProofDataRecordHeadIfNeeded(r.BlockID) latestProofData := keeper.getLatestProofDataRecord() if latestProofData != nil { curProofID = latestProofData.ProofID + 1 } else { - curProofID = 1 + curProofID = ancientInitSequenceID } } - log.Info("keep proof", "record", r) proofRecord, err := keeper.queryProposedProof(r) if err == nil { if hasTruncatedMeta || !putKeeperMetaRecordOnce { @@ -175,6 +176,7 @@ func (keeper *proofKeeper) getKeeperMetaRecordList() []keeperMetaRecord { } metaList = append(metaList, m) } + log.Info("Succeed to get meta list", "list", metaList) return metaList } @@ -205,6 +207,7 @@ func (keeper *proofKeeper) truncateKeeperMetaRecordHeadIfNeeded(blockID uint64) if err != nil { log.Crit("Failed to truncate keeper meta head", "err", err) } + log.Info("Succeed to truncate keeper meta", "block_id", blockID, "has_truncated", hasTruncated) return hasTruncated } @@ -222,9 +225,11 @@ func (keeper *proofKeeper) putKeeperMetaRecord(m *keeperMetaRecord) { func (keeper *proofKeeper) truncateProofDataRecordHeadIfNeeded(blockID uint64) { latestProofDataRecord := keeper.getLatestProofDataRecord() if latestProofDataRecord == nil { + log.Info("Skip to truncate proof data due to proof data is empty") return } if blockID > latestProofDataRecord.BlockID { + log.Info("Skip to truncate proof data due to block id is newer") return } @@ -243,11 +248,13 @@ func (keeper *proofKeeper) truncateProofDataRecordHeadIfNeeded(blockID uint64) { proofID = proofID - 1 } rawdb.TruncateProofDataHead(keeper.proofDataDB, truncateProofID) + log.Info("Succeed to truncate proof data", "block_id", blockID, "truncate_proof_id", truncateProofID) } func (keeper *proofKeeper) getLatestProofDataRecord() *proofDataRecord { latestProofData := rawdb.GetLatestProofData(keeper.proofDataDB) if latestProofData == nil { + log.Info("Skip get latest proof data record due to empty") return nil } var data proofDataRecord @@ -255,12 +262,14 @@ func (keeper *proofKeeper) getLatestProofDataRecord() *proofDataRecord { if err != nil { log.Crit("Failed to unmarshal proof data", "err", err) } + log.Info("Succeed to get latest proof data", "record", data) return &data } func (keeper *proofKeeper) getProofDataRecord(proofID uint64) *proofDataRecord { latestProofData := rawdb.GetProofData(keeper.proofDataDB, proofID) if latestProofData == nil { + log.Info("Skip get proof data record due not found", "proof_id", proofID) return nil } var data proofDataRecord @@ -268,6 +277,7 @@ func (keeper *proofKeeper) getProofDataRecord(proofID uint64) *proofDataRecord { if err != nil { log.Crit("Failed to unmarshal proof data", "err", err) } + log.Info("Succeed to get proof data", "record", data) return &data } diff --git a/core/rawdb/accessors_proof.go b/core/rawdb/accessors_proof.go index 114e3dba17..bbe47f63a8 100644 --- a/core/rawdb/accessors_proof.go +++ b/core/rawdb/accessors_proof.go @@ -6,7 +6,7 @@ import ( ) const ( - blockNumberLength = 32 + blockNumberLength = 8 // uint64 is 8bytes ) // Keeper Meta @@ -33,8 +33,9 @@ func GetLatestProofData(f *ResettableFreezer) []byte { if proofTable == nil { return nil } - blob, err := f.Ancient(proposeProofTable, proofTable.items.Load()) + blob, err := f.Ancient(proposeProofTable, proofTable.items.Load()-1) if err != nil { + log.Error("Failed to get latest proof data", "latest_proof_id", proofTable.items.Load()-1, "error", err) return nil } return blob @@ -56,9 +57,13 @@ func TruncateProofDataHead(f *ResettableFreezer, proofID uint64) { f.freezer.TruncateHead(proofID) } -func PutProofData(db ethdb.AncientWriter, id uint64, proof []byte) { +func PutProofData(db ethdb.AncientWriter, proofID uint64, proof []byte) { db.ModifyAncients(func(op ethdb.AncientWriteOp) error { - op.AppendRaw(proposeProofTable, id-1, proof) + err := op.AppendRaw(proposeProofTable, proofID, proof) + if err != nil { + // todo: panic + log.Error("Failed to put proof data", "proof_id", proofID, "error", err) + } return nil }) } diff --git a/core/rawdb/accessors_proof_test.go b/core/rawdb/accessors_proof_test.go new file mode 100644 index 0000000000..04d8429483 --- /dev/null +++ b/core/rawdb/accessors_proof_test.go @@ -0,0 +1,71 @@ +package rawdb + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +const ( + testAncientProofDir = "./test_ancient_proof" +) + +var ( + testAncientProofDB *ResettableFreezer + mockData1 = []byte{'a'} + mockData2 = []byte{'1'} +) + +func setupTestEnv() { + testAncientProofDB, _ = NewProofFreezer(testAncientProofDir, false) +} + +func cleanupTestEnv() { + testAncientProofDB.Close() + os.RemoveAll(testAncientProofDir) + +} + +func TestProofDataAPI(t *testing.T) { + setupTestEnv() + var proofData []byte + + // case1: empty db + proofData = GetLatestProofData(testAncientProofDB) + assert.Nil(t, proofData) + + // case2: mismatch sequence put failed + mismatchProofID := uint64(2) // should=0 + PutProofData(testAncientProofDB, mismatchProofID, mockData1) + proofData = GetLatestProofData(testAncientProofDB) + assert.Nil(t, proofData) + + // case3: put/get succeed + matchProofID := uint64(0) + PutProofData(testAncientProofDB, matchProofID, mockData1) + PutProofData(testAncientProofDB, matchProofID+1, mockData2) + proofData = GetLatestProofData(testAncientProofDB) + assert.Equal(t, proofData, mockData2) + proofData = GetProofData(testAncientProofDB, 0) + assert.Equal(t, proofData, mockData1) + proofData = GetProofData(testAncientProofDB, 1) + assert.Equal(t, proofData, mockData2) + + // case4: truncate + TruncateProofDataHead(testAncientProofDB, 1) + proofData = GetProofData(testAncientProofDB, 1) + assert.Nil(t, proofData) + proofData = GetProofData(testAncientProofDB, 0) + assert.Equal(t, proofData, mockData1) + + // case5: restart + testAncientProofDB.Close() + setupTestEnv() + proofData = GetProofData(testAncientProofDB, 0) + assert.Equal(t, proofData, mockData1) + proofData = GetLatestProofData(testAncientProofDB) + assert.Equal(t, proofData, mockData1) + + cleanupTestEnv() +}