@xyo-network/xl1-protocol-sdk 1.18.0-rc.1 → 1.18.0
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/CreatableProvider/AbstractCreatableProvider.d.ts +6 -5
- package/dist/neutral/CreatableProvider/AbstractCreatableProvider.d.ts.map +1 -1
- package/dist/neutral/CreatableProvider/CreatableProvider.d.ts +5 -5
- package/dist/neutral/CreatableProvider/CreatableProvider.d.ts.map +1 -1
- package/dist/neutral/CreatableProvider/CreatableProviderRegistry.d.ts.map +1 -1
- package/dist/neutral/CreatableProvider/ProviderFactory.d.ts.map +1 -1
- package/dist/neutral/CreatableProvider/ProviderFactoryLocator.d.ts.map +1 -1
- package/dist/neutral/config/Config.d.ts +2 -2
- package/dist/neutral/config/Services.d.ts +2 -2
- package/dist/neutral/config/Services.d.ts.map +1 -1
- package/dist/neutral/index.mjs +537 -211
- package/dist/neutral/index.mjs.map +1 -1
- package/dist/neutral/model/ChainQualification.d.ts +42 -0
- package/dist/neutral/model/ChainQualification.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/primitives/chain/getWindowedChain.d.ts +26 -0
- package/dist/neutral/primitives/chain/getWindowedChain.d.ts.map +1 -0
- package/dist/neutral/primitives/chain/index.d.ts +1 -0
- package/dist/neutral/primitives/chain/index.d.ts.map +1 -1
- package/dist/neutral/primitives/index.d.ts +1 -0
- package/dist/neutral/primitives/index.d.ts.map +1 -1
- package/dist/neutral/primitives/rewards/networkStakeStepRewardPositionWeight.d.ts +1 -1
- package/dist/neutral/primitives/uncle/findBestUncle.d.ts +24 -0
- package/dist/neutral/primitives/uncle/findBestUncle.d.ts.map +1 -0
- package/dist/neutral/primitives/uncle/findUncles.d.ts +26 -0
- package/dist/neutral/primitives/uncle/findUncles.d.ts.map +1 -0
- package/dist/neutral/primitives/uncle/index.d.ts +4 -0
- package/dist/neutral/primitives/uncle/index.d.ts.map +1 -0
- package/dist/neutral/primitives/uncle/scoreUncle.d.ts +3 -0
- package/dist/neutral/primitives/uncle/scoreUncle.d.ts.map +1 -0
- package/dist/neutral/provider/viewer/XyoViewer.d.ts +7 -5
- package/dist/neutral/provider/viewer/XyoViewer.d.ts.map +1 -1
- package/dist/neutral/simple/accountBalance/SimpleAccountBalanceViewer.d.ts +61 -10
- package/dist/neutral/simple/accountBalance/SimpleAccountBalanceViewer.d.ts.map +1 -1
- package/dist/neutral/simple/blockValidation/SimpleBlockValidationViewer.d.ts +31 -0
- package/dist/neutral/simple/blockValidation/SimpleBlockValidationViewer.d.ts.map +1 -0
- package/dist/neutral/simple/blockValidation/index.d.ts +2 -0
- package/dist/neutral/simple/blockValidation/index.d.ts.map +1 -0
- package/dist/neutral/simple/datalake/AbstractSimpleDataLake.d.ts +1 -1
- package/dist/neutral/simple/datalake/AbstractSimpleDataLake.d.ts.map +1 -1
- package/dist/neutral/simple/datalake/SimpleDataLakeViewer.d.ts.map +1 -1
- package/dist/neutral/simple/index.d.ts +1 -0
- package/dist/neutral/simple/index.d.ts.map +1 -1
- package/dist/neutral/simple/timesync/SimpleTimeSyncViewer.d.ts.map +1 -1
- package/dist/neutral/summary/model/summary.d.ts +0 -1
- package/dist/neutral/summary/model/summary.d.ts.map +1 -1
- package/dist/neutral/summary/primitives/balances/balancesSummary.d.ts +2 -2
- package/dist/neutral/summary/primitives/balances/balancesSummary.d.ts.map +1 -1
- package/dist/neutral/summary/primitives/schemas/schemasSummary.d.ts +2 -2
- package/dist/neutral/summary/primitives/schemas/schemasSummary.d.ts.map +1 -1
- package/dist/neutral/summary/primitives/transfers/transfersSummary.d.ts +2 -2
- package/dist/neutral/summary/primitives/transfers/transfersSummary.d.ts.map +1 -1
- package/dist/neutral/viewers/AccountBalance.d.ts +35 -15
- package/dist/neutral/viewers/AccountBalance.d.ts.map +1 -1
- package/dist/neutral/viewers/BlockValidation.d.ts +54 -0
- package/dist/neutral/viewers/BlockValidation.d.ts.map +1 -0
- package/dist/neutral/viewers/StakeIntent.d.ts +2 -2
- package/dist/neutral/viewers/StakeIntent.d.ts.map +1 -1
- package/dist/neutral/viewers/TransactionValidation.d.ts +35 -0
- package/dist/neutral/viewers/TransactionValidation.d.ts.map +1 -0
- package/dist/neutral/viewers/index.d.ts +2 -0
- package/dist/neutral/viewers/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/CreatableProvider/AbstractCreatableProvider.ts +22 -6
- package/src/CreatableProvider/CreatableProvider.ts +5 -5
- package/src/CreatableProvider/CreatableProviderRegistry.ts +1 -0
- package/src/CreatableProvider/ProviderFactory.ts +3 -2
- package/src/CreatableProvider/ProviderFactoryLocator.ts +2 -1
- package/src/config/Services.ts +4 -2
- package/src/model/ChainQualification.ts +33 -0
- package/src/model/index.ts +1 -1
- package/src/primitives/chain/getWindowedChain.ts +23 -0
- package/src/primitives/chain/index.ts +1 -0
- package/src/primitives/index.ts +1 -0
- package/src/primitives/rewards/networkStakeStepRewardPositionWeight.ts +1 -1
- package/src/primitives/uncle/findBestUncle.ts +8 -0
- package/src/primitives/uncle/findUncles.ts +75 -0
- package/src/primitives/uncle/index.ts +3 -0
- package/src/primitives/uncle/scoreUncle.ts +6 -0
- package/src/provider/viewer/XyoViewer.ts +7 -7
- package/src/simple/accountBalance/SimpleAccountBalanceViewer.ts +46 -30
- package/src/simple/blockValidation/SimpleBlockValidationViewer.ts +126 -0
- package/src/simple/blockValidation/index.ts +1 -0
- package/src/simple/datalake/AbstractSimpleDataLake.ts +2 -1
- package/src/simple/datalake/SimpleDataLakeViewer.ts +0 -1
- package/src/simple/index.ts +1 -0
- package/src/simple/timesync/SimpleTimeSyncViewer.ts +1 -1
- package/src/summary/model/summary.ts +0 -1
- package/src/summary/primitives/balances/balancesSummary.ts +12 -12
- package/src/summary/primitives/schemas/schemasSummary.ts +12 -10
- package/src/summary/primitives/transfers/transfersSummary.ts +14 -16
- package/src/viewers/AccountBalance.ts +22 -14
- package/src/viewers/BlockValidation.ts +47 -0
- package/src/viewers/StakeIntent.ts +2 -2
- package/src/viewers/TransactionValidation.ts +35 -0
- package/src/viewers/index.ts +2 -0
- package/dist/neutral/model/Qualified.d.ts +0 -6
- package/dist/neutral/model/Qualified.d.ts.map +0 -1
- package/src/model/Qualified.ts +0 -9
|
@@ -2,6 +2,7 @@ import type { Address, Hash } from '@xylabs/sdk-js'
|
|
|
2
2
|
import {
|
|
3
3
|
asHash,
|
|
4
4
|
assertEx, exists, isDefined, spanRootAsync,
|
|
5
|
+
ZERO_ADDRESS,
|
|
5
6
|
} from '@xylabs/sdk-js'
|
|
6
7
|
import type { WithHashMeta, WithStorageMeta } from '@xyo-network/payload-model'
|
|
7
8
|
import type {
|
|
@@ -16,7 +17,9 @@ import {
|
|
|
16
17
|
import { deepCalculateFramesFromRange } from '../../block/index.ts'
|
|
17
18
|
import type { CreatableProviderParams } from '../../CreatableProvider/index.ts'
|
|
18
19
|
import { AbstractCreatableProvider, creatableProvider } from '../../CreatableProvider/index.ts'
|
|
19
|
-
import
|
|
20
|
+
import {
|
|
21
|
+
ChainQualification, type ChainQualified, isChainQualifiedHeadConfig, isChainQualifiedRangeConfig,
|
|
22
|
+
} from '../../model/index.ts'
|
|
20
23
|
import type {
|
|
21
24
|
BalanceStepSummaryContext,
|
|
22
25
|
TransfersStepSummary,
|
|
@@ -27,6 +30,7 @@ import {
|
|
|
27
30
|
transfersStepSummaryFromRange,
|
|
28
31
|
} from '../../summary/index.ts'
|
|
29
32
|
import {
|
|
33
|
+
AccountBalanceConfig,
|
|
30
34
|
type AccountBalanceHistoryItem, type AccountBalanceViewer, AccountBalanceViewerMoniker,
|
|
31
35
|
type BlockViewer,
|
|
32
36
|
BlockViewerMoniker,
|
|
@@ -64,17 +68,17 @@ export class SimpleAccountBalanceViewer extends AbstractCreatableProvider<Simple
|
|
|
64
68
|
return await super.paramsHandler({ ...params })
|
|
65
69
|
}
|
|
66
70
|
|
|
67
|
-
async accountBalance(address: Address,
|
|
68
|
-
const balances = await this.accountBalances([address],
|
|
71
|
+
async accountBalance(address: Address, config?: AccountBalanceConfig) {
|
|
72
|
+
const balances = await this.accountBalances([address], config)
|
|
69
73
|
return balances[address] ?? AttoXL1(0n)
|
|
70
74
|
}
|
|
71
75
|
|
|
72
|
-
accountBalanceHistories(
|
|
73
|
-
|
|
76
|
+
async accountBalanceHistories(addresses: Address[], config: AccountBalanceConfig = {}) {
|
|
77
|
+
return (await this.qualifiedAccountBalanceHistories(addresses, config))[0]
|
|
74
78
|
}
|
|
75
79
|
|
|
76
|
-
async accountBalanceHistory(address: Address,
|
|
77
|
-
const range =
|
|
80
|
+
async accountBalanceHistory(address: Address, config?: AccountBalanceConfig) {
|
|
81
|
+
const range = isChainQualifiedRangeConfig(config) ? config.range : undefined
|
|
78
82
|
const startingRange = asXL1BlockRange(range ?? [0, await this.blockViewer.currentBlockNumber()], true)
|
|
79
83
|
const blockNumbers = await this.distillTransferHistory(address, startingRange)
|
|
80
84
|
const blocks = (await Promise.all(blockNumbers.map(async bn => await this.blockViewer.blockByNumber(bn)))).filter(exists)
|
|
@@ -101,8 +105,8 @@ export class SimpleAccountBalanceViewer extends AbstractCreatableProvider<Simple
|
|
|
101
105
|
return result
|
|
102
106
|
}
|
|
103
107
|
|
|
104
|
-
async accountBalances(address: Address[],
|
|
105
|
-
const [result] = (await this.qualifiedAccountBalances(address,
|
|
108
|
+
async accountBalances(address: Address[], config?: AccountBalanceConfig) {
|
|
109
|
+
const [result] = (await this.qualifiedAccountBalances(address, config ?? {}))
|
|
106
110
|
return result
|
|
107
111
|
}
|
|
108
112
|
|
|
@@ -113,57 +117,69 @@ export class SimpleAccountBalanceViewer extends AbstractCreatableProvider<Simple
|
|
|
113
117
|
|
|
114
118
|
async qualifiedAccountBalanceHistories(
|
|
115
119
|
addresses: Address[],
|
|
116
|
-
|
|
117
|
-
)
|
|
118
|
-
const head =
|
|
119
|
-
const range =
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
120
|
+
config: AccountBalanceConfig,
|
|
121
|
+
) {
|
|
122
|
+
const head = isChainQualifiedHeadConfig(config) ? config.head : await this.blockViewer.currentBlockHash()
|
|
123
|
+
const range = isChainQualifiedRangeConfig(config)
|
|
124
|
+
? config.range
|
|
125
|
+
: asXL1BlockRange([0,
|
|
126
|
+
assertEx(
|
|
127
|
+
await this.blockViewer.blockByHash(head),
|
|
128
|
+
() => `Error: Could not find block with hash ${head}`,
|
|
129
|
+
)[0].block])
|
|
130
|
+
const qualifiedEntries = await Promise.all(addresses.map(async address => ([
|
|
125
131
|
address,
|
|
126
132
|
await this.qualifiedAccountBalanceHistory(address, range),
|
|
127
|
-
])))
|
|
133
|
+
]))) satisfies [Address, ChainQualified<AccountBalanceHistoryItem[]>][]
|
|
128
134
|
|
|
129
135
|
const entries = qualifiedEntries.map(([address, [history]]) => {
|
|
130
136
|
return [address, history]
|
|
131
137
|
})
|
|
132
|
-
const qualifiedRange = qualifiedEntries[0][1][1]
|
|
133
|
-
const qualifiedHeadHash = qualifiedEntries[0][1][
|
|
138
|
+
const qualifiedRange = qualifiedEntries[0][1][1].range
|
|
139
|
+
const qualifiedHeadHash = qualifiedEntries[0][1][1].head
|
|
134
140
|
|
|
135
141
|
// check for drift
|
|
136
|
-
for (const [_, [__, range,
|
|
142
|
+
for (const [_, [__, { range, head }]] of qualifiedEntries) {
|
|
137
143
|
assertEx(
|
|
138
144
|
range[0] === qualifiedRange[0] && range[1] === qualifiedRange[1],
|
|
139
145
|
() => 'Inconsistent ranges in qualifiedAccountBalanceHistories',
|
|
140
146
|
)
|
|
141
147
|
assertEx(
|
|
142
|
-
|
|
148
|
+
head === qualifiedHeadHash,
|
|
143
149
|
() => 'Inconsistent head hashes in qualifiedAccountBalanceHistories',
|
|
144
150
|
)
|
|
145
151
|
}
|
|
146
152
|
|
|
147
|
-
return [Object.fromEntries(entries), qualifiedRange, qualifiedHeadHash]
|
|
153
|
+
return [Object.fromEntries(entries), { range: qualifiedRange, head: qualifiedHeadHash }] satisfies
|
|
154
|
+
[Record<Address, AccountBalanceHistoryItem[]>, ChainQualification]
|
|
148
155
|
}
|
|
149
156
|
|
|
150
157
|
async qualifiedAccountBalances(
|
|
151
158
|
address: Address[],
|
|
152
|
-
|
|
153
|
-
): Promise<
|
|
159
|
+
config: AccountBalanceConfig,
|
|
160
|
+
): Promise<ChainQualified<Record<Address, AttoXL1>>> {
|
|
154
161
|
return await spanRootAsync('qualifiedAccountsBalances', async () => {
|
|
155
162
|
const qualifiedSummary = await balancesSummary(
|
|
156
|
-
this.balanceSummaryContext,
|
|
163
|
+
{ ...this.balanceSummaryContext },
|
|
164
|
+
config,
|
|
157
165
|
)
|
|
158
166
|
const result: Record<Address, AttoXL1> = {}
|
|
159
167
|
for (const addr of address) {
|
|
160
168
|
const summaryBalance = qualifiedSummary[0][addr] ?? 0n
|
|
161
169
|
result[addr] = AttoXL1(summaryBalance < 0n ? 0n : summaryBalance)
|
|
162
170
|
}
|
|
163
|
-
return [result, qualifiedSummary[1]
|
|
171
|
+
return [result, qualifiedSummary[1]]
|
|
164
172
|
})
|
|
165
173
|
}
|
|
166
174
|
|
|
175
|
+
override async startHandler() {
|
|
176
|
+
await super.startHandler()
|
|
177
|
+
await Promise.all([
|
|
178
|
+
this.accountBalance(ZERO_ADDRESS),
|
|
179
|
+
this.accountBalanceHistory(ZERO_ADDRESS),
|
|
180
|
+
])
|
|
181
|
+
}
|
|
182
|
+
|
|
167
183
|
private async distillTransferHistory(address: Address, range: XL1BlockRange, max: number = 50): Promise<XL1BlockNumber[]> {
|
|
168
184
|
if ((range[1] - range[0]) <= StepSizes[0] || max <= 1) {
|
|
169
185
|
return Array.from({ length: range[1] - range[0] + 1 }, (_, i) => range[1] - i).slice(0, max).map(n => asXL1BlockNumber(n, true))
|
|
@@ -205,7 +221,7 @@ export class SimpleAccountBalanceViewer extends AbstractCreatableProvider<Simple
|
|
|
205
221
|
private async qualifiedAccountBalanceHistory(
|
|
206
222
|
address: Address,
|
|
207
223
|
headOrRange?: Hash | XL1BlockRange,
|
|
208
|
-
): Promise<
|
|
224
|
+
): Promise<ChainQualified<AccountBalanceHistoryItem[]>> {
|
|
209
225
|
const range = asRange(headOrRange)
|
|
210
226
|
const headHash = asHash(headOrRange)
|
|
211
227
|
const [head] = assertEx(isDefined(headHash)
|
|
@@ -234,6 +250,6 @@ export class SimpleAccountBalanceViewer extends AbstractCreatableProvider<Simple
|
|
|
234
250
|
null,
|
|
235
251
|
transfer] satisfies AccountBalanceHistoryItem))
|
|
236
252
|
}
|
|
237
|
-
return [result, startingRange, head._hash]
|
|
253
|
+
return [result, { range: startingRange, head: head._hash }]
|
|
238
254
|
}
|
|
239
255
|
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { exists } from '@xylabs/sdk-js'
|
|
2
|
+
import {
|
|
3
|
+
asXL1BlockRange,
|
|
4
|
+
ChainId,
|
|
5
|
+
type SignedHydratedBlockWithHashMeta,
|
|
6
|
+
} from '@xyo-network/xl1-protocol'
|
|
7
|
+
|
|
8
|
+
import type { CreatableProviderParams } from '../../CreatableProvider/index.ts'
|
|
9
|
+
import { AbstractCreatableProvider, creatableProvider } from '../../CreatableProvider/index.ts'
|
|
10
|
+
import { findUncles, getWindowedChain } from '../../primitives/index.ts'
|
|
11
|
+
import type {
|
|
12
|
+
HydratedBlockStateValidationFunction, HydratedBlockValidationError, HydratedBlockValidationFunction,
|
|
13
|
+
} from '../../validation/index.ts'
|
|
14
|
+
import type {
|
|
15
|
+
AccountBalanceViewer,
|
|
16
|
+
BlockValidationConfig,
|
|
17
|
+
BlockValidationQualification,
|
|
18
|
+
BlockValidationViewer,
|
|
19
|
+
} from '../../viewers/index.ts'
|
|
20
|
+
import {
|
|
21
|
+
AccountBalanceViewerMoniker,
|
|
22
|
+
BlockValidationViewerMoniker, BlockViewer, BlockViewerMoniker,
|
|
23
|
+
} from '../../viewers/index.ts'
|
|
24
|
+
|
|
25
|
+
export interface SimpleBlockValidationViewerParams extends CreatableProviderParams {
|
|
26
|
+
maxUncleWindowSize: number
|
|
27
|
+
state?: HydratedBlockStateValidationFunction
|
|
28
|
+
value?: HydratedBlockValidationFunction
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@creatableProvider()
|
|
32
|
+
export class SimpleBlockValidationViewer extends AbstractCreatableProvider<SimpleBlockValidationViewerParams> implements BlockValidationViewer {
|
|
33
|
+
static readonly defaultMoniker = BlockValidationViewerMoniker
|
|
34
|
+
static readonly monikers = [BlockValidationViewerMoniker]
|
|
35
|
+
moniker = SimpleBlockValidationViewer.defaultMoniker
|
|
36
|
+
|
|
37
|
+
private _accountBalanceViewer!: AccountBalanceViewer
|
|
38
|
+
private _blockViewer!: BlockViewer
|
|
39
|
+
private _uncleWindowedChainCache: SignedHydratedBlockWithHashMeta[] | null = null
|
|
40
|
+
|
|
41
|
+
protected get blockViewer() {
|
|
42
|
+
return this._blockViewer
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
protected get maxUncleWindowSize() {
|
|
46
|
+
return this.params.maxUncleWindowSize
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static override async paramsHandler(params: Partial<SimpleBlockValidationViewerParams>): Promise<SimpleBlockValidationViewerParams> {
|
|
50
|
+
return {
|
|
51
|
+
...await super.paramsHandler(params),
|
|
52
|
+
maxUncleWindowSize: params.maxUncleWindowSize ?? 100,
|
|
53
|
+
} satisfies SimpleBlockValidationViewerParams
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
override async createHandler() {
|
|
57
|
+
await super.createHandler()
|
|
58
|
+
this._accountBalanceViewer = await this.locator.getInstance<AccountBalanceViewer>(AccountBalanceViewerMoniker)
|
|
59
|
+
this._blockViewer = await this.locator.getInstance<BlockViewer>(BlockViewerMoniker)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async qualifiedValidateBlock(
|
|
63
|
+
block: SignedHydratedBlockWithHashMeta,
|
|
64
|
+
config?: BlockValidationConfig,
|
|
65
|
+
): Promise<[HydratedBlockValidationError[], BlockValidationQualification]> {
|
|
66
|
+
return (await this.qualifiedValidateBlocks([block], config))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async qualifiedValidateBlocks(
|
|
70
|
+
blocks: SignedHydratedBlockWithHashMeta[],
|
|
71
|
+
config?: BlockValidationConfig,
|
|
72
|
+
): Promise<[HydratedBlockValidationError[], BlockValidationQualification]> {
|
|
73
|
+
const { value, state } = config ?? {
|
|
74
|
+
shape: true, links: true, state: true,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const [headBlock] = await this.blockViewer.currentBlock()
|
|
78
|
+
const chainId = headBlock.chain
|
|
79
|
+
|
|
80
|
+
const validateValue = value ? this.doValidateValue.bind(this) : undefined
|
|
81
|
+
const validateState = state ? this.doValidateState.bind(this) : undefined
|
|
82
|
+
|
|
83
|
+
return [(await Promise.all([
|
|
84
|
+
validateValue?.(blocks, chainId), validateState?.(blocks, chainId),
|
|
85
|
+
].filter(exists))).flat(), { head: headBlock._hash, range: asXL1BlockRange([0, headBlock.block], true) }]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async validateBlock(block: SignedHydratedBlockWithHashMeta, config?: BlockValidationConfig): Promise<HydratedBlockValidationError[]> {
|
|
89
|
+
return (await this.validateBlocks([block], config))
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async validateBlocks(blocks: SignedHydratedBlockWithHashMeta[], config?: BlockValidationConfig): Promise<HydratedBlockValidationError[]> {
|
|
93
|
+
return (await this.qualifiedValidateBlocks(blocks, config))[0]
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private async doValidateState(blocks: SignedHydratedBlockWithHashMeta[], chainId: ChainId): Promise<HydratedBlockValidationError[]> {
|
|
97
|
+
const windowedUncleChain = await this.updateWindowedChainCache()
|
|
98
|
+
|
|
99
|
+
const uncles = findUncles(this.context, windowedUncleChain, blocks)
|
|
100
|
+
|
|
101
|
+
if (uncles.length !== 1) {
|
|
102
|
+
throw new Error(`No uncles or greater than one uncle found in block validation, which is not supported [${uncles.length}]`)
|
|
103
|
+
}
|
|
104
|
+
return (await Promise.all(uncles[0].map(async (block) => {
|
|
105
|
+
return await this.params.state!(
|
|
106
|
+
block,
|
|
107
|
+
chainId,
|
|
108
|
+
{ accountBalance: this._accountBalanceViewer },
|
|
109
|
+
)
|
|
110
|
+
}))).flat()
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private async doValidateValue(blocks: SignedHydratedBlockWithHashMeta[], chainId: ChainId): Promise<HydratedBlockValidationError[]> {
|
|
114
|
+
return (await Promise.all(blocks.map(async (block) => {
|
|
115
|
+
return await this.params.value!(
|
|
116
|
+
block,
|
|
117
|
+
chainId,
|
|
118
|
+
)
|
|
119
|
+
}))).flat()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private async updateWindowedChainCache() {
|
|
123
|
+
this._uncleWindowedChainCache = await getWindowedChain(this.blockViewer, this.maxUncleWindowSize, this._uncleWindowedChainCache ?? [])
|
|
124
|
+
return [...this._uncleWindowedChainCache]
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SimpleBlockValidationViewer.ts'
|
|
@@ -14,7 +14,8 @@ MapTypeRead<Hash, DataLakeData> = MapTypeRead<Hash, DataLakeData>> extends
|
|
|
14
14
|
map: TMap
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export class AbstractSimpleDataLake<TParams extends AbstractSimpleDataLakeParams = AbstractSimpleDataLakeParams> extends
|
|
17
|
+
export abstract class AbstractSimpleDataLake<TParams extends AbstractSimpleDataLakeParams = AbstractSimpleDataLakeParams> extends
|
|
18
|
+
AbstractCreatableProvider<TParams> {
|
|
18
19
|
get allowedSchemas(): Schema[] | undefined {
|
|
19
20
|
return this.params.allowedSchemas
|
|
20
21
|
}
|
package/src/simple/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './accountBalance/index.ts'
|
|
2
2
|
export * from './block/index.ts'
|
|
3
3
|
export * from './blockReward/index.ts'
|
|
4
|
+
export * from './blockValidation/index.ts'
|
|
4
5
|
export * from './chainStake/index.ts'
|
|
5
6
|
export * from './client/index.ts'
|
|
6
7
|
export * from './datalake/index.ts'
|
|
@@ -13,7 +13,6 @@ export interface ChainSummaryContextBase<TPayload extends Payload,
|
|
|
13
13
|
T extends (MapTypeRead<string, TPayload>)> extends BaseContext {
|
|
14
14
|
stepSemaphores: Semaphore[]
|
|
15
15
|
summaryMap: T
|
|
16
|
-
windowSize?: number
|
|
17
16
|
}
|
|
18
17
|
|
|
19
18
|
export interface ChainSummaryContextRead<T extends Payload> extends ChainSummaryContextBase<T, MapTypeRead<string, T>>, ChainContextRead {}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import type { Address } from '@xylabs/sdk-js'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
} from '@xylabs/sdk-js'
|
|
5
|
-
import {
|
|
6
|
-
asBlockBoundWitnessWithStorageMeta, asXL1BlockNumber, asXL1BlockRange,
|
|
7
|
-
} from '@xyo-network/xl1-protocol'
|
|
2
|
+
import { asAddress, spanRootAsync } from '@xylabs/sdk-js'
|
|
3
|
+
import { asBlockBoundWitnessWithStorageMeta, asXL1BlockRange } from '@xyo-network/xl1-protocol'
|
|
8
4
|
|
|
9
5
|
import { deepCalculateFramesFromRange } from '../../../block/index.ts'
|
|
10
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
type ChainQualified, type ChainQualifiedConfig, isChainQualifiedHeadConfig,
|
|
8
|
+
isChainQualifiedRangeConfig,
|
|
9
|
+
} from '../../../model/index.ts'
|
|
11
10
|
import { parseSignedBigInt } from '../../../SignedBigInt.ts'
|
|
12
11
|
import type { BalanceStepSummaryContext } from '../../model/index.ts'
|
|
13
12
|
import { balancesStepSummaryFromRange } from './balancesStepSummaryFromRange.ts'
|
|
14
13
|
|
|
15
14
|
export async function balancesSummary(
|
|
16
15
|
context: BalanceStepSummaryContext,
|
|
17
|
-
|
|
16
|
+
config?: ChainQualifiedConfig,
|
|
17
|
+
): Promise<ChainQualified<Record<Address, bigint>>> {
|
|
18
18
|
return await spanRootAsync('balancesSummary', async () => {
|
|
19
|
-
const [headHash] = await context.head()
|
|
19
|
+
const [headHash] = isChainQualifiedHeadConfig(config) ? [config.head] : await context.head()
|
|
20
20
|
const headResult = await context.store.chainMap.get(headHash)
|
|
21
21
|
const headBoundWitness = asBlockBoundWitnessWithStorageMeta(headResult, () => `Head block not found for hash: ${headHash}`)
|
|
22
|
-
const
|
|
22
|
+
const range = isChainQualifiedRangeConfig(config) ? config.range : asXL1BlockRange([0, headBoundWitness.block], true)
|
|
23
23
|
const ranges = deepCalculateFramesFromRange(asXL1BlockRange(
|
|
24
|
-
|
|
24
|
+
range,
|
|
25
25
|
{ name: 'balancesSummary' },
|
|
26
26
|
))
|
|
27
27
|
const summaries = await Promise.all(ranges.map(range => balancesStepSummaryFromRange(context, range)))
|
|
@@ -32,6 +32,6 @@ export async function balancesSummary(
|
|
|
32
32
|
balances[validAddress] = (balances[validAddress] ?? 0n) + parseSignedBigInt(balance)
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
return [balances,
|
|
35
|
+
return [balances, { range, head: headHash }]
|
|
36
36
|
})
|
|
37
37
|
}
|
|
@@ -1,24 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { spanRootAsync } from '@xylabs/sdk-js'
|
|
2
2
|
import type { Schema } from '@xyo-network/payload-model'
|
|
3
|
-
import {
|
|
4
|
-
asBlockBoundWitnessWithStorageMeta, asXL1BlockNumber, asXL1BlockRange,
|
|
5
|
-
} from '@xyo-network/xl1-protocol'
|
|
3
|
+
import { asBlockBoundWitnessWithStorageMeta, asXL1BlockRange } from '@xyo-network/xl1-protocol'
|
|
6
4
|
|
|
7
5
|
import { deepCalculateFramesFromRange } from '../../../block/index.ts'
|
|
8
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
type ChainQualified, type ChainQualifiedConfig, isChainQualifiedHeadConfig,
|
|
8
|
+
isChainQualifiedRangeConfig,
|
|
9
|
+
} from '../../../model/index.ts'
|
|
9
10
|
import type { SchemasStepSummaryContext } from '../../model/index.ts'
|
|
10
11
|
import { schemasStepSummaryFromRange } from './schemasStepSummaryFromRange.ts'
|
|
11
12
|
|
|
12
13
|
export async function schemasSummary(
|
|
13
14
|
context: SchemasStepSummaryContext,
|
|
14
|
-
|
|
15
|
+
config?: ChainQualifiedConfig,
|
|
16
|
+
): Promise<ChainQualified<Record<Schema, number>>> {
|
|
15
17
|
return await spanRootAsync('schemasSummary', async () => {
|
|
16
|
-
const [headHash] = await context.head()
|
|
18
|
+
const [headHash] = isChainQualifiedHeadConfig(config) ? [config.head] : await context.head()
|
|
17
19
|
const headResult = await context.store.chainMap.get(headHash)
|
|
18
20
|
const headBoundWitness = asBlockBoundWitnessWithStorageMeta(headResult, () => `Head block not found for hash: ${headHash}`)
|
|
19
|
-
const
|
|
21
|
+
const range = isChainQualifiedRangeConfig(config) ? config.range : asXL1BlockRange([0, headBoundWitness.block], true)
|
|
20
22
|
const ranges = deepCalculateFramesFromRange(asXL1BlockRange(
|
|
21
|
-
|
|
23
|
+
range,
|
|
22
24
|
{ name: 'schemasSummary' },
|
|
23
25
|
))
|
|
24
26
|
const summaries = await Promise.all(ranges.map(range => schemasStepSummaryFromRange(context, range)))
|
|
@@ -28,6 +30,6 @@ export async function schemasSummary(
|
|
|
28
30
|
results[schema] = (results[schema] ?? 0) + count
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
|
-
return [results,
|
|
33
|
+
return [results, { range, head: headHash }]
|
|
32
34
|
})
|
|
33
35
|
}
|
|
@@ -1,31 +1,29 @@
|
|
|
1
1
|
import type { Address, Hash } from '@xylabs/sdk-js'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
} from '@xylabs/sdk-js'
|
|
5
|
-
import {
|
|
6
|
-
asBlockBoundWitnessWithStorageMeta, asXL1BlockNumber, asXL1BlockRange,
|
|
7
|
-
} from '@xyo-network/xl1-protocol'
|
|
2
|
+
import { asAddress, spanRootAsync } from '@xylabs/sdk-js'
|
|
3
|
+
import { asBlockBoundWitnessWithStorageMeta, asXL1BlockRange } from '@xyo-network/xl1-protocol'
|
|
8
4
|
|
|
9
5
|
import { deepCalculateFramesFromRange } from '../../../block/index.ts'
|
|
10
|
-
import type {
|
|
6
|
+
import type { ChainQualified, ChainQualifiedConfig } from '../../../model/index.ts'
|
|
7
|
+
import { isChainQualifiedHeadConfig, isChainQualifiedRangeConfig } from '../../../model/index.ts'
|
|
11
8
|
import { parseSignedBigInt } from '../../../SignedBigInt.ts'
|
|
12
9
|
import type { TransfersStepSummaryContext } from '../../index.ts'
|
|
13
10
|
import { transfersStepSummaryFromRange } from './transfersStepSummaryFromRange.ts'
|
|
14
11
|
|
|
15
12
|
// the summary of amount of rewards claimed from the step reward pool by addresses
|
|
16
13
|
export async function transfersSummary(
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
context: TransfersStepSummaryContext,
|
|
15
|
+
config?: ChainQualifiedConfig,
|
|
16
|
+
): Promise<ChainQualified<Record<Address, Record<Address, bigint>>>> {
|
|
19
17
|
return await spanRootAsync('transferSummary', async () => {
|
|
20
|
-
const [headHash] = await
|
|
21
|
-
const headResult = await
|
|
22
|
-
const headBoundWitness = asBlockBoundWitnessWithStorageMeta(headResult, () => `Head block not found for hash: ${
|
|
23
|
-
const
|
|
18
|
+
const [headHash] = isChainQualifiedHeadConfig(config) ? [config.head] : await context.head()
|
|
19
|
+
const headResult = await context.store.chainMap.get(headHash)
|
|
20
|
+
const headBoundWitness = asBlockBoundWitnessWithStorageMeta(headResult, () => `Head block not found for hash: ${headHash}`)
|
|
21
|
+
const range = isChainQualifiedRangeConfig(config) ? config.range : asXL1BlockRange([0, headBoundWitness.block], true)
|
|
24
22
|
const ranges = deepCalculateFramesFromRange(asXL1BlockRange(
|
|
25
|
-
|
|
23
|
+
range,
|
|
26
24
|
{ name: 'transfersSummary' },
|
|
27
25
|
))
|
|
28
|
-
const summaries = await Promise.all(ranges.map(range => transfersStepSummaryFromRange(
|
|
26
|
+
const summaries = await Promise.all(ranges.map(range => transfersStepSummaryFromRange(context, range)))
|
|
29
27
|
const transfers: Record<Address, Record<Address, bigint>> = {}
|
|
30
28
|
for (let summary of summaries) {
|
|
31
29
|
for (const [from, toMap] of Object.entries(summary.transfers)) {
|
|
@@ -37,7 +35,7 @@ export async function transfersSummary(
|
|
|
37
35
|
}
|
|
38
36
|
}
|
|
39
37
|
}
|
|
40
|
-
return [transfers,
|
|
38
|
+
return [transfers, { range, head: headHash }]
|
|
41
39
|
})
|
|
42
40
|
}
|
|
43
41
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import type
|
|
2
|
-
|
|
3
|
-
} from '@xylabs/sdk-js'
|
|
1
|
+
import { type Address, type Promisable } from '@xylabs/sdk-js'
|
|
2
|
+
import { zodIsFactory } from '@xylabs/zod'
|
|
4
3
|
import { WithHashMetaZod } from '@xyo-network/payload-model'
|
|
5
4
|
import {
|
|
6
5
|
type AttoXL1,
|
|
7
6
|
TransferZod,
|
|
8
|
-
type XL1BlockRange,
|
|
9
7
|
} from '@xyo-network/xl1-protocol'
|
|
10
8
|
import { BlockBoundWitnessZod, TransactionBoundWitnessZod } from '@xyo-network/xl1-protocol'
|
|
11
9
|
import z from 'zod'
|
|
12
10
|
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
import {
|
|
12
|
+
ChainQualificationZod,
|
|
13
|
+
type ChainQualified,
|
|
14
|
+
ChainQualifiedConfigZod,
|
|
15
|
+
type Provider,
|
|
16
16
|
} from '../model/index.ts'
|
|
17
17
|
|
|
18
18
|
export const AccountBalanceHistoryItemZod = z.tuple([
|
|
@@ -23,19 +23,27 @@ export const AccountBalanceHistoryItemZod = z.tuple([
|
|
|
23
23
|
|
|
24
24
|
export type AccountBalanceHistoryItem = z.infer<typeof AccountBalanceHistoryItemZod>
|
|
25
25
|
|
|
26
|
+
export const AccountBalanceQualificationZod = ChainQualificationZod
|
|
27
|
+
export type AccountBalanceQualification = z.infer<typeof AccountBalanceQualificationZod>
|
|
28
|
+
export const isAccountBalanceQualification = zodIsFactory(AccountBalanceQualificationZod)
|
|
29
|
+
|
|
30
|
+
export const AccountBalanceConfigZod = ChainQualifiedConfigZod
|
|
31
|
+
export type AccountBalanceConfig = z.infer<typeof AccountBalanceConfigZod>
|
|
32
|
+
export const isAccountBalanceCOnfig = zodIsFactory(AccountBalanceConfigZod)
|
|
33
|
+
|
|
26
34
|
export interface AccountBalanceViewerMethods {
|
|
27
35
|
qualifiedAccountBalanceHistories(
|
|
28
36
|
address: Address[],
|
|
29
|
-
|
|
30
|
-
): Promisable<
|
|
31
|
-
qualifiedAccountBalances(address: Address[],
|
|
37
|
+
config: AccountBalanceConfig
|
|
38
|
+
): Promisable<ChainQualified<Record<Address, AccountBalanceHistoryItem[]>>>
|
|
39
|
+
qualifiedAccountBalances(address: Address[], config: AccountBalanceConfig): Promisable<ChainQualified<Record<Address, AttoXL1>>>
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
export interface AccountBalanceViewer extends AccountBalanceViewerMethods, Provider<AccountBalanceViewerMoniker> {
|
|
35
|
-
accountBalance(address: Address,
|
|
36
|
-
accountBalanceHistories(address: Address[],
|
|
37
|
-
accountBalanceHistory(address: Address,
|
|
38
|
-
accountBalances(address: Address[],
|
|
43
|
+
accountBalance(address: Address, config?: AccountBalanceConfig): Promisable<AttoXL1>
|
|
44
|
+
accountBalanceHistories(address: Address[], config?: AccountBalanceConfig): Promisable<Record<Address, AccountBalanceHistoryItem[]>>
|
|
45
|
+
accountBalanceHistory(address: Address, config?: AccountBalanceConfig): Promisable<AccountBalanceHistoryItem[]>
|
|
46
|
+
accountBalances(address: Address[], config?: AccountBalanceConfig): Promisable<Record<Address, AttoXL1>>
|
|
39
47
|
}
|
|
40
48
|
|
|
41
49
|
export const AccountBalanceViewerMoniker = 'AccountBalanceViewer' as const
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type Promisable } from '@xylabs/sdk-js'
|
|
2
|
+
import { zodIsFactory } from '@xylabs/zod'
|
|
3
|
+
import type { HydratedBlock, SignedHydratedBlockWithHashMeta } from '@xyo-network/xl1-protocol'
|
|
4
|
+
import z from 'zod'
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ChainQualificationZod, ChainQualifiedHeadConfigZod, ChainQualifiedRangeConfigZod, type Provider,
|
|
8
|
+
} from '../model/index.ts'
|
|
9
|
+
import type { HydratedBlockValidationError } from '../validation/index.ts'
|
|
10
|
+
|
|
11
|
+
export const BlockValidationQualificationZod = ChainQualificationZod
|
|
12
|
+
export type BlockValidationQualification = z.infer<typeof BlockValidationQualificationZod>
|
|
13
|
+
export const isBlockValidationQualification = zodIsFactory(BlockValidationQualificationZod)
|
|
14
|
+
|
|
15
|
+
export const BlockValidationConfigFieldsZod = z.object({
|
|
16
|
+
value: z.boolean().optional(),
|
|
17
|
+
state: z.boolean().optional(),
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
export const BlockValidationConfigZod = z.union([
|
|
21
|
+
BlockValidationConfigFieldsZod.extend(ChainQualifiedHeadConfigZod.shape),
|
|
22
|
+
BlockValidationConfigFieldsZod.extend(ChainQualifiedRangeConfigZod.shape),
|
|
23
|
+
BlockValidationConfigFieldsZod,
|
|
24
|
+
z.object({}),
|
|
25
|
+
])
|
|
26
|
+
|
|
27
|
+
export type BlockValidationConfig = z.infer<typeof BlockValidationConfigZod>
|
|
28
|
+
export const isBlockValidationConfig = zodIsFactory(BlockValidationConfigZod)
|
|
29
|
+
|
|
30
|
+
export interface BlockValidationViewerMethods {
|
|
31
|
+
qualifiedValidateBlocks(
|
|
32
|
+
blocks: HydratedBlock[],
|
|
33
|
+
config?: BlockValidationConfig
|
|
34
|
+
): Promisable<[HydratedBlockValidationError[], BlockValidationQualification]>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const BlockValidationViewerMoniker = 'BlockValidationViewer' as const
|
|
38
|
+
export type BlockValidationViewerMoniker = typeof BlockValidationViewerMoniker
|
|
39
|
+
|
|
40
|
+
export interface BlockValidationViewer extends BlockValidationViewerMethods, Provider<BlockValidationViewerMoniker> {
|
|
41
|
+
qualifiedValidateBlock(
|
|
42
|
+
block: SignedHydratedBlockWithHashMeta,
|
|
43
|
+
config?: BlockValidationConfig
|
|
44
|
+
): Promisable<[HydratedBlockValidationError[], BlockValidationQualification]>
|
|
45
|
+
validateBlock(block: SignedHydratedBlockWithHashMeta, config?: BlockValidationConfig): Promisable<HydratedBlockValidationError[]>
|
|
46
|
+
validateBlocks(blocks: SignedHydratedBlockWithHashMeta[], config?: BlockValidationConfig): Promisable<HydratedBlockValidationError[]>
|
|
47
|
+
}
|
|
@@ -3,10 +3,10 @@ import type {
|
|
|
3
3
|
} from '@xylabs/sdk-js'
|
|
4
4
|
import type { ChainStakeIntent, XL1BlockRange } from '@xyo-network/xl1-protocol'
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type { ChainQualified, Provider } from '../model/index.ts'
|
|
7
7
|
|
|
8
8
|
export interface StakeIntentViewerMethods {
|
|
9
|
-
qualifiedIntentByAddress(address: Address, headOrRange?: Hash | XL1BlockRange): Promisable<
|
|
9
|
+
qualifiedIntentByAddress(address: Address, headOrRange?: Hash | XL1BlockRange): Promisable<ChainQualified<ChainStakeIntent | null>>
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export const StakeIntentViewerMoniker = 'StakeIntentViewer' as const
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type Promisable } from '@xylabs/sdk-js'
|
|
2
|
+
import { zodIsFactory } from '@xylabs/zod'
|
|
3
|
+
import { type HydratedTransaction, type ValidationError } from '@xyo-network/xl1-protocol'
|
|
4
|
+
import type z from 'zod'
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ChainQualificationZod, ChainQualifiedConfigZod, type Provider,
|
|
8
|
+
} from '../model/index.ts'
|
|
9
|
+
|
|
10
|
+
export const TransactionValidationQualificationZod = ChainQualificationZod
|
|
11
|
+
export type TransactionValidationQualification = z.infer<typeof TransactionValidationQualificationZod>
|
|
12
|
+
export const isTransactionValidationQualification = zodIsFactory(TransactionValidationQualificationZod)
|
|
13
|
+
|
|
14
|
+
export const TransactionValidationConfigZod = ChainQualifiedConfigZod
|
|
15
|
+
export type TransactionValidationConfig = z.infer<typeof TransactionValidationConfigZod>
|
|
16
|
+
export const isTransactionValidationConfig = zodIsFactory(TransactionValidationConfigZod)
|
|
17
|
+
|
|
18
|
+
export interface TransactionValidationViewerMethods {
|
|
19
|
+
qualifiedValidateTransactions(
|
|
20
|
+
transactions: HydratedTransaction[],
|
|
21
|
+
config?: TransactionValidationConfig
|
|
22
|
+
): Promisable<[ValidationError[][], TransactionValidationQualification]>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const TransactionValidationViewerMoniker = 'TransactionValidationViewer' as const
|
|
26
|
+
export type TransactionValidationViewerMoniker = typeof TransactionValidationViewerMoniker
|
|
27
|
+
|
|
28
|
+
export interface TransactionValidationViewer extends TransactionValidationViewerMethods, Provider<TransactionValidationViewerMoniker> {
|
|
29
|
+
qualifiedValidateTransaction(
|
|
30
|
+
transaction: HydratedTransaction,
|
|
31
|
+
config?: TransactionValidationConfig
|
|
32
|
+
): Promisable<[ValidationError[], TransactionValidationQualification]>
|
|
33
|
+
validateTransaction(transaction: HydratedTransaction[], config?: TransactionValidationConfig): Promisable<ValidationError[]>
|
|
34
|
+
validateTransactions(transactions: HydratedTransaction[], config?: TransactionValidationConfig): Promisable<ValidationError[][]>
|
|
35
|
+
}
|