Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Fix getTransactions web3.js method #26099

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion web3.js/src/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3566,7 +3566,16 @@ export class Connection {
if ('error' in res) {
throw new Error('failed to get transactions: ' + res.error.message);
}
return res.result;
Copy link
Contributor

Choose a reason for hiding this comment

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

Wow. Somehow TypeScript, despite the fact that it knows the type of res.result, typed the outer resasany`.

image

I wonder if this is because they have the same name (the variable name is shadowed).

Copy link
Contributor

Choose a reason for hiding this comment

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

Found out the root cause of this. #26102

const result = res.result;
if (!result) return result;

return {
...result,
transaction: {
...result.transaction,
message: new Message(result.transaction.message),
},
};
Comment on lines +3572 to +3578
Copy link
Contributor

Choose a reason for hiding this comment

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

Slight preference for pulling this out into a method (getTransactionResponseFromGetTransactionsResult()so thatgetTransactionandgetTransactions` can share it, but no big deal – what you've done here is more readable.

});

return res;
Expand Down
135 changes: 135 additions & 0 deletions web3.js/test/connection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2197,6 +2197,141 @@ describe('Connection', function () {
expect(nullResponse).to.be.null;
});

it('get transactions', async function () {
await mockRpcResponse({
method: 'getSlot',
params: [],
value: 1,
});

while ((await connection.getSlot()) <= 0) {
continue;
}

await mockRpcResponse({
method: 'getBlock',
params: [1],
value: {
blockHeight: 0,
blockTime: 1614281964,
blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
parentSlot: 0,
transactions: [
{
meta: {
fee: 10000,
postBalances: [499260347380, 15298080, 1, 1, 1],
preBalances: [499260357380, 15298080, 1, 1, 1],
status: {Ok: null},
err: null,
},
transaction: {
message: {
accountKeys: [
'va12u4o9DipLEB2z4fuoHszroq1U9NcAB9aooFDPJSf',
'57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
'SysvarS1otHashes111111111111111111111111111',
'SysvarC1ock11111111111111111111111111111111',
'Vote111111111111111111111111111111111111111',
],
header: {
numReadonlySignedAccounts: 0,
numReadonlyUnsignedAccounts: 3,
numRequiredSignatures: 2,
},
instructions: [
{
accounts: [1, 2, 3],
data: '37u9WtQpcm6ULa3VtWDFAWoQc1hUvybPrA3dtx99tgHvvcE7pKRZjuGmn7VX2tC3JmYDYGG7',
programIdIndex: 4,
},
],
recentBlockhash: 'GeyAFFRY3WGpmam2hbgrKw4rbU2RKzfVLm5QLSeZwTZE',
},
signatures: [
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt',
'4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG',
],
},
},
],
},
});

// Find a block that has a transaction.
await mockRpcResponse({
method: 'getFirstAvailableBlock',
params: [],
value: 1,
});
let slot = await connection.getFirstAvailableBlock();

let transaction: string | undefined;
while (!transaction) {
const block = await connection.getBlock(slot);
if (block && block.transactions.length > 0) {
transaction = block.transactions[0].transaction.signatures[0];
continue;
}
slot++;
}

await mockRpcBatchResponse({
batch: [
{
methodName: 'getTransaction',
args: [transaction],
},
],
result: [
{
slot,
transaction: {
message: {
accountKeys: [
'va12u4o9DipLEB2z4fuoHszroq1U9NcAB9aooFDPJSf',
'57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
'SysvarS1otHashes111111111111111111111111111',
'SysvarC1ock11111111111111111111111111111111',
'Vote111111111111111111111111111111111111111',
],
header: {
numReadonlySignedAccounts: 0,
numReadonlyUnsignedAccounts: 3,
numRequiredSignatures: 2,
},
instructions: [
{
accounts: [1, 2, 3],
data: '37u9WtQpcm6ULa3VtWDFAWoQc1hUvybPrA3dtx99tgHvvcE7pKRZjuGmn7VX2tC3JmYDYGG7',
programIdIndex: 4,
},
],
recentBlockhash: 'GeyAFFRY3WGpmam2hbgrKw4rbU2RKzfVLm5QLSeZwTZE',
},
signatures: [
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt',
'4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG',
],
},
meta: {
fee: 10000,
postBalances: [499260347380, 15298080, 1, 1, 1],
preBalances: [499260357380, 15298080, 1, 1, 1],
status: {Ok: null},
err: null,
},
},
],
});
const [firstResult] = await connection.getTransactions([transaction]);
if (firstResult == null) {
expect.fail('Expected `getTransactions()` to return one result');
}
expect(firstResult.transaction.message.isAccountSigner(0)).to.be.true;
});

if (mockServer) {
it('get parsed confirmed transaction coerces public keys of inner instructions', async () => {
const confirmedTransaction: TransactionSignature =
Expand Down