feat: add getBlock and getTransaction apis (#17449)
This commit is contained in:
@ -1283,6 +1283,151 @@ describe('Connection', () => {
|
||||
expect(result).to.be.empty;
|
||||
});
|
||||
|
||||
it('get transaction', async () => {
|
||||
await mockRpcResponse({
|
||||
method: 'getSlot',
|
||||
params: [],
|
||||
value: 1,
|
||||
});
|
||||
|
||||
while ((await connection.getSlot()) <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await mockRpcResponse({
|
||||
method: 'getConfirmedBlock',
|
||||
params: [1],
|
||||
value: {
|
||||
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, usually Block 1
|
||||
let slot = 0;
|
||||
let confirmedTransaction: string | undefined;
|
||||
while (!confirmedTransaction) {
|
||||
slot++;
|
||||
const block = await connection.getBlock(slot);
|
||||
if (block && block.transactions.length > 0) {
|
||||
confirmedTransaction = block.transactions[0].transaction.signatures[0];
|
||||
}
|
||||
}
|
||||
|
||||
await mockRpcResponse({
|
||||
method: 'getConfirmedTransaction',
|
||||
params: [confirmedTransaction],
|
||||
value: {
|
||||
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 result = await connection.getTransaction(confirmedTransaction);
|
||||
|
||||
if (!result) {
|
||||
expect(result).to.be.ok;
|
||||
return;
|
||||
}
|
||||
|
||||
const resultSignature = result.transaction.signatures[0];
|
||||
expect(resultSignature).to.eq(confirmedTransaction);
|
||||
|
||||
const newAddress = Keypair.generate().publicKey;
|
||||
const recentSignature = await helpers.airdrop({
|
||||
connection,
|
||||
address: newAddress,
|
||||
amount: 1,
|
||||
});
|
||||
|
||||
await mockRpcResponse({
|
||||
method: 'getConfirmedTransaction',
|
||||
params: [recentSignature],
|
||||
value: null,
|
||||
});
|
||||
|
||||
// Signature hasn't been finalized yet
|
||||
const nullResponse = await connection.getTransaction(recentSignature);
|
||||
expect(nullResponse).to.be.null;
|
||||
});
|
||||
|
||||
it('get confirmed transaction', async () => {
|
||||
await mockRpcResponse({
|
||||
method: 'getSlot',
|
||||
@ -1535,6 +1680,121 @@ describe('Connection', () => {
|
||||
});
|
||||
}
|
||||
|
||||
it('get block', async () => {
|
||||
await mockRpcResponse({
|
||||
method: 'getSlot',
|
||||
params: [],
|
||||
value: 1,
|
||||
});
|
||||
|
||||
while ((await connection.getSlot()) <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await mockRpcResponse({
|
||||
method: 'getConfirmedBlock',
|
||||
params: [0],
|
||||
value: {
|
||||
blockTime: 1614281964,
|
||||
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||
parentSlot: 0,
|
||||
transactions: [],
|
||||
},
|
||||
});
|
||||
|
||||
// Block 0 never has any transactions in test validator
|
||||
const block0 = await connection.getBlock(0);
|
||||
if (!block0) {
|
||||
expect(block0).not.to.be.null;
|
||||
return;
|
||||
}
|
||||
|
||||
const blockhash0 = block0.blockhash;
|
||||
expect(block0.transactions).to.have.length(0);
|
||||
expect(blockhash0).not.to.be.null;
|
||||
expect(block0.previousBlockhash).not.to.be.null;
|
||||
expect(block0.parentSlot).to.eq(0);
|
||||
|
||||
await mockRpcResponse({
|
||||
method: 'getConfirmedBlock',
|
||||
params: [1],
|
||||
value: {
|
||||
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, usually Block 1
|
||||
let x = 1;
|
||||
while (x < 10) {
|
||||
const block1 = await connection.getBlock(x);
|
||||
if (block1 && block1.transactions.length >= 1) {
|
||||
expect(block1.previousBlockhash).to.eq(blockhash0);
|
||||
expect(block1.blockhash).not.to.be.null;
|
||||
expect(block1.parentSlot).to.eq(0);
|
||||
expect(block1.transactions[0].transaction).not.to.be.null;
|
||||
break;
|
||||
}
|
||||
x++;
|
||||
}
|
||||
|
||||
await mockRpcResponse({
|
||||
method: 'getConfirmedBlock',
|
||||
params: [Number.MAX_SAFE_INTEGER],
|
||||
error: {
|
||||
message: `Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
||||
},
|
||||
});
|
||||
await expect(
|
||||
connection.getBlock(Number.MAX_SAFE_INTEGER),
|
||||
).to.be.rejectedWith(
|
||||
`Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('get confirmed block', async () => {
|
||||
await mockRpcResponse({
|
||||
method: 'getSlot',
|
||||
|
Reference in New Issue
Block a user