fix: repair web3 connection tests by making fewer assumptions about the existence of particular blocks (#23921)
* fix: repair 'get confirmed signatures for address' test in web3.js * fix: repair 'get signatures for address' test in web3.js * fix: repair 'get parsed confirmed transactions' test in web3.js * fix: repair 'get transaction' test in web3.js * fix: repair 'get confirmed transaction' test in web3.js * fix: repair 'get block' test in web3.js * fix: repair 'get confirmed block' test in web3.js * fix: repair 'get block signatures' test in web3.js * fix: repair 'get block time' test in web3.js Co-authored-by: steveluscher <github@steveluscher.com>
This commit is contained in:
parent
c8c3c4359f
commit
412d9be445
|
@ -24,7 +24,10 @@ import {DEFAULT_TICKS_PER_SLOT, NUM_TICKS_PER_SECOND} from '../src/timing';
|
||||||
import {MOCK_PORT, url} from './url';
|
import {MOCK_PORT, url} from './url';
|
||||||
import {
|
import {
|
||||||
BLOCKHASH_CACHE_TIMEOUT_MS,
|
BLOCKHASH_CACHE_TIMEOUT_MS,
|
||||||
|
BlockResponse,
|
||||||
|
BlockSignatures,
|
||||||
Commitment,
|
Commitment,
|
||||||
|
ConfirmedBlock,
|
||||||
EpochInfo,
|
EpochInfo,
|
||||||
InflationGovernor,
|
InflationGovernor,
|
||||||
SlotInfo,
|
SlotInfo,
|
||||||
|
@ -71,7 +74,7 @@ const verifySignatureStatus = (
|
||||||
return status;
|
return status;
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Connection', () => {
|
describe('Connection', function () {
|
||||||
let connection: Connection;
|
let connection: Connection;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
connection = new Connection(url);
|
connection = new Connection(url);
|
||||||
|
@ -999,12 +1002,17 @@ describe('Connection', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find a block that has a transaction, usually Block 1
|
// Find a block that has a transaction.
|
||||||
let slot = 0;
|
await mockRpcResponse({
|
||||||
|
method: 'getFirstAvailableBlock',
|
||||||
|
params: [],
|
||||||
|
value: 1,
|
||||||
|
});
|
||||||
|
let slot = await connection.getFirstAvailableBlock();
|
||||||
|
|
||||||
let address: PublicKey | undefined;
|
let address: PublicKey | undefined;
|
||||||
let expectedSignature: string | undefined;
|
let expectedSignature: string | undefined;
|
||||||
while (!address || !expectedSignature) {
|
while (!address || !expectedSignature) {
|
||||||
slot++;
|
|
||||||
const block = await connection.getConfirmedBlock(slot);
|
const block = await connection.getConfirmedBlock(slot);
|
||||||
if (block.transactions.length > 0) {
|
if (block.transactions.length > 0) {
|
||||||
const {signature, publicKey} =
|
const {signature, publicKey} =
|
||||||
|
@ -1012,8 +1020,10 @@ describe('Connection', () => {
|
||||||
if (signature) {
|
if (signature) {
|
||||||
address = publicKey;
|
address = publicKey;
|
||||||
expectedSignature = bs58.encode(signature);
|
expectedSignature = bs58.encode(signature);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
slot++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// getConfirmedSignaturesForAddress tests...
|
// getConfirmedSignaturesForAddress tests...
|
||||||
|
@ -1174,12 +1184,17 @@ describe('Connection', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find a block that has a transaction, usually Block 1
|
// Find a block that has a transaction.
|
||||||
let slot = 0;
|
await mockRpcResponse({
|
||||||
|
method: 'getFirstAvailableBlock',
|
||||||
|
params: [],
|
||||||
|
value: 1,
|
||||||
|
});
|
||||||
|
let slot = await connection.getFirstAvailableBlock();
|
||||||
|
|
||||||
let address: PublicKey | undefined;
|
let address: PublicKey | undefined;
|
||||||
let expectedSignature: string | undefined;
|
let expectedSignature: string | undefined;
|
||||||
while (!address || !expectedSignature) {
|
while (!address || !expectedSignature) {
|
||||||
slot++;
|
|
||||||
const block = await connection.getConfirmedBlock(slot);
|
const block = await connection.getConfirmedBlock(slot);
|
||||||
if (block.transactions.length > 0) {
|
if (block.transactions.length > 0) {
|
||||||
const {signature, publicKey} =
|
const {signature, publicKey} =
|
||||||
|
@ -1187,8 +1202,10 @@ describe('Connection', () => {
|
||||||
if (signature) {
|
if (signature) {
|
||||||
address = publicKey;
|
address = publicKey;
|
||||||
expectedSignature = bs58.encode(signature);
|
expectedSignature = bs58.encode(signature);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
slot++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSignaturesForAddress tests...
|
// getSignaturesForAddress tests...
|
||||||
|
@ -1278,17 +1295,24 @@ describe('Connection', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find a block that has a transaction, usually Block 1
|
// Find a block that has a transaction.
|
||||||
let slot = 0;
|
await mockRpcResponse({
|
||||||
|
method: 'getFirstAvailableBlock',
|
||||||
|
params: [],
|
||||||
|
value: 1,
|
||||||
|
});
|
||||||
|
let slot = await connection.getFirstAvailableBlock();
|
||||||
|
|
||||||
let confirmedTransaction: string | undefined;
|
let confirmedTransaction: string | undefined;
|
||||||
while (!confirmedTransaction) {
|
while (!confirmedTransaction) {
|
||||||
slot++;
|
|
||||||
const block = await connection.getConfirmedBlock(slot);
|
const block = await connection.getConfirmedBlock(slot);
|
||||||
for (const tx of block.transactions) {
|
for (const tx of block.transactions) {
|
||||||
if (tx.transaction.signature) {
|
if (tx.transaction.signature) {
|
||||||
confirmedTransaction = bs58.encode(tx.transaction.signature);
|
confirmedTransaction = bs58.encode(tx.transaction.signature);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
slot++;
|
||||||
}
|
}
|
||||||
|
|
||||||
await mockRpcBatchResponse({
|
await mockRpcBatchResponse({
|
||||||
|
@ -1551,15 +1575,22 @@ describe('Connection', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find a block that has a transaction, usually Block 1
|
// Find a block that has a transaction.
|
||||||
let slot = 0;
|
await mockRpcResponse({
|
||||||
|
method: 'getFirstAvailableBlock',
|
||||||
|
params: [],
|
||||||
|
value: 1,
|
||||||
|
});
|
||||||
|
let slot = await connection.getFirstAvailableBlock();
|
||||||
|
|
||||||
let transaction: string | undefined;
|
let transaction: string | undefined;
|
||||||
while (!transaction) {
|
while (!transaction) {
|
||||||
slot++;
|
|
||||||
const block = await connection.getBlock(slot);
|
const block = await connection.getBlock(slot);
|
||||||
if (block && block.transactions.length > 0) {
|
if (block && block.transactions.length > 0) {
|
||||||
transaction = block.transactions[0].transaction.signatures[0];
|
transaction = block.transactions[0].transaction.signatures[0];
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
slot++;
|
||||||
}
|
}
|
||||||
|
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
|
@ -1694,17 +1725,24 @@ describe('Connection', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find a block that has a transaction, usually Block 1
|
// Find a block that has a transaction.
|
||||||
let slot = 0;
|
await mockRpcResponse({
|
||||||
|
method: 'getFirstAvailableBlock',
|
||||||
|
params: [],
|
||||||
|
value: 1,
|
||||||
|
});
|
||||||
|
let slot = await connection.getFirstAvailableBlock();
|
||||||
|
|
||||||
let confirmedTransaction: string | undefined;
|
let confirmedTransaction: string | undefined;
|
||||||
while (!confirmedTransaction) {
|
while (!confirmedTransaction) {
|
||||||
slot++;
|
|
||||||
const block = await connection.getConfirmedBlock(slot);
|
const block = await connection.getConfirmedBlock(slot);
|
||||||
for (const tx of block.transactions) {
|
for (const tx of block.transactions) {
|
||||||
if (tx.transaction.signature) {
|
if (tx.transaction.signature) {
|
||||||
confirmedTransaction = bs58.encode(tx.transaction.signature);
|
confirmedTransaction = bs58.encode(tx.transaction.signature);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
slot++;
|
||||||
}
|
}
|
||||||
|
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
|
@ -1885,243 +1923,339 @@ describe('Connection', () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
it('get block', async () => {
|
describe('get block', function () {
|
||||||
await mockRpcResponse({
|
beforeEach(async function () {
|
||||||
method: 'getSlot',
|
await mockRpcResponse({
|
||||||
params: [],
|
method: 'getSlot',
|
||||||
value: 1,
|
params: [],
|
||||||
|
value: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
while ((await connection.getSlot()) <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
while ((await connection.getSlot()) <= 0) {
|
it('gets the genesis block', async function () {
|
||||||
continue;
|
await mockRpcResponse({
|
||||||
}
|
method: 'getBlock',
|
||||||
|
params: [0],
|
||||||
|
value: {
|
||||||
|
blockHeight: 0,
|
||||||
|
blockTime: 1614281964,
|
||||||
|
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
parentSlot: 0,
|
||||||
|
transactions: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await mockRpcResponse({
|
let maybeBlock0: BlockResponse | null;
|
||||||
method: 'getBlock',
|
try {
|
||||||
params: [0],
|
maybeBlock0 = await connection.getBlock(0);
|
||||||
value: {
|
} catch (e) {
|
||||||
blockHeight: 0,
|
if (process.env.TEST_LIVE) {
|
||||||
blockTime: 1614281964,
|
console.warn(
|
||||||
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
'WARNING: We ran no assertions about the genesis block because block 0 ' +
|
||||||
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
'could not be found. See https://github.com/solana-labs/solana/issues/23853.',
|
||||||
parentSlot: 0,
|
);
|
||||||
transactions: [],
|
this.skip();
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 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: '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
|
|
||||||
// Compare data with parent
|
|
||||||
let x = 1;
|
|
||||||
while (x < 10) {
|
|
||||||
const block1 = await connection.getBlock(x);
|
|
||||||
if (block1 && block1.transactions.length >= 1) {
|
|
||||||
if (block1.parentSlot == 0) {
|
|
||||||
expect(block1.previousBlockhash).to.eq(blockhash0);
|
|
||||||
} else {
|
} else {
|
||||||
const parentBlock = await connection.getBlock(block1.parentSlot);
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(maybeBlock0).not.to.be.null;
|
||||||
|
const block0 = maybeBlock0!;
|
||||||
|
|
||||||
|
// Block 0 never has any transactions in test validator
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('gets a block having a parent', async function () {
|
||||||
|
// Mock parent of block with transaction.
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getBlock',
|
||||||
|
params: [0],
|
||||||
|
value: {
|
||||||
|
blockHeight: 0,
|
||||||
|
blockTime: 1614281964,
|
||||||
|
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
parentSlot: 0,
|
||||||
|
transactions: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// Mock block with transaction.
|
||||||
|
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 *and* a parent.
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getFirstAvailableBlock',
|
||||||
|
params: [],
|
||||||
|
value: 0,
|
||||||
|
});
|
||||||
|
let candidateSlot = (await connection.getFirstAvailableBlock()) + 1;
|
||||||
|
let result:
|
||||||
|
| {
|
||||||
|
blockWithTransaction: BlockResponse;
|
||||||
|
parentBlock: BlockResponse;
|
||||||
|
}
|
||||||
|
| undefined;
|
||||||
|
while (!result) {
|
||||||
|
const candidateBlock = await connection.getBlock(candidateSlot);
|
||||||
|
if (candidateBlock && candidateBlock.transactions.length) {
|
||||||
|
const parentBlock = await connection.getBlock(candidateSlot - 1);
|
||||||
if (parentBlock) {
|
if (parentBlock) {
|
||||||
expect(block1.previousBlockhash).to.eq(parentBlock.blockhash);
|
result = {blockWithTransaction: candidateBlock, parentBlock};
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect(block1.blockhash).not.to.be.null;
|
candidateSlot++;
|
||||||
expect(block1.transactions[0].transaction).not.to.be.null;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
x++;
|
|
||||||
}
|
|
||||||
|
|
||||||
await mockRpcResponse({
|
// Compare data with parent
|
||||||
method: 'getBlock',
|
expect(result.blockWithTransaction.previousBlockhash).to.eq(
|
||||||
params: [Number.MAX_SAFE_INTEGER],
|
result.parentBlock.blockhash,
|
||||||
error: {
|
);
|
||||||
message: `Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
expect(result.blockWithTransaction.blockhash).not.to.be.null;
|
||||||
},
|
expect(result.blockWithTransaction.transactions[0].transaction).not.to.be
|
||||||
|
.null;
|
||||||
|
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getBlock',
|
||||||
|
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}`,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
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 () => {
|
describe('get confirmed block', function () {
|
||||||
await mockRpcResponse({
|
beforeEach(async function () {
|
||||||
method: 'getSlot',
|
await mockRpcResponse({
|
||||||
params: [],
|
method: 'getSlot',
|
||||||
value: 1,
|
params: [],
|
||||||
|
value: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
while ((await connection.getSlot()) <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
while ((await connection.getSlot()) <= 0) {
|
it('gets the genesis block', async function () {
|
||||||
continue;
|
await mockRpcResponse({
|
||||||
}
|
method: 'getConfirmedBlock',
|
||||||
|
params: [0],
|
||||||
|
value: {
|
||||||
|
blockHeight: 0,
|
||||||
|
blockTime: 1614281964,
|
||||||
|
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
parentSlot: 0,
|
||||||
|
transactions: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await mockRpcResponse({
|
let block0: ConfirmedBlock;
|
||||||
method: 'getConfirmedBlock',
|
try {
|
||||||
params: [0],
|
block0 = await connection.getConfirmedBlock(0);
|
||||||
value: {
|
} catch (e) {
|
||||||
blockTime: 1614281964,
|
if (process.env.TEST_LIVE) {
|
||||||
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
console.warn(
|
||||||
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
'WARNING: We ran no assertions about the genesis block because block 0 ' +
|
||||||
parentSlot: 0,
|
'could not be found. See https://github.com/solana-labs/solana/issues/23853.',
|
||||||
transactions: [],
|
);
|
||||||
},
|
this.skip();
|
||||||
});
|
|
||||||
|
|
||||||
// Block 0 never has any transactions in test validator
|
|
||||||
const block0 = await connection.getConfirmedBlock(0);
|
|
||||||
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
|
|
||||||
// Compare data with parent
|
|
||||||
let x = 1;
|
|
||||||
while (x < 10) {
|
|
||||||
const block1 = await connection.getConfirmedBlock(x);
|
|
||||||
if (block1.transactions.length >= 1) {
|
|
||||||
if (block1.parentSlot == 0) {
|
|
||||||
expect(block1.previousBlockhash).to.eq(blockhash0);
|
|
||||||
} else {
|
} else {
|
||||||
const parentBlock = await connection.getBlock(block1.parentSlot);
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block 0 never has any transactions in test validator
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('gets a block having a parent', async function () {
|
||||||
|
// Mock parent of block with transaction.
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getConfirmedBlock',
|
||||||
|
params: [0],
|
||||||
|
value: {
|
||||||
|
blockHeight: 0,
|
||||||
|
blockTime: 1614281964,
|
||||||
|
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
parentSlot: 0,
|
||||||
|
transactions: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// Mock block with transaction.
|
||||||
|
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 *and* a parent.
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getFirstAvailableBlock',
|
||||||
|
params: [],
|
||||||
|
value: 0,
|
||||||
|
});
|
||||||
|
let candidateSlot = (await connection.getFirstAvailableBlock()) + 1;
|
||||||
|
let result:
|
||||||
|
| {
|
||||||
|
blockWithTransaction: ConfirmedBlock;
|
||||||
|
parentBlock: ConfirmedBlock;
|
||||||
|
}
|
||||||
|
| undefined;
|
||||||
|
while (!result) {
|
||||||
|
const candidateBlock = await connection.getConfirmedBlock(
|
||||||
|
candidateSlot,
|
||||||
|
);
|
||||||
|
if (candidateBlock && candidateBlock.transactions.length) {
|
||||||
|
const parentBlock = await connection.getConfirmedBlock(
|
||||||
|
candidateSlot - 1,
|
||||||
|
);
|
||||||
if (parentBlock) {
|
if (parentBlock) {
|
||||||
expect(block1.previousBlockhash).to.eq(parentBlock.blockhash);
|
result = {blockWithTransaction: candidateBlock, parentBlock};
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect(block1.blockhash).not.to.be.null;
|
candidateSlot++;
|
||||||
expect(block1.transactions[0].transaction).not.to.be.null;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
x++;
|
|
||||||
}
|
|
||||||
|
|
||||||
await mockRpcResponse({
|
// Compare data with parent
|
||||||
method: 'getConfirmedBlock',
|
expect(result.blockWithTransaction.previousBlockhash).to.eq(
|
||||||
params: [Number.MAX_SAFE_INTEGER],
|
result.parentBlock.blockhash,
|
||||||
error: {
|
);
|
||||||
message: `Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
expect(result.blockWithTransaction.blockhash).not.to.be.null;
|
||||||
},
|
expect(result.blockWithTransaction.transactions[0].transaction).not.to.be
|
||||||
|
.null;
|
||||||
|
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getConfirmedBlock',
|
||||||
|
params: [Number.MAX_SAFE_INTEGER],
|
||||||
|
error: {
|
||||||
|
message: `Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await expect(
|
||||||
|
connection.getConfirmedBlock(Number.MAX_SAFE_INTEGER),
|
||||||
|
).to.be.rejectedWith(
|
||||||
|
`Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
await expect(
|
|
||||||
connection.getConfirmedBlock(Number.MAX_SAFE_INTEGER),
|
|
||||||
).to.be.rejectedWith(
|
|
||||||
`Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('get blocks between two slots', async () => {
|
it('get blocks between two slots', async () => {
|
||||||
|
@ -2172,101 +2306,156 @@ describe('Connection', () => {
|
||||||
expect(blocks).to.contain(latestSlot);
|
expect(blocks).to.contain(latestSlot);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('get block signatures', async () => {
|
describe('get block signatures', function () {
|
||||||
await mockRpcResponse({
|
beforeEach(async function () {
|
||||||
method: 'getSlot',
|
await mockRpcResponse({
|
||||||
params: [],
|
method: 'getSlot',
|
||||||
value: 1,
|
params: [],
|
||||||
|
value: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
while ((await connection.getSlot()) <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
while ((await connection.getSlot()) <= 0) {
|
it('gets the genesis block', async function () {
|
||||||
continue;
|
await mockRpcResponse({
|
||||||
}
|
method: 'getBlock',
|
||||||
|
params: [
|
||||||
await mockRpcResponse({
|
0,
|
||||||
method: 'getBlock',
|
{
|
||||||
params: [
|
transactionDetails: 'signatures',
|
||||||
0,
|
rewards: false,
|
||||||
{
|
},
|
||||||
transactionDetails: 'signatures',
|
|
||||||
rewards: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
value: {
|
|
||||||
blockHeight: 0,
|
|
||||||
blockTime: 1614281964,
|
|
||||||
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
|
||||||
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
|
||||||
parentSlot: 0,
|
|
||||||
signatures: [],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Block 0 never has any transactions in test validator
|
|
||||||
const block0 = await connection.getBlockSignatures(0);
|
|
||||||
const blockhash0 = block0.blockhash;
|
|
||||||
expect(block0.signatures).to.have.length(0);
|
|
||||||
expect(blockhash0).not.to.be.null;
|
|
||||||
expect(block0.previousBlockhash).not.to.be.null;
|
|
||||||
expect(block0.parentSlot).to.eq(0);
|
|
||||||
expect(block0).to.not.have.property('rewards');
|
|
||||||
|
|
||||||
await mockRpcResponse({
|
|
||||||
method: 'getBlock',
|
|
||||||
params: [
|
|
||||||
1,
|
|
||||||
{
|
|
||||||
transactionDetails: 'signatures',
|
|
||||||
rewards: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
value: {
|
|
||||||
blockHeight: 1,
|
|
||||||
blockTime: 1614281964,
|
|
||||||
blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
|
||||||
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
|
||||||
parentSlot: 0,
|
|
||||||
signatures: [
|
|
||||||
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt',
|
|
||||||
'4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG',
|
|
||||||
],
|
],
|
||||||
},
|
value: {
|
||||||
|
blockHeight: 0,
|
||||||
|
blockTime: 1614281964,
|
||||||
|
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
parentSlot: 0,
|
||||||
|
signatures: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let block0: BlockSignatures;
|
||||||
|
try {
|
||||||
|
block0 = await connection.getBlockSignatures(0);
|
||||||
|
} catch (e) {
|
||||||
|
if (process.env.TEST_LIVE) {
|
||||||
|
console.warn(
|
||||||
|
'WARNING: We ran no assertions about the genesis block because block 0 ' +
|
||||||
|
'could not be found. See https://github.com/solana-labs/solana/issues/23853.',
|
||||||
|
);
|
||||||
|
this.skip();
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block 0 never has any transactions in test validator
|
||||||
|
const blockhash0 = block0.blockhash;
|
||||||
|
expect(block0.signatures).to.have.length(0);
|
||||||
|
expect(blockhash0).not.to.be.null;
|
||||||
|
expect(block0.previousBlockhash).not.to.be.null;
|
||||||
|
expect(block0.parentSlot).to.eq(0);
|
||||||
|
expect(block0).to.not.have.property('rewards');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find a block that has a transaction
|
it('gets a block having a parent', async function () {
|
||||||
// Compare data with parent
|
// Mock parent of block with transaction.
|
||||||
let x = 1;
|
await mockRpcResponse({
|
||||||
while (x < 10) {
|
method: 'getBlock',
|
||||||
const block1 = await connection.getBlockSignatures(x);
|
params: [
|
||||||
if (block1.signatures.length >= 1) {
|
0,
|
||||||
if (block1.parentSlot == 0) {
|
{
|
||||||
expect(block1.previousBlockhash).to.eq(blockhash0);
|
transactionDetails: 'signatures',
|
||||||
} else {
|
rewards: false,
|
||||||
const parentBlock = await connection.getBlock(block1.parentSlot);
|
},
|
||||||
|
],
|
||||||
|
value: {
|
||||||
|
blockHeight: 0,
|
||||||
|
blockTime: 1614281964,
|
||||||
|
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
parentSlot: 0,
|
||||||
|
signatures: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// Mock block with transaction.
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getBlock',
|
||||||
|
params: [
|
||||||
|
1,
|
||||||
|
{
|
||||||
|
transactionDetails: 'signatures',
|
||||||
|
rewards: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
value: {
|
||||||
|
blockHeight: 1,
|
||||||
|
blockTime: 1614281964,
|
||||||
|
blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
||||||
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
parentSlot: 0,
|
||||||
|
signatures: [
|
||||||
|
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt',
|
||||||
|
'4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Find a block that has a transaction *and* a parent.
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getFirstAvailableBlock',
|
||||||
|
params: [],
|
||||||
|
value: 0,
|
||||||
|
});
|
||||||
|
let candidateSlot = (await connection.getFirstAvailableBlock()) + 1;
|
||||||
|
let result:
|
||||||
|
| {
|
||||||
|
blockWithTransaction: BlockSignatures;
|
||||||
|
parentBlock: BlockSignatures;
|
||||||
|
}
|
||||||
|
| undefined;
|
||||||
|
while (!result) {
|
||||||
|
const candidateBlock = await connection.getBlockSignatures(
|
||||||
|
candidateSlot,
|
||||||
|
);
|
||||||
|
if (candidateBlock && candidateBlock.signatures.length) {
|
||||||
|
const parentBlock = await connection.getBlockSignatures(
|
||||||
|
candidateSlot - 1,
|
||||||
|
);
|
||||||
if (parentBlock) {
|
if (parentBlock) {
|
||||||
expect(block1.previousBlockhash).to.eq(parentBlock.blockhash);
|
result = {blockWithTransaction: candidateBlock, parentBlock};
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect(block1.blockhash).not.to.be.null;
|
candidateSlot++;
|
||||||
expect(block1.signatures[0]).not.to.be.null;
|
|
||||||
expect(block1).to.not.have.property('rewards');
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
x++;
|
|
||||||
}
|
|
||||||
|
|
||||||
await mockRpcResponse({
|
// Compare data with parent
|
||||||
method: 'getBlock',
|
expect(result.blockWithTransaction.previousBlockhash).to.eq(
|
||||||
params: [Number.MAX_SAFE_INTEGER],
|
result.parentBlock.blockhash,
|
||||||
error: {
|
);
|
||||||
message: `Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
expect(result.blockWithTransaction.blockhash).not.to.be.null;
|
||||||
},
|
expect(result.blockWithTransaction.signatures[0]).not.to.be.null;
|
||||||
|
expect(result.blockWithTransaction).to.not.have.property('rewards');
|
||||||
|
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getBlock',
|
||||||
|
params: [Number.MAX_SAFE_INTEGER],
|
||||||
|
error: {
|
||||||
|
message: `Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await expect(
|
||||||
|
connection.getBlockSignatures(Number.MAX_SAFE_INTEGER),
|
||||||
|
).to.be.rejectedWith(
|
||||||
|
`Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
await expect(
|
|
||||||
connection.getBlockSignatures(Number.MAX_SAFE_INTEGER),
|
|
||||||
).to.be.rejectedWith(
|
|
||||||
`Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('get recent blockhash', async () => {
|
it('get recent blockhash', async () => {
|
||||||
|
@ -2355,7 +2544,13 @@ describe('Connection', () => {
|
||||||
value: 10000,
|
value: 10000,
|
||||||
});
|
});
|
||||||
|
|
||||||
const blockTime = await connection.getBlockTime(1);
|
await mockRpcResponse({
|
||||||
|
method: 'getFirstAvailableBlock',
|
||||||
|
params: [],
|
||||||
|
value: 1,
|
||||||
|
});
|
||||||
|
const slot = await connection.getFirstAvailableBlock();
|
||||||
|
const blockTime = await connection.getBlockTime(slot);
|
||||||
if (blockTime === null) {
|
if (blockTime === null) {
|
||||||
expect(blockTime).not.to.be.null;
|
expect(blockTime).not.to.be.null;
|
||||||
} else {
|
} else {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue