Fix explorer account history search
This commit is contained in:
parent
d989cc60f6
commit
74c44009a7
|
@ -43,66 +43,106 @@ export class HistoryManager {
|
||||||
this.accountHistory.delete(address);
|
this.accountHistory.delete(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchAccountHistory(pubkey: PublicKey, refresh: boolean) {
|
// Fetch a batch of confirmed signatures but decrease fetch count until
|
||||||
|
// the batch is small enough to be queried for statuses.
|
||||||
|
async fetchConfirmedSignatureBatch(
|
||||||
|
pubkey: PublicKey,
|
||||||
|
start: number,
|
||||||
|
fetchCount: number,
|
||||||
|
forward: boolean
|
||||||
|
): Promise<{
|
||||||
|
batch: Array<TransactionSignature>;
|
||||||
|
batchRange: SlotRange;
|
||||||
|
}> {
|
||||||
|
const fullRange = await this.fullRange(false);
|
||||||
|
const nextRange = (): SlotRange => {
|
||||||
|
if (forward) {
|
||||||
|
return {
|
||||||
|
min: start,
|
||||||
|
max: Math.min(fullRange.max, start + fetchCount - 1),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
min: Math.max(fullRange.min, start - fetchCount + 1),
|
||||||
|
max: start,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let batch: TransactionSignature[] = [];
|
||||||
|
let batchRange = nextRange();
|
||||||
|
while (batchRange.max > batchRange.min) {
|
||||||
|
batch = await this.connection.getConfirmedSignaturesForAddress(
|
||||||
|
pubkey,
|
||||||
|
batchRange.min,
|
||||||
|
batchRange.max
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fetched too many results, refetch with a smaller range (1/8)
|
||||||
|
if (batch.length > 4 * MAX_STATUS_BATCH_SIZE) {
|
||||||
|
fetchCount = Math.ceil(fetchCount / 8);
|
||||||
|
batchRange = nextRange();
|
||||||
|
} else {
|
||||||
|
batch = batch.reverse();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { batchRange, batch };
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchAccountHistory(pubkey: PublicKey, searchForward: boolean) {
|
||||||
const address = pubkey.toBase58();
|
const address = pubkey.toBase58();
|
||||||
|
|
||||||
if (this.accountLock.get(address) === true) return;
|
if (this.accountLock.get(address) === true) return;
|
||||||
this.accountLock.set(address, true);
|
this.accountLock.set(address, true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let slotLookBack = 100;
|
// Start with only 250 slots in case queried account is a vote account
|
||||||
const fullRange = await this.fullRange(refresh);
|
let slotFetchCount = 250;
|
||||||
|
const fullRange = await this.fullRange(searchForward);
|
||||||
const currentRange = this.accountRanges.get(address);
|
const currentRange = this.accountRanges.get(address);
|
||||||
|
|
||||||
// Determine query range based on already queried range
|
// Determine query range based on already queried range
|
||||||
let range;
|
let startSlot: number;
|
||||||
if (currentRange) {
|
if (currentRange) {
|
||||||
if (refresh) {
|
if (searchForward) {
|
||||||
const min = currentRange.max + 1;
|
startSlot = currentRange.max + 1;
|
||||||
const max = Math.min(min + slotLookBack - 1, fullRange.max);
|
|
||||||
if (max < min) return;
|
|
||||||
range = { min, max };
|
|
||||||
} else {
|
} else {
|
||||||
const max = currentRange.min - 1;
|
startSlot = currentRange.min - 1;
|
||||||
const min = Math.max(max - slotLookBack + 1, fullRange.min);
|
|
||||||
if (max < min) return;
|
|
||||||
range = { min, max };
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const max = fullRange.max;
|
searchForward = false;
|
||||||
const min = Math.max(fullRange.min, max - slotLookBack + 1);
|
startSlot = fullRange.max;
|
||||||
range = { min, max };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gradually fetch more history if nothing found
|
// Gradually fetch more history if not too many signatures were found
|
||||||
let signatures: string[] = [];
|
let signatures: string[] = [];
|
||||||
let nextRange = { ...range };
|
let range: SlotRange = { min: startSlot, max: startSlot };
|
||||||
for (var i = 0; i < 5; i++) {
|
for (var i = 0; i < 5; i++) {
|
||||||
signatures = (
|
const { batch, batchRange } = await this.fetchConfirmedSignatureBatch(
|
||||||
await this.connection.getConfirmedSignaturesForAddress(
|
pubkey,
|
||||||
pubkey,
|
startSlot,
|
||||||
nextRange.min,
|
slotFetchCount,
|
||||||
nextRange.max
|
searchForward
|
||||||
)
|
);
|
||||||
).reverse();
|
|
||||||
if (refresh) break;
|
|
||||||
if (signatures.length > 0) break;
|
|
||||||
if (range.min <= fullRange.min) break;
|
|
||||||
|
|
||||||
switch (slotLookBack) {
|
range.min = Math.min(range.min, batchRange.min);
|
||||||
case 100:
|
range.max = Math.max(range.max, batchRange.max);
|
||||||
slotLookBack = 1000;
|
|
||||||
break;
|
if (searchForward) {
|
||||||
case 1000:
|
signatures = batch.concat(signatures);
|
||||||
slotLookBack = 10000;
|
startSlot = batchRange.max + 1;
|
||||||
break;
|
} else {
|
||||||
|
signatures = signatures.concat(batch);
|
||||||
|
startSlot = batchRange.min - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
range.min = Math.max(nextRange.min - slotLookBack, fullRange.min);
|
if (signatures.length > MAX_STATUS_BATCH_SIZE / 2) break;
|
||||||
nextRange = {
|
if (range.min <= fullRange.min) break;
|
||||||
min: range.min,
|
|
||||||
max: nextRange.min - 1,
|
// Bump look-back not that we know the account is probably not a vote account
|
||||||
};
|
slotFetchCount = 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch the statuses for all confirmed signatures
|
// Fetch the statuses for all confirmed signatures
|
||||||
|
@ -141,7 +181,7 @@ export class HistoryManager {
|
||||||
|
|
||||||
// Append / prepend newly fetched statuses
|
// Append / prepend newly fetched statuses
|
||||||
let newTransactions;
|
let newTransactions;
|
||||||
if (refresh) {
|
if (searchForward) {
|
||||||
newTransactions = transactions.concat(currentTransactions);
|
newTransactions = transactions.concat(currentTransactions);
|
||||||
} else {
|
} else {
|
||||||
newTransactions = currentTransactions.concat(transactions);
|
newTransactions = currentTransactions.concat(transactions);
|
||||||
|
|
Loading…
Reference in New Issue