@xyo-network/xl1-protocol-sdk 1.16.26 → 1.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/neutral/ChainServiceCollectionV2.d.ts +8 -35
- package/dist/neutral/ChainServiceCollectionV2.d.ts.map +1 -1
- package/dist/neutral/block/hydrate/flattenHydratedBlocks.d.ts +2 -3
- package/dist/neutral/block/hydrate/flattenHydratedBlocks.d.ts.map +1 -1
- package/dist/neutral/index.d.ts +2 -0
- package/dist/neutral/index.d.ts.map +1 -1
- package/dist/neutral/index.mjs +1765 -1251
- package/dist/neutral/index.mjs.map +1 -1
- package/dist/neutral/model/PayloadBundle/bundledPayloadToHydratedBlock.d.ts +4 -0
- package/dist/neutral/model/PayloadBundle/bundledPayloadToHydratedBlock.d.ts.map +1 -0
- package/dist/neutral/model/PayloadBundle/hydratedBlockToPayloadBundle.d.ts +4 -0
- package/dist/neutral/model/PayloadBundle/hydratedBlockToPayloadBundle.d.ts.map +1 -0
- package/dist/neutral/model/PayloadBundle/index.d.ts +2 -0
- package/dist/neutral/model/PayloadBundle/index.d.ts.map +1 -1
- package/dist/neutral/model/Qualified.d.ts +6 -0
- package/dist/neutral/model/Qualified.d.ts.map +1 -0
- package/dist/neutral/model/index.d.ts +1 -1
- package/dist/neutral/model/index.d.ts.map +1 -1
- package/dist/neutral/payloads/index.d.ts +0 -1
- package/dist/neutral/payloads/index.d.ts.map +1 -1
- package/dist/neutral/primitives/index.d.ts +2 -1
- package/dist/neutral/primitives/index.d.ts.map +1 -1
- package/dist/neutral/primitives/rewardFromBlockNumber.d.ts +3 -0
- package/dist/neutral/primitives/rewardFromBlockNumber.d.ts.map +1 -0
- package/dist/neutral/primitives/state/findMostRecentBlock.d.ts +11 -0
- package/dist/neutral/primitives/state/findMostRecentBlock.d.ts.map +1 -0
- package/dist/neutral/primitives/state/hydratedBlockByNumber.d.ts +4 -0
- package/dist/neutral/primitives/state/hydratedBlockByNumber.d.ts.map +1 -0
- package/dist/neutral/primitives/state/index.d.ts +3 -0
- package/dist/neutral/primitives/state/index.d.ts.map +1 -0
- package/dist/neutral/provider/XyoRunner.d.ts +5 -1
- package/dist/neutral/provider/XyoRunner.d.ts.map +1 -1
- package/dist/neutral/provider/viewer/XyoViewer.d.ts +9 -4
- package/dist/neutral/provider/viewer/XyoViewer.d.ts.map +1 -1
- package/dist/neutral/provider/viewer/index.d.ts +0 -1
- package/dist/neutral/provider/viewer/index.d.ts.map +1 -1
- package/dist/neutral/runners/Block.d.ts +8 -0
- package/dist/neutral/runners/Block.d.ts.map +1 -0
- package/dist/neutral/runners/Mempool.d.ts +9 -0
- package/dist/neutral/runners/Mempool.d.ts.map +1 -0
- package/dist/neutral/runners/index.d.ts +3 -0
- package/dist/neutral/runners/index.d.ts.map +1 -0
- package/dist/neutral/services/BlockProducerService.d.ts +2 -2
- package/dist/neutral/services/BlockProducerService.d.ts.map +1 -1
- package/dist/neutral/services/Chain/BaseChainService.d.ts +0 -2
- package/dist/neutral/services/Chain/BaseChainService.d.ts.map +1 -1
- package/dist/neutral/services/Chain/ChainService.d.ts +2 -3
- package/dist/neutral/services/Chain/ChainService.d.ts.map +1 -1
- package/dist/neutral/services/Chain/index.d.ts +0 -1
- package/dist/neutral/services/Chain/index.d.ts.map +1 -1
- package/dist/neutral/services/index.d.ts +0 -2
- package/dist/neutral/services/index.d.ts.map +1 -1
- package/dist/neutral/simple/accountBalance/SimpleAccountBalanceViewer.d.ts +9 -5
- package/dist/neutral/simple/accountBalance/SimpleAccountBalanceViewer.d.ts.map +1 -1
- package/dist/neutral/simple/block/SimpleBlockViewer.d.ts +55 -0
- package/dist/neutral/simple/block/SimpleBlockViewer.d.ts.map +1 -0
- package/dist/neutral/simple/block/index.d.ts +2 -0
- package/dist/neutral/simple/block/index.d.ts.map +1 -0
- package/dist/neutral/simple/blockReward/SimpleBlockRewardViewer.d.ts +16 -0
- package/dist/neutral/simple/blockReward/SimpleBlockRewardViewer.d.ts.map +1 -0
- package/dist/neutral/simple/blockReward/index.d.ts +2 -0
- package/dist/neutral/simple/blockReward/index.d.ts.map +1 -0
- package/dist/neutral/simple/chain/SimpleChainViewer.d.ts +12 -0
- package/dist/neutral/simple/chain/SimpleChainViewer.d.ts.map +1 -0
- package/dist/neutral/simple/chain/index.d.ts +2 -0
- package/dist/neutral/simple/chain/index.d.ts.map +1 -0
- package/dist/neutral/simple/index.d.ts +3 -0
- package/dist/neutral/simple/index.d.ts.map +1 -1
- package/dist/neutral/simple/mempool/SimpleMempoolRunner.d.ts +15 -0
- package/dist/neutral/simple/mempool/SimpleMempoolRunner.d.ts.map +1 -0
- package/dist/neutral/simple/mempool/SimpleMempoolViewer.d.ts +10 -4
- package/dist/neutral/simple/mempool/SimpleMempoolViewer.d.ts.map +1 -1
- package/dist/neutral/simple/mempool/index.d.ts +1 -0
- package/dist/neutral/simple/mempool/index.d.ts.map +1 -1
- package/dist/neutral/summary/index.d.ts +3 -0
- package/dist/neutral/summary/index.d.ts.map +1 -0
- package/dist/neutral/summary/model/BalancesStepSummary.d.ts.map +1 -0
- package/dist/neutral/summary/model/SchemasStepSummary.d.ts.map +1 -0
- package/dist/neutral/summary/model/StepSummary.d.ts.map +1 -0
- package/dist/neutral/summary/model/TransfersSummary.d.ts.map +1 -0
- package/dist/neutral/{payloads/summary → summary/model}/index.d.ts +1 -0
- package/dist/neutral/summary/model/index.d.ts.map +1 -0
- package/dist/neutral/{model → summary/model}/summary.d.ts +3 -4
- package/dist/neutral/summary/model/summary.d.ts.map +1 -0
- package/dist/neutral/{primitives/summary → summary/primitives}/balances/balancesStepSummaryFromRange.d.ts +1 -2
- package/dist/neutral/summary/primitives/balances/balancesStepSummaryFromRange.d.ts.map +1 -0
- package/dist/neutral/summary/primitives/balances/balancesSummary.d.ts +5 -0
- package/dist/neutral/summary/primitives/balances/balancesSummary.d.ts.map +1 -0
- package/dist/neutral/summary/primitives/balances/index.d.ts.map +1 -0
- package/dist/neutral/{primitives/summary → summary/primitives}/index.d.ts.map +1 -1
- package/dist/neutral/summary/primitives/schemas/index.d.ts.map +1 -0
- package/dist/neutral/{primitives/summary → summary/primitives}/schemas/schemasStepSummaryFromRange.d.ts +1 -2
- package/dist/neutral/summary/primitives/schemas/schemasStepSummaryFromRange.d.ts.map +1 -0
- package/dist/neutral/summary/primitives/schemas/schemasSummary.d.ts +5 -0
- package/dist/neutral/summary/primitives/schemas/schemasSummary.d.ts.map +1 -0
- package/dist/neutral/summary/primitives/transfers/index.d.ts.map +1 -0
- package/dist/neutral/{primitives/summary → summary/primitives}/transfers/transfersStepSummaryFromRange.d.ts +1 -2
- package/dist/neutral/summary/primitives/transfers/transfersStepSummaryFromRange.d.ts.map +1 -0
- package/dist/neutral/summary/primitives/transfers/transfersSummary.d.ts +6 -0
- package/dist/neutral/summary/primitives/transfers/transfersSummary.d.ts.map +1 -0
- package/dist/neutral/utils/HydratedCache.d.ts +16 -0
- package/dist/neutral/utils/HydratedCache.d.ts.map +1 -0
- package/dist/neutral/utils/index.d.ts +1 -0
- package/dist/neutral/utils/index.d.ts.map +1 -1
- package/dist/neutral/viewers/AccountBalance.d.ts +5 -2
- package/dist/neutral/viewers/AccountBalance.d.ts.map +1 -1
- package/dist/neutral/viewers/Block.d.ts +9 -5
- package/dist/neutral/viewers/Block.d.ts.map +1 -1
- package/dist/neutral/viewers/BlockReward.d.ts +8 -0
- package/dist/neutral/viewers/BlockReward.d.ts.map +1 -0
- package/dist/neutral/viewers/Chain.d.ts +2 -0
- package/dist/neutral/viewers/Chain.d.ts.map +1 -1
- package/dist/neutral/viewers/ChainStakeViewer.d.ts +6 -0
- package/dist/neutral/viewers/ChainStakeViewer.d.ts.map +1 -0
- package/dist/neutral/viewers/Mempool.d.ts +8 -1
- package/dist/neutral/viewers/Mempool.d.ts.map +1 -1
- package/dist/neutral/viewers/StakeIntent.d.ts +10 -0
- package/dist/neutral/viewers/StakeIntent.d.ts.map +1 -0
- package/dist/neutral/{provider/viewer → viewers}/StepViewer.d.ts +2 -2
- package/dist/neutral/viewers/StepViewer.d.ts.map +1 -0
- package/dist/neutral/viewers/index.d.ts +3 -0
- package/dist/neutral/viewers/index.d.ts.map +1 -1
- package/package.json +18 -18
- package/src/ChainServiceCollectionV2.ts +12 -39
- package/src/block/hydrate/flattenHydratedBlocks.ts +2 -3
- package/src/index.ts +2 -1
- package/src/model/PayloadBundle/bundledPayloadToHydratedBlock.ts +14 -0
- package/src/model/PayloadBundle/hydratedBlockToPayloadBundle.ts +18 -0
- package/src/model/PayloadBundle/index.ts +2 -0
- package/src/model/Qualified.ts +9 -0
- package/src/model/index.ts +1 -1
- package/src/payloads/index.ts +0 -1
- package/src/primitives/index.ts +2 -1
- package/src/primitives/rewardFromBlockNumber.ts +25 -0
- package/src/primitives/state/findMostRecentBlock.ts +44 -0
- package/src/primitives/state/hydratedBlockByNumber.ts +19 -0
- package/src/primitives/state/index.ts +2 -0
- package/src/provider/XyoRunner.ts +7 -1
- package/src/provider/viewer/XyoViewer.ts +18 -7
- package/src/provider/viewer/index.ts +0 -1
- package/src/runners/Block.ts +10 -0
- package/src/runners/Mempool.ts +9 -0
- package/src/runners/index.ts +2 -0
- package/src/services/BlockProducerService.ts +3 -2
- package/src/services/Chain/BaseChainService.ts +1 -3
- package/src/services/Chain/ChainService.ts +4 -3
- package/src/services/Chain/index.ts +0 -1
- package/src/services/index.ts +0 -2
- package/src/simple/accountBalance/SimpleAccountBalanceViewer.ts +104 -18
- package/src/simple/block/SimpleBlockViewer.ts +172 -0
- package/src/simple/block/index.ts +1 -0
- package/src/simple/blockReward/SimpleBlockRewardViewer.ts +34 -0
- package/src/simple/blockReward/index.ts +1 -0
- package/src/simple/chain/SimpleChainViewer.ts +25 -0
- package/src/simple/chain/index.ts +1 -0
- package/src/simple/gateway/SimpleXyoGatewayRunner.ts +1 -1
- package/src/simple/index.ts +3 -0
- package/src/simple/mempool/SimpleMempoolRunner.ts +47 -0
- package/src/simple/mempool/SimpleMempoolViewer.ts +34 -8
- package/src/simple/mempool/index.ts +1 -0
- package/src/simple/timesync/SimpleTimeSyncViewer.ts +1 -1
- package/src/summary/index.ts +2 -0
- package/src/{payloads/summary → summary/model}/index.ts +1 -0
- package/src/{model → summary/model}/summary.ts +5 -4
- package/src/{primitives/summary → summary/primitives}/balances/balancesStepSummaryFromRange.ts +4 -3
- package/src/{primitives/summary → summary/primitives}/balances/balancesSummary.ts +6 -5
- package/src/{primitives/summary → summary/primitives}/schemas/schemasStepSummaryFromRange.ts +3 -3
- package/src/{primitives/summary → summary/primitives}/schemas/schemasSummary.ts +7 -6
- package/src/{primitives/summary → summary/primitives}/transfers/transfersStepSummaryFromRange.ts +4 -3
- package/src/{primitives/summary → summary/primitives}/transfers/transfersSummary.ts +6 -5
- package/src/utils/HydratedCache.ts +38 -0
- package/src/utils/index.ts +1 -0
- package/src/viewers/AccountBalance.ts +9 -2
- package/src/viewers/Block.ts +10 -6
- package/src/viewers/BlockReward.ts +9 -0
- package/src/viewers/Chain.ts +2 -0
- package/src/viewers/ChainStakeViewer.ts +7 -0
- package/src/viewers/Mempool.ts +10 -1
- package/src/viewers/StakeIntent.ts +14 -0
- package/src/{provider/viewer → viewers}/StepViewer.ts +2 -2
- package/src/viewers/index.ts +3 -0
- package/dist/neutral/model/summary.d.ts.map +0 -1
- package/dist/neutral/payloads/summary/BalancesStepSummary.d.ts.map +0 -1
- package/dist/neutral/payloads/summary/SchemasStepSummary.d.ts.map +0 -1
- package/dist/neutral/payloads/summary/StepSummary.d.ts.map +0 -1
- package/dist/neutral/payloads/summary/TransfersSummary.d.ts.map +0 -1
- package/dist/neutral/payloads/summary/index.d.ts.map +0 -1
- package/dist/neutral/primitives/summary/balances/balancesStepSummaryFromRange.d.ts.map +0 -1
- package/dist/neutral/primitives/summary/balances/balancesSummary.d.ts +0 -4
- package/dist/neutral/primitives/summary/balances/balancesSummary.d.ts.map +0 -1
- package/dist/neutral/primitives/summary/balances/index.d.ts.map +0 -1
- package/dist/neutral/primitives/summary/schemas/index.d.ts.map +0 -1
- package/dist/neutral/primitives/summary/schemas/schemasStepSummaryFromRange.d.ts.map +0 -1
- package/dist/neutral/primitives/summary/schemas/schemasSummary.d.ts +0 -4
- package/dist/neutral/primitives/summary/schemas/schemasSummary.d.ts.map +0 -1
- package/dist/neutral/primitives/summary/transfers/index.d.ts.map +0 -1
- package/dist/neutral/primitives/summary/transfers/transfersStepSummaryFromRange.d.ts.map +0 -1
- package/dist/neutral/primitives/summary/transfers/transfersSummary.d.ts +0 -5
- package/dist/neutral/primitives/summary/transfers/transfersSummary.d.ts.map +0 -1
- package/dist/neutral/provider/viewer/StepViewer.d.ts.map +0 -1
- package/dist/neutral/services/BlockRewardService.d.ts +0 -5
- package/dist/neutral/services/BlockRewardService.d.ts.map +0 -1
- package/dist/neutral/services/BlockRewardServiceV2.d.ts +0 -6
- package/dist/neutral/services/BlockRewardServiceV2.d.ts.map +0 -1
- package/dist/neutral/services/Chain/interfaces/ChainStakeViewer.d.ts +0 -4
- package/dist/neutral/services/Chain/interfaces/ChainStakeViewer.d.ts.map +0 -1
- package/dist/neutral/services/Chain/interfaces/ChainStaker.d.ts +0 -6
- package/dist/neutral/services/Chain/interfaces/ChainStaker.d.ts.map +0 -1
- package/dist/neutral/services/Chain/interfaces/index.d.ts +0 -3
- package/dist/neutral/services/Chain/interfaces/index.d.ts.map +0 -1
- package/src/services/BlockRewardService.ts +0 -6
- package/src/services/BlockRewardServiceV2.ts +0 -8
- package/src/services/Chain/interfaces/ChainStakeViewer.ts +0 -5
- package/src/services/Chain/interfaces/ChainStaker.ts +0 -5
- package/src/services/Chain/interfaces/index.ts +0 -2
- /package/dist/neutral/{payloads/summary → summary/model}/BalancesStepSummary.d.ts +0 -0
- /package/dist/neutral/{payloads/summary → summary/model}/SchemasStepSummary.d.ts +0 -0
- /package/dist/neutral/{payloads/summary → summary/model}/StepSummary.d.ts +0 -0
- /package/dist/neutral/{payloads/summary → summary/model}/TransfersSummary.d.ts +0 -0
- /package/dist/neutral/{primitives/summary → summary/primitives}/balances/index.d.ts +0 -0
- /package/dist/neutral/{primitives/summary → summary/primitives}/index.d.ts +0 -0
- /package/dist/neutral/{primitives/summary → summary/primitives}/schemas/index.d.ts +0 -0
- /package/dist/neutral/{primitives/summary → summary/primitives}/transfers/index.d.ts +0 -0
- /package/src/{payloads/summary → summary/model}/BalancesStepSummary.ts +0 -0
- /package/src/{payloads/summary → summary/model}/SchemasStepSummary.ts +0 -0
- /package/src/{payloads/summary → summary/model}/StepSummary.ts +0 -0
- /package/src/{payloads/summary → summary/model}/TransfersSummary.ts +0 -0
- /package/src/{primitives/summary → summary/primitives}/balances/index.ts +0 -0
- /package/src/{primitives/summary → summary/primitives}/index.ts +0 -0
- /package/src/{primitives/summary → summary/primitives}/schemas/index.ts +0 -0
- /package/src/{primitives/summary → summary/primitives}/transfers/index.ts +0 -0
package/src/payloads/index.ts
CHANGED
package/src/primitives/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './readPayloadMapFromStore.ts'
|
|
2
|
+
export * from './rewardFromBlockNumber.ts'
|
|
3
|
+
export * from './state/index.ts'
|
|
2
4
|
export * from './step/index.ts'
|
|
3
|
-
export * from './summary/index.ts'
|
|
4
5
|
export * from './timeBudget.ts'
|
|
5
6
|
export * from './transaction/index.ts'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { toFixedPoint } from '@xylabs/sdk-js'
|
|
2
|
+
import { asAttoXL1, type XL1BlockNumber } from '@xyo-network/xl1-protocol'
|
|
3
|
+
|
|
4
|
+
export const rewardFromBlockNumber = (places = 18) => {
|
|
5
|
+
return (
|
|
6
|
+
blockNumber: XL1BlockNumber,
|
|
7
|
+
startingReward = asAttoXL1(toFixedPoint(30_000n, places)),
|
|
8
|
+
blocksPerStep = 1_000_000,
|
|
9
|
+
stepFactorNumerator = 90n,
|
|
10
|
+
stepFactorDenominator = 100n,
|
|
11
|
+
minBlockReward = asAttoXL1(toFixedPoint(30n, places)),
|
|
12
|
+
creatorReward = asAttoXL1(toFixedPoint(20_000_000_000n, places)),
|
|
13
|
+
) => {
|
|
14
|
+
if (blockNumber === 0) {
|
|
15
|
+
return creatorReward
|
|
16
|
+
}
|
|
17
|
+
const step = Math.floor((blockNumber + blocksPerStep) / blocksPerStep)
|
|
18
|
+
const stepExp = BigInt(step - 1)
|
|
19
|
+
const poweredNumerator = stepExp > 0 ? stepFactorNumerator ** stepExp : 1n
|
|
20
|
+
const poweredDenominator = stepExp > 0 ? stepFactorDenominator ** stepExp : 1n
|
|
21
|
+
let reward = (startingReward * poweredNumerator) / poweredDenominator
|
|
22
|
+
// eslint-disable-next-line unicorn/prefer-math-min-max
|
|
23
|
+
return asAttoXL1((reward < minBlockReward) ? minBlockReward : reward)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { NextOptions, ReadArchivist } from '@xyo-network/archivist-model'
|
|
2
|
+
import type {
|
|
3
|
+
Payload, Sequence, WithStorageMeta,
|
|
4
|
+
} from '@xyo-network/payload-model'
|
|
5
|
+
import type { SignedBlockBoundWitnessWithHashMeta } from '@xyo-network/xl1-protocol'
|
|
6
|
+
import { isSignedBlockBoundWitnessWithStorageMeta } from '@xyo-network/xl1-protocol'
|
|
7
|
+
|
|
8
|
+
// TODO: Use some smart value relative to DEFAULT_BLOCK_SIZE
|
|
9
|
+
// to ensure we're likely to find it in a single request
|
|
10
|
+
// without bringing back too much data
|
|
11
|
+
const DEFAULT_NEXT_OPTIONS: NextOptions = { limit: 50 }
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Iterates an archivist to find the most recent block
|
|
15
|
+
* @param chainArchivist The archivist to iterate over for the most recent chain block
|
|
16
|
+
* @param nextOptions The options to use when iterating the archivist
|
|
17
|
+
* @param maxIterations The max number of iterations to perform when finding the most recent block
|
|
18
|
+
* @returns The most recent block found in the archivist or undefined if no blocks are found
|
|
19
|
+
*/
|
|
20
|
+
export const findMostRecentBlock = async (
|
|
21
|
+
chainArchivist: ReadArchivist,
|
|
22
|
+
nextOptions: NextOptions = DEFAULT_NEXT_OPTIONS,
|
|
23
|
+
maxIterations = Number.POSITIVE_INFINITY,
|
|
24
|
+
): Promise<SignedBlockBoundWitnessWithHashMeta | undefined> => {
|
|
25
|
+
let mostRecentBlock: SignedBlockBoundWitnessWithHashMeta | undefined
|
|
26
|
+
let cursor: Sequence | undefined
|
|
27
|
+
let batch: WithStorageMeta<Payload>[]
|
|
28
|
+
let iterations = 0
|
|
29
|
+
do {
|
|
30
|
+
batch = await chainArchivist.next({
|
|
31
|
+
...nextOptions, order: 'desc', cursor,
|
|
32
|
+
})
|
|
33
|
+
const blocks = batch.filter(isSignedBlockBoundWitnessWithStorageMeta)
|
|
34
|
+
const last = blocks?.at(0)
|
|
35
|
+
if (last) {
|
|
36
|
+
mostRecentBlock = last
|
|
37
|
+
break
|
|
38
|
+
} else {
|
|
39
|
+
cursor = batch.at(-1)?._sequence
|
|
40
|
+
}
|
|
41
|
+
iterations = iterations + 1
|
|
42
|
+
} while (batch.length > 0 && iterations < maxIterations)
|
|
43
|
+
return mostRecentBlock
|
|
44
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { assertEx } from '@xylabs/sdk-js'
|
|
2
|
+
import type { HydratedBlockWithHashMeta, XL1BlockNumber } from '@xyo-network/xl1-protocol'
|
|
3
|
+
|
|
4
|
+
import { blockFromBlockNumber, hydrateBlock } from '../../block/index.ts'
|
|
5
|
+
import { type ChainContextRead, withContextCacheResponse } from '../../model/index.ts'
|
|
6
|
+
|
|
7
|
+
export async function hydratedBlockByNumber(context: ChainContextRead, blockNumber: XL1BlockNumber): Promise<HydratedBlockWithHashMeta | null> {
|
|
8
|
+
if (blockNumber < 0) throw new Error(`Block number ${blockNumber} is less than 0`)
|
|
9
|
+
if (blockNumber > Number.MAX_SAFE_INTEGER) throw new Error(`Block number ${blockNumber} is greater than the maximum safe integer`)
|
|
10
|
+
if (blockNumber % 1 !== 0) throw new Error(`Block number ${blockNumber} is not an integer`)
|
|
11
|
+
const cacheKey = `${blockNumber}`
|
|
12
|
+
return await withContextCacheResponse(context, 'hydratedBlockByNumber', cacheKey, async () => {
|
|
13
|
+
const block = assertEx(
|
|
14
|
+
await blockFromBlockNumber(context, blockNumber),
|
|
15
|
+
() => `Could not find block for block number ${blockNumber}`,
|
|
16
|
+
)
|
|
17
|
+
return await hydrateBlock(context.store, block._hash)
|
|
18
|
+
})
|
|
19
|
+
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { Hash, Promisable } from '@xylabs/sdk-js'
|
|
2
2
|
import type { SignedHydratedTransaction } from '@xyo-network/xl1-protocol'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
import type { MempoolRunner } from '../runners/index.ts'
|
|
5
|
+
|
|
6
|
+
export interface XyoRunnerMethods {
|
|
5
7
|
broadcastTransaction(transaction: SignedHydratedTransaction): Promisable<Hash>
|
|
6
8
|
}
|
|
9
|
+
|
|
10
|
+
export interface XyoRunner extends XyoRunnerMethods {
|
|
11
|
+
mempool?: MempoolRunner
|
|
12
|
+
}
|
|
@@ -1,26 +1,37 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
Address, Hash, Promisable,
|
|
3
|
+
} from '@xylabs/sdk-js'
|
|
4
|
+
import type { AttoXL1, XL1BlockRange } from '@xyo-network/xl1-protocol'
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
AccountBalanceHistoryItem,
|
|
2
8
|
AccountBalanceViewer,
|
|
3
|
-
|
|
4
|
-
|
|
9
|
+
BlockViewer,
|
|
10
|
+
BlockViewerMethods,
|
|
5
11
|
ChainViewerMethods,
|
|
6
12
|
ForkViewerMethods,
|
|
13
|
+
MempoolViewer,
|
|
7
14
|
NetworkStakeStepRewardViewer,
|
|
8
15
|
StakeViewerMethods,
|
|
16
|
+
StepViewer,
|
|
9
17
|
TransactionViewerMethods,
|
|
10
18
|
TransferBalanceViewerMethods,
|
|
11
19
|
} from '../../viewers/index.ts'
|
|
12
20
|
import type { NetworkStakeViewer } from './NetworkStake/index.ts'
|
|
13
|
-
import type { StepViewer } from './StepViewer.ts'
|
|
14
21
|
|
|
15
|
-
export interface XyoViewerMethods extends
|
|
16
|
-
|
|
17
|
-
ChainViewerMethods,
|
|
22
|
+
export interface XyoViewerMethods extends
|
|
23
|
+
TransferBalanceViewerMethods, NetworkStakeStepRewardViewer,
|
|
24
|
+
Pick<ChainViewerMethods, 'chainId'>, BlockViewerMethods, TransactionViewerMethods, StakeViewerMethods, ForkViewerMethods {
|
|
25
|
+
accountBalance(address: Address, headOrRange?: Hash | XL1BlockRange): Promisable<AttoXL1>
|
|
26
|
+
accountBalanceHistory(address: Address, headOrRange?: Hash | XL1BlockRange): Promisable<AccountBalanceHistoryItem[]>
|
|
18
27
|
}
|
|
19
28
|
|
|
20
|
-
export interface XyoViewer extends XyoViewerMethods {
|
|
29
|
+
export interface XyoViewer extends BlockViewer, XyoViewerMethods {
|
|
21
30
|
account?: {
|
|
22
31
|
balance?: AccountBalanceViewer
|
|
23
32
|
}
|
|
33
|
+
block?: BlockViewer
|
|
34
|
+
mempool?: MempoolViewer
|
|
24
35
|
networkStake?: NetworkStakeViewer
|
|
25
36
|
step?: StepViewer
|
|
26
37
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SignedBlockBoundWitnessWithHashMeta, SignedHydratedBlockWithHashMeta } from '@xyo-network/xl1-protocol'
|
|
2
|
+
|
|
3
|
+
export interface BlockRunnerMethods {
|
|
4
|
+
produceNextBlock(head: SignedBlockBoundWitnessWithHashMeta, force: true): Promise<SignedHydratedBlockWithHashMeta>
|
|
5
|
+
produceNextBlock(head: SignedBlockBoundWitnessWithHashMeta, force?: false): Promise<SignedHydratedBlockWithHashMeta | undefined>
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface BlockRunner extends BlockRunnerMethods {
|
|
9
|
+
|
|
10
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Hash } from '@xylabs/sdk-js'
|
|
2
|
+
import type { SignedHydratedBlock, SignedHydratedTransaction } from '@xyo-network/xl1-protocol'
|
|
3
|
+
|
|
4
|
+
export interface MempoolRunnerMethods {
|
|
5
|
+
submitBlocks(blocks: SignedHydratedBlock[]): Promise<Hash[]>
|
|
6
|
+
submitTransactions(transactions: SignedHydratedTransaction[]): Promise<Hash[]>
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface MempoolRunner extends MempoolRunnerMethods {}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
Addressable,
|
|
3
|
-
BlockBoundWitness,
|
|
3
|
+
BlockBoundWitness, IterableRepository,
|
|
4
|
+
SignedHydratedBlockWithHashMeta,
|
|
4
5
|
} from '@xyo-network/xl1-protocol'
|
|
5
6
|
|
|
6
|
-
export type NextBlockProducer = IterableRepository<BlockBoundWitness,
|
|
7
|
+
export type NextBlockProducer = IterableRepository<BlockBoundWitness, SignedHydratedBlockWithHashMeta | undefined>
|
|
7
8
|
|
|
8
9
|
export interface BlockProducerService extends Addressable, NextBlockProducer {}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ChainContractViewer, ChainStakeViewer, ChainViewer,
|
|
3
|
+
} from '../../viewers/index.ts'
|
|
2
4
|
import type { BaseChainService } from './BaseChainService.ts'
|
|
3
|
-
import type { ChainStaker, ChainStakeViewer } from './interfaces/index.ts'
|
|
4
5
|
|
|
5
|
-
export interface ChainService extends ChainContractViewer, ChainStakeViewer,
|
|
6
|
+
export interface ChainService extends ChainContractViewer, ChainStakeViewer, ChainViewer, BaseChainService {}
|
package/src/services/index.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export * from './AccountTransfersService.ts'
|
|
2
2
|
export * from './BlockProducerService.ts'
|
|
3
|
-
export * from './BlockRewardService.ts'
|
|
4
|
-
export * from './BlockRewardServiceV2.ts'
|
|
5
3
|
export * from './Chain/index.ts'
|
|
6
4
|
export * from './ChainIterator/index.ts'
|
|
7
5
|
export * from './Election.ts'
|
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
} from '@xylabs/sdk-js'
|
|
4
4
|
import {
|
|
5
5
|
AbstractCreatable,
|
|
6
|
+
asHash,
|
|
6
7
|
assertEx, exists, isDefined,
|
|
7
8
|
} from '@xylabs/sdk-js'
|
|
8
9
|
import { spanRootAsync } from '@xylabs/telemetry'
|
|
@@ -17,9 +18,15 @@ import {
|
|
|
17
18
|
} from '@xyo-network/xl1-protocol'
|
|
18
19
|
|
|
19
20
|
import { deepCalculateFramesFromRange } from '../../block/index.ts'
|
|
20
|
-
import type {
|
|
21
|
-
import type {
|
|
22
|
-
|
|
21
|
+
import type { Qualified } from '../../model/index.ts'
|
|
22
|
+
import type {
|
|
23
|
+
BalanceStepSummaryContext, TransfersStepSummary,
|
|
24
|
+
TransfersStepSummaryContext,
|
|
25
|
+
} from '../../summary/index.ts'
|
|
26
|
+
import {
|
|
27
|
+
balancesSummary,
|
|
28
|
+
transfersStepSummaryFromRange,
|
|
29
|
+
} from '../../summary/index.ts'
|
|
23
30
|
import type {
|
|
24
31
|
AccountBalanceHistoryItem, AccountBalanceViewer, BlockViewer,
|
|
25
32
|
} from '../../viewers/index.ts'
|
|
@@ -27,7 +34,7 @@ import type {
|
|
|
27
34
|
export interface SimpleAccountBalanceViewerParams extends CreatableParams {
|
|
28
35
|
blockViewer: BlockViewer
|
|
29
36
|
context: BalanceStepSummaryContext
|
|
30
|
-
|
|
37
|
+
transfersSummaryContext: TransfersStepSummaryContext
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
export class SimpleAccountBalanceViewer extends AbstractCreatable<SimpleAccountBalanceViewerParams> implements AccountBalanceViewer {
|
|
@@ -39,23 +46,27 @@ export class SimpleAccountBalanceViewer extends AbstractCreatable<SimpleAccountB
|
|
|
39
46
|
return this.params.context!
|
|
40
47
|
}
|
|
41
48
|
|
|
42
|
-
get
|
|
43
|
-
return this.params.
|
|
49
|
+
get transfersSummaryContext(): TransfersStepSummaryContext {
|
|
50
|
+
return this.params.transfersSummaryContext!
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
static override async paramsHandler(params: Partial<SimpleAccountBalanceViewerParams>) {
|
|
47
54
|
assertEx(params.blockViewer, () => 'blockViewer is required')
|
|
48
55
|
assertEx(params.context, () => 'context is required')
|
|
49
|
-
assertEx(params.
|
|
56
|
+
assertEx(params.transfersSummaryContext, () => 'transfersSummaryContext is required')
|
|
50
57
|
|
|
51
58
|
return { ...await super.paramsHandler(params) }
|
|
52
59
|
}
|
|
53
60
|
|
|
54
61
|
async accountBalance(address: Address, headOrRange?: XL1BlockRange | Hash): Promise<AttoXL1> {
|
|
55
|
-
const balances = await this.
|
|
62
|
+
const balances = await this.accountBalances([address], headOrRange)
|
|
56
63
|
return balances[address] ?? AttoXL1(0n)
|
|
57
64
|
}
|
|
58
65
|
|
|
66
|
+
accountBalanceHistories(_addresses: Address[], _rangeOrHash?: XL1BlockRange | Hash): Promise<Record<Address, AccountBalanceHistoryItem[]>> {
|
|
67
|
+
throw new Error('Method [accountBalanceHistories] not implemented.')
|
|
68
|
+
}
|
|
69
|
+
|
|
59
70
|
async accountBalanceHistory(address: Address, headOrRange?: XL1BlockRange | Hash): Promise<AccountBalanceHistoryItem[]> {
|
|
60
71
|
const range = asRange(headOrRange)
|
|
61
72
|
const startingRange = asXL1BlockRange(range ?? [0, await this.blockViewer.currentBlockNumber()], true)
|
|
@@ -84,24 +95,64 @@ export class SimpleAccountBalanceViewer extends AbstractCreatable<SimpleAccountB
|
|
|
84
95
|
return result
|
|
85
96
|
}
|
|
86
97
|
|
|
87
|
-
async
|
|
88
|
-
|
|
89
|
-
|
|
98
|
+
async accountBalances(address: Address[], _headOrRange?: XL1BlockRange | Hash): Promise<Record<Address, AttoXL1>> {
|
|
99
|
+
const [result] = (await this.qualifiedAccountBalances(address, _headOrRange))
|
|
100
|
+
return result
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async qualifiedAccountBalanceHistories(
|
|
104
|
+
addresses: Address[],
|
|
105
|
+
headOrRange?: Hash | XL1BlockRange,
|
|
106
|
+
): Promise<Qualified<Record<Address, AccountBalanceHistoryItem[]>>> {
|
|
107
|
+
const head = asHash(headOrRange) ?? await this.blockViewer.currentBlockHash()
|
|
108
|
+
const range = asXL1BlockRange(headOrRange) ?? asXL1BlockRange([0,
|
|
109
|
+
assertEx(
|
|
110
|
+
await this.blockViewer.blockByHash(head),
|
|
111
|
+
() => `Error: Could not find block with hash ${head}`,
|
|
112
|
+
)[0].block])
|
|
113
|
+
const qualifiedEntries: [Address, Qualified<AccountBalanceHistoryItem[]>][] = await Promise.all(addresses.map(async address => ([
|
|
114
|
+
address,
|
|
115
|
+
await this.qualifiedAccountBalanceHistory(address, range),
|
|
116
|
+
])))
|
|
117
|
+
|
|
118
|
+
const entries = qualifiedEntries.map(([address, [history]]) => {
|
|
119
|
+
return [address, history]
|
|
120
|
+
})
|
|
121
|
+
const qualifiedRange = qualifiedEntries[0][1][1]
|
|
122
|
+
const qualifiedHeadHash = qualifiedEntries[0][1][2]
|
|
123
|
+
|
|
124
|
+
// check for drift
|
|
125
|
+
for (const [_, [__, range, headHash]] of qualifiedEntries) {
|
|
126
|
+
assertEx(
|
|
127
|
+
range[0] === qualifiedRange[0] && range[1] === qualifiedRange[1],
|
|
128
|
+
() => 'Inconsistent ranges in qualifiedAccountBalanceHistories',
|
|
129
|
+
)
|
|
130
|
+
assertEx(
|
|
131
|
+
headHash === qualifiedHeadHash,
|
|
132
|
+
() => 'Inconsistent head hashes in qualifiedAccountBalanceHistories',
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return [Object.fromEntries(entries), qualifiedRange, qualifiedHeadHash]
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async qualifiedAccountBalances(
|
|
140
|
+
address: Address[],
|
|
141
|
+
_headOrRange?: Hash | XL1BlockRange,
|
|
142
|
+
): Promise<Qualified<Record<Address, AttoXL1>>> {
|
|
143
|
+
return await spanRootAsync('qualifiedAccountsBalances', async () => {
|
|
144
|
+
const qualifiedSummary = await balancesSummary(
|
|
90
145
|
this.context,
|
|
91
146
|
)
|
|
92
147
|
const result: Record<Address, AttoXL1> = {}
|
|
93
148
|
for (const addr of address) {
|
|
94
|
-
const summaryBalance =
|
|
149
|
+
const summaryBalance = qualifiedSummary[0][addr] ?? 0n
|
|
95
150
|
result[addr] = AttoXL1(summaryBalance < 0n ? 0n : summaryBalance)
|
|
96
151
|
}
|
|
97
|
-
return result
|
|
152
|
+
return [result, qualifiedSummary[1], qualifiedSummary[2]]
|
|
98
153
|
})
|
|
99
154
|
}
|
|
100
155
|
|
|
101
|
-
accountsBalancesHistory(_addresses: Address[], _rangeOrHash?: XL1BlockRange | Hash): Promise<Partial<Record<Address, AccountBalanceHistoryItem[]>>> {
|
|
102
|
-
throw new Error('Method not implemented.')
|
|
103
|
-
}
|
|
104
|
-
|
|
105
156
|
private async distillTransferHistory(address: Address, range: XL1BlockRange, max: number = 50): Promise<XL1BlockNumber[]> {
|
|
106
157
|
if ((range[1] - range[0]) <= StepSizes[0] || max <= 1) {
|
|
107
158
|
return Array.from({ length: range[1] - range[0] + 1 }, (_, i) => range[1] - i).slice(0, max).map(n => asXL1BlockNumber(n, true))
|
|
@@ -109,7 +160,7 @@ export class SimpleAccountBalanceViewer extends AbstractCreatable<SimpleAccountB
|
|
|
109
160
|
const frames = deepCalculateFramesFromRange(asXL1BlockRange(range, true))
|
|
110
161
|
const transferSummaryPairs = await Promise.all(frames.map(
|
|
111
162
|
async (frame) => {
|
|
112
|
-
return [frame, await transfersStepSummaryFromRange(this.
|
|
163
|
+
return [frame, await transfersStepSummaryFromRange(this.transfersSummaryContext, frame)]
|
|
113
164
|
},
|
|
114
165
|
)) as [XL1BlockRange, WithStorageMeta<TransfersStepSummary>][]
|
|
115
166
|
|
|
@@ -139,4 +190,39 @@ export class SimpleAccountBalanceViewer extends AbstractCreatable<SimpleAccountB
|
|
|
139
190
|
}
|
|
140
191
|
return [...resultBlockNumbers].toSorted((a, b) => b - a).slice(0, max)
|
|
141
192
|
}
|
|
193
|
+
|
|
194
|
+
private async qualifiedAccountBalanceHistory(
|
|
195
|
+
address: Address,
|
|
196
|
+
headOrRange?: Hash | XL1BlockRange,
|
|
197
|
+
): Promise<Qualified<AccountBalanceHistoryItem[]>> {
|
|
198
|
+
const range = asRange(headOrRange)
|
|
199
|
+
const headHash = asHash(headOrRange)
|
|
200
|
+
const [head] = assertEx(isDefined(headHash)
|
|
201
|
+
? (await this.blockViewer.blockByHash(headHash))
|
|
202
|
+
: (await this.blockViewer.currentBlock()), () => 'Could not resolve head block')
|
|
203
|
+
const startingRange = asXL1BlockRange(range ?? [0, head.block], true)
|
|
204
|
+
const blockNumbers = await this.distillTransferHistory(address, startingRange)
|
|
205
|
+
const blocks = (await Promise.all(blockNumbers.map(async bn => await this.blockViewer.blockByNumber(bn)))).filter(exists)
|
|
206
|
+
const result: AccountBalanceHistoryItem[] = []
|
|
207
|
+
for (const block of blocks) {
|
|
208
|
+
const transferIndexes = block[0].payload_schemas.map((schema, index) => schema === TransferSchema ? index : undefined).filter(exists)
|
|
209
|
+
const transfers = transferIndexes.map((index) => {
|
|
210
|
+
const hash = block[0].payload_hashes[index]
|
|
211
|
+
return assertEx(
|
|
212
|
+
block[1].find(p => p._hash === hash) as WithStorageMeta<Transfer>,
|
|
213
|
+
() => `Error: Could not find Transfer with hash ${hash} in block ${block[0]._hash}`,
|
|
214
|
+
)
|
|
215
|
+
}).filter(exists).filter(t => ((t.from === address) || (isDefined(t.transfers[address]))))
|
|
216
|
+
if (transfers.length === 0) {
|
|
217
|
+
continue
|
|
218
|
+
}
|
|
219
|
+
const pairs: [SignedBlockBoundWitnessWithHashMeta, WithHashMeta<Transfer>][] = (transfers.map((transfer) => {
|
|
220
|
+
return [block[0], transfer]
|
|
221
|
+
}))
|
|
222
|
+
result.push(...pairs.map(([block, transfer]) => [block,
|
|
223
|
+
null,
|
|
224
|
+
transfer] satisfies AccountBalanceHistoryItem))
|
|
225
|
+
}
|
|
226
|
+
return [result, startingRange, head._hash]
|
|
227
|
+
}
|
|
142
228
|
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import type { CreatableParams, Hash } from '@xylabs/sdk-js'
|
|
2
|
+
import {
|
|
3
|
+
AbstractCreatable,
|
|
4
|
+
assertEx,
|
|
5
|
+
exists,
|
|
6
|
+
isDefined,
|
|
7
|
+
spanRootAsync,
|
|
8
|
+
} from '@xylabs/sdk-js'
|
|
9
|
+
import type { ReadArchivist } from '@xyo-network/archivist-model'
|
|
10
|
+
import type { Payload, WithHashMeta } from '@xyo-network/payload-model'
|
|
11
|
+
import {
|
|
12
|
+
asSignedHydratedBlockWithHashMeta,
|
|
13
|
+
asXL1BlockNumber,
|
|
14
|
+
type SignedHydratedBlockWithHashMeta,
|
|
15
|
+
type XL1BlockNumber,
|
|
16
|
+
} from '@xyo-network/xl1-protocol'
|
|
17
|
+
|
|
18
|
+
import { hydrateBlock } from '../../block/index.ts'
|
|
19
|
+
import { LruCacheMap } from '../../driver/index.ts'
|
|
20
|
+
import type {
|
|
21
|
+
ChainContextRead,
|
|
22
|
+
ChainStoreRead, PayloadMap,
|
|
23
|
+
} from '../../model/index.ts'
|
|
24
|
+
import { findMostRecentBlock, hydratedBlockByNumber } from '../../primitives/index.ts'
|
|
25
|
+
import { HydratedCache } from '../../utils/index.ts'
|
|
26
|
+
import type { BlockViewer } from '../../viewers/index.ts'
|
|
27
|
+
|
|
28
|
+
export interface SimpleBlockViewerParams extends CreatableParams {
|
|
29
|
+
context: ChainContextRead
|
|
30
|
+
finalizedArchivist?: ReadArchivist
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export class SimpleBlockViewer extends AbstractCreatable<SimpleBlockViewerParams> implements BlockViewer {
|
|
34
|
+
private _payloadCache: PayloadMap<WithHashMeta<Payload>> | undefined
|
|
35
|
+
private _signedHydratedBlockCache: HydratedCache<SignedHydratedBlockWithHashMeta> | undefined
|
|
36
|
+
|
|
37
|
+
get context(): ChainContextRead {
|
|
38
|
+
return this.params.context!
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get finalizedArchivist(): ReadArchivist {
|
|
42
|
+
return this.params.finalizedArchivist!
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
protected get hydratedBlockCache(): HydratedCache<SignedHydratedBlockWithHashMeta> {
|
|
46
|
+
if (this._signedHydratedBlockCache) return this._signedHydratedBlockCache
|
|
47
|
+
const chainMap = this.context.store.chainMap
|
|
48
|
+
this._signedHydratedBlockCache = new HydratedCache<SignedHydratedBlockWithHashMeta>(chainMap, async (
|
|
49
|
+
{ chainMap }: ChainStoreRead,
|
|
50
|
+
hash: Hash,
|
|
51
|
+
maxDepth?: number,
|
|
52
|
+
minDepth?: number,
|
|
53
|
+
) => {
|
|
54
|
+
const result = await hydrateBlock({ chainMap }, hash, maxDepth, minDepth)
|
|
55
|
+
return asSignedHydratedBlockWithHashMeta(result, true)
|
|
56
|
+
}, 200)
|
|
57
|
+
return this._signedHydratedBlockCache
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
protected get payloadCache(): PayloadMap<WithHashMeta<Payload>> {
|
|
61
|
+
if (this._payloadCache) return this._payloadCache
|
|
62
|
+
this._payloadCache = new LruCacheMap<Hash, WithHashMeta<Payload>>({ max: 10_000 })
|
|
63
|
+
return this._payloadCache
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static override async paramsHandler(params: Partial<SimpleBlockViewerParams>) {
|
|
67
|
+
assertEx(params.context, () => 'context is required')
|
|
68
|
+
assertEx(params.finalizedArchivist, () => 'finalizedArchivist is required')
|
|
69
|
+
|
|
70
|
+
return { ...await super.paramsHandler(params) }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async blockByHash(hash: Hash): Promise<SignedHydratedBlockWithHashMeta | null> {
|
|
74
|
+
return await spanRootAsync('blockByHash', async () => {
|
|
75
|
+
const cache = this.hydratedBlockCache
|
|
76
|
+
return await cache.get(hash)
|
|
77
|
+
}, this.tracer)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async blockByNumber(blockNumber: XL1BlockNumber): Promise<SignedHydratedBlockWithHashMeta | null> {
|
|
81
|
+
return await spanRootAsync('blockByNumber', async () => {
|
|
82
|
+
return asSignedHydratedBlockWithHashMeta(await hydratedBlockByNumber(this.context, blockNumber)) ?? null
|
|
83
|
+
}, this.tracer)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async blocksByHash(hash: Hash, limit = 50): Promise<SignedHydratedBlockWithHashMeta[]> {
|
|
87
|
+
return await spanRootAsync('blocksByHash', async () => {
|
|
88
|
+
assertEx(limit > 0, () => 'limit must be greater than 0')
|
|
89
|
+
assertEx(limit <= 100, () => 'limit must be less than 100')
|
|
90
|
+
const blocks: SignedHydratedBlockWithHashMeta[] = []
|
|
91
|
+
let current = await this.blockByHash(hash)
|
|
92
|
+
while (current && blocks.length < limit) {
|
|
93
|
+
blocks.push(current)
|
|
94
|
+
const previousHash = current[0].previous
|
|
95
|
+
if (previousHash === null) break
|
|
96
|
+
current = await this.blockByHash(previousHash)
|
|
97
|
+
}
|
|
98
|
+
return blocks.map(b => asSignedHydratedBlockWithHashMeta(b, true))
|
|
99
|
+
}, this.tracer)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async blocksByNumber(blockNumber: XL1BlockNumber, limit = 50): Promise<SignedHydratedBlockWithHashMeta[]> {
|
|
103
|
+
return await spanRootAsync('blocksByHash', async () => {
|
|
104
|
+
assertEx(limit > 0, () => 'limit must be greater than 0')
|
|
105
|
+
assertEx(limit <= 100, () => 'limit must be less than 100')
|
|
106
|
+
const blocks: SignedHydratedBlockWithHashMeta[] = []
|
|
107
|
+
let current = await this.blockByNumber(blockNumber)
|
|
108
|
+
while (current && blocks.length < limit) {
|
|
109
|
+
blocks.push(current)
|
|
110
|
+
if (current[0].block === 0) break
|
|
111
|
+
const previousNumber = asXL1BlockNumber(current[0].block - 1, true)
|
|
112
|
+
current = await this.blockByNumber(previousNumber)
|
|
113
|
+
}
|
|
114
|
+
return blocks.map(b => asSignedHydratedBlockWithHashMeta(b, true))
|
|
115
|
+
}, this.tracer)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async currentBlock(): Promise<SignedHydratedBlockWithHashMeta> {
|
|
119
|
+
return await spanRootAsync('currentBlock', async () => {
|
|
120
|
+
const currentHead = assertEx(await this.getCurrentHead(), () => 'Could not find most recent block')
|
|
121
|
+
const cache = this.hydratedBlockCache
|
|
122
|
+
const block = await cache.get(currentHead._hash)
|
|
123
|
+
if (!block) {
|
|
124
|
+
console.log(`Could not find current block with hash ${currentHead!._hash}`)
|
|
125
|
+
}
|
|
126
|
+
return assertEx(block, () => 'Could not find current block')
|
|
127
|
+
}, this.tracer)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async currentBlockHash(): Promise<Hash> {
|
|
131
|
+
return await spanRootAsync('currentBlockHash', async () => {
|
|
132
|
+
const currentHead = assertEx(await this.getCurrentHead(), () => 'Could not find most recent block')
|
|
133
|
+
return currentHead._hash
|
|
134
|
+
}, this.tracer)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async currentBlockNumber(): Promise<XL1BlockNumber> {
|
|
138
|
+
return await spanRootAsync('currentBlockNumber', async () => {
|
|
139
|
+
const currentHead = assertEx(await this.getCurrentHead(), () => 'Could not find most recent block')
|
|
140
|
+
return asXL1BlockNumber(currentHead.block, { name: 'currentBlockNumber' })
|
|
141
|
+
}, this.tracer)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async payloadByHash(hash: Hash): Promise<WithHashMeta<Payload> | null> {
|
|
145
|
+
const cachedPayload = await this.payloadCache.get(hash)
|
|
146
|
+
if (cachedPayload) {
|
|
147
|
+
return cachedPayload
|
|
148
|
+
} else {
|
|
149
|
+
const [result] = await this.finalizedArchivist.get([hash])
|
|
150
|
+
if (isDefined(result)) {
|
|
151
|
+
await this.payloadCache.set(hash, result)
|
|
152
|
+
}
|
|
153
|
+
return result ?? null
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async payloadsByHash(hashes: Hash[]): Promise<WithHashMeta<Payload>[]> {
|
|
158
|
+
let remainingHashes = [...hashes]
|
|
159
|
+
const cachedPayloads = await this.payloadCache.getMany(remainingHashes)
|
|
160
|
+
const cachedHashes = new Set(cachedPayloads.map(p => p._hash))
|
|
161
|
+
remainingHashes = remainingHashes.filter(h => !cachedHashes.has(h))
|
|
162
|
+
const remainingPayloads = remainingHashes.length > 0
|
|
163
|
+
? await this.finalizedArchivist.get(remainingHashes)
|
|
164
|
+
: []
|
|
165
|
+
return [...cachedPayloads, ...remainingPayloads.filter(exists)]
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
protected async getCurrentHead() {
|
|
169
|
+
const chainArchivist = this.finalizedArchivist
|
|
170
|
+
return await findMostRecentBlock(chainArchivist)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SimpleBlockViewer.ts'
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AbstractCreatable,
|
|
3
|
+
creatable, CreatableParams, Promisable,
|
|
4
|
+
} from '@xylabs/sdk-js'
|
|
5
|
+
import { AttoXL1, XL1BlockNumber } from '@xyo-network/xl1-protocol'
|
|
6
|
+
|
|
7
|
+
import { rewardFromBlockNumber } from '../../primitives/index.ts'
|
|
8
|
+
import { BlockRewardViewer } from '../../viewers/index.ts'
|
|
9
|
+
|
|
10
|
+
export interface SimpleBlockRewardViewerParams extends CreatableParams {
|
|
11
|
+
creatorReward: AttoXL1
|
|
12
|
+
initialReward: AttoXL1
|
|
13
|
+
minRewardPerBlock: AttoXL1
|
|
14
|
+
stepFactorDenominator: bigint
|
|
15
|
+
stepFactorNumerator: bigint
|
|
16
|
+
stepSize: XL1BlockNumber
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@creatable()
|
|
20
|
+
export class SimpleBlockRewardViewer extends AbstractCreatable<SimpleBlockRewardViewerParams> implements BlockRewardViewer {
|
|
21
|
+
protected rewardFromBlockNumber = rewardFromBlockNumber(18)
|
|
22
|
+
|
|
23
|
+
allowedRewardForBlock(block: XL1BlockNumber): Promisable<AttoXL1> {
|
|
24
|
+
return this.rewardFromBlockNumber(
|
|
25
|
+
block,
|
|
26
|
+
this.params.initialReward,
|
|
27
|
+
this.params.stepSize,
|
|
28
|
+
this.params.stepFactorNumerator,
|
|
29
|
+
this.params.stepFactorDenominator,
|
|
30
|
+
this.params.minRewardPerBlock,
|
|
31
|
+
this.params.creatorReward,
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SimpleBlockRewardViewer.ts'
|