@xyo-network/chain-producer 1.17.1 → 1.17.3
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/node/ProducerActor.d.ts +12 -0
- package/dist/node/ProducerActor.d.ts.map +1 -1
- package/dist/node/index.mjs +25 -1
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/runProducer.d.ts +1 -1
- package/dist/node/runProducer.d.ts.map +1 -1
- package/package.json +19 -19
- package/src/ProducerActor.ts +2 -0
- package/src/runProducer.ts +28 -8
|
@@ -42,9 +42,21 @@ export declare class ProducerActor extends Actor<ProducerActorParams> {
|
|
|
42
42
|
mnemonic?: string | undefined;
|
|
43
43
|
};
|
|
44
44
|
bridge: {
|
|
45
|
+
chainRpcApiUrl: string;
|
|
46
|
+
feeFixed: import("@xylabs/sdk-js").Hex;
|
|
47
|
+
feeRateBasisPoints: number;
|
|
45
48
|
host: string;
|
|
49
|
+
maxBridgeAmount: import("@xylabs/sdk-js").Hex;
|
|
50
|
+
minBridgeAmount: import("@xylabs/sdk-js").Hex;
|
|
46
51
|
port: number;
|
|
52
|
+
remoteBridgeContractAddress: import("@xylabs/sdk-js").Address;
|
|
53
|
+
remoteChainId: import("@xylabs/sdk-js").Hex;
|
|
54
|
+
remoteTokenAddress: import("@xylabs/sdk-js").Hex;
|
|
55
|
+
escrowAddress?: import("@xylabs/sdk-js").Address | undefined;
|
|
56
|
+
feesAddress?: import("@xylabs/sdk-js").Address | undefined;
|
|
47
57
|
mnemonic?: string | undefined;
|
|
58
|
+
xl1ChainId?: import("@xylabs/sdk-js").Hex | undefined;
|
|
59
|
+
xl1TokenAddress?: import("@xylabs/sdk-js").Hex | undefined;
|
|
48
60
|
};
|
|
49
61
|
chain: {
|
|
50
62
|
id?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProducerActor.d.ts","sourceRoot":"","sources":["../../src/ProducerActor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAMnD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,EAAE,KAAK,EAAE,KAAK,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAG1E,OAAO,KAAK,EACV,OAAO,EACP,gBAAgB,EAAE,yBAAyB,EAC3C,cAAc,EACf,MAAM,2BAA2B,CAAA;AAElC,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EAAE,iBAAiB,EAAE,WAAW,EACpD,MAAM,EACN,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,cAAc,EACf,MAAM,+BAA+B,CAAA;AAGtC,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC;IAC5C,OAAO,EAAE,eAAe,CAAA;IACxB,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QACP,aAAa,EAAE,aAAa,CAAA;KAC7B,CAAA;IACD,OAAO,EAAE;QACP,oBAAoB,EAAE,oBAAoB,CAAA;QAC1C,WAAW,EAAE,WAAW,CAAA;QACxB,aAAa,EAAE,aAAa,CAAA;QAC5B,iBAAiB,EAAE,iBAAiB,CAAA;QACpC,IAAI,EAAE,cAAc,CAAA;KACrB,CAAA;CACF,CAAC,CAAA;AAKF,qBACa,aAAc,SAAQ,KAAK,CAAC,mBAAmB,CAAC;IAC3D,SAAS,CAAC,kBAAkB,EAAE,yBAAyB,GAAG,SAAS,CAAA;IACnE,SAAS,CAAC,wBAAwB,EAAE,gBAAgB,GAAG,SAAS,CAAA;IAChE,SAAS,CAAC,iBAAiB,EAAE,UAAU,GAAG,SAAS,CAAA;IACnD,SAAS,CAAC,qCAAqC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAA;IAChF,SAAS,CAAC,mCAAmC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAA;IAC9E,SAAS,CAAC,4BAA4B,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAA;IACvE,SAAS,CAAC,6BAA6B,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAA;IAExE,OAAO,CAAC,kBAAkB,CAAc;IACxC,OAAO,CAAC,SAAS,CAAkC;IAEnD,SAAS,KAAK,OAAO,oBAEpB;IAED,SAAS,KAAK,oBAAoB,yBAEjC;IAED,SAAS,KAAK,WAAW,gBAExB;IAED,SAAS,KAAK,OAAO,iCAEpB;IAED,SAAS,KAAK,MAAM
|
|
1
|
+
{"version":3,"file":"ProducerActor.d.ts","sourceRoot":"","sources":["../../src/ProducerActor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAMnD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,EAAE,KAAK,EAAE,KAAK,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAG1E,OAAO,KAAK,EACV,OAAO,EACP,gBAAgB,EAAE,yBAAyB,EAC3C,cAAc,EACf,MAAM,2BAA2B,CAAA;AAElC,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EAAE,iBAAiB,EAAE,WAAW,EACpD,MAAM,EACN,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,cAAc,EACf,MAAM,+BAA+B,CAAA;AAGtC,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC;IAC5C,OAAO,EAAE,eAAe,CAAA;IACxB,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QACP,aAAa,EAAE,aAAa,CAAA;KAC7B,CAAA;IACD,OAAO,EAAE;QACP,oBAAoB,EAAE,oBAAoB,CAAA;QAC1C,WAAW,EAAE,WAAW,CAAA;QACxB,aAAa,EAAE,aAAa,CAAA;QAC5B,iBAAiB,EAAE,iBAAiB,CAAA;QACpC,IAAI,EAAE,cAAc,CAAA;KACrB,CAAA;CACF,CAAC,CAAA;AAKF,qBACa,aAAc,SAAQ,KAAK,CAAC,mBAAmB,CAAC;IAC3D,SAAS,CAAC,kBAAkB,EAAE,yBAAyB,GAAG,SAAS,CAAA;IACnE,SAAS,CAAC,wBAAwB,EAAE,gBAAgB,GAAG,SAAS,CAAA;IAChE,SAAS,CAAC,iBAAiB,EAAE,UAAU,GAAG,SAAS,CAAA;IACnD,SAAS,CAAC,qCAAqC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAA;IAChF,SAAS,CAAC,mCAAmC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAA;IAC9E,SAAS,CAAC,4BAA4B,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAA;IACvE,SAAS,CAAC,6BAA6B,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAA;IAExE,OAAO,CAAC,kBAAkB,CAAc;IACxC,OAAO,CAAC,SAAS,CAAkC;IAEnD,SAAS,KAAK,OAAO,oBAEpB;IAED,SAAS,KAAK,oBAAoB,yBAEjC;IAED,SAAS,KAAK,WAAW,gBAExB;IAED,SAAS,KAAK,OAAO,iCAEpB;IAED,SAAS,KAAK,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAEnB;IAED,SAAS,KAAK,aAAa,kBAE1B;IAED,SAAS,KAAK,aAAa,kBAE1B;IAED,SAAS,KAAK,QAAQ,yBAErB;IAED,SAAS,KAAK,iBAAiB,sBAE9B;WAEqB,aAAa,CAAC,CAAC,SAAS,WAAW,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;;;;;;;;;IAI/D,aAAa;IAuCb,YAAY;cAiCX,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;cA8C7B,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;cAiEhC,yBAAyB,CAAC,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;cAkB7G,sBAAsB,IAAI,OAAO,CAAC,OAAO,CAAC;cAe1C,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;CAWzD"}
|
package/dist/node/index.mjs
CHANGED
|
@@ -157,6 +157,8 @@ var ProducerActor = class extends Actor {
|
|
|
157
157
|
this.logger?.log("Published block:", displayBlockNumber, nextBlock[0].block);
|
|
158
158
|
this._producerActorBlocksPublished?.add(1, this._metricAttributes);
|
|
159
159
|
this._lastProducedBlock = nextBlock;
|
|
160
|
+
} else {
|
|
161
|
+
this.logger?.log("No block produced at this time.");
|
|
160
162
|
}
|
|
161
163
|
}
|
|
162
164
|
});
|
|
@@ -229,6 +231,7 @@ ProducerActor = _ts_decorate([
|
|
|
229
231
|
import { assertEx, exists } from "@xylabs/sdk-js";
|
|
230
232
|
import { initProducerAccount } from "@xyo-network/chain-orchestration";
|
|
231
233
|
import { initBlockRewardViewer, initChainService, initTimeService } from "@xyo-network/chain-services";
|
|
234
|
+
import { ChainContractViewerMoniker } from "@xyo-network/xl1-protocol-sdk";
|
|
232
235
|
import { AccountBalanceViewerRpcSchemas, BlockViewerRpcSchemas, HttpRpcTransport, JsonRpcAccountBalanceViewer, JsonRpcBlockViewer, JsonRpcMempoolRunner, JsonRpcMempoolViewer, JsonRpcStakeTotalsViewer, MempoolRunnerRpcSchemas, MempoolViewerRpcSchemas, StakeTotalsViewerRpcSchemas } from "@xyo-network/xl1-rpc";
|
|
233
236
|
var runProducer = /* @__PURE__ */ __name(async (context) => {
|
|
234
237
|
const { config, logger, orchestrator } = context;
|
|
@@ -253,11 +256,32 @@ var runProducer = /* @__PURE__ */ __name(async (context) => {
|
|
|
253
256
|
const mempoolRunner = new JsonRpcMempoolRunner(new HttpRpcTransport(endpoint, {
|
|
254
257
|
...MempoolRunnerRpcSchemas
|
|
255
258
|
}));
|
|
256
|
-
const
|
|
259
|
+
const chainService = await initChainService({
|
|
257
260
|
account,
|
|
258
261
|
config,
|
|
259
262
|
logger
|
|
260
263
|
});
|
|
264
|
+
const chainContractViewer = {
|
|
265
|
+
forkedAtBlockNumber: /* @__PURE__ */ __name(function() {
|
|
266
|
+
return chainService.forkedAtBlockNumber();
|
|
267
|
+
}, "forkedAtBlockNumber"),
|
|
268
|
+
forkedAtHash: /* @__PURE__ */ __name(function() {
|
|
269
|
+
return chainService.forkedAtHash();
|
|
270
|
+
}, "forkedAtHash"),
|
|
271
|
+
forkedChainId: /* @__PURE__ */ __name(function() {
|
|
272
|
+
return chainService.forkedChainId();
|
|
273
|
+
}, "forkedChainId"),
|
|
274
|
+
minWithdrawalBlocks: /* @__PURE__ */ __name(function() {
|
|
275
|
+
return chainService.minWithdrawalBlocks();
|
|
276
|
+
}, "minWithdrawalBlocks"),
|
|
277
|
+
rewardsContract: /* @__PURE__ */ __name(function() {
|
|
278
|
+
return chainService.rewardsContract();
|
|
279
|
+
}, "rewardsContract"),
|
|
280
|
+
stakingTokenAddress: /* @__PURE__ */ __name(function() {
|
|
281
|
+
return chainService.stakingTokenAddress();
|
|
282
|
+
}, "stakingTokenAddress"),
|
|
283
|
+
moniker: ChainContractViewerMoniker
|
|
284
|
+
};
|
|
261
285
|
const blockRewardViewer = await initBlockRewardViewer({
|
|
262
286
|
config,
|
|
263
287
|
logger,
|
package/dist/node/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ProducerActor.ts","../../src/runProducer.ts"],"sourcesContent":["import type { Attributes, Counter } from '@opentelemetry/api'\nimport type { CreatableName } from '@xylabs/sdk-js'\nimport {\n asAddress,\n creatable, isDefined, isUndefined, toHex,\n ZERO_ADDRESS,\n} from '@xylabs/sdk-js'\nimport { AccountInstance } from '@xyo-network/account-model'\nimport { Actor, type ActorParams } from '@xyo-network/chain-orchestration'\nimport { createDeclarationIntent } from '@xyo-network/chain-protocol'\nimport { SimpleBlockRunner, SimpleBlockRunnerParams } from '@xyo-network/chain-services'\nimport type {\n ChainId,\n ChainStakeIntent, HydratedBlockWithHashMeta,\n XL1BlockNumber,\n} from '@xyo-network/xl1-protocol'\nimport { asXL1BlockNumber } from '@xyo-network/xl1-protocol'\nimport {\n AccountBalanceViewer,\n BlockProducerService, BlockRewardViewer, BlockViewer, buildTransaction,\n Config,\n MempoolRunner,\n MempoolViewer,\n StakeTotalsViewer,\n TimeSyncViewer,\n} from '@xyo-network/xl1-protocol-sdk'\nimport { Mutex } from 'async-mutex'\n\nexport type ProducerActorParams = ActorParams<{\n account: AccountInstance\n blockRewardViewer: BlockRewardViewer\n chainId: ChainId\n config: Config\n runners: {\n mempoolRunner: MempoolRunner\n }\n viewers: {\n accountBalanceViewer: AccountBalanceViewer\n blockViewer: BlockViewer\n mempoolViewer: MempoolViewer\n stakeTotalsViewer: StakeTotalsViewer\n time: TimeSyncViewer\n }\n}>\n\nconst SHOULD_REGISTER_REDECLARATION_INTENT_TIMER = true\nconst TEN_MINUTES = 10 * 60 * 1000 // 10 minutes in milliseconds\n\n@creatable()\nexport class ProducerActor extends Actor<ProducerActorParams> {\n protected _lastProducedBlock: HydratedBlockWithHashMeta | undefined\n protected _lastRedeclarationIntent: ChainStakeIntent | undefined\n protected _metricAttributes: Attributes | undefined\n protected _producerActorBlockProductionAttempts: Counter<Attributes> | undefined\n protected _producerActorBlockProductionChecks: Counter<Attributes> | undefined\n protected _producerActorBlocksProduced: Counter<Attributes> | undefined\n protected _producerActorBlocksPublished: Counter<Attributes> | undefined\n\n private _produceBlockMutex = new Mutex()\n private _producer: BlockProducerService | undefined\n\n protected get account() {\n return this.params.account!\n }\n\n protected get accountBalanceViewer() {\n return this.params.viewers.accountBalanceViewer!\n }\n\n protected get blockViewer() {\n return this.params.viewers.blockViewer!\n }\n\n protected get chainId() {\n return this.params.chainId!\n }\n\n protected get config() {\n return this.params.config!\n }\n\n protected get mempoolRunner() {\n return this.params.runners.mempoolRunner!\n }\n\n protected get mempoolViewer() {\n return this.params.viewers.mempoolViewer!\n }\n\n protected get producer() {\n return this._producer!\n }\n\n protected get stakeTotalsViewer() {\n return this.params.viewers.stakeTotalsViewer!\n }\n\n static override async paramsHandler<T extends ActorParams>(params?: Partial<T>) {\n return await super.paramsHandler({ ...params, name: (params?.name ?? 'Producer') as CreatableName })\n }\n\n override async createHandler() {\n await super.createHandler()\n // Create the consistent meter attributes that will\n // be included with all metrics from this actor\n this._metricAttributes = { address: this.account.address.toString() }\n // Create the metrics\n this._producerActorBlockProductionChecks = this.meter?.createCounter(\n 'producer_actor_block_production_checks',\n { description: 'Number of block production checks' },\n )\n this._producerActorBlockProductionAttempts = this.meter?.createCounter(\n 'producer_actor_block_production_attempts',\n { description: 'Number of block production attempts' },\n )\n this._producerActorBlocksProduced = this.meter?.createCounter(\n 'producer_actor_blocks_produced',\n { description: 'Number of blocks produced' },\n )\n this._producerActorBlocksPublished = this.meter?.createCounter(\n 'producer_actor_blocks_published',\n { description: 'Number of blocks published' },\n )\n const params = {\n account: this.account,\n balanceViewer: this.accountBalanceViewer,\n config: this.config,\n chainId: this.chainId,\n mempoolRunner: this.mempoolRunner,\n mempoolViewer: this.mempoolViewer,\n blockRewardViewer: this.params.blockRewardViewer!,\n rewardAddress: asAddress(\n this.config.producer.rewardAddress ?? ZERO_ADDRESS,\n () => `Producer config must have a valid reward address configured [${this.params.config.producer.rewardAddress}]`,\n ),\n time: this.params.viewers.time!,\n } satisfies SimpleBlockRunnerParams\n this._producer = await SimpleBlockRunner.create(params)\n }\n\n override async startHandler() {\n await super.startHandler()\n // Register a timer to check if we should produce a block\n this.registerTimer('BlockProductionTimer', async () => {\n await this.produceBlock()\n }, 2000, 1500/* 500 */)\n\n if (SHOULD_REGISTER_REDECLARATION_INTENT_TIMER) {\n // Register a timer to check if we should redeclare the producer\n this.registerTimer('ProducerRedeclarationTimer', async () => {\n await this.redeclareIntent()\n }, TEN_MINUTES, TEN_MINUTES)\n }\n }\n\n // protected async calculateBlocksUntilProducerDeclarationExpiration(currentBlock: number): Promise<number> {\n // // Decide if we need to redeclare intent\n // const ranges = await this.stakeIntentService.getDeclaredCandidateRanges(this.account.address, 'producer')\n // // TODO: This doesn't handle the case where the producer had declared a range for the future\n // // but we're in a range that's not the future\n // // Sort in ascending order based on ending range to get range with highest ending block\n // const lastRange = ranges.toSorted((a, b) => a[1] > b[1] ? 1 : -1).at(-1)\n\n // // Use the most recent range's end block as the current declaration end OR\n // const [, currentDeclarationEnd] = lastRange\n // // If we have no ranges, we need to declare intent, so use the current block\n // ?? [undefined, currentBlock]\n\n // // Calculate the time until the producer's declaration expires\n // const timeToProducerExpiration = currentDeclarationEnd - currentBlock\n // return timeToProducerExpiration\n // }\n\n protected async produceBlock(): Promise<void> {\n this._producerActorBlockProductionChecks?.add(1, this._metricAttributes)\n await this.spanAsync('produceBlock', async () => {\n if (this._produceBlockMutex.isLocked()) {\n this.logger?.log('Skipping block production, previous production still in progress')\n return\n }\n\n await this._produceBlockMutex.runExclusive(async () => {\n // Get the updated head\n const headStart = Date.now()\n const head = (await this.blockViewer.currentBlock())[0]\n const headDuration = Date.now() - headStart\n if (headDuration > 500) this.logger?.warn(`[Slow] Fetched head in ${headDuration}ms: 0x${toHex(head._hash)}`)\n // Check if we've already produced the next block for this head\n const headHash = head._hash\n // If our last produced block was the next block for the current head, we do not\n // need to produce another. This prevents duplicate blocks from being produced\n if (this._lastProducedBlock && this._lastProducedBlock[0].previous === headHash) {\n this.logger?.log('Block already produced:', `0x${toHex(this._lastProducedBlock[0].block)}`, this._lastProducedBlock[0].block)\n } else {\n this._producerActorBlockProductionAttempts?.add(1, this._metricAttributes)\n // Produce the next block\n const nextStart = Date.now()\n const nextBlock = await this.producer.next(head)\n const nextDuration = Date.now() - nextStart\n if (nextDuration > 1000) this.logger?.warn(`[Slow] Generated next block in ${nextDuration}ms, block: ${nextBlock?.[0]._hash}`)\n // If it was produced\n if (nextBlock) {\n const displayBlockNumber = `0x${toHex(nextBlock[0].block)}`\n this.logger?.log('Produced block:', displayBlockNumber)\n this._producerActorBlocksProduced?.add(1, this._metricAttributes)\n // Insert the block into the chain\n await this.mempoolRunner.submitBlocks([nextBlock])\n this.logger?.log('Published block:', displayBlockNumber, nextBlock[0].block)\n this._producerActorBlocksPublished?.add(1, this._metricAttributes)\n // Record that we have produced a block so we do not produce it again\n this._lastProducedBlock = nextBlock\n }\n }\n })\n })\n }\n\n protected async redeclareIntent(): Promise<void> {\n await this.spanAsync('redeclareIntent', async () => {\n // Decide if we should redeclare intent\n if (this.params.config.producer.disableIntentRedeclaration) return\n\n // Get the current block\n const head = (await this.blockViewer.currentBlock())[0]\n if (isUndefined(head)) return\n const currentBlock = head.block\n\n // // Calculate the time until the producer's declaration expires\n // const blocksUntilExpiration = await this.calculateBlocksUntilProducerDeclarationExpiration(currentBlock)\n\n // // Allow the producer time to redeclare itself via block production\n // // (for free) before submitting a redeclaration intent transaction.\n // if (blocksUntilExpiration > BaseBlockProducerService.RedeclarationWindow * 0.1) {\n // // Clear any previous redeclaration intent\n // this._lastRedeclarationIntent = undefined\n // // No need to redeclare yet\n // return\n // }\n\n // If we already have a valid redeclaration intent, do not create another\n // unless it has expired.\n if (this._lastRedeclarationIntent) {\n // Check if the last redeclaration intent is still valid\n if (this._lastRedeclarationIntent.exp > currentBlock) return\n // If it has expired, clear the last redeclaration intent\n this._lastRedeclarationIntent = undefined\n }\n\n // Check if we have a valid balance before declaring intent\n if (!await this.validateCurrentBalance()) {\n this.logger?.error(\n `Add balance to address ${this.account.address} for the producer to declare it's intent.`,\n )\n return\n }\n\n // Check if we have a valid stake before declaring intent\n if (!(await this.validateCurrentStake())) {\n this.logger?.error(\n `Add stake to contract address ${this.params.config.chain.id}`\n + ' for the producer to declare it\\'s intent.',\n )\n return\n }\n\n // Create a redeclaration intent\n this.logger?.log('Creating redeclaration intent for producer:', this.account.address)\n const redeclarationIntent = createDeclarationIntent(\n this.account.address,\n 'producer',\n currentBlock,\n currentBlock + SimpleBlockRunner.RedeclarationDuration,\n )\n\n // Submit the redeclaration intent\n await this.submitRedeclarationIntent(currentBlock, redeclarationIntent)\n\n // On successful submission, save the redeclaration intent\n this._lastRedeclarationIntent = redeclarationIntent\n })\n }\n\n protected async submitRedeclarationIntent(currentBlock: XL1BlockNumber, redeclarationIntent: ChainStakeIntent): Promise<void> {\n this.logger?.log('Submitting redeclaration intent for producer:', this.account.address)\n // Create a transaction to submit the redeclaration intent\n const tx = await buildTransaction(\n this.chainId,\n [redeclarationIntent],\n [],\n this.account,\n currentBlock,\n asXL1BlockNumber(currentBlock + 1000, true),\n )\n\n // Submit the redeclaration intent\n await this.mempoolRunner.submitTransactions([tx])\n\n this.logger?.log('Submitted redeclaration intent for producer:', this.account.address)\n }\n\n protected async validateCurrentBalance(): Promise<boolean> {\n // Check if we have a valid balance before declaring intent\n const head = this._lastProducedBlock?.[0]._hash\n if (isDefined(head)) {\n const balances = await this.accountBalanceViewer.accountBalances([this.account.address], head)\n const currentBalance = balances[this.account.address] ?? 0n\n if (currentBalance <= 0n) {\n this.logger?.error(`Producer ${this.account.address} has no balance.`)\n return false\n }\n return true\n }\n return true\n }\n\n protected async validateCurrentStake(): Promise<boolean> {\n // Use StakeIntentService to get the required minimum stake\n const requiredMinimumStake = 1n // this.stakeIntentService.getRequiredMinimumStakeForIntent('producer')\n // Check if we have a valid stake before declaring intent\n const currentStake = await this.stakeTotalsViewer.activeByStaked(this.account.address)\n if (currentStake < requiredMinimumStake) {\n this.logger?.error(`Producer ${this.account.address} has insufficient stake.`)\n return false\n }\n return true\n }\n}\n","import {\n assertEx, exists, type Logger,\n} from '@xylabs/sdk-js'\nimport {\n initProducerAccount, initStakeViewer, type OrchestratorInstance,\n} from '@xyo-network/chain-orchestration'\nimport {\n initBlockRewardViewer, initChainService, initTimeService,\n} from '@xyo-network/chain-services'\nimport { type Config } from '@xyo-network/xl1-protocol-sdk'\nimport {\n AccountBalanceViewerRpcSchemas, BlockViewerRpcSchemas, HttpRpcTransport, JsonRpcAccountBalanceViewer,\n JsonRpcBlockViewer,\n JsonRpcMempoolRunner,\n JsonRpcMempoolViewer,\n JsonRpcStakeTotalsViewer,\n MempoolRunnerRpcSchemas,\n MempoolViewerRpcSchemas,\n StakeTotalsViewerRpcSchemas,\n} from '@xyo-network/xl1-rpc'\n\nimport { ProducerActor, type ProducerActorParams } from './ProducerActor.ts'\n\ninterface RunProducerContext {\n config: Config\n logger: Logger\n orchestrator: OrchestratorInstance\n}\n\nexport const runProducer = async (context: RunProducerContext) => {\n const {\n config, logger, orchestrator,\n } = context\n\n const endpoint = assertEx(config.services?.apiEndpoint, () => 'No API endpoint configured')\n const account = await initProducerAccount({ config, logger })\n const accountBalanceViewer = new JsonRpcAccountBalanceViewer(new HttpRpcTransport(endpoint, { ...AccountBalanceViewerRpcSchemas }))\n const blockViewer = new JsonRpcBlockViewer(new HttpRpcTransport(endpoint, { ...BlockViewerRpcSchemas }))\n const stakeTotalsViewer = new JsonRpcStakeTotalsViewer(new HttpRpcTransport(endpoint, { ...StakeTotalsViewerRpcSchemas }))\n const chainId = (await blockViewer.currentBlock())[0].chain\n const mempoolViewer = new JsonRpcMempoolViewer(new HttpRpcTransport(endpoint, { ...MempoolViewerRpcSchemas }))\n const mempoolRunner = new JsonRpcMempoolRunner(new HttpRpcTransport(endpoint, { ...MempoolRunnerRpcSchemas }))\n const chainContractViewer = await initChainService({\n account, config, logger,\n })\n const blockRewardViewer = await initBlockRewardViewer({\n config, logger, chainContractViewer,\n })\n const timeSyncViewer = await initTimeService({\n config, logger, blockViewer,\n })\n\n // Create actors\n const params = {\n account,\n id: 'ProducerActor',\n chainId,\n config,\n viewers: {\n accountBalanceViewer,\n blockViewer,\n stakeTotalsViewer,\n mempoolViewer,\n time: timeSyncViewer,\n },\n blockRewardViewer,\n runners: { mempoolRunner },\n logger,\n } satisfies ProducerActorParams\n // const apiEndpoint = config.services.apiEndpoint\n // const balances = isDefined(apiEndpoint) ? undefined : await BalanceActor.create(params)\n const producer = await ProducerActor.create(params)\n const actors = [producer].filter(exists)\n\n for (const actor of actors) {\n // Register the actor with the orchestrator\n await orchestrator.registerActor(actor)\n }\n // Start the orchestrator => automatically activates the actor\n await orchestrator.start()\n}\n"],"mappings":"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","names":["asAddress","creatable","isDefined","isUndefined","toHex","ZERO_ADDRESS","Actor","createDeclarationIntent","SimpleBlockRunner","asXL1BlockNumber","buildTransaction","Mutex","SHOULD_REGISTER_REDECLARATION_INTENT_TIMER","TEN_MINUTES","ProducerActor","Actor","_lastProducedBlock","_lastRedeclarationIntent","_metricAttributes","_producerActorBlockProductionAttempts","_producerActorBlockProductionChecks","_producerActorBlocksProduced","_producerActorBlocksPublished","_produceBlockMutex","Mutex","_producer","account","params","accountBalanceViewer","viewers","blockViewer","chainId","config","mempoolRunner","runners","mempoolViewer","producer","stakeTotalsViewer","paramsHandler","name","createHandler","address","toString","meter","createCounter","description","balanceViewer","blockRewardViewer","rewardAddress","asAddress","ZERO_ADDRESS","time","SimpleBlockRunner","create","startHandler","registerTimer","produceBlock","redeclareIntent","add","spanAsync","isLocked","logger","log","runExclusive","headStart","Date","now","head","currentBlock","headDuration","warn","toHex","_hash","headHash","previous","block","nextStart","nextBlock","next","nextDuration","displayBlockNumber","submitBlocks","disableIntentRedeclaration","isUndefined","exp","undefined","validateCurrentBalance","error","validateCurrentStake","chain","id","redeclarationIntent","createDeclarationIntent","RedeclarationDuration","submitRedeclarationIntent","tx","buildTransaction","asXL1BlockNumber","submitTransactions","isDefined","balances","accountBalances","currentBalance","requiredMinimumStake","currentStake","activeByStaked","assertEx","exists","initProducerAccount","initBlockRewardViewer","initChainService","initTimeService","AccountBalanceViewerRpcSchemas","BlockViewerRpcSchemas","HttpRpcTransport","JsonRpcAccountBalanceViewer","JsonRpcBlockViewer","JsonRpcMempoolRunner","JsonRpcMempoolViewer","JsonRpcStakeTotalsViewer","MempoolRunnerRpcSchemas","MempoolViewerRpcSchemas","StakeTotalsViewerRpcSchemas","runProducer","context","config","logger","orchestrator","endpoint","assertEx","services","apiEndpoint","account","initProducerAccount","accountBalanceViewer","JsonRpcAccountBalanceViewer","HttpRpcTransport","AccountBalanceViewerRpcSchemas","blockViewer","JsonRpcBlockViewer","BlockViewerRpcSchemas","stakeTotalsViewer","JsonRpcStakeTotalsViewer","StakeTotalsViewerRpcSchemas","chainId","currentBlock","chain","mempoolViewer","JsonRpcMempoolViewer","MempoolViewerRpcSchemas","mempoolRunner","JsonRpcMempoolRunner","MempoolRunnerRpcSchemas","chainContractViewer","initChainService","blockRewardViewer","initBlockRewardViewer","timeSyncViewer","initTimeService","params","id","viewers","time","runners","producer","ProducerActor","create","actors","filter","exists","actor","registerActor","start"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ProducerActor.ts","../../src/runProducer.ts"],"sourcesContent":["import type { Attributes, Counter } from '@opentelemetry/api'\nimport type { CreatableName } from '@xylabs/sdk-js'\nimport {\n asAddress,\n creatable, isDefined, isUndefined, toHex,\n ZERO_ADDRESS,\n} from '@xylabs/sdk-js'\nimport { AccountInstance } from '@xyo-network/account-model'\nimport { Actor, type ActorParams } from '@xyo-network/chain-orchestration'\nimport { createDeclarationIntent } from '@xyo-network/chain-protocol'\nimport { SimpleBlockRunner, SimpleBlockRunnerParams } from '@xyo-network/chain-services'\nimport type {\n ChainId,\n ChainStakeIntent, HydratedBlockWithHashMeta,\n XL1BlockNumber,\n} from '@xyo-network/xl1-protocol'\nimport { asXL1BlockNumber } from '@xyo-network/xl1-protocol'\nimport {\n AccountBalanceViewer,\n BlockProducerService, BlockRewardViewer, BlockViewer, buildTransaction,\n Config,\n MempoolRunner,\n MempoolViewer,\n StakeTotalsViewer,\n TimeSyncViewer,\n} from '@xyo-network/xl1-protocol-sdk'\nimport { Mutex } from 'async-mutex'\n\nexport type ProducerActorParams = ActorParams<{\n account: AccountInstance\n blockRewardViewer: BlockRewardViewer\n chainId: ChainId\n config: Config\n runners: {\n mempoolRunner: MempoolRunner\n }\n viewers: {\n accountBalanceViewer: AccountBalanceViewer\n blockViewer: BlockViewer\n mempoolViewer: MempoolViewer\n stakeTotalsViewer: StakeTotalsViewer\n time: TimeSyncViewer\n }\n}>\n\nconst SHOULD_REGISTER_REDECLARATION_INTENT_TIMER = true\nconst TEN_MINUTES = 10 * 60 * 1000 // 10 minutes in milliseconds\n\n@creatable()\nexport class ProducerActor extends Actor<ProducerActorParams> {\n protected _lastProducedBlock: HydratedBlockWithHashMeta | undefined\n protected _lastRedeclarationIntent: ChainStakeIntent | undefined\n protected _metricAttributes: Attributes | undefined\n protected _producerActorBlockProductionAttempts: Counter<Attributes> | undefined\n protected _producerActorBlockProductionChecks: Counter<Attributes> | undefined\n protected _producerActorBlocksProduced: Counter<Attributes> | undefined\n protected _producerActorBlocksPublished: Counter<Attributes> | undefined\n\n private _produceBlockMutex = new Mutex()\n private _producer: BlockProducerService | undefined\n\n protected get account() {\n return this.params.account!\n }\n\n protected get accountBalanceViewer() {\n return this.params.viewers.accountBalanceViewer!\n }\n\n protected get blockViewer() {\n return this.params.viewers.blockViewer!\n }\n\n protected get chainId() {\n return this.params.chainId!\n }\n\n protected get config() {\n return this.params.config!\n }\n\n protected get mempoolRunner() {\n return this.params.runners.mempoolRunner!\n }\n\n protected get mempoolViewer() {\n return this.params.viewers.mempoolViewer!\n }\n\n protected get producer() {\n return this._producer!\n }\n\n protected get stakeTotalsViewer() {\n return this.params.viewers.stakeTotalsViewer!\n }\n\n static override async paramsHandler<T extends ActorParams>(params?: Partial<T>) {\n return await super.paramsHandler({ ...params, name: (params?.name ?? 'Producer') as CreatableName })\n }\n\n override async createHandler() {\n await super.createHandler()\n // Create the consistent meter attributes that will\n // be included with all metrics from this actor\n this._metricAttributes = { address: this.account.address.toString() }\n // Create the metrics\n this._producerActorBlockProductionChecks = this.meter?.createCounter(\n 'producer_actor_block_production_checks',\n { description: 'Number of block production checks' },\n )\n this._producerActorBlockProductionAttempts = this.meter?.createCounter(\n 'producer_actor_block_production_attempts',\n { description: 'Number of block production attempts' },\n )\n this._producerActorBlocksProduced = this.meter?.createCounter(\n 'producer_actor_blocks_produced',\n { description: 'Number of blocks produced' },\n )\n this._producerActorBlocksPublished = this.meter?.createCounter(\n 'producer_actor_blocks_published',\n { description: 'Number of blocks published' },\n )\n const params = {\n account: this.account,\n balanceViewer: this.accountBalanceViewer,\n config: this.config,\n chainId: this.chainId,\n mempoolRunner: this.mempoolRunner,\n mempoolViewer: this.mempoolViewer,\n blockRewardViewer: this.params.blockRewardViewer!,\n rewardAddress: asAddress(\n this.config.producer.rewardAddress ?? ZERO_ADDRESS,\n () => `Producer config must have a valid reward address configured [${this.params.config.producer.rewardAddress}]`,\n ),\n time: this.params.viewers.time!,\n } satisfies SimpleBlockRunnerParams\n this._producer = await SimpleBlockRunner.create(params)\n }\n\n override async startHandler() {\n await super.startHandler()\n // Register a timer to check if we should produce a block\n this.registerTimer('BlockProductionTimer', async () => {\n await this.produceBlock()\n }, 2000, 1500/* 500 */)\n\n if (SHOULD_REGISTER_REDECLARATION_INTENT_TIMER) {\n // Register a timer to check if we should redeclare the producer\n this.registerTimer('ProducerRedeclarationTimer', async () => {\n await this.redeclareIntent()\n }, TEN_MINUTES, TEN_MINUTES)\n }\n }\n\n // protected async calculateBlocksUntilProducerDeclarationExpiration(currentBlock: number): Promise<number> {\n // // Decide if we need to redeclare intent\n // const ranges = await this.stakeIntentService.getDeclaredCandidateRanges(this.account.address, 'producer')\n // // TODO: This doesn't handle the case where the producer had declared a range for the future\n // // but we're in a range that's not the future\n // // Sort in ascending order based on ending range to get range with highest ending block\n // const lastRange = ranges.toSorted((a, b) => a[1] > b[1] ? 1 : -1).at(-1)\n\n // // Use the most recent range's end block as the current declaration end OR\n // const [, currentDeclarationEnd] = lastRange\n // // If we have no ranges, we need to declare intent, so use the current block\n // ?? [undefined, currentBlock]\n\n // // Calculate the time until the producer's declaration expires\n // const timeToProducerExpiration = currentDeclarationEnd - currentBlock\n // return timeToProducerExpiration\n // }\n\n protected async produceBlock(): Promise<void> {\n this._producerActorBlockProductionChecks?.add(1, this._metricAttributes)\n await this.spanAsync('produceBlock', async () => {\n if (this._produceBlockMutex.isLocked()) {\n this.logger?.log('Skipping block production, previous production still in progress')\n return\n }\n\n await this._produceBlockMutex.runExclusive(async () => {\n // Get the updated head\n const headStart = Date.now()\n const head = (await this.blockViewer.currentBlock())[0]\n const headDuration = Date.now() - headStart\n if (headDuration > 500) this.logger?.warn(`[Slow] Fetched head in ${headDuration}ms: 0x${toHex(head._hash)}`)\n // Check if we've already produced the next block for this head\n const headHash = head._hash\n // If our last produced block was the next block for the current head, we do not\n // need to produce another. This prevents duplicate blocks from being produced\n if (this._lastProducedBlock && this._lastProducedBlock[0].previous === headHash) {\n this.logger?.log('Block already produced:', `0x${toHex(this._lastProducedBlock[0].block)}`, this._lastProducedBlock[0].block)\n } else {\n this._producerActorBlockProductionAttempts?.add(1, this._metricAttributes)\n // Produce the next block\n const nextStart = Date.now()\n const nextBlock = await this.producer.next(head)\n const nextDuration = Date.now() - nextStart\n if (nextDuration > 1000) this.logger?.warn(`[Slow] Generated next block in ${nextDuration}ms, block: ${nextBlock?.[0]._hash}`)\n // If it was produced\n if (nextBlock) {\n const displayBlockNumber = `0x${toHex(nextBlock[0].block)}`\n this.logger?.log('Produced block:', displayBlockNumber)\n this._producerActorBlocksProduced?.add(1, this._metricAttributes)\n // Insert the block into the chain\n await this.mempoolRunner.submitBlocks([nextBlock])\n this.logger?.log('Published block:', displayBlockNumber, nextBlock[0].block)\n this._producerActorBlocksPublished?.add(1, this._metricAttributes)\n // Record that we have produced a block so we do not produce it again\n this._lastProducedBlock = nextBlock\n } else {\n this.logger?.log('No block produced at this time.')\n }\n }\n })\n })\n }\n\n protected async redeclareIntent(): Promise<void> {\n await this.spanAsync('redeclareIntent', async () => {\n // Decide if we should redeclare intent\n if (this.params.config.producer.disableIntentRedeclaration) return\n\n // Get the current block\n const head = (await this.blockViewer.currentBlock())[0]\n if (isUndefined(head)) return\n const currentBlock = head.block\n\n // // Calculate the time until the producer's declaration expires\n // const blocksUntilExpiration = await this.calculateBlocksUntilProducerDeclarationExpiration(currentBlock)\n\n // // Allow the producer time to redeclare itself via block production\n // // (for free) before submitting a redeclaration intent transaction.\n // if (blocksUntilExpiration > BaseBlockProducerService.RedeclarationWindow * 0.1) {\n // // Clear any previous redeclaration intent\n // this._lastRedeclarationIntent = undefined\n // // No need to redeclare yet\n // return\n // }\n\n // If we already have a valid redeclaration intent, do not create another\n // unless it has expired.\n if (this._lastRedeclarationIntent) {\n // Check if the last redeclaration intent is still valid\n if (this._lastRedeclarationIntent.exp > currentBlock) return\n // If it has expired, clear the last redeclaration intent\n this._lastRedeclarationIntent = undefined\n }\n\n // Check if we have a valid balance before declaring intent\n if (!await this.validateCurrentBalance()) {\n this.logger?.error(\n `Add balance to address ${this.account.address} for the producer to declare it's intent.`,\n )\n return\n }\n\n // Check if we have a valid stake before declaring intent\n if (!(await this.validateCurrentStake())) {\n this.logger?.error(\n `Add stake to contract address ${this.params.config.chain.id}`\n + ' for the producer to declare it\\'s intent.',\n )\n return\n }\n\n // Create a redeclaration intent\n this.logger?.log('Creating redeclaration intent for producer:', this.account.address)\n const redeclarationIntent = createDeclarationIntent(\n this.account.address,\n 'producer',\n currentBlock,\n currentBlock + SimpleBlockRunner.RedeclarationDuration,\n )\n\n // Submit the redeclaration intent\n await this.submitRedeclarationIntent(currentBlock, redeclarationIntent)\n\n // On successful submission, save the redeclaration intent\n this._lastRedeclarationIntent = redeclarationIntent\n })\n }\n\n protected async submitRedeclarationIntent(currentBlock: XL1BlockNumber, redeclarationIntent: ChainStakeIntent): Promise<void> {\n this.logger?.log('Submitting redeclaration intent for producer:', this.account.address)\n // Create a transaction to submit the redeclaration intent\n const tx = await buildTransaction(\n this.chainId,\n [redeclarationIntent],\n [],\n this.account,\n currentBlock,\n asXL1BlockNumber(currentBlock + 1000, true),\n )\n\n // Submit the redeclaration intent\n await this.mempoolRunner.submitTransactions([tx])\n\n this.logger?.log('Submitted redeclaration intent for producer:', this.account.address)\n }\n\n protected async validateCurrentBalance(): Promise<boolean> {\n // Check if we have a valid balance before declaring intent\n const head = this._lastProducedBlock?.[0]._hash\n if (isDefined(head)) {\n const balances = await this.accountBalanceViewer.accountBalances([this.account.address], head)\n const currentBalance = balances[this.account.address] ?? 0n\n if (currentBalance <= 0n) {\n this.logger?.error(`Producer ${this.account.address} has no balance.`)\n return false\n }\n return true\n }\n return true\n }\n\n protected async validateCurrentStake(): Promise<boolean> {\n // Use StakeIntentService to get the required minimum stake\n const requiredMinimumStake = 1n // this.stakeIntentService.getRequiredMinimumStakeForIntent('producer')\n // Check if we have a valid stake before declaring intent\n const currentStake = await this.stakeTotalsViewer.activeByStaked(this.account.address)\n if (currentStake < requiredMinimumStake) {\n this.logger?.error(`Producer ${this.account.address} has insufficient stake.`)\n return false\n }\n return true\n }\n}\n","import type { Address, Logger } from '@xylabs/sdk-js'\nimport { assertEx, exists } from '@xylabs/sdk-js'\nimport { initProducerAccount, type OrchestratorInstance } from '@xyo-network/chain-orchestration'\nimport {\n initBlockRewardViewer, initChainService, initTimeService,\n} from '@xyo-network/chain-services'\nimport {\n type ChainContractViewer, ChainContractViewerMoniker, type Config,\n} from '@xyo-network/xl1-protocol-sdk'\nimport {\n AccountBalanceViewerRpcSchemas, BlockViewerRpcSchemas, HttpRpcTransport, JsonRpcAccountBalanceViewer,\n JsonRpcBlockViewer,\n JsonRpcMempoolRunner,\n JsonRpcMempoolViewer,\n JsonRpcStakeTotalsViewer,\n MempoolRunnerRpcSchemas,\n MempoolViewerRpcSchemas,\n StakeTotalsViewerRpcSchemas,\n} from '@xyo-network/xl1-rpc'\n\nimport { ProducerActor, type ProducerActorParams } from './ProducerActor.ts'\n\ninterface RunProducerContext {\n config: Config\n logger: Logger\n orchestrator: OrchestratorInstance\n}\n\nexport const runProducer = async (context: RunProducerContext) => {\n const {\n config, logger, orchestrator,\n } = context\n\n const endpoint = assertEx(config.services?.apiEndpoint, () => 'No API endpoint configured')\n const account = await initProducerAccount({ config, logger })\n const accountBalanceViewer = new JsonRpcAccountBalanceViewer(new HttpRpcTransport(endpoint, { ...AccountBalanceViewerRpcSchemas }))\n const blockViewer = new JsonRpcBlockViewer(new HttpRpcTransport(endpoint, { ...BlockViewerRpcSchemas }))\n const stakeTotalsViewer = new JsonRpcStakeTotalsViewer(new HttpRpcTransport(endpoint, { ...StakeTotalsViewerRpcSchemas }))\n const chainId = (await blockViewer.currentBlock())[0].chain\n const mempoolViewer = new JsonRpcMempoolViewer(new HttpRpcTransport(endpoint, { ...MempoolViewerRpcSchemas }))\n const mempoolRunner = new JsonRpcMempoolRunner(new HttpRpcTransport(endpoint, { ...MempoolRunnerRpcSchemas }))\n const chainService = await initChainService({\n account, config, logger,\n })\n const chainContractViewer = {\n forkedAtBlockNumber: function (): Promise<bigint> {\n return chainService.forkedAtBlockNumber()\n },\n forkedAtHash: function (): Promise<bigint> {\n return chainService.forkedAtHash()\n },\n forkedChainId: function (): Promise<Address> {\n return chainService.forkedChainId()\n },\n minWithdrawalBlocks: function (): Promise<bigint> {\n return chainService.minWithdrawalBlocks()\n },\n rewardsContract: function (): Promise<string> {\n return chainService.rewardsContract()\n },\n stakingTokenAddress: function (): Promise<string> {\n return chainService.stakingTokenAddress()\n },\n moniker: ChainContractViewerMoniker,\n } satisfies ChainContractViewer\n const blockRewardViewer = await initBlockRewardViewer({\n config, logger, chainContractViewer,\n })\n const timeSyncViewer = await initTimeService({\n config, logger, blockViewer,\n })\n\n // Create actors\n const params = {\n account,\n id: 'ProducerActor',\n chainId,\n config,\n viewers: {\n accountBalanceViewer,\n blockViewer,\n stakeTotalsViewer,\n mempoolViewer,\n time: timeSyncViewer,\n },\n blockRewardViewer,\n runners: { mempoolRunner },\n logger,\n } satisfies ProducerActorParams\n // const apiEndpoint = config.services.apiEndpoint\n // const balances = isDefined(apiEndpoint) ? undefined : await BalanceActor.create(params)\n const producer = await ProducerActor.create(params)\n const actors = [producer].filter(exists)\n\n for (const actor of actors) {\n // Register the actor with the orchestrator\n await orchestrator.registerActor(actor)\n }\n // Start the orchestrator => automatically activates the actor\n await orchestrator.start()\n}\n"],"mappings":"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","names":["asAddress","creatable","isDefined","isUndefined","toHex","ZERO_ADDRESS","Actor","createDeclarationIntent","SimpleBlockRunner","asXL1BlockNumber","buildTransaction","Mutex","SHOULD_REGISTER_REDECLARATION_INTENT_TIMER","TEN_MINUTES","ProducerActor","Actor","_lastProducedBlock","_lastRedeclarationIntent","_metricAttributes","_producerActorBlockProductionAttempts","_producerActorBlockProductionChecks","_producerActorBlocksProduced","_producerActorBlocksPublished","_produceBlockMutex","Mutex","_producer","account","params","accountBalanceViewer","viewers","blockViewer","chainId","config","mempoolRunner","runners","mempoolViewer","producer","stakeTotalsViewer","paramsHandler","name","createHandler","address","toString","meter","createCounter","description","balanceViewer","blockRewardViewer","rewardAddress","asAddress","ZERO_ADDRESS","time","SimpleBlockRunner","create","startHandler","registerTimer","produceBlock","redeclareIntent","add","spanAsync","isLocked","logger","log","runExclusive","headStart","Date","now","head","currentBlock","headDuration","warn","toHex","_hash","headHash","previous","block","nextStart","nextBlock","next","nextDuration","displayBlockNumber","submitBlocks","disableIntentRedeclaration","isUndefined","exp","undefined","validateCurrentBalance","error","validateCurrentStake","chain","id","redeclarationIntent","createDeclarationIntent","RedeclarationDuration","submitRedeclarationIntent","tx","buildTransaction","asXL1BlockNumber","submitTransactions","isDefined","balances","accountBalances","currentBalance","requiredMinimumStake","currentStake","activeByStaked","assertEx","exists","initProducerAccount","initBlockRewardViewer","initChainService","initTimeService","ChainContractViewerMoniker","AccountBalanceViewerRpcSchemas","BlockViewerRpcSchemas","HttpRpcTransport","JsonRpcAccountBalanceViewer","JsonRpcBlockViewer","JsonRpcMempoolRunner","JsonRpcMempoolViewer","JsonRpcStakeTotalsViewer","MempoolRunnerRpcSchemas","MempoolViewerRpcSchemas","StakeTotalsViewerRpcSchemas","runProducer","context","config","logger","orchestrator","endpoint","assertEx","services","apiEndpoint","account","initProducerAccount","accountBalanceViewer","JsonRpcAccountBalanceViewer","HttpRpcTransport","AccountBalanceViewerRpcSchemas","blockViewer","JsonRpcBlockViewer","BlockViewerRpcSchemas","stakeTotalsViewer","JsonRpcStakeTotalsViewer","StakeTotalsViewerRpcSchemas","chainId","currentBlock","chain","mempoolViewer","JsonRpcMempoolViewer","MempoolViewerRpcSchemas","mempoolRunner","JsonRpcMempoolRunner","MempoolRunnerRpcSchemas","chainService","initChainService","chainContractViewer","forkedAtBlockNumber","forkedAtHash","forkedChainId","minWithdrawalBlocks","rewardsContract","stakingTokenAddress","moniker","ChainContractViewerMoniker","blockRewardViewer","initBlockRewardViewer","timeSyncViewer","initTimeService","params","id","viewers","time","runners","producer","ProducerActor","create","actors","filter","exists","actor","registerActor","start"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runProducer.d.ts","sourceRoot":"","sources":["../../src/runProducer.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"runProducer.d.ts","sourceRoot":"","sources":["../../src/runProducer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAErD,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,kCAAkC,CAAA;AAIjG,OAAO,EACiD,KAAK,MAAM,EAClE,MAAM,+BAA+B,CAAA;AActC,UAAU,kBAAkB;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,oBAAoB,CAAA;CACnC;AAED,eAAO,MAAM,WAAW,GAAU,SAAS,kBAAkB,kBAwE5D,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xyo-network/chain-producer",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.3",
|
|
4
4
|
"description": "XYO Layer One Producer",
|
|
5
5
|
"homepage": "https://xylabs.com",
|
|
6
6
|
"bugs": {
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
"types": "tsc --noEmit -p tsconfig.test.json"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@xylabs/sdk-js": "~5.0.
|
|
53
|
-
"@xyo-network/chain-orchestration": "~1.17.
|
|
54
|
-
"@xyo-network/chain-protocol": "~1.17.
|
|
55
|
-
"@xyo-network/chain-services": "~1.17.
|
|
56
|
-
"@xyo-network/xl1-protocol": "~1.14.
|
|
57
|
-
"@xyo-network/xl1-protocol-sdk": "~1.17.
|
|
58
|
-
"@xyo-network/xl1-rpc": "~1.17.
|
|
52
|
+
"@xylabs/sdk-js": "~5.0.51",
|
|
53
|
+
"@xyo-network/chain-orchestration": "~1.17.3",
|
|
54
|
+
"@xyo-network/chain-protocol": "~1.17.3",
|
|
55
|
+
"@xyo-network/chain-services": "~1.17.3",
|
|
56
|
+
"@xyo-network/xl1-protocol": "~1.14.17",
|
|
57
|
+
"@xyo-network/xl1-protocol-sdk": "~1.17.3",
|
|
58
|
+
"@xyo-network/xl1-rpc": "~1.17.3",
|
|
59
59
|
"async-mutex": "~0.5.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
@@ -64,20 +64,20 @@
|
|
|
64
64
|
"@types/cors": "~2.8.19",
|
|
65
65
|
"@types/express": "5.0.6",
|
|
66
66
|
"@types/express-serve-static-core": "~5.1.0",
|
|
67
|
-
"@types/node": "~24.10.
|
|
68
|
-
"@xylabs/sdk-js": "~5.0.
|
|
67
|
+
"@types/node": "~24.10.3",
|
|
68
|
+
"@xylabs/sdk-js": "~5.0.51",
|
|
69
69
|
"@xylabs/ts-scripts-yarn3": "~7.2.8",
|
|
70
70
|
"@xylabs/tsconfig": "~7.2.8",
|
|
71
|
-
"@xyo-network/account": "~5.2.
|
|
72
|
-
"@xyo-network/account-model": "~5.2.
|
|
73
|
-
"@xyo-network/archivist-abstract": "~5.2.
|
|
71
|
+
"@xyo-network/account": "~5.2.17",
|
|
72
|
+
"@xyo-network/account-model": "~5.2.17",
|
|
73
|
+
"@xyo-network/archivist-abstract": "~5.2.17",
|
|
74
74
|
"@xyo-network/bios-model": "~7.2.0",
|
|
75
|
-
"@xyo-network/boundwitness-builder": "~5.2.
|
|
76
|
-
"@xyo-network/chain-services": "~1.17.
|
|
77
|
-
"@xyo-network/module-abstract-mongodb": "~5.2.
|
|
78
|
-
"@xyo-network/module-model-mongodb": "~5.2.
|
|
79
|
-
"@xyo-network/node-memory": "~5.2.
|
|
80
|
-
"@xyo-network/xl1-protocol": "~1.14.
|
|
75
|
+
"@xyo-network/boundwitness-builder": "~5.2.17",
|
|
76
|
+
"@xyo-network/chain-services": "~1.17.3",
|
|
77
|
+
"@xyo-network/module-abstract-mongodb": "~5.2.17",
|
|
78
|
+
"@xyo-network/module-model-mongodb": "~5.2.17",
|
|
79
|
+
"@xyo-network/node-memory": "~5.2.17",
|
|
80
|
+
"@xyo-network/xl1-protocol": "~1.14.17",
|
|
81
81
|
"dotenv": "~17.2.3",
|
|
82
82
|
"eslint": "^9.39.1",
|
|
83
83
|
"nodemon": "~3.1.11",
|
package/src/ProducerActor.ts
CHANGED
|
@@ -209,6 +209,8 @@ export class ProducerActor extends Actor<ProducerActorParams> {
|
|
|
209
209
|
this._producerActorBlocksPublished?.add(1, this._metricAttributes)
|
|
210
210
|
// Record that we have produced a block so we do not produce it again
|
|
211
211
|
this._lastProducedBlock = nextBlock
|
|
212
|
+
} else {
|
|
213
|
+
this.logger?.log('No block produced at this time.')
|
|
212
214
|
}
|
|
213
215
|
}
|
|
214
216
|
})
|
package/src/runProducer.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
} from '@
|
|
4
|
-
import {
|
|
5
|
-
initProducerAccount, initStakeViewer, type OrchestratorInstance,
|
|
6
|
-
} from '@xyo-network/chain-orchestration'
|
|
1
|
+
import type { Address, Logger } from '@xylabs/sdk-js'
|
|
2
|
+
import { assertEx, exists } from '@xylabs/sdk-js'
|
|
3
|
+
import { initProducerAccount, type OrchestratorInstance } from '@xyo-network/chain-orchestration'
|
|
7
4
|
import {
|
|
8
5
|
initBlockRewardViewer, initChainService, initTimeService,
|
|
9
6
|
} from '@xyo-network/chain-services'
|
|
10
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
type ChainContractViewer, ChainContractViewerMoniker, type Config,
|
|
9
|
+
} from '@xyo-network/xl1-protocol-sdk'
|
|
11
10
|
import {
|
|
12
11
|
AccountBalanceViewerRpcSchemas, BlockViewerRpcSchemas, HttpRpcTransport, JsonRpcAccountBalanceViewer,
|
|
13
12
|
JsonRpcBlockViewer,
|
|
@@ -40,9 +39,30 @@ export const runProducer = async (context: RunProducerContext) => {
|
|
|
40
39
|
const chainId = (await blockViewer.currentBlock())[0].chain
|
|
41
40
|
const mempoolViewer = new JsonRpcMempoolViewer(new HttpRpcTransport(endpoint, { ...MempoolViewerRpcSchemas }))
|
|
42
41
|
const mempoolRunner = new JsonRpcMempoolRunner(new HttpRpcTransport(endpoint, { ...MempoolRunnerRpcSchemas }))
|
|
43
|
-
const
|
|
42
|
+
const chainService = await initChainService({
|
|
44
43
|
account, config, logger,
|
|
45
44
|
})
|
|
45
|
+
const chainContractViewer = {
|
|
46
|
+
forkedAtBlockNumber: function (): Promise<bigint> {
|
|
47
|
+
return chainService.forkedAtBlockNumber()
|
|
48
|
+
},
|
|
49
|
+
forkedAtHash: function (): Promise<bigint> {
|
|
50
|
+
return chainService.forkedAtHash()
|
|
51
|
+
},
|
|
52
|
+
forkedChainId: function (): Promise<Address> {
|
|
53
|
+
return chainService.forkedChainId()
|
|
54
|
+
},
|
|
55
|
+
minWithdrawalBlocks: function (): Promise<bigint> {
|
|
56
|
+
return chainService.minWithdrawalBlocks()
|
|
57
|
+
},
|
|
58
|
+
rewardsContract: function (): Promise<string> {
|
|
59
|
+
return chainService.rewardsContract()
|
|
60
|
+
},
|
|
61
|
+
stakingTokenAddress: function (): Promise<string> {
|
|
62
|
+
return chainService.stakingTokenAddress()
|
|
63
|
+
},
|
|
64
|
+
moniker: ChainContractViewerMoniker,
|
|
65
|
+
} satisfies ChainContractViewer
|
|
46
66
|
const blockRewardViewer = await initBlockRewardViewer({
|
|
47
67
|
config, logger, chainContractViewer,
|
|
48
68
|
})
|