@xyo-network/chain-services 1.16.26 → 1.17.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/AccountBalance/BaseAccountBalanceService.d.ts +2 -3
- package/dist/neutral/AccountBalance/BaseAccountBalanceService.d.ts.map +1 -1
- package/dist/neutral/AccountBalance/accountBalanceServiceFromArchivist.d.ts.map +1 -1
- package/dist/neutral/BlockProducer/BaseBlockProducerService.d.ts +4 -4
- package/dist/neutral/BlockProducer/BaseBlockProducerService.d.ts.map +1 -1
- package/dist/neutral/ChainBlockNumberIteration/ChainBlockNumberIterationService.d.ts +20 -10
- package/dist/neutral/ChainBlockNumberIteration/ChainBlockNumberIterationService.d.ts.map +1 -1
- package/dist/neutral/ChainService/Evm/Evm.d.ts +4 -4
- package/dist/neutral/ChainService/Evm/Evm.d.ts.map +1 -1
- package/dist/neutral/ChainService/Memory/Memory.d.ts +4 -4
- package/dist/neutral/ChainService/Memory/Memory.d.ts.map +1 -1
- package/dist/neutral/ChainValidator/XyoValidator.d.ts +4 -4
- package/dist/neutral/ChainValidator/XyoValidator.d.ts.map +1 -1
- package/dist/neutral/Election/BaseElectionService.d.ts +3 -3
- package/dist/neutral/Election/BaseElectionService.d.ts.map +1 -1
- package/dist/neutral/PendingTransactions/BasePendingTransactions.d.ts +3 -4
- package/dist/neutral/PendingTransactions/BasePendingTransactions.d.ts.map +1 -1
- package/dist/neutral/StakeIntent/XyoStakeIntentService.d.ts +3 -3
- package/dist/neutral/StakeIntent/XyoStakeIntentService.d.ts.map +1 -1
- package/dist/neutral/Time/BaseTimeSyncService.d.ts +3 -6
- package/dist/neutral/Time/BaseTimeSyncService.d.ts.map +1 -1
- package/dist/neutral/blockViewerFromChainIteratorAndArchivist.d.ts.map +1 -1
- package/dist/neutral/index.mjs +115 -67
- package/dist/neutral/index.mjs.map +1 -1
- package/package.json +10 -10
- package/src/AccountBalance/BaseAccountBalanceService.ts +2 -4
- package/src/AccountBalance/accountBalanceServiceFromArchivist.ts +3 -2
- package/src/BlockProducer/BaseBlockProducerService.ts +5 -5
- package/src/ChainBlockNumberIteration/ChainBlockNumberIterationService.ts +61 -5
- package/src/ChainService/Evm/Evm.ts +34 -32
- package/src/ChainService/Memory/Memory.ts +9 -7
- package/src/ChainValidator/XyoValidator.ts +6 -6
- package/src/Election/BaseElectionService.ts +5 -4
- package/src/PendingTransactions/BasePendingTransactions.ts +6 -5
- package/src/StakeIntent/XyoStakeIntentService.ts +9 -13
- package/src/Time/BaseTimeSyncService.ts +6 -16
- package/src/blockViewerFromChainIteratorAndArchivist.ts +12 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@xyo-network/chain-services",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.17.0",
|
|
5
5
|
"description": "XYO Layer One SDK Services",
|
|
6
6
|
"homepage": "https://xylabs.com",
|
|
7
7
|
"bugs": {
|
|
@@ -48,17 +48,17 @@
|
|
|
48
48
|
"@xyo-network/boundwitness-model": "~5.2.10",
|
|
49
49
|
"@xyo-network/boundwitness-validator": "~5.2.10",
|
|
50
50
|
"@xyo-network/boundwitness-wrapper": "~5.2.10",
|
|
51
|
-
"@xyo-network/chain-analyze": "~1.
|
|
52
|
-
"@xyo-network/chain-modules": "~1.
|
|
53
|
-
"@xyo-network/chain-protocol": "~1.
|
|
54
|
-
"@xyo-network/chain-utils": "~1.
|
|
51
|
+
"@xyo-network/chain-analyze": "~1.17.0",
|
|
52
|
+
"@xyo-network/chain-modules": "~1.17.0",
|
|
53
|
+
"@xyo-network/chain-protocol": "~1.17.0",
|
|
54
|
+
"@xyo-network/chain-utils": "~1.17.0",
|
|
55
55
|
"@xyo-network/payload-builder": "~5.2.10",
|
|
56
56
|
"@xyo-network/payload-model": "~5.2.10",
|
|
57
57
|
"@xyo-network/typechain": "~4.0.10",
|
|
58
58
|
"@xyo-network/xl1-protocol": "~1.14.15",
|
|
59
|
-
"@xyo-network/xl1-protocol-sdk": "~1.
|
|
60
|
-
"@xyo-network/xl1-validation": "~1.
|
|
61
|
-
"@xyo-network/xl1-wrappers": "~1.
|
|
59
|
+
"@xyo-network/xl1-protocol-sdk": "~1.17.0",
|
|
60
|
+
"@xyo-network/xl1-validation": "~1.17.0",
|
|
61
|
+
"@xyo-network/xl1-wrappers": "~1.17.0",
|
|
62
62
|
"async-mutex": "~0.5.0",
|
|
63
63
|
"ethers": "6.15.0",
|
|
64
64
|
"lru-cache": "~11.2.2",
|
|
@@ -72,12 +72,12 @@
|
|
|
72
72
|
"@xylabs/vitest-extended": "~5.0.46",
|
|
73
73
|
"@xyo-network/account": "~5.2.10",
|
|
74
74
|
"@xyo-network/account-model": "~5.2.10",
|
|
75
|
-
"@xyo-network/chain-validation": "~1.
|
|
75
|
+
"@xyo-network/chain-validation": "~1.17.0",
|
|
76
76
|
"@xyo-network/wallet": "~5.2.10",
|
|
77
77
|
"eslint": "^9.39.1",
|
|
78
78
|
"tslib": "~2.8.1",
|
|
79
79
|
"typescript": "~5.9.3",
|
|
80
|
-
"vitest": "~4.0.
|
|
80
|
+
"vitest": "~4.0.14",
|
|
81
81
|
"vitest-mock-extended": "~3.1.0",
|
|
82
82
|
"web3-types": "~1.10.0"
|
|
83
83
|
},
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
balancesSummary,
|
|
11
11
|
BalanceStepSummaryContext,
|
|
12
12
|
BlockViewer,
|
|
13
|
-
EventingChainBlockNumberIteratorService,
|
|
14
13
|
SimpleAccountBalanceViewer,
|
|
15
14
|
TransfersStepSummaryContext,
|
|
16
15
|
} from '@xyo-network/xl1-protocol-sdk'
|
|
@@ -30,9 +29,8 @@ export const BaseAccountBalanceServiceParamsZod = z.object({
|
|
|
30
29
|
export interface BaseAccountBalanceServiceParams extends BaseServiceParams {
|
|
31
30
|
blockViewer: BlockViewer
|
|
32
31
|
chainArchivist: ReadArchivist
|
|
33
|
-
chainIterator: EventingChainBlockNumberIteratorService
|
|
34
32
|
context: BalanceStepSummaryContext
|
|
35
|
-
|
|
33
|
+
transfersSummaryContext: TransfersStepSummaryContext
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
@creatable()
|
|
@@ -93,7 +91,7 @@ export class BaseAccountBalanceService extends BaseService<BaseAccountBalanceSer
|
|
|
93
91
|
override async createHandler() {
|
|
94
92
|
this.accountBalanceViewer = await SimpleAccountBalanceViewer.create({
|
|
95
93
|
context: this.params.context,
|
|
96
|
-
|
|
94
|
+
transfersSummaryContext: this.params.transfersSummaryContext,
|
|
97
95
|
blockViewer: this.blockViewer,
|
|
98
96
|
})
|
|
99
97
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { Hash } from '@xylabs/sdk-js'
|
|
2
2
|
import { assertEx } from '@xylabs/sdk-js'
|
|
3
3
|
import type { ReadArchivist } from '@xyo-network/archivist-model'
|
|
4
|
-
import { findMostRecentBlock } from '@xyo-network/chain-protocol'
|
|
5
4
|
import type { Payload, WithStorageMeta } from '@xyo-network/payload-model'
|
|
6
5
|
import type { ChainId } from '@xyo-network/xl1-protocol'
|
|
7
6
|
import { StepSizes } from '@xyo-network/xl1-protocol'
|
|
8
7
|
import type { AccountBalanceViewer, BalancesStepSummary } from '@xyo-network/xl1-protocol-sdk'
|
|
9
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
findMostRecentBlock, LruCacheMap, readPayloadMapFromStore,
|
|
10
|
+
} from '@xyo-network/xl1-protocol-sdk'
|
|
10
11
|
import { Semaphore } from 'async-mutex'
|
|
11
12
|
|
|
12
13
|
import { BaseAccountBalanceService } from './BaseAccountBalanceService.ts'
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
Transfer, XYO_STEP_REWARD_ADDRESS,
|
|
16
16
|
} from '@xyo-network/xl1-protocol'
|
|
17
17
|
import {
|
|
18
|
-
AccountBalanceViewer, BlockProducerService, Config,
|
|
18
|
+
AccountBalanceViewer, BlockProducerService, Config, MempoolViewer, StakeIntentService, TimeSyncViewer,
|
|
19
19
|
} from '@xyo-network/xl1-protocol-sdk'
|
|
20
20
|
import z from 'zod'
|
|
21
21
|
|
|
@@ -49,7 +49,7 @@ export const BaseBlockProducerServiceParamsZod = z.object({
|
|
|
49
49
|
|
|
50
50
|
export interface BaseBlockProducerServiceParams extends XyoValidatorParams<Pick<Config, 'producer'>> {
|
|
51
51
|
balanceService: AccountBalanceViewer
|
|
52
|
-
pendingTransactionsService:
|
|
52
|
+
pendingTransactionsService: MempoolViewer
|
|
53
53
|
rejectedTransactionsArchivist: ArchivistInstance
|
|
54
54
|
rewardAddress: Address
|
|
55
55
|
time: TimeSyncViewer
|
|
@@ -94,8 +94,8 @@ export class BaseBlockProducerService extends BaseService<BaseBlockProducerServi
|
|
|
94
94
|
return assertEx(this.params.balanceService, () => 'balanceService is required')
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
protected get
|
|
98
|
-
return assertEx(this.params.
|
|
97
|
+
protected get blockViewer() {
|
|
98
|
+
return assertEx(this.params.blockViewer, () => 'blockViewer is required')
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
protected get chainId() {
|
|
@@ -203,7 +203,7 @@ export class BaseBlockProducerService extends BaseService<BaseBlockProducerServi
|
|
|
203
203
|
const { block: previousBlock } = assertEx(asBlockBoundWitness(head), () => 'Invalid head block')
|
|
204
204
|
const nextBlock = previousBlock + 1
|
|
205
205
|
const nextBlockTransactionsStart = Date.now()
|
|
206
|
-
const nextBlockTransactions = await this.pendingTransactionsService.
|
|
206
|
+
const nextBlockTransactions = await this.pendingTransactionsService.pendingTransactions({ limit: BaseBlockProducerService.DefaultBlockSize })
|
|
207
207
|
const nextBlockTransactionsDuration = Date.now() - nextBlockTransactionsStart
|
|
208
208
|
if (nextBlockTransactionsDuration > 200) {
|
|
209
209
|
this.logger?.warn(`[Slow] Fetched ${nextBlockTransactions.length} pending transactions in ${nextBlockTransactionsDuration}ms}`)
|
|
@@ -1,24 +1,30 @@
|
|
|
1
|
-
import type { Hex } from '@xylabs/sdk-js'
|
|
1
|
+
import type { Hash, Hex } from '@xylabs/sdk-js'
|
|
2
2
|
import {
|
|
3
3
|
assertEx,
|
|
4
4
|
isDefined, isNull, isUndefined,
|
|
5
5
|
} from '@xylabs/sdk-js'
|
|
6
6
|
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
7
7
|
import type { Payload, WithStorageMeta } from '@xyo-network/payload-model'
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
BlockBoundWitness, SignedHydratedBlockWithHashMeta, XL1BlockNumber,
|
|
10
|
+
} from '@xyo-network/xl1-protocol'
|
|
9
11
|
import {
|
|
10
|
-
asBlockBoundWitness, asBlockBoundWitnessWithStorageMeta, isBlockBoundWitnessWithHashMeta,
|
|
12
|
+
asBlockBoundWitness, asBlockBoundWitnessWithStorageMeta, asSignedHydratedBlockWithHashMeta, asXL1BlockNumber, isBlockBoundWitnessWithHashMeta,
|
|
11
13
|
} from '@xyo-network/xl1-protocol'
|
|
12
14
|
import type {
|
|
13
|
-
|
|
15
|
+
BlockViewer,
|
|
16
|
+
ChainIteratorServiceEventData,
|
|
17
|
+
ChainStoreRead,
|
|
18
|
+
PayloadMapRead,
|
|
14
19
|
} from '@xyo-network/xl1-protocol-sdk'
|
|
20
|
+
import { hydrateBlock } from '@xyo-network/xl1-protocol-sdk'
|
|
15
21
|
import { LRUCache } from 'lru-cache'
|
|
16
22
|
|
|
17
23
|
import { BaseService } from '../BaseService.ts'
|
|
18
24
|
import type { XyoChainIteratorParams } from './model/index.ts'
|
|
19
25
|
|
|
20
26
|
export class ChainBlockNumberIterationService extends BaseService<XyoChainIteratorParams, ChainIteratorServiceEventData>
|
|
21
|
-
implements
|
|
27
|
+
implements BlockViewer {
|
|
22
28
|
protected _blocksByBlockNumber = new LRUCache<number, WithStorageMeta<BlockBoundWitness>>({ max: 10_000 })
|
|
23
29
|
protected _currentHead: WithStorageMeta<BlockBoundWitness> | undefined
|
|
24
30
|
|
|
@@ -26,6 +32,56 @@ export class ChainBlockNumberIterationService extends BaseService<XyoChainIterat
|
|
|
26
32
|
|
|
27
33
|
get chainMap(): PayloadMapRead<WithStorageMeta<Payload>> { return assertEx(this.params.chainMap) }
|
|
28
34
|
|
|
35
|
+
get chainStoreRead() {
|
|
36
|
+
return { chainMap: this.chainMap } satisfies ChainStoreRead
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async blockByHash(hash: Hash): Promise<SignedHydratedBlockWithHashMeta | null> {
|
|
40
|
+
return asSignedHydratedBlockWithHashMeta(await hydrateBlock(this.chainStoreRead, hash)) ?? null
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async blockByNumber(block: XL1BlockNumber): Promise<SignedHydratedBlockWithHashMeta | null> {
|
|
44
|
+
return asSignedHydratedBlockWithHashMeta(await this.get(block)) ?? null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async blocksByHash(hash: Hash, limit: number = 100): Promise<SignedHydratedBlockWithHashMeta[]> {
|
|
48
|
+
const results: SignedHydratedBlockWithHashMeta[] = []
|
|
49
|
+
let currentBlock = await this.blockByHash(hash)
|
|
50
|
+
while (currentBlock !== null && (isUndefined(limit) || results.length < limit)) {
|
|
51
|
+
results.push(currentBlock)
|
|
52
|
+
const previousHash = currentBlock[0].previous
|
|
53
|
+
if (isNull(previousHash)) break
|
|
54
|
+
currentBlock = await this.blockByHash(previousHash)
|
|
55
|
+
}
|
|
56
|
+
return results
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async blocksByNumber(blockNumber: XL1BlockNumber, limit: number = 100): Promise<SignedHydratedBlockWithHashMeta[]> {
|
|
60
|
+
const results: SignedHydratedBlockWithHashMeta[] = []
|
|
61
|
+
let currentBlock = await this.blockByNumber(blockNumber)
|
|
62
|
+
while (currentBlock !== null && (isUndefined(limit) || results.length < limit)) {
|
|
63
|
+
results.push(currentBlock)
|
|
64
|
+
if (currentBlock[0].block === 0) break
|
|
65
|
+
const previousNumber = asXL1BlockNumber(currentBlock[0].block - 1, true)
|
|
66
|
+
currentBlock = await this.blockByNumber(previousNumber)
|
|
67
|
+
}
|
|
68
|
+
return results
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async currentBlock(): Promise<SignedHydratedBlockWithHashMeta> {
|
|
72
|
+
return assertEx(await this.blockByHash(await this.currentBlockHash()), () => 'Current block not found')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async currentBlockHash(): Promise<Hash> {
|
|
76
|
+
const head = assertEx(await this.head(), () => 'Head is not set')
|
|
77
|
+
return head._hash
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async currentBlockNumber(): Promise<XL1BlockNumber> {
|
|
81
|
+
const head = assertEx(await this.head(), () => 'Head is not set')
|
|
82
|
+
return head.block
|
|
83
|
+
}
|
|
84
|
+
|
|
29
85
|
async get(block: number): Promise<WithStorageMeta<BlockBoundWitness>> {
|
|
30
86
|
const head = await this.head()
|
|
31
87
|
// if(isUndefined(head)) return undefined
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Address, Hex, Promisable,
|
|
3
|
+
} from '@xylabs/sdk-js'
|
|
2
4
|
import {
|
|
3
5
|
assertEx, toAddress, toEthAddress,
|
|
4
6
|
} from '@xylabs/sdk-js'
|
|
@@ -13,7 +15,7 @@ import type { BaseServiceParams } from '../../model/index.ts'
|
|
|
13
15
|
|
|
14
16
|
export interface EvmChainServiceParams extends BaseServiceParams {
|
|
15
17
|
contract: StakedXyoChain
|
|
16
|
-
id:
|
|
18
|
+
id: Hex
|
|
17
19
|
runner: ContractRunner
|
|
18
20
|
}
|
|
19
21
|
|
|
@@ -21,91 +23,91 @@ export interface EvmChainServiceParams extends BaseServiceParams {
|
|
|
21
23
|
* A class that represents a chain stake as backed by an EVM smart contract
|
|
22
24
|
*/
|
|
23
25
|
export class EvmChainService extends BaseService<EvmChainServiceParams> implements ChainService {
|
|
24
|
-
get chainId(): Address {
|
|
25
|
-
return assertEx(this.params.id)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
get contract() {
|
|
29
|
-
if (this.params.contract === undefined) {
|
|
30
|
-
this.params.contract = StakedXyoChainFactory.connect(
|
|
31
|
-
toEthAddress(this.chainId),
|
|
32
|
-
this.params.runner,
|
|
33
|
-
) as StakedXyoChain
|
|
34
|
-
}
|
|
35
|
-
return assertEx(this.params.contract)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
26
|
get runner(): ContractRunner {
|
|
39
27
|
return assertEx(this.params.runner)
|
|
40
28
|
}
|
|
41
29
|
|
|
42
30
|
async active(): Promise<bigint> {
|
|
43
|
-
return await this.contract.active()
|
|
31
|
+
return await (await this.contract()).active()
|
|
44
32
|
}
|
|
45
33
|
|
|
46
34
|
async activeByStaked(staked: Address): Promise<bigint> {
|
|
47
|
-
return await this.contract.activeByAddressStaked(getAddress(toEthAddress(staked)))
|
|
35
|
+
return await (await this.contract()).activeByAddressStaked(getAddress(toEthAddress(staked)))
|
|
48
36
|
}
|
|
49
37
|
|
|
50
38
|
async activeByStaker(address: Address): Promise<bigint> {
|
|
51
|
-
return await this.contract.activeByStaker(getAddress(toEthAddress(address)))
|
|
39
|
+
return await (await this.contract()).activeByStaker(getAddress(toEthAddress(address)))
|
|
52
40
|
}
|
|
53
41
|
|
|
54
42
|
async addStake(staked: Address, amount: bigint): Promise<boolean> {
|
|
55
|
-
const result = await this.contract.addStake(getAddress(toEthAddress(staked)), amount)
|
|
43
|
+
const result = await (await this.contract()).addStake(getAddress(toEthAddress(staked)), amount)
|
|
56
44
|
await result.wait()
|
|
57
45
|
return true
|
|
58
46
|
}
|
|
59
47
|
|
|
48
|
+
chainId(): Promisable<Hex> {
|
|
49
|
+
return assertEx(this.params.id)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async contract() {
|
|
53
|
+
if (this.params.contract === undefined) {
|
|
54
|
+
this.params.contract = StakedXyoChainFactory.connect(
|
|
55
|
+
toEthAddress(await this.chainId()),
|
|
56
|
+
this.params.runner,
|
|
57
|
+
) as StakedXyoChain
|
|
58
|
+
}
|
|
59
|
+
return assertEx(this.params.contract)
|
|
60
|
+
}
|
|
61
|
+
|
|
60
62
|
async forkedAtBlockNumber(): Promise<bigint> {
|
|
61
|
-
return await this.contract.forkedAtBlockNumber()
|
|
63
|
+
return await (await this.contract()).forkedAtBlockNumber()
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
async forkedAtHash(): Promise<bigint> {
|
|
65
|
-
return await this.contract.forkedAtHash()
|
|
67
|
+
return await (await this.contract()).forkedAtHash()
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
async forkedChainId(): Promise<Address> {
|
|
69
|
-
return toAddress(await this.contract.forkedChainId())
|
|
71
|
+
return toAddress(await (await this.contract()).forkedChainId())
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
async minWithdrawalBlocks(): Promise<bigint> {
|
|
73
|
-
return await this.contract.minWithdrawalBlocks()
|
|
75
|
+
return await (await this.contract()).minWithdrawalBlocks()
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
async pending(): Promise<bigint> {
|
|
77
|
-
return await this.contract.pending()
|
|
79
|
+
return await (await this.contract()).pending()
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
async pendingByStaker(staker: Address): Promise<bigint> {
|
|
81
|
-
return await this.contract.pendingByStaker(getAddress(toEthAddress(staker)))
|
|
83
|
+
return await (await this.contract()).pendingByStaker(getAddress(toEthAddress(staker)))
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
async removeStake(slot: bigint): Promise<boolean> {
|
|
85
|
-
const result = await this.contract.removeStake(slot)
|
|
87
|
+
const result = await (await this.contract()).removeStake(slot)
|
|
86
88
|
await result.wait()
|
|
87
89
|
return true
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
async rewardsContract(): Promise<string> {
|
|
91
|
-
return await this.contract.rewardsContract()
|
|
93
|
+
return await (await this.contract()).rewardsContract()
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
async stakingTokenAddress(): Promise<string> {
|
|
95
|
-
return await this.contract.stakingTokenAddress()
|
|
97
|
+
return await (await this.contract()).stakingTokenAddress()
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
async withdrawStake(slot: bigint): Promise<boolean> {
|
|
99
|
-
const result = await this.contract.withdrawStake(slot)
|
|
101
|
+
const result = await (await this.contract()).withdrawStake(slot)
|
|
100
102
|
await result.wait()
|
|
101
103
|
return true
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
async withdrawn(): Promise<bigint> {
|
|
105
|
-
return await this.contract.withdrawn()
|
|
107
|
+
return await (await this.contract()).withdrawn()
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
async withdrawnByStaker(staker: string): Promise<bigint> {
|
|
109
|
-
return await this.contract.withdrawnByStaker(getAddress(staker))
|
|
111
|
+
return await (await this.contract()).withdrawnByStaker(getAddress(staker))
|
|
110
112
|
}
|
|
111
113
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Address, Hex, Promisable,
|
|
3
|
+
} from '@xylabs/sdk-js'
|
|
2
4
|
import {
|
|
3
5
|
assertEx, toAddress, ZERO_ADDRESS,
|
|
4
6
|
} from '@xylabs/sdk-js'
|
|
@@ -8,20 +10,16 @@ import { BaseService } from '../../BaseService.ts'
|
|
|
8
10
|
import type { BaseServiceParams } from '../../model/index.ts'
|
|
9
11
|
|
|
10
12
|
export interface MemoryChainServiceParams extends BaseServiceParams<Pick<Config, 'producer'>> {
|
|
11
|
-
chainId:
|
|
13
|
+
chainId: Hex
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* A class that represents a chain stake as backed in memory
|
|
16
18
|
*/
|
|
17
19
|
export class MemoryChainService extends BaseService<MemoryChainServiceParams> implements ChainService {
|
|
18
|
-
protected _chainId:
|
|
20
|
+
protected _chainId: Hex | undefined
|
|
19
21
|
protected _simulatedStake: bigint = 1n
|
|
20
22
|
|
|
21
|
-
get chainId(): Address {
|
|
22
|
-
return assertEx(this._chainId, () => 'Chain ID not set')
|
|
23
|
-
}
|
|
24
|
-
|
|
25
23
|
async active(): Promise<bigint> {
|
|
26
24
|
return await Promise.resolve(this._simulatedStake)
|
|
27
25
|
}
|
|
@@ -38,6 +36,10 @@ export class MemoryChainService extends BaseService<MemoryChainServiceParams> im
|
|
|
38
36
|
return await Promise.resolve(true)
|
|
39
37
|
}
|
|
40
38
|
|
|
39
|
+
chainId(): Promisable<Hex> {
|
|
40
|
+
return assertEx(this._chainId, () => 'Chain ID not set')
|
|
41
|
+
}
|
|
42
|
+
|
|
41
43
|
override createHandler(): void {
|
|
42
44
|
const { minStake = 1 } = this.params.config.producer ?? {}
|
|
43
45
|
this._simulatedStake = BigInt(minStake)
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
Promisable,
|
|
4
4
|
} from '@xylabs/sdk-js'
|
|
5
5
|
import { AccountInstance } from '@xyo-network/account-model'
|
|
6
|
-
import { ArchivistInstance
|
|
6
|
+
import { ArchivistInstance } from '@xyo-network/archivist-model'
|
|
7
7
|
import {
|
|
8
8
|
BlockBoundWitness,
|
|
9
9
|
ChainId,
|
|
10
10
|
SignedHydratedTransactionWithStorageMeta,
|
|
11
11
|
} from '@xyo-network/xl1-protocol'
|
|
12
12
|
import {
|
|
13
|
-
BlockRewardService, ElectionService, HydratedBlockStateValidationFunction, StakeIntentService,
|
|
13
|
+
BlockRewardService, BlockViewer, ElectionService, HydratedBlockStateValidationFunction, StakeIntentService,
|
|
14
14
|
} from '@xyo-network/xl1-protocol-sdk'
|
|
15
15
|
|
|
16
16
|
import { BaseService } from '../BaseService.ts'
|
|
@@ -19,7 +19,7 @@ import { Validator } from './model/index.ts'
|
|
|
19
19
|
|
|
20
20
|
export interface XyoValidatorParams<TConfig extends EmptyObject = EmptyObject> extends BaseServiceParams<TConfig> {
|
|
21
21
|
account: AccountInstance
|
|
22
|
-
|
|
22
|
+
blockViewer: BlockViewer
|
|
23
23
|
chainId: ChainId
|
|
24
24
|
electionService: ElectionService
|
|
25
25
|
pendingBundledTransactionsArchivist: ArchivistInstance
|
|
@@ -38,8 +38,8 @@ export class XyoValidator<TParams extends XyoValidatorParams = XyoValidatorParam
|
|
|
38
38
|
return assertEx(this.params.account, () => 'account is required')
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
protected get
|
|
42
|
-
return assertEx(this.params.
|
|
41
|
+
protected get blockViewer() {
|
|
42
|
+
return assertEx(this.params.blockViewer, () => 'blockViewer is required')
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
protected get chainInfo() {
|
|
@@ -66,7 +66,7 @@ export class XyoValidator<TParams extends XyoValidatorParams = XyoValidatorParam
|
|
|
66
66
|
async validatePendingTransaction(hydratedTransaction: SignedHydratedTransactionWithStorageMeta): Promise<boolean> {
|
|
67
67
|
const [tx] = hydratedTransaction
|
|
68
68
|
// Ensure not confirmed already (replay attack)
|
|
69
|
-
if ((await this.
|
|
69
|
+
if ((await this.blockViewer.blockByHash(tx._hash)) !== undefined) return false
|
|
70
70
|
// TODO: Ensure transaction is valid (double spend, has voucher, has required stake, etc.)
|
|
71
71
|
// TODO: Ensure validator stake is valid
|
|
72
72
|
return await Promise.resolve(true)
|
|
@@ -5,22 +5,23 @@ import { hexToLast4BytesInt, shuffleWithSeed } from '@xyo-network/chain-utils'
|
|
|
5
5
|
import { WithHashMeta } from '@xyo-network/payload-model'
|
|
6
6
|
import { BlockBoundWitness } from '@xyo-network/xl1-protocol'
|
|
7
7
|
import type {
|
|
8
|
-
|
|
8
|
+
BlockViewer,
|
|
9
|
+
ChainStakeViewer, ElectionService, StakeIntentService,
|
|
9
10
|
} from '@xyo-network/xl1-protocol-sdk'
|
|
10
11
|
|
|
11
12
|
import { BaseService } from '../BaseService.ts'
|
|
12
13
|
import { BaseServiceParams } from '../model/index.ts'
|
|
13
14
|
|
|
14
15
|
export interface BaseElectionServicesParams extends BaseServiceParams {
|
|
15
|
-
|
|
16
|
+
blockViewer?: BlockViewer
|
|
16
17
|
chainStakeViewer?: ChainStakeViewer
|
|
17
18
|
stakeIntentService?: StakeIntentService
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
@creatable()
|
|
21
22
|
export class BaseElectionService extends BaseService<BaseElectionServicesParams> implements ElectionService {
|
|
22
|
-
get
|
|
23
|
-
return assertEx(this.params.
|
|
23
|
+
get blockViewer() {
|
|
24
|
+
return assertEx(this.params.blockViewer, () => 'No block viewer')
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
get chainStakeViewer() {
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
} from '@xylabs/sdk-js'
|
|
8
8
|
import { MemoryArchivist } from '@xyo-network/archivist-memory'
|
|
9
9
|
import { ArchivistInstance } from '@xyo-network/archivist-model'
|
|
10
|
-
import { findMostRecentBlock } from '@xyo-network/chain-protocol'
|
|
11
10
|
import {
|
|
12
11
|
Payload, PayloadBundle, Sequence, WithStorageMeta,
|
|
13
12
|
} from '@xyo-network/payload-model'
|
|
@@ -17,7 +16,9 @@ import {
|
|
|
17
16
|
SignedHydratedTransactionWithStorageMeta,
|
|
18
17
|
XL1BlockNumber,
|
|
19
18
|
} from '@xyo-network/xl1-protocol'
|
|
20
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
findMostRecentBlock, MempoolViewer, PendingTransactionsOptions,
|
|
21
|
+
} from '@xyo-network/xl1-protocol-sdk'
|
|
21
22
|
import { TransactionJsonSchemaValidator, validateTransaction } from '@xyo-network/xl1-validation'
|
|
22
23
|
import { Mutex } from 'async-mutex'
|
|
23
24
|
|
|
@@ -35,7 +36,7 @@ export interface BasePendingTransactionsServiceParams extends BaseServiceParams
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
@creatable()
|
|
38
|
-
export class BasePendingTransactionsService extends BaseService<BasePendingTransactionsServiceParams> implements
|
|
39
|
+
export class BasePendingTransactionsService extends BaseService<BasePendingTransactionsServiceParams> implements MempoolViewer {
|
|
39
40
|
private static readonly MutexPriority = {
|
|
40
41
|
/**
|
|
41
42
|
* Priority for inserting new transactions
|
|
@@ -142,12 +143,12 @@ export class BasePendingTransactionsService extends BaseService<BasePendingTrans
|
|
|
142
143
|
})
|
|
143
144
|
}
|
|
144
145
|
|
|
145
|
-
async
|
|
146
|
+
async pendingTransactions({ limit = 100 }: PendingTransactionsOptions = {}): Promise<SignedHydratedTransactionWithStorageMeta[]> {
|
|
146
147
|
return await this.spanAsync('getPendingTransactions', async () => {
|
|
147
148
|
// Acquires an exclusive mutex to ensure no race conditions while accessing pending transactions.
|
|
148
149
|
return await this._updateCuratedPendingTransactionsArchivistMutex.runExclusive(async () => {
|
|
149
150
|
// Find the supplied head
|
|
150
|
-
let
|
|
151
|
+
let lastHead = (filterAs(await this.chainArchivist.next({ limit: 100 }), x => asBlockBoundWitnessWithHashMeta(x))).at(-1)
|
|
151
152
|
if (isUndefined(lastHead)) return []
|
|
152
153
|
|
|
153
154
|
await this.pruneCuratedPendingTransactionsArchivist(lastHead._hash)
|
|
@@ -19,9 +19,9 @@ import {
|
|
|
19
19
|
} from '@xyo-network/xl1-protocol'
|
|
20
20
|
import {
|
|
21
21
|
asChainIndexingServiceStateWithStorageMeta,
|
|
22
|
+
BlockViewer,
|
|
22
23
|
ChainIndexingServiceState, ChainIndexingServiceStateSchema, ChainStakeViewer,
|
|
23
24
|
Config,
|
|
24
|
-
EventingChainBlockNumberIteratorService,
|
|
25
25
|
isChainIndexingServiceState,
|
|
26
26
|
readPayloadMapFromStore,
|
|
27
27
|
StakeIntentService,
|
|
@@ -34,8 +34,8 @@ import { BaseService } from '../BaseService.ts'
|
|
|
34
34
|
import { BaseServiceParams } from '../model/index.ts'
|
|
35
35
|
|
|
36
36
|
export interface XyoStakeIntentServiceParams extends BaseServiceParams<Pick<Config, 'producer'>> {
|
|
37
|
+
blockViewer?: BlockViewer
|
|
37
38
|
chainArchivist?: ArchivistInstance
|
|
38
|
-
chainIterator?: EventingChainBlockNumberIteratorService
|
|
39
39
|
chainStakeViewer?: ChainStakeViewer
|
|
40
40
|
stakeIntentStateArchivist?: ArchivistInstance
|
|
41
41
|
}
|
|
@@ -65,12 +65,12 @@ export class XyoStakeIntentService extends BaseService<XyoStakeIntentServicePara
|
|
|
65
65
|
protected _stakeCache = new LRUCache<Address, bigint>({ max: STAKE_CACHE_MAX_ENTRIES })
|
|
66
66
|
protected _updateMutex = new Mutex()
|
|
67
67
|
|
|
68
|
-
protected get
|
|
69
|
-
return assertEx(this.params.
|
|
68
|
+
protected get blockViewer() {
|
|
69
|
+
return assertEx(this.params.blockViewer, () => 'blockViewer not set')
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
protected get
|
|
73
|
-
return assertEx(this.params.
|
|
72
|
+
protected get chainArchivist() {
|
|
73
|
+
return assertEx(this.params.chainArchivist, () => 'chainArchivist not set')
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
protected get chainStakeViewer() {
|
|
@@ -82,13 +82,9 @@ export class XyoStakeIntentService extends BaseService<XyoStakeIntentServicePara
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
override async createHandler() {
|
|
85
|
-
this.
|
|
86
|
-
await this.updateIndex()
|
|
87
|
-
})
|
|
88
|
-
const head = await this.chainIterator.head()
|
|
85
|
+
const head = await this.blockViewer.currentBlock()
|
|
89
86
|
if (isUndefined(head)) return
|
|
90
|
-
|
|
91
|
-
await this.recoverState(headHash)
|
|
87
|
+
await this.recoverState(head[0]._hash)
|
|
92
88
|
}
|
|
93
89
|
|
|
94
90
|
async getDeclaredCandidateRanges(address: Address, intent: Intent): Promise<Readonly<Readonly<[number, number]>[]>> {
|
|
@@ -208,7 +204,7 @@ export class XyoStakeIntentService extends BaseService<XyoStakeIntentServicePara
|
|
|
208
204
|
}
|
|
209
205
|
await this._updateMutex.runExclusive(async () => {
|
|
210
206
|
return await this.spanAsync('updateIndex', async () => {
|
|
211
|
-
const currentHead = await this.
|
|
207
|
+
const currentHead = (await this.blockViewer.currentBlock())[0]
|
|
212
208
|
if (isUndefined(currentHead)) return
|
|
213
209
|
return await timeBudget('XyoStakeIntentService.updateIndex', console, async () => {
|
|
214
210
|
const currentHeadHash = currentHead._hash
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { creatable, EmptyObject } from '@xylabs/sdk-js'
|
|
2
|
-
import { ReadArchivist } from '@xyo-network/archivist-model'
|
|
3
2
|
import { TimeDomain, TimePayload } from '@xyo-network/xl1-protocol'
|
|
4
3
|
import {
|
|
5
|
-
|
|
4
|
+
BlockViewer,
|
|
5
|
+
SimpleTimeSyncViewer, TimeSyncViewer,
|
|
6
6
|
} from '@xyo-network/xl1-protocol-sdk'
|
|
7
7
|
import { Provider } from 'ethers'
|
|
8
8
|
|
|
9
9
|
import { BaseService } from '../BaseService.ts'
|
|
10
|
-
import { blockViewerFromChainIteratorAndArchivist } from '../blockViewerFromChainIteratorAndArchivist.ts'
|
|
11
10
|
import { BaseServiceParams } from '../model/index.ts'
|
|
12
11
|
|
|
13
12
|
export interface BaseTimeServiceParams<TConfig extends EmptyObject = EmptyObject> extends BaseServiceParams<TConfig> {
|
|
14
|
-
|
|
15
|
-
chainIterator: EventingChainBlockNumberIteratorService
|
|
13
|
+
blockViewer: BlockViewer
|
|
16
14
|
ethProvider?: Provider
|
|
17
15
|
}
|
|
18
16
|
|
|
@@ -20,12 +18,8 @@ export interface BaseTimeServiceParams<TConfig extends EmptyObject = EmptyObject
|
|
|
20
18
|
export class BaseTimeSyncService extends BaseService<BaseTimeServiceParams> implements TimeSyncViewer {
|
|
21
19
|
protected timeSyncViewer!: TimeSyncViewer
|
|
22
20
|
|
|
23
|
-
protected get
|
|
24
|
-
return this.params.
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
protected get chainIterator() {
|
|
28
|
-
return this.params.chainIterator
|
|
21
|
+
protected get blockViewer() {
|
|
22
|
+
return this.params.blockViewer
|
|
29
23
|
}
|
|
30
24
|
|
|
31
25
|
protected get ethProvider() {
|
|
@@ -38,11 +32,7 @@ export class BaseTimeSyncService extends BaseService<BaseTimeServiceParams> impl
|
|
|
38
32
|
|
|
39
33
|
override async createHandler(): Promise<void> {
|
|
40
34
|
await super.createHandler()
|
|
41
|
-
|
|
42
|
-
this.chainIterator,
|
|
43
|
-
this.chainArchivist,
|
|
44
|
-
)
|
|
45
|
-
this.timeSyncViewer = new SimpleTimeSyncViewer(blockViewer, this.ethProvider)
|
|
35
|
+
this.timeSyncViewer = new SimpleTimeSyncViewer(this.blockViewer, this.ethProvider)
|
|
46
36
|
}
|
|
47
37
|
|
|
48
38
|
async currentTime(domain: TimeDomain): Promise<[string, number]> {
|
|
@@ -44,6 +44,18 @@ export function blockViewerFromChainIteratorAndArchivist(
|
|
|
44
44
|
}
|
|
45
45
|
return results
|
|
46
46
|
},
|
|
47
|
+
blocksByNumber: async function (number: XL1BlockNumber, limit = 10): Promise<SignedHydratedBlockWithHashMeta[]> {
|
|
48
|
+
const results: SignedHydratedBlockWithHashMeta[] = []
|
|
49
|
+
for (let i = 0; i < limit; i++) {
|
|
50
|
+
const block = await this.blockByNumber(number)
|
|
51
|
+
if (block) {
|
|
52
|
+
results.push(block)
|
|
53
|
+
} else {
|
|
54
|
+
break
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return results
|
|
58
|
+
},
|
|
47
59
|
currentBlock: async function (): Promise<SignedHydratedBlockWithHashMeta> {
|
|
48
60
|
const head = await chainIterator.head()
|
|
49
61
|
return this.blockByHash(head._hash) as Promise<SignedHydratedBlockWithHashMeta>
|