From c403601b297b460c21f24229f2b7063a44492f8d Mon Sep 17 00:00:00 2001 From: Dhananjay Purohit Date: Tue, 19 Mar 2024 11:37:13 +0530 Subject: [PATCH 1/4] fix: refactor getUnconfirmedTx --- attestation/attestclient.go | 19 ++++++++++++++++++ attestation/attestservice.go | 7 +++++-- db/db.go | 1 + db/db_fake.go | 8 +++++++- db/db_mongo.go | 39 ++++++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 3 deletions(-) diff --git a/attestation/attestclient.go b/attestation/attestclient.go index 2f59243..3a0c1d1 100644 --- a/attestation/attestclient.go +++ b/attestation/attestclient.go @@ -12,6 +12,7 @@ import ( confpkg "mainstay/config" "mainstay/crypto" "mainstay/log" + "mainstay/models" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcjson" @@ -577,3 +578,21 @@ func (w *AttestClient) getUnconfirmedTx() (bool, chainhash.Hash, error) { } return false, chainhash.Hash{}, nil } + +func (w *AttestClient) getUnconfirmedTxFromCommitments(latestAttestations []models.Attestation) (bool, chainhash.Hash, error) { + mempool, err := w.MainClient.GetRawMempool() + if err != nil { + return false, chainhash.Hash{}, err + } + + for _, attest := range latestAttestations { + for _, mem := range mempool { + if attest.Txid.IsEqual(mem) { + if w.verifyTxOnSubchain(*mem) { + return true, *mem, nil + } + } + } + } + return false, chainhash.Hash{}, nil +} diff --git a/attestation/attestservice.go b/attestation/attestservice.go index df9e48d..d36767a 100644 --- a/attestation/attestservice.go +++ b/attestation/attestservice.go @@ -320,9 +320,12 @@ func (s *AttestService) stateInitWalletFailure() { // - If no attestation found, check last unconfirmed from db func (s *AttestService) doStateInit() { log.Infoln("*AttestService* INITIATING ATTESTATION PROCESS") - + latestCommitments, err := s.server.dbInterface.GetUnconfirmedAttestations(); + if err != nil { + return + } // find the state of the attestation - unconfirmed, unconfirmedTxid, unconfirmedErr := s.attester.getUnconfirmedTx() + unconfirmed, unconfirmedTxid, unconfirmedErr := s.attester.getUnconfirmedTxFromCommitments(latestCommitments) if s.setFailure(unconfirmedErr) { return // will rebound to init } else if unconfirmed { // check mempool for unconfirmed - added check in case something gets rejected diff --git a/db/db.go b/db/db.go index be42cde..21ea274 100644 --- a/db/db.go +++ b/db/db.go @@ -26,6 +26,7 @@ type Db interface { getAttestationMerkleRoot(chainhash.Hash) (string, error) // get methods required by server + GetUnconfirmedAttestations() ([]models.Attestation, error) GetLatestAttestationMerkleRoot(bool) (string, error) GetClientCommitments() ([]models.ClientCommitment, error) GetAttestationMerkleCommitments(chainhash.Hash) ([]models.CommitmentMerkleCommitment, error) diff --git a/db/db_fake.go b/db/db_fake.go index 4d0ff60..8a8c19e 100644 --- a/db/db_fake.go +++ b/db/db_fake.go @@ -21,6 +21,7 @@ type DbFake struct { MerkleCommitments []models.CommitmentMerkleCommitment MerkleProofs []models.CommitmentMerkleProof latestCommitments []models.ClientCommitment + latestAttestations []models.Attestation } // Return new DbFake instance @@ -30,7 +31,8 @@ func NewDbFake() *DbFake { []models.AttestationInfo{}, []models.CommitmentMerkleCommitment{}, []models.CommitmentMerkleProof{}, - []models.ClientCommitment{}} + []models.ClientCommitment{}, + []models.Attestation{}} } // Save latest attestation to Attestations @@ -145,6 +147,10 @@ func (d *DbFake) getAttestationMerkleRoot(txid chainhash.Hash) (string, error) { return "", nil } +func (d *DbFake) GetUnconfirmedAttestations() ([]models.Attestation, error) { + return d.latestAttestations, nil +} + // Return commitment for attestation with given txid func (d *DbFake) GetAttestationMerkleCommitments(txid chainhash.Hash) ([]models.CommitmentMerkleCommitment, error) { // get merkle root of attestation diff --git a/db/db_mongo.go b/db/db_mongo.go index 1a8d02c..dab3926 100644 --- a/db/db_mongo.go +++ b/db/db_mongo.go @@ -398,6 +398,45 @@ func (d *DbMongo) getAttestationMerkleRoot(txid chainhash.Hash) (string, error) return attestationDoc.Lookup(models.CommitmentMerkleRootName).StringValue(), nil } +func (d *DbMongo) GetUnconfirmedAttestations() ([]models.Attestation, error) { + // Filter for unconfirmed attestations + confirmedFilter := bsonx.Doc{{models.AttestationConfirmedName, bsonx.Boolean(false)}} + + // Find all unconfirmed attestations + cursor, err := d.db.Collection(ColNameAttestation).Find(d.ctx, confirmedFilter) + if err != nil { + return nil, errors.New(fmt.Sprintf("%s %v", ErrorAttestationGet, err)) + } + defer func() { + if err := cursor.Close(d.ctx); err != nil { + // Log or handle closing error + } + }() + + // Iterate over cursor and collect unconfirmed attestations + var attestations []models.Attestation + for { + // Call cursor.Next with only context + moreDocs := cursor.Next(d.ctx) + if !moreDocs { + // No more documents found, break the loop + break + } + if err != nil { + return nil, errors.New(fmt.Sprintf("%s %v", ErrorAttestationGet, err)) + } + + // Decode document into an attestation object (optional if using All) + var attestation models.Attestation + if err := cursor.Decode(d.ctx); err != nil { + return nil, errors.New(fmt.Sprintf("%s %v", ErrorAttestationGet, err)) + } + attestations = append(attestations, attestation) + } + + return attestations, nil +} + // Return Commitment from MerkleCommitment commitments for attestation with given txid hash func (d *DbMongo) GetAttestationMerkleCommitments(txid chainhash.Hash) ([]models.CommitmentMerkleCommitment, error) { // get merkle root of attestation From 4a7120c2a28c5dd4cb670be1143f9d7227168db8 Mon Sep 17 00:00:00 2001 From: Dhananjay Purohit Date: Tue, 19 Mar 2024 13:07:52 +0530 Subject: [PATCH 2/4] chore: debug test failure --- attestation/attestclient.go | 3 ++- attestation/attestservice.go | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/attestation/attestclient.go b/attestation/attestclient.go index 3a0c1d1..2d05abf 100644 --- a/attestation/attestclient.go +++ b/attestation/attestclient.go @@ -584,7 +584,8 @@ func (w *AttestClient) getUnconfirmedTxFromCommitments(latestAttestations []mode if err != nil { return false, chainhash.Hash{}, err } - + fmt.Printf("mempool %v", mempool) + fmt.Printf("latest Attestaions %v", latestAttestations) for _, attest := range latestAttestations { for _, mem := range mempool { if attest.Txid.IsEqual(mem) { diff --git a/attestation/attestservice.go b/attestation/attestservice.go index d36767a..20d85c3 100644 --- a/attestation/attestservice.go +++ b/attestation/attestservice.go @@ -320,12 +320,13 @@ func (s *AttestService) stateInitWalletFailure() { // - If no attestation found, check last unconfirmed from db func (s *AttestService) doStateInit() { log.Infoln("*AttestService* INITIATING ATTESTATION PROCESS") - latestCommitments, err := s.server.dbInterface.GetUnconfirmedAttestations(); + latestAttestations, err := s.server.dbInterface.GetUnconfirmedAttestations() + log.Infof("latest commitment %v", latestAttestations) if err != nil { return } // find the state of the attestation - unconfirmed, unconfirmedTxid, unconfirmedErr := s.attester.getUnconfirmedTxFromCommitments(latestCommitments) + unconfirmed, unconfirmedTxid, unconfirmedErr := s.attester.getUnconfirmedTxFromCommitments(latestAttestations) if s.setFailure(unconfirmedErr) { return // will rebound to init } else if unconfirmed { // check mempool for unconfirmed - added check in case something gets rejected From 2bca4a631eb910aab686ee1d4db5472dc1f156e1 Mon Sep 17 00:00:00 2001 From: Dhananjay Purohit Date: Tue, 19 Mar 2024 13:11:59 +0530 Subject: [PATCH 3/4] fix: import error --- attestation/attestclient.go | 1 + 1 file changed, 1 insertion(+) diff --git a/attestation/attestclient.go b/attestation/attestclient.go index 2d05abf..2805640 100644 --- a/attestation/attestclient.go +++ b/attestation/attestclient.go @@ -8,6 +8,7 @@ import ( "encoding/hex" "errors" "math" + "fmt" confpkg "mainstay/config" "mainstay/crypto" From 8bd211dd400080a3e2fce90dd5af92ad96a9f694 Mon Sep 17 00:00:00 2001 From: Dhananjay Purohit Date: Tue, 19 Mar 2024 17:29:54 +0530 Subject: [PATCH 4/4] fix: add logic to scan mempool if no attestations in the table --- attestation/attestclient.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/attestation/attestclient.go b/attestation/attestclient.go index 2805640..d2b616a 100644 --- a/attestation/attestclient.go +++ b/attestation/attestclient.go @@ -587,14 +587,22 @@ func (w *AttestClient) getUnconfirmedTxFromCommitments(latestAttestations []mode } fmt.Printf("mempool %v", mempool) fmt.Printf("latest Attestaions %v", latestAttestations) - for _, attest := range latestAttestations { - for _, mem := range mempool { - if attest.Txid.IsEqual(mem) { - if w.verifyTxOnSubchain(*mem) { - return true, *mem, nil + if (len(latestAttestations) > 0) { + for _, attest := range latestAttestations { + for _, mem := range mempool { + if attest.Txid.IsEqual(mem) { + if w.verifyTxOnSubchain(*mem) { + return true, *mem, nil + } } - } - } - } + } + } + } else { + for _, hash := range mempool { + if w.verifyTxOnSubchain(*hash) { + return true, *hash, nil + } + } + } return false, chainhash.Hash{}, nil }