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

fix: TransactionMessage.decompile() now counts the correct number of unsigned, writable accounts #28990

Merged
merged 2 commits into from Nov 30, 2022
Merged

fix: TransactionMessage.decompile() now counts the correct number of unsigned, writable accounts #28990

merged 2 commits into from Nov 30, 2022

Conversation

steveluscher
Copy link
Contributor

@steveluscher steveluscher commented Nov 30, 2022

Problem

Message headers give you the following:

  • number of required signatures (numRequiredSignatures)
  • number of read-only signed accounts (numReadonlySignedAccounts)
  • number of read-only unsigned accounts (numReadonlyUnsignedAccounts)

If we want to know how many writable unsigned accounts there are, we have to:

  • start with the total number of accounts
  • subtract the number of those that are signers (numRequiredSignatures)
  • subtract the number of read-only unsigned accounts (numReadonlyUnsignedAccounts)

That spells:

const numWritableUnsignedAccounts =
  message.staticAccountKeys.length -
  numRequiredSignatures -
  numReadonlyUnsignedAccounts;

Unfortunately, we forgot to subtract out the number of signers, making it possible to overcount numWritableUnsignedAccounts. This played havoc when deserializing messages like the one in #28900's repro.

All of this could result in accounts being needlessly marked as writeable, which could only serve to make the network slower (ie. causing the validator to run transactions in serial that could otherwise have been safely run in parallel).

Summary of Changes

Fixes #28900.

@github-actions github-actions bot added the web3.js Related to the JavaScript client label Nov 30, 2022
@codecov
Copy link

codecov bot commented Nov 30, 2022

Codecov Report

Merging #28990 (b08bce0) into master (4267a15) will decrease coverage by 0.4%.
The diff coverage is n/a.

@@            Coverage Diff            @@
##           master   #28990     +/-   ##
=========================================
- Coverage    77.1%    76.7%   -0.5%     
=========================================
  Files          55       55             
  Lines        2934     3084    +150     
  Branches      408      454     +46     
=========================================
+ Hits         2264     2367    +103     
- Misses        529      559     +30     
- Partials      141      158     +17     

@@ -49,7 +49,9 @@ export class TransactionMessage {
assert(numWritableSignedAccounts > 0, 'Message header is invalid');

const numWritableUnsignedAccounts =
message.staticAccountKeys.length - numReadonlyUnsignedAccounts;
message.staticAccountKeys.length -
numRequiredSignatures -
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Without this change, the test in this commit incorrectly marks the last account as writable.

@steveluscher steveluscher merged commit 491d4f3 into solana-labs:master Nov 30, 2022
@steveluscher steveluscher deleted the repair-deserialization-versioned-transactions branch November 30, 2022 17:57
@steveluscher
Copy link
Contributor Author

Got the idea to double check the Rust code, and found it to already be correct.

let num_unsigned_accounts = num_account_keys.saturating_sub(num_signed_accounts);
let num_writable_unsigned_accounts = num_unsigned_accounts
.saturating_sub(usize::from(header.num_readonly_unsigned_accounts));

gnapoli23 pushed a commit to gnapoli23/solana that referenced this pull request Dec 16, 2022
…unsigned, writable accounts (solana-labs#28990)

* Test that `TransactionMessage.decompile()` can decompile a legacy `Message`

* `TransactionMessage.decompile()` now correctly accounts for the number of writable unsigned accounts
nickfrosty pushed a commit to nickfrosty/solana that referenced this pull request Jan 4, 2023
…unsigned, writable accounts (solana-labs#28990)

* Test that `TransactionMessage.decompile()` can decompile a legacy `Message`

* `TransactionMessage.decompile()` now correctly accounts for the number of writable unsigned accounts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
web3.js Related to the JavaScript client
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[web3.js] Discrepancy between legacy Transaction API and new VersionedTransaction API
2 participants