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: process tx after push #813

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open

Conversation

r4mmer
Copy link
Member

@r4mmer r4mmer commented Feb 4, 2025

Motivation

The process to send a transaction from the wallet-lib includes the steps:

  1. Choose inputs, outputs and metadata that will define the transaction.
  2. Create a Transaction instance and calculate the metadata for mining.
  3. Send the tx to the tx-mining-service and get the parents and nonce.
  4. Push the tx to the fullnode.
  5. Fullnode will send the tx back via websocket since we are subscribed to at least 1 address on it.
  6. Process the tx received via websocket and calculate changes in balances, utxos, etc.

Once the push-tx call successfully returns we can safely assume that it was accepted and propagated to the network, but the wallet is only made aware of this after the fullnode sends the tx via websocket. This wait period can vary depending on the network, fullnode and connection RTT, and can take up to a few seconds.

The main goal of this PR is to make the wallet process the transaction without the wait period since we already know its contents and that it is accepted when step 4 ends.
This will save the wallet a few seconds between each tx which will increase the maximum tx throughput of the wallets while not affecting the normal usage.

Acceptance Criteria

  • Convert Transaction instance to websocket tx format (IHistoryTx interface)
  • Add the converted tx to storage after it is accepted by the fullnode on the SendTransaction facade.
  • Process tx as soon as possible.

Security Checklist

  • Make sure you do not include new dependencies in the project unless strictly necessary and do not include dev-dependencies as production ones. More dependencies increase the possibility of one of them being hijacked and affecting us.

@r4mmer r4mmer self-assigned this Feb 4, 2025
Copy link

codecov bot commented Feb 4, 2025

Codecov Report

Attention: Patch coverage is 66.66667% with 24 lines in your changes missing coverage. Please review.

Project coverage is 65.80%. Comparing base (9c78996) to head (aabb513).

Files with missing lines Patch % Lines
src/utils/transaction.ts 68.62% 14 Missing and 2 partials ⚠️
src/new/sendTransaction.ts 0.00% 6 Missing ⚠️
src/models/p2sh.ts 0.00% 1 Missing ⚠️
src/models/script_data.ts 0.00% 1 Missing ⚠️

❌ Your patch check has failed because the patch coverage (66.66%) is below the target coverage (70.00%). You can increase the patch coverage or adjust the target coverage.
❌ Your project check has failed because the head coverage (65.80%) is below the target coverage (75.00%). You can increase the head coverage or adjust the target coverage.

❗ There is a different number of reports uploaded between BASE (9c78996) and HEAD (aabb513). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (9c78996) HEAD (aabb513)
2 1
Additional details and impacted files
@@             Coverage Diff             @@
##           master     #813       +/-   ##
===========================================
- Coverage   81.02%   65.80%   -15.23%     
===========================================
  Files          91       91               
  Lines        7190     7259       +69     
  Branches     1517     1537       +20     
===========================================
- Hits         5826     4777     -1049     
- Misses       1351     2399     +1048     
- Partials       13       83       +70     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

export async function createTokenHelper(hWallet, name, symbol, amount, options) {
export async function createTokenHelper(hWallet, name, symbol, amount, options = {}) {
Copy link
Member Author

Choose a reason for hiding this comment

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

unrelated to line
All changes in this file are related to typing, some jsdoc types that were not converted into ts types.
This removes some typing alerts from the tests.
Obs: We don't have alerts on the CI because we exclude tests from tsc

src/api/txApi.ts Outdated
Comment on lines 81 to 80
getTransaction(id, resolve): Promise<void | AxiosResponse<TransactionSchema>> {
getTransaction(id, resolve): Promise<void> {
Copy link
Member Author

Choose a reason for hiding this comment

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

The getTransaction method does not return a TransactionSchema, it passes the TransactionSchema instance to the resolve argument.
We could type resolve: (a: TransactionSchema) => void which is correct, but some other parts of the lib break due to being reliant on the implicit typing.

@@ -422,6 +424,23 @@ export default class SendTransaction extends EventEmitter {
throw new WalletError(ErrorMessages.TRANSACTION_IS_NULL);
}
this.transaction.updateHash();
if (this.storage) {
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the core of the PR.

When we push a transaction we need to convert it from a Transaction instance to a IHistoryTx (which is what is received via websocket) and add it to the storage with normal processing.

If we are creating a token we should also add it to the tokens here because the fullnode may not know that this token exists when we ask for the name and symbol for this UID. It also saves us from making an extraneous API call.

@r4mmer r4mmer requested review from tuliomir, glevco and pedroferreira1 and removed request for pedroferreira1 and glevco February 11, 2025 13:56
@r4mmer r4mmer requested a review from tuliomir February 24, 2025 16:01
await this.addToken(this.getNativeTokenData());
}

async addToken(data: ITokenData): Promise<void> {
Copy link
Member

Choose a reason for hiding this comment

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

Missing docstring

Comment on lines +562 to +566
const storeToken = await store.getToken(uid);
if (storeToken === null) {
// saveToken will ignore the meta and save only the token config
await store.saveToken(tokenData);
}
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this the same as the new storage.addToken method created?

tuliomir
tuliomir previously approved these changes Feb 26, 2025
tx.hash = 'no-outputs-case';
tx.inputs = [new Input('no-outputs', 0)];
await expect(transaction.convertTransactionToHistoryTx(tx, storage)).rejects.toThrow(
'Index outsite of tx output array bounds'
Copy link
Contributor

Choose a reason for hiding this comment

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

fix: minor typo

Suggested change
'Index outsite of tx output array bounds'
'Index outside of tx output array bounds'

…nd-to-storage

* origin/master:
  tests: use rocksdb in the integration tests (#819)
  feat: transaction template (#808)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Review (Done)
Development

Successfully merging this pull request may close these issues.

3 participants