Skip to content

Commit

Permalink
refactor the time computation config
Browse files Browse the repository at this point in the history
  • Loading branch information
ecioppettini committed Dec 13, 2023
1 parent 22dc556 commit 3eaa6c4
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 35 deletions.
4 changes: 2 additions & 2 deletions packages/engine/paima-funnel/src/cde/cardanoPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import type {
import { ChainDataExtensionDatumType, DEFAULT_FUNNEL_TIMEOUT, timeout } from '@paima/utils';
import { Routes, query } from '@dcspark/carp-client/client/src';
import type { DelegationForPoolResponse } from '@dcspark/carp-client/shared/models/DelegationForPool';
import { absoluteSlotToEpoch } from '../funnels/carp/funnel.js';

export default async function getCdeData(
url: string,
extension: ChainDataExtensionCardanoDelegation,
fromAbsoluteSlot: number,
toAbsoluteSlot: number,
getBlockNumber: (slot: number) => number
getBlockNumber: (slot: number) => number,
absoluteSlotToEpoch: (slot: number) => number
): Promise<ChainDataExtensionDatum[]> {
const events = await timeout(
query(url, Routes.delegationForPool, {
Expand Down
78 changes: 45 additions & 33 deletions packages/engine/paima-funnel/src/funnels/carp/funnel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,42 @@ import { getCardanoEpoch } from '@paima/db';

const delayForWaitingForFinalityLoop = 1000;

// This returns the unix timestamp of the first block in the Shelley era of the
// configured network, and the slot of the corresponding block.
function knownShelleyTime(): { timestamp: number; absoluteSlot: number } {
type Era = {
firstSlot: number;
startEpoch: number;
slotsPerEpoch: number;
timestamp: number;
};

function shelleyEra(): Era {
switch (ENV.CARDANO_NETWORK) {
case 'preview':
return { timestamp: 1666656000, absoluteSlot: 0 };
return {
firstSlot: 0,
startEpoch: 0,
slotsPerEpoch: 86400,
timestamp: 1666656000,
};
case 'preprod':
return { timestamp: 1655769600, absoluteSlot: 86400 };
return {
firstSlot: 86400,
startEpoch: 4,
slotsPerEpoch: 432000,
timestamp: 1655769600,
};
case 'mainnet':
return { timestamp: 1596059091, absoluteSlot: 4492800 };
return {
firstSlot: 4492800,
startEpoch: 208,
slotsPerEpoch: 432000,
timestamp: 1596059091,
};
default:
throw new Error('unknown cardano network');
}
}

function shelleyEra(): { firstSlot: number; startEpoch: number; slotsPerEpoch: number } {
switch (ENV.CARDANO_NETWORK) {
case 'preview':
return { firstSlot: 0, startEpoch: 0, slotsPerEpoch: 86400 };
case 'preprod':
return { firstSlot: 86400, startEpoch: 4, slotsPerEpoch: 432000 };
case 'mainnet':
return { firstSlot: 4492800, startEpoch: 208, slotsPerEpoch: 432000 };
default:
throw new Error('unknown cardano network');
}
}

export function absoluteSlotToEpoch(slot: number): number {
const era = shelleyEra();
function absoluteSlotToEpoch(era: Era, slot: number): number {
const slotRelativeToEra = slot - era.firstSlot;

if (slotRelativeToEra >= 0) {
Expand Down Expand Up @@ -86,14 +92,12 @@ Note: The state pairing only matters after the presync stage is done, so as
long as the timestamp of the block specified in START_BLOCKHEIGHT happens after
the first Shelley block, we don't need to consider the previous Cardano era (if any).
*/
function timestampToAbsoluteSlot(timestamp: number, confirmationDepth: number): number {
function timestampToAbsoluteSlot(era: Era, timestamp: number, confirmationDepth: number): number {
const cardanoAvgBlockPeriod = 20;
// map timestamps with a delta, since we are waiting for blocks.
const confirmationTimeDelta = cardanoAvgBlockPeriod * confirmationDepth;

const era = knownShelleyTime();

return timestamp - confirmationTimeDelta - era.timestamp + era.absoluteSlot;
return timestamp - confirmationTimeDelta - era.timestamp + era.firstSlot;
}

export class CarpFunnel extends BaseFunnel implements ChainFunnel {
Expand All @@ -111,9 +115,11 @@ export class CarpFunnel extends BaseFunnel implements ChainFunnel {
this.readPresyncData.bind(this);
this.getDbTx.bind(this);
this.bufferedData = null;
this.era = shelleyEra();
}

private bufferedData: ChainData[] | null;
private era: Era;

public override async readData(blockHeight: number): Promise<ChainData[]> {
if (!this.bufferedData || this.bufferedData[0].blockNumber != blockHeight) {
Expand Down Expand Up @@ -150,7 +156,8 @@ export class CarpFunnel extends BaseFunnel implements ChainFunnel {
this.sharedData.extensions,
lastTimestamp,
this.cache,
this.confirmationDepth
this.confirmationDepth,
this.era
);

const composed = composeChainData(this.bufferedData, grouped);
Expand All @@ -160,7 +167,8 @@ export class CarpFunnel extends BaseFunnel implements ChainFunnel {
data.internalEvents = [] as InternalEvent[];

const epoch = absoluteSlotToEpoch(
timestampToAbsoluteSlot(data.timestamp, this.confirmationDepth)
this.era,
timestampToAbsoluteSlot(this.era, data.timestamp, this.confirmationDepth)
);

const prevEpoch = this.cache.getState().epoch;
Expand Down Expand Up @@ -201,7 +209,8 @@ export class CarpFunnel extends BaseFunnel implements ChainFunnel {
Math.min(arg.to, this.cache.getState().startingSlot - 1),
slot => {
return slot;
}
},
slot => absoluteSlotToEpoch(this.era, slot)
);
return data;
})
Expand Down Expand Up @@ -249,6 +258,7 @@ export class CarpFunnel extends BaseFunnel implements ChainFunnel {

newEntry.updateStartingSlot(
timestampToAbsoluteSlot(
shelleyEra(),
(await sharedData.web3.eth.getBlock(startingBlockHeight)).timestamp as number,
confirmationDepth
)
Expand Down Expand Up @@ -280,14 +290,15 @@ async function readDataInternal(
extensions: ChainDataExtension[],
lastTimestamp: number,
cache: CarpFunnelCacheEntry,
confirmationDepth: number
confirmationDepth: number,
era: Era
): Promise<PresyncChainData[]> {
// the lower range is exclusive
const min = timestampToAbsoluteSlot(lastTimestamp, confirmationDepth);
const min = timestampToAbsoluteSlot(era, lastTimestamp, confirmationDepth);
// the upper range is inclusive
const maxElement = data[data.length - 1];

const max = timestampToAbsoluteSlot(maxElement.timestamp, confirmationDepth);
const max = timestampToAbsoluteSlot(era, maxElement.timestamp, confirmationDepth);

cache.updateLastPoint(maxElement.blockNumber, maxElement.timestamp);

Expand All @@ -312,7 +323,7 @@ async function readDataInternal(

const blockNumbers = data.reduce(
(dict, data) => {
dict[timestampToAbsoluteSlot(data.timestamp, confirmationDepth)] = data.blockNumber;
dict[timestampToAbsoluteSlot(era, data.timestamp, confirmationDepth)] = data.blockNumber;
return dict;
},
{} as { [slot: number]: number }
Expand Down Expand Up @@ -343,7 +354,8 @@ async function readDataInternal(
extension,
min,
Math.min(max, extension.stopSlot || max),
mapSlotToBlockNumber
mapSlotToBlockNumber,
slot => absoluteSlotToEpoch(era, slot)
);

return data;
Expand Down

0 comments on commit 3eaa6c4

Please sign in to comment.