fix: lock recent blockhash poll to prevent concurrent polling
This commit is contained in:
committed by
Justin Starry
parent
d6ecb2699f
commit
7aa8b1c658
@ -1377,6 +1377,7 @@ export class Connection {
|
|||||||
transactionSignatures: Array<string>,
|
transactionSignatures: Array<string>,
|
||||||
};
|
};
|
||||||
_disableBlockhashCaching: boolean = false;
|
_disableBlockhashCaching: boolean = false;
|
||||||
|
_pollingBlockhash: boolean = false;
|
||||||
_accountChangeSubscriptions: {[number]: AccountSubscriptionInfo} = {};
|
_accountChangeSubscriptions: {[number]: AccountSubscriptionInfo} = {};
|
||||||
_accountChangeSubscriptionCounter: number = 0;
|
_accountChangeSubscriptionCounter: number = 0;
|
||||||
_programAccountChangeSubscriptions: {
|
_programAccountChangeSubscriptions: {
|
||||||
@ -2478,6 +2479,10 @@ export class Connection {
|
|||||||
|
|
||||||
async _recentBlockhash(disableCache: boolean): Promise<Blockhash> {
|
async _recentBlockhash(disableCache: boolean): Promise<Blockhash> {
|
||||||
if (!disableCache) {
|
if (!disableCache) {
|
||||||
|
// Wait for polling to finish
|
||||||
|
while (this._pollingBlockhash) {
|
||||||
|
await sleep(100);
|
||||||
|
}
|
||||||
// Attempt to use a recent blockhash for up to 30 seconds
|
// Attempt to use a recent blockhash for up to 30 seconds
|
||||||
const expired =
|
const expired =
|
||||||
Date.now() - this._blockhashInfo.lastFetch >=
|
Date.now() - this._blockhashInfo.lastFetch >=
|
||||||
@ -2491,27 +2496,32 @@ export class Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _pollNewBlockhash(): Promise<Blockhash> {
|
async _pollNewBlockhash(): Promise<Blockhash> {
|
||||||
const startTime = Date.now();
|
this._pollingBlockhash = true;
|
||||||
for (let i = 0; i < 50; i++) {
|
try {
|
||||||
const {blockhash} = await this.getRecentBlockhash('max');
|
const startTime = Date.now();
|
||||||
|
for (let i = 0; i < 50; i++) {
|
||||||
|
const {blockhash} = await this.getRecentBlockhash('max');
|
||||||
|
|
||||||
if (this._blockhashInfo.recentBlockhash != blockhash) {
|
if (this._blockhashInfo.recentBlockhash != blockhash) {
|
||||||
this._blockhashInfo = {
|
this._blockhashInfo = {
|
||||||
recentBlockhash: blockhash,
|
recentBlockhash: blockhash,
|
||||||
lastFetch: new Date(),
|
lastFetch: new Date(),
|
||||||
transactionSignatures: [],
|
transactionSignatures: [],
|
||||||
simulatedSignatures: [],
|
simulatedSignatures: [],
|
||||||
};
|
};
|
||||||
return blockhash;
|
return blockhash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sleep for approximately half a slot
|
||||||
|
await sleep(MS_PER_SLOT / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sleep for approximately half a slot
|
throw new Error(
|
||||||
await sleep(MS_PER_SLOT / 2);
|
`Unable to obtain a new blockhash after ${Date.now() - startTime}ms`,
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
this._pollingBlockhash = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(
|
|
||||||
`Unable to obtain a new blockhash after ${Date.now() - startTime}ms`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user