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

feat(SPV-1535) handle ARC callback #935

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

chris-4chain
Copy link
Contributor

Pull Request Checklist

  • πŸ“– I created my PR using provided : CODE_STANDARDS
  • πŸ“– I have read the short Code of Conduct: CODE_OF_CONDUCT
  • 🏠 I tested my changes locally.
  • βœ… I have provided tests for my changes.
  • πŸ“ I have used conventional commits.
  • πŸ“— I have updated any related documentation.
  • πŸ’Ύ PR was issued based on the Github or Jira issue.

@chris-4chain chris-4chain requested a review from a team as a code owner February 27, 2025 08:46
Copy link

Manual Tests

ℹ️ Remember to ask team members to perform manual tests and to assign tested label after testing.

@codecov-commenter
Copy link

codecov-commenter commented Feb 27, 2025

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

Attention: Patch coverage is 2.76498% with 211 lines in your changes missing coverage. Please review.

Project coverage is 35.30%. Comparing base (1c04eb0) to head (80602a5).

Files with missing lines Patch % Lines
engine/v2/transaction/txsync/txsync_service.go 0.00% 48 Missing ⚠️
engine/v2/database/repository/transactions.go 0.00% 41 Missing ⚠️
engine/chain/internal/arc/callback.go 0.00% 34 Missing ⚠️
engine/testabilities/assert_engine.go 0.00% 33 Missing ⚠️
engine/tester/http_sniffer.go 0.00% 13 Missing ⚠️
...egrationtests/testabilities/ability_arc_actions.go 0.00% 10 Missing ⚠️
engine/testabilities/fixture_configopts.go 0.00% 6 Missing ⚠️
engine/testabilities/fixture_engine.go 0.00% 6 Missing ⚠️
.../integrationtests/testabilities/ability_actions.go 0.00% 5 Missing ⚠️
engine/tester/paymailmock/mock_paymail_client.go 0.00% 4 Missing ⚠️
... and 5 more
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #935      +/-   ##
==========================================
- Coverage   35.63%   35.30%   -0.33%     
==========================================
  Files         424      427       +3     
  Lines       20035    20236     +201     
==========================================
+ Hits         7139     7145       +6     
- Misses      12299    12494     +195     
  Partials      597      597              
Flag Coverage Ξ”
unittests 35.30% <2.76%> (-0.33%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Ξ”
...al/integrationtests/testabilities/assert_actors.go 0.00% <ΓΈ> (ΓΈ)
engine/chain/models/tx_info.go 0.00% <ΓΈ> (ΓΈ)
engine/client_internal.go 70.72% <100.00%> (+0.67%) ⬆️
engine/v2/database/tracked_transaction.go 0.00% <ΓΈ> (ΓΈ)
initializer/config_to_options.go 0.00% <ΓΈ> (ΓΈ)
...ions/testabilities/assert_spvwallet_application.go 0.00% <0.00%> (ΓΈ)
...egrationtests/testabilities/fixture_user_actors.go 0.00% <0.00%> (ΓΈ)
config/utils.go 14.28% <0.00%> (-2.39%) ⬇️
engine/client.go 56.32% <33.33%> (-0.45%) ⬇️
server/server.go 5.95% <0.00%> (-0.23%) ⬇️
... and 10 more

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Ξ” = absolute <relative> (impact), ΓΈ = not affected, ? = missing data
Powered by Codecov. Last update 1c04eb0...80602a5. Read the comment docs.

},
"On SentToNetwork do nothing": {
txInfo: minimalTxInfo(chainmodels.SentToNetwork),
expectStatus: "BROADCASTED",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor suggestion: Would it make sense to group these statuses into constants rather than writing them directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, there is such type already defined - I'll adjust this :)

Model(&database.TrackedTransaction{}).
WithContext(ctx).
Where("id = ?", txID).
Update("tx_status", status).Error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand it, at this stage of development we are not considering implementing concurrency control mechanisms to avoid stale data? πŸ€”

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't understand - could you explain what you're thinking about?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that he is saying that you can override tx_status that was already set by different process/routine

const bearerSchema = "Bearer "

// RegisterCallback registers the ARC callback handler and sets up final URL sent to ARC during broadcast.
func (s *Service) RegisterCallback(handler chainmodels.TXInfoHandler, router *gin.Engine) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... imho it should be done in a standard way (like the one for swagger v2)
It's counter intuitive to search for that thing in arc service

Comment on lines +22 to +28
hostURL, err := url.Parse(s.arcCfg.Callback.URL)
if err != nil {
panic(spverrors.Wrapf(err, "failed to parse ARC callback URL: %s", s.arcCfg.Callback.URL))
}

hostURL.Path = callbackPath
s.arcCfg.Callback.URL = hostURL.String()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe Callback config could have a method for getting callback path and full callback url

if err != nil {
return spverrors.Wrapf(err, "failed to parse merkle path for transaction %s", txInfo.TxID)
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider adding a check for merklepath (or maybe it will be checked during creation of BEEF hex - worth checking):

Suggested change
_, err = bump.ComputeRootHex(lo.ToPtr(txInfo.TxID))
if err != nil {
return spverrors.Wrapf(err, "failed to validate merkle path %s for transaction %s", txInfo.MerklePath, txInfo.TxID)
}

This will prevent updating merkle path to some invalid value.

Or maybe if error occurs we should store info about this πŸ€”

The only problem here is that, it is taking some time to calculate this root - but actually we're doing the same for each and every beef

return spverrors.Wrapf(err, "failed to get BEEF hex for transaction %s", txInfo.TxID)
}

err = s.transactionsRepo.SetAsMined(ctx, txInfo.TxID, txInfo.BlockHash, txInfo.BlockHeight, beefHex)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry but I don't like this approach, because it is forceing us to move a lot of logic into database layer, which doens't allow to test anything without running the integration tests.

I would suggest to:

  • get domain transaction from repository
  • check if last update is older then TxInfo timestamp
    • if not then omit
  • call set problematic if it's problematic
  • call tx.Mined(blockhash, merklepath)
    • in set merkle path it should mark it as mined
    • set block height from merklepath
    • set block hash from block hash
    • build beef with merkle path
    • remove raw tx
  • save tx

"block_height": blockHeight,
"tx_status": txmodels.TxStatusMined,
"beef_hex": beefHex,
}).Error
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should clear also connection with SourceTxInputs because those entries are not needed anymore.


// when:
test.txInfo.TxID = receiveTxID
when.ARC().ReceivesCallback(test.txInfo)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be rather πŸ™ˆ :

Suggested change
when.ARC().ReceivesCallback(test.txInfo)
when.ARC().SendsCallback(test.txInfo)

WithTxID(receiveTxID).
WithTxStatus(test.expectStatus)

// TODO: Assert for tx block height/hash and BEEF after Searching Transactions is implemented
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should actually add those information to operations endpoint - because it seems like a common thing that we display in wallets (and use for whatsonchain links)

t.Run(name, func(t *testing.T) {
// given:
given, when, then := testabilities.New(t)
cleanup := given.StartedSPVWalletV2(testengine.WithARCCallback("https://example.com", testabilities.ARCCallbackToken))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we make those configs default?

@@ -0,0 +1,101 @@
package integrationtests
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it in integrations tests?

It should be rather test next to the http handler,
You probably could use a Faucet().TopUp() then and make a different ARC callbacks for different statuses.


type arcActions struct {
t testing.TB
fixture *fixture
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have access to SPVWalletApplicationFixture,
maybe it could return config, and you could take auth token from config πŸ€”

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants