trac-msb 0.2.26 → 0.3.0-beta.2
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/SECURITY.md +2 -2
- package/cli/commandHandler.js +317 -20
- package/cli/handlers.js +9 -1
- package/cli/interactive.js +4 -3
- package/cli/tokenSupplyAudit.js +90 -0
- package/msb.mjs +1 -0
- package/package.json +15 -6
- package/rpc/create_server.js +12 -3
- package/rpc/handlers.js +121 -0
- package/rpc/routes/v1.js +12 -0
- package/src/codecs/apply/applyOperationCodec.js +334 -0
- package/src/codecs/apply/applyOperations.generated.cjs +6380 -0
- package/src/codecs/consensus/v1/consensusV1.generated.cjs +3508 -0
- package/src/codecs/consensus/v1/consensusV1OperationCodec.js +161 -0
- package/src/codecs/consensus/v1/vdfConfigCodec.js +83 -0
- package/src/{utils/protobuf → codecs/network/v1}/networkV1.generated.cjs +664 -393
- package/src/codecs/network/v1/networkV1OperationCodec.js +25 -0
- package/src/codecs/protobufRuntime.cjs +95 -0
- package/src/codecs/state/escrowEntryCodec.js +45 -0
- package/src/codecs/state/state.generated.cjs +659 -0
- package/src/config/args.js +0 -1
- package/src/config/config.js +41 -7
- package/src/config/env.js +33 -9
- package/src/core/consensus/epochAppenderSelection/EpochAppenderSelectionError.js +55 -0
- package/src/core/consensus/epochAppenderSelection/EpochAppenderSelectionOperations.js +118 -0
- package/src/core/consensus/epochAppenderSelection/EpochAppenderSelector.js +1042 -0
- package/src/core/consensus/epochAppenderSelection/createEpochAppenderSelector.js +23 -0
- package/src/core/consensus/epochAppenderSelection/epochAppenderSelectionLedgerReader.js +274 -0
- package/src/core/consensus/epochAppenderSelection/epochAppenderSelectionState.js +488 -0
- package/src/core/consensus/epochAppenderSelection/epochAppenderSelectionStorage.js +93 -0
- package/src/core/consensus/quorum.js +11 -0
- package/src/core/consensus/services/EpochCoordinationRound.js +839 -0
- package/src/core/consensus/services/EpochCoordinatorOperations.js +211 -0
- package/src/core/consensus/services/EpochCoordinatorService.js +335 -0
- package/src/core/consensus/services/EpochRoundListeners.js +116 -0
- package/src/core/consensus/services/EpochStateMachine.js +141 -0
- package/src/core/consensus/services/VDFBare.js +291 -0
- package/src/core/consensus/services/VDFNode.js +111 -0
- package/src/core/consensus/services/VDFProgressWatchdog.js +79 -0
- package/src/core/consensus/services/VDFService.js +87 -0
- package/src/core/consensus/services/VDFServiceManager.js +147 -0
- package/src/core/consensus/services/createVDFService.js +16 -0
- package/src/core/consensus/services/vdf-guardian.js +32 -0
- package/src/core/consensus/services/vdf-worker.js +90 -0
- package/src/core/network/Network.js +327 -238
- package/src/core/network/protocols/consensus/IndexerMessages.js +72 -0
- package/src/core/network/protocols/consensus/v1/ConsensusV1ConnectionPolicy.js +57 -0
- package/src/core/network/protocols/consensus/v1/ConsensusV1MessageRouter.js +147 -0
- package/src/core/network/protocols/consensus/v1/ConsensusV1Protocol.js +72 -0
- package/src/core/network/protocols/consensus/v1/IndexerPendingRequestService.js +108 -0
- package/src/core/network/protocols/consensus/v1/V1ConsensusProtocolError.js +29 -0
- package/src/core/network/protocols/consensus/v1/handlers/V1EpochAppendOperationHandler.js +68 -0
- package/src/core/network/protocols/consensus/v1/handlers/V1EpochProofProposalOperationHandler.js +226 -0
- package/src/core/network/protocols/consensus/v1/validators/ConsensusValidationSchema.js +192 -0
- package/src/core/network/protocols/consensus/v1/validators/V1BaseConsensusOperation.js +428 -0
- package/src/core/network/protocols/consensus/v1/validators/V1EpochAppendReply.js +47 -0
- package/src/core/network/protocols/consensus/v1/validators/V1EpochAppendRequest.js +17 -0
- package/src/core/network/protocols/consensus/v1/validators/V1EpochProofProposalApproval.js +116 -0
- package/src/core/network/protocols/consensus/v1/validators/V1EpochProofProposalRequest.js +152 -0
- package/src/core/network/protocols/consensus/v1/validators/consensusValidationSchemaHelpers.js +145 -0
- package/src/core/network/protocols/shared/ConnectionOperationHandler.js +27 -0
- package/src/core/network/protocols/{NetworkMessages.js → validators/ValidatorMessages.js} +24 -14
- package/src/core/network/protocols/{ProtocolSession.js → validators/ValidatorProtocolSession.js} +22 -25
- package/src/core/network/protocols/{legacy/NetworkMessageRouter.js → validators/legacy/ValidatorLegacyMessageRouter.js} +6 -6
- package/src/core/network/protocols/{LegacyProtocol.js → validators/legacy/ValidatorLegacyProtocol.js} +9 -7
- package/src/core/network/protocols/{legacy → validators/legacy}/handlers/BaseStateOperationHandler.js +1 -1
- package/src/core/network/protocols/{legacy → validators/legacy}/handlers/LegacyGetRequestHandler.js +5 -5
- package/src/core/network/protocols/{legacy → validators/legacy}/handlers/LegacyRoleOperationHandler.js +5 -5
- package/src/core/network/protocols/{legacy → validators/legacy}/handlers/LegacySubnetworkOperationHandler.js +5 -5
- package/src/core/network/protocols/{legacy → validators/legacy}/handlers/LegacyTransferOperationHandler.js +5 -5
- package/src/core/network/protocols/{ProtocolInterface.js → validators/shared/ValidatorProtocolInterface.js} +5 -5
- package/src/core/network/protocols/{shared → validators/shared}/validators/PartialBootstrapDeploymentValidator.js +1 -1
- package/src/core/network/protocols/validators/shared/validators/PartialHtlcValidator.js +325 -0
- package/src/core/network/protocols/{shared → validators/shared}/validators/PartialOperationValidator.js +44 -21
- package/src/core/network/protocols/{shared → validators/shared}/validators/PartialRoleAccessValidator.js +3 -3
- package/src/core/network/protocols/{shared → validators/shared}/validators/PartialTransactionValidator.js +3 -3
- package/src/core/network/protocols/{shared → validators/shared}/validators/PartialTransferValidator.js +4 -4
- package/src/core/network/protocols/{v1 → validators/v1}/V1ProtocolError.js +1 -1
- package/src/core/network/{services/PendingRequestService.js → protocols/validators/v1/ValidatorPendingRequestService.js} +19 -82
- package/src/core/network/protocols/{v1/NetworkMessageRouter.js → validators/v1/ValidatorV1MessageRouter.js} +9 -9
- package/src/core/network/protocols/{V1Protocol.js → validators/v1/ValidatorV1Protocol.js} +10 -8
- package/src/core/network/protocols/{connectionPolicies.js → validators/v1/connectionPolicies.js} +1 -1
- package/src/core/network/protocols/{v1 → validators/v1}/handlers/V1BaseOperationHandler.js +6 -23
- package/src/core/network/protocols/{v1 → validators/v1}/handlers/V1BroadcastTransactionOperationHandler.js +14 -9
- package/src/core/network/protocols/{v1 → validators/v1}/handlers/V1LivenessOperationHandler.js +5 -4
- package/src/core/network/protocols/{v1 → validators/v1}/handlers/broadcastTransaction/BroadcastTransactionErrorMapper.js +3 -3
- package/src/core/network/protocols/{v1 → validators/v1}/handlers/broadcastTransaction/BroadcastTransactionOperationStrategies.js +44 -1
- package/src/core/network/protocols/{v1 → validators/v1}/handlers/broadcastTransaction/BroadcastTransactionPayloadUtils.js +1 -1
- package/src/core/network/protocols/{v1 → validators/v1}/validators/V1BaseOperation.js +19 -15
- package/src/core/network/protocols/{v1 → validators/v1}/validators/V1BroadcastTransactionRequest.js +2 -2
- package/src/core/network/protocols/{v1 → validators/v1}/validators/V1BroadcastTransactionResponse.js +34 -18
- package/src/core/network/protocols/{v1 → validators/v1}/validators/V1ValidationSchema.js +3 -3
- package/src/core/network/services/IndexerConnectionManager.js +88 -0
- package/src/core/network/services/TransactionPoolService.js +11 -18
- package/src/core/network/services/TransactionRateLimiterService.js +1 -1
- package/src/core/network/services/ValidatorConnectionManager.js +163 -0
- package/src/core/network/services/{MessageOrchestrator.js → ValidatorMessageOrchestrator.js} +34 -42
- package/src/core/network/services/ValidatorObserverService.js +21 -36
- package/src/core/network/shared/BasePendingRequestService.js +67 -0
- package/src/core/network/shared/PeerConnectionManager.js +185 -0
- package/src/core/state/State.js +1803 -159
- package/src/core/state/StateEventQueue.js +69 -0
- package/src/core/state/utils/address.js +10 -6
- package/src/core/state/utils/epochProof.js +109 -0
- package/src/core/state/utils/escrowEntry.js +178 -0
- package/src/core/state/validators/StateValidationSchema.js +757 -0
- package/src/core/state/validators/stateValidationRules.js +312 -0
- package/src/index.js +280 -67
- package/src/messages/consensus/v1/ConsensusMessageBuilder.js +368 -0
- package/src/messages/consensus/v1/ConsensusMessageDirector.js +142 -0
- package/src/messages/consensus/v1/consensusMessageFactory.js +12 -0
- package/src/messages/consensus/v1/epochAppendMessage.js +58 -0
- package/src/messages/network/v1/NetworkMessageBuilder.js +15 -7
- package/src/messages/state/ApplyStateMessageBuilder.js +499 -13
- package/src/messages/state/ApplyStateMessageDirector.js +261 -2
- package/src/utils/StateMachine.js +125 -0
- package/src/utils/applyOperations.js +45 -2
- package/src/utils/buffer.js +239 -59
- package/src/utils/consensusConfig.js +76 -0
- package/src/utils/constants.js +174 -73
- package/src/utils/helpers.js +0 -25
- package/src/utils/htlcLock.js +122 -0
- package/src/utils/logger.js +10 -4
- package/src/utils/migrationUtils.js +2 -1
- package/src/utils/normalizers.js +113 -0
- package/src/utils/scheduler/SchedulableService.js +107 -0
- package/src/utils/{Scheduler.js → scheduler/Scheduler.js} +56 -17
- package/src/core/network/services/ConnectionManager.js +0 -406
- package/src/utils/check.js +0 -525
- package/src/utils/protobuf/applyOperations.cjs +0 -1373
- package/src/utils/protobuf/operationHelpers.js +0 -81
- /package/src/core/network/protocols/{legacy → validators/legacy}/handlers/LegacyResponseHandler.js +0 -0
- /package/src/core/network/protocols/{legacy → validators/legacy}/validators/ValidatorResponse.js +0 -0
- /package/src/core/network/protocols/{legacy → validators/legacy}/validators/base/BaseResponse.js +0 -0
- /package/src/core/network/protocols/{v1 → validators/v1}/validators/V1LivenessRequest.js +0 -0
- /package/src/core/network/protocols/{v1 → validators/v1}/validators/V1LivenessResponse.js +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { OperationType } from '../../utils/constants.js';
|
|
1
|
+
import { ConsensusVersion, OperationType } from '../../utils/constants.js';
|
|
2
|
+
import { encodeEpochProofV1 } from '../../codecs/apply/applyOperationCodec.js';
|
|
3
|
+
import { uint8ToBuffer } from '../../utils/buffer.js';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Director that orchestrates ApplyStateMessageBuilder for partial and complete messages.
|
|
@@ -511,6 +513,263 @@ class ApplyStateMessageDirector {
|
|
|
511
513
|
.build();
|
|
512
514
|
return this.#builder.getPayload();
|
|
513
515
|
}
|
|
514
|
-
}
|
|
515
516
|
|
|
517
|
+
/**
|
|
518
|
+
* Build a complete set epoch payload.
|
|
519
|
+
* @param {string|Buffer} invokerAddress
|
|
520
|
+
* @param {string|Buffer} proofData
|
|
521
|
+
* @param {Array<string|Buffer>} approvals
|
|
522
|
+
* @returns {Promise<object>}
|
|
523
|
+
*/
|
|
524
|
+
async buildCompleteSetEpochMessage(invokerAddress, proofData, approvals) {
|
|
525
|
+
if (!this.#builder) throw new Error('Builder has not been set.');
|
|
526
|
+
const schemaVersion = uint8ToBuffer(ConsensusVersion.VDF_V1);
|
|
527
|
+
const epochData = encodeEpochProofV1({ pd: proofData, app: approvals });
|
|
528
|
+
|
|
529
|
+
await this.#builder
|
|
530
|
+
.setPhase('complete')
|
|
531
|
+
.setOutput('buffer')
|
|
532
|
+
.setOperationType(OperationType.SET_EPOCH)
|
|
533
|
+
.setAddress(invokerAddress)
|
|
534
|
+
.setEpochData(schemaVersion, epochData)
|
|
535
|
+
.build();
|
|
536
|
+
return this.#builder.getPayload();
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Build a complete set genesis epoch payload.
|
|
541
|
+
* @param {string|Buffer} invokerAddress
|
|
542
|
+
* @param {string|Buffer} txValidity
|
|
543
|
+
* @param {Buffer} encodedConsensusConfig
|
|
544
|
+
* @returns {Promise<object>}
|
|
545
|
+
*/
|
|
546
|
+
async buildCompleteSetGenesisEpochMessage(invokerAddress, txValidity, encodedConsensusConfig) {
|
|
547
|
+
if (!this.#builder) throw new Error('Builder has not been set.');
|
|
548
|
+
await this.#builder
|
|
549
|
+
.setPhase('complete')
|
|
550
|
+
.setOutput('buffer')
|
|
551
|
+
.setOperationType(OperationType.SET_GENESIS_EPOCH)
|
|
552
|
+
.setAddress(invokerAddress)
|
|
553
|
+
.setTxValidity(txValidity)
|
|
554
|
+
.setConsensusConfig(encodedConsensusConfig)
|
|
555
|
+
.build();
|
|
556
|
+
return this.#builder.getPayload();
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* Build a complete set consensus config payload.
|
|
561
|
+
* @param {string|Buffer} invokerAddress
|
|
562
|
+
* @param {string|Buffer} txValidity
|
|
563
|
+
* @param {Buffer} encodedConsensusConfig
|
|
564
|
+
* @returns {Promise<object>}
|
|
565
|
+
*/
|
|
566
|
+
async buildCompleteSetConsensusConfigMessage(invokerAddress, txValidity, encodedConsensusConfig) {
|
|
567
|
+
if (!this.#builder) throw new Error('Builder has not been set.');
|
|
568
|
+
await this.#builder
|
|
569
|
+
.setPhase('complete')
|
|
570
|
+
.setOutput('buffer')
|
|
571
|
+
.setOperationType(OperationType.SET_CONSENSUS_CONFIG)
|
|
572
|
+
.setAddress(invokerAddress)
|
|
573
|
+
.setTxValidity(txValidity)
|
|
574
|
+
.setConsensusConfig(encodedConsensusConfig)
|
|
575
|
+
.build();
|
|
576
|
+
return this.#builder.getPayload();
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Build a partial HTLC lock operation.
|
|
581
|
+
* The transaction hash produced by the builder is the lock identifier.
|
|
582
|
+
*
|
|
583
|
+
* @param {string|Buffer} invokerAddress Locker address.
|
|
584
|
+
* @param {string|Buffer} txValidity Current transaction-validity value.
|
|
585
|
+
* @param {object} lock Canonical HTLC lock terms and authorizations.
|
|
586
|
+
* @param {string|Buffer} [lock.metadata] Opaque application bytes (1–1024 bytes), or their hex representation.
|
|
587
|
+
* @param {'json'|'buffer'} output Output format.
|
|
588
|
+
* @returns {Promise<object>}
|
|
589
|
+
*/
|
|
590
|
+
async buildPartialHtlcLockOperationMessage(invokerAddress, txValidity, lock, output = 'buffer') {
|
|
591
|
+
if (!this.#builder) throw new Error('Builder has not been set.');
|
|
592
|
+
const {
|
|
593
|
+
claimAddress,
|
|
594
|
+
refundAddress,
|
|
595
|
+
amount,
|
|
596
|
+
feeAmount,
|
|
597
|
+
feeRecipient,
|
|
598
|
+
hashLock,
|
|
599
|
+
refundEpoch,
|
|
600
|
+
metadata,
|
|
601
|
+
signerSet,
|
|
602
|
+
threshold,
|
|
603
|
+
cosignerSignatures = [],
|
|
604
|
+
nonce
|
|
605
|
+
} = lock ?? {};
|
|
606
|
+
|
|
607
|
+
const builder = this.#builder
|
|
608
|
+
.setPhase('partial')
|
|
609
|
+
.setOutput(output)
|
|
610
|
+
.setOperationType(OperationType.HTLC_LOCK)
|
|
611
|
+
.setAddress(invokerAddress)
|
|
612
|
+
.setTxValidity(txValidity)
|
|
613
|
+
.setAmount(amount)
|
|
614
|
+
.setHtlcClaimAddress(claimAddress)
|
|
615
|
+
.setHtlcRefundAddress(refundAddress)
|
|
616
|
+
.setHtlcFeeAmount(feeAmount)
|
|
617
|
+
.setHtlcFeeRecipient(feeRecipient)
|
|
618
|
+
.setHtlcHashLock(hashLock)
|
|
619
|
+
.setHtlcRefundEpoch(refundEpoch)
|
|
620
|
+
.setHtlcMetadata(metadata)
|
|
621
|
+
.setHtlcSignerSet(signerSet)
|
|
622
|
+
.setHtlcThreshold(threshold)
|
|
623
|
+
.setHtlcCosignerSignatures(cosignerSignatures);
|
|
624
|
+
|
|
625
|
+
if (nonce !== undefined) builder.setNonce(nonce);
|
|
626
|
+
await builder.build();
|
|
627
|
+
return this.#builder.getPayload();
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Build a signed partial HTLC claim payload.
|
|
632
|
+
* @param {string|Buffer} invokerAddress
|
|
633
|
+
* @param {string|Buffer} txValidity
|
|
634
|
+
* @param {string|Buffer} lockId
|
|
635
|
+
* @param {string|Buffer} preimage
|
|
636
|
+
* @returns {Promise<object>}
|
|
637
|
+
*/
|
|
638
|
+
async buildPartialHtlcClaimOperationMessage(invokerAddress, txValidity, lockId, preimage) {
|
|
639
|
+
if (!this.#builder) throw new Error('Builder has not been set.');
|
|
640
|
+
await this.#builder
|
|
641
|
+
.setPhase('partial')
|
|
642
|
+
.setOutput('buffer')
|
|
643
|
+
.setOperationType(OperationType.HTLC_CLAIM)
|
|
644
|
+
.setAddress(invokerAddress)
|
|
645
|
+
.setTxValidity(txValidity)
|
|
646
|
+
.setHtlcLockId(lockId)
|
|
647
|
+
.setHtlcPreimage(preimage)
|
|
648
|
+
.build();
|
|
649
|
+
return this.#builder.getPayload();
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Add validator metadata to an already validated partial HTLC lock operation.
|
|
654
|
+
*
|
|
655
|
+
* @param {string|Buffer} invokerAddress Locker address.
|
|
656
|
+
* @param {object} operation Decoded partial hlo payload.
|
|
657
|
+
* @returns {Promise<object>}
|
|
658
|
+
*/
|
|
659
|
+
async buildCompleteHtlcLockOperationMessage(invokerAddress, operation) {
|
|
660
|
+
if (!this.#builder) throw new Error('Builder has not been set.');
|
|
661
|
+
await this.#builder
|
|
662
|
+
.setPhase('complete')
|
|
663
|
+
.setOutput('buffer')
|
|
664
|
+
.setOperationType(OperationType.HTLC_LOCK)
|
|
665
|
+
.setAddress(invokerAddress)
|
|
666
|
+
.setTxHash(operation?.tx)
|
|
667
|
+
.setTxValidity(operation?.txv)
|
|
668
|
+
.setAmount(operation?.am)
|
|
669
|
+
.setHtlcClaimAddress(operation?.ca)
|
|
670
|
+
.setHtlcRefundAddress(operation?.ra)
|
|
671
|
+
.setHtlcFeeAmount(operation?.fa)
|
|
672
|
+
.setHtlcFeeRecipient(operation?.fr)
|
|
673
|
+
.setHtlcHashLock(operation?.hl)
|
|
674
|
+
.setHtlcRefundEpoch(operation?.re)
|
|
675
|
+
.setHtlcMetadata(operation?.md)
|
|
676
|
+
.setHtlcSignerSet(operation?.ss)
|
|
677
|
+
.setHtlcThreshold(operation?.th)
|
|
678
|
+
.setHtlcCosignerSignatures(operation?.cs)
|
|
679
|
+
.setIncomingNonce(operation?.in)
|
|
680
|
+
.setIncomingSignature(operation?.is)
|
|
681
|
+
.build();
|
|
682
|
+
return this.#builder.getPayload();
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
/**
|
|
686
|
+
* Complete a submitter-signed HTLC claim with validator metadata.
|
|
687
|
+
* @param {string|Buffer} invokerAddress
|
|
688
|
+
* @param {string|Buffer} transactionHash
|
|
689
|
+
* @param {string|Buffer} txValidity
|
|
690
|
+
* @param {string|Buffer} lockId
|
|
691
|
+
* @param {string|Buffer} preimage
|
|
692
|
+
* @param {string|Buffer} incomingNonce
|
|
693
|
+
* @param {string|Buffer} incomingSignature
|
|
694
|
+
* @returns {Promise<object>}
|
|
695
|
+
*/
|
|
696
|
+
async buildCompleteHtlcClaimOperationMessage(
|
|
697
|
+
invokerAddress,
|
|
698
|
+
transactionHash,
|
|
699
|
+
txValidity,
|
|
700
|
+
lockId,
|
|
701
|
+
preimage,
|
|
702
|
+
incomingNonce,
|
|
703
|
+
incomingSignature
|
|
704
|
+
) {
|
|
705
|
+
if (!this.#builder) throw new Error('Builder has not been set.');
|
|
706
|
+
await this.#builder
|
|
707
|
+
.setPhase('complete')
|
|
708
|
+
.setOutput('buffer')
|
|
709
|
+
.setOperationType(OperationType.HTLC_CLAIM)
|
|
710
|
+
.setAddress(invokerAddress)
|
|
711
|
+
.setTxHash(transactionHash)
|
|
712
|
+
.setTxValidity(txValidity)
|
|
713
|
+
.setHtlcLockId(lockId)
|
|
714
|
+
.setHtlcPreimage(preimage)
|
|
715
|
+
.setIncomingNonce(incomingNonce)
|
|
716
|
+
.setIncomingSignature(incomingSignature)
|
|
717
|
+
.build();
|
|
718
|
+
return this.#builder.getPayload();
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Build a signed partial HTLC refund payload.
|
|
723
|
+
* @param {string|Buffer} invokerAddress
|
|
724
|
+
* @param {string|Buffer} txValidity
|
|
725
|
+
* @param {string|Buffer} lockId
|
|
726
|
+
* @param {'json'|'buffer'} output
|
|
727
|
+
* @returns {Promise<object>}
|
|
728
|
+
*/
|
|
729
|
+
async buildPartialHtlcRefundOperationMessage(invokerAddress, txValidity, lockId, output = 'buffer') {
|
|
730
|
+
if (!this.#builder) throw new Error('Builder has not been set.');
|
|
731
|
+
await this.#builder
|
|
732
|
+
.setPhase('partial')
|
|
733
|
+
.setOutput(output)
|
|
734
|
+
.setOperationType(OperationType.HTLC_REFUND)
|
|
735
|
+
.setAddress(invokerAddress)
|
|
736
|
+
.setTxValidity(txValidity)
|
|
737
|
+
.setHtlcLockId(lockId)
|
|
738
|
+
.build();
|
|
739
|
+
return this.#builder.getPayload();
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Add validator metadata to a validated, submitter-signed HTLC refund.
|
|
744
|
+
* @param {string|Buffer} invokerAddress
|
|
745
|
+
* @param {string|Buffer} transactionHash
|
|
746
|
+
* @param {string|Buffer} txValidity
|
|
747
|
+
* @param {string|Buffer} lockId
|
|
748
|
+
* @param {string|Buffer} incomingNonce
|
|
749
|
+
* @param {string|Buffer} incomingSignature
|
|
750
|
+
* @returns {Promise<object>}
|
|
751
|
+
*/
|
|
752
|
+
async buildCompleteHtlcRefundOperationMessage(
|
|
753
|
+
invokerAddress,
|
|
754
|
+
transactionHash,
|
|
755
|
+
txValidity,
|
|
756
|
+
lockId,
|
|
757
|
+
incomingNonce,
|
|
758
|
+
incomingSignature
|
|
759
|
+
) {
|
|
760
|
+
if (!this.#builder) throw new Error('Builder has not been set.');
|
|
761
|
+
await this.#builder
|
|
762
|
+
.setPhase('complete')
|
|
763
|
+
.setOutput('buffer')
|
|
764
|
+
.setOperationType(OperationType.HTLC_REFUND)
|
|
765
|
+
.setAddress(invokerAddress)
|
|
766
|
+
.setTxHash(transactionHash)
|
|
767
|
+
.setTxValidity(txValidity)
|
|
768
|
+
.setHtlcLockId(lockId)
|
|
769
|
+
.setIncomingNonce(incomingNonce)
|
|
770
|
+
.setIncomingSignature(incomingSignature)
|
|
771
|
+
.build();
|
|
772
|
+
return this.#builder.getPayload();
|
|
773
|
+
}
|
|
774
|
+
}
|
|
516
775
|
export default ApplyStateMessageDirector;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import ReadyResource from 'ready-resource';
|
|
2
|
+
|
|
3
|
+
const READY_RESOURCE_EVENTS = ['ready', 'close'];
|
|
4
|
+
|
|
5
|
+
export class StateMachine extends ReadyResource {
|
|
6
|
+
#state;
|
|
7
|
+
#context = {};
|
|
8
|
+
#discardState;
|
|
9
|
+
#listeners = new Map();
|
|
10
|
+
#transitions;
|
|
11
|
+
#handlers;
|
|
12
|
+
#transition = null;
|
|
13
|
+
|
|
14
|
+
constructor(transitions, initialState, discardState, handlers = {}) {
|
|
15
|
+
super();
|
|
16
|
+
if (!transitions) throw new Error('StateMachine: transitions is required');
|
|
17
|
+
if (!initialState) throw new Error('StateMachine: initialState is required');
|
|
18
|
+
if (discardState === undefined) throw new Error('StateMachine: discardState is required (pass null to disable context clearing)');
|
|
19
|
+
|
|
20
|
+
this.#transitions = transitions;
|
|
21
|
+
this.#state = initialState;
|
|
22
|
+
this.#discardState = discardState;
|
|
23
|
+
this.#handlers = handlers;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async _close() {
|
|
27
|
+
this.clearListeners();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get state() {
|
|
31
|
+
return this.#state;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get context() {
|
|
35
|
+
return this.#context;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
appendContext(payload = {}) {
|
|
39
|
+
Object.assign(this.#context, payload);
|
|
40
|
+
return this.#context;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
shouldRun() {
|
|
44
|
+
return this.closing === null && !this.closed;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async send(event, payload = {}) {
|
|
48
|
+
if (!this.shouldRun()) return false;
|
|
49
|
+
|
|
50
|
+
const next = this.#transitions[this.#state]?.[event];
|
|
51
|
+
if (!next) return false;
|
|
52
|
+
|
|
53
|
+
this.appendContext(payload);
|
|
54
|
+
|
|
55
|
+
const prev = this.#state;
|
|
56
|
+
const transition = { machine: this, prev, next, context: this.#context };
|
|
57
|
+
this.#transition = transition;
|
|
58
|
+
this.#state = next;
|
|
59
|
+
await this.#emit(event, transition);
|
|
60
|
+
|
|
61
|
+
// Another transition may have run while an event listener was awaited.
|
|
62
|
+
if (!this.shouldRun() || this.#transition !== transition) return false;
|
|
63
|
+
|
|
64
|
+
if (this.#discardState !== null && next === this.#discardState) {
|
|
65
|
+
this.#context = {};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
await this.#dispatch(next);
|
|
69
|
+
|
|
70
|
+
return transition;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// The initial state is assigned directly in the constructor, not reached via send(),
|
|
74
|
+
// so its handler never fires on its own - nothing ever "transitions into" it. This
|
|
75
|
+
// dispatches to the current state's handler once, the same way any other transition
|
|
76
|
+
// does, so callers never need to know which state that is.
|
|
77
|
+
async enter(payload = {}) {
|
|
78
|
+
if (!this.shouldRun()) return false;
|
|
79
|
+
|
|
80
|
+
this.appendContext(payload);
|
|
81
|
+
|
|
82
|
+
const transition = { machine: this, prev: null, next: this.#state, context: this.#context };
|
|
83
|
+
this.#transition = transition;
|
|
84
|
+
await this.#emit('ENTER', transition);
|
|
85
|
+
|
|
86
|
+
if (!this.shouldRun() || this.#transition !== transition) return false;
|
|
87
|
+
|
|
88
|
+
await this.#dispatch(transition.next);
|
|
89
|
+
|
|
90
|
+
return transition;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async #dispatch(state) {
|
|
94
|
+
const handler = this.#handlers[state];
|
|
95
|
+
if (handler) await handler(this.#context, this);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
on(event, fn) {
|
|
99
|
+
if (READY_RESOURCE_EVENTS.includes(event)) {
|
|
100
|
+
super.on(event, fn);
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!this.#listeners.has(event)) this.#listeners.set(event, []);
|
|
105
|
+
|
|
106
|
+
this.#listeners.get(event).push(fn);
|
|
107
|
+
return this;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
clearListeners() {
|
|
111
|
+
this.#listeners.clear();
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async #emit(event, data) {
|
|
116
|
+
for (const fn of this.#listeners.get(event) ?? []) {
|
|
117
|
+
if (!this.shouldRun() || this.#transition !== data) return;
|
|
118
|
+
await fn(data);
|
|
119
|
+
}
|
|
120
|
+
for (const fn of this.#listeners.get('*') ?? []) {
|
|
121
|
+
if (!this.shouldRun() || this.#transition !== data) return;
|
|
122
|
+
await fn({ event, ...data });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -48,6 +48,26 @@ const isBalanceInitialization = type => {
|
|
|
48
48
|
].includes(type);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
const isHtlc = type => {
|
|
52
|
+
return [
|
|
53
|
+
OperationType.HTLC_LOCK,
|
|
54
|
+
OperationType.HTLC_CLAIM,
|
|
55
|
+
OperationType.HTLC_REFUND
|
|
56
|
+
].includes(type);
|
|
57
|
+
}
|
|
58
|
+
const isSetEpoch = type => {
|
|
59
|
+
return [
|
|
60
|
+
OperationType.SET_EPOCH
|
|
61
|
+
].includes(type);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const isConsensusControl = type => {
|
|
65
|
+
return [
|
|
66
|
+
OperationType.SET_GENESIS_EPOCH,
|
|
67
|
+
OperationType.SET_CONSENSUS_CONFIG
|
|
68
|
+
].includes(type);
|
|
69
|
+
}
|
|
70
|
+
|
|
51
71
|
const operationToPayload = type => {
|
|
52
72
|
const fromTo = [
|
|
53
73
|
{
|
|
@@ -77,6 +97,26 @@ const operationToPayload = type => {
|
|
|
77
97
|
{
|
|
78
98
|
condition: isBalanceInitialization,
|
|
79
99
|
jsonPath: 'bio'
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
condition: type => type === OperationType.HTLC_LOCK,
|
|
103
|
+
jsonPath: 'hlo'
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
condition: type => type === OperationType.HTLC_CLAIM,
|
|
107
|
+
jsonPath: 'hco'
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
condition: type => type === OperationType.HTLC_REFUND,
|
|
111
|
+
jsonPath: 'hro'
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
condition: isSetEpoch,
|
|
115
|
+
jsonPath: 'seo'
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
condition: isConsensusControl,
|
|
119
|
+
jsonPath: 'cco'
|
|
80
120
|
}
|
|
81
121
|
]
|
|
82
122
|
const match = fromTo.find(entry => !!entry.condition(type))
|
|
@@ -91,5 +131,8 @@ export {
|
|
|
91
131
|
isBootstrapDeployment,
|
|
92
132
|
operationToPayload,
|
|
93
133
|
isTransfer,
|
|
94
|
-
isBalanceInitialization
|
|
95
|
-
|
|
134
|
+
isBalanceInitialization,
|
|
135
|
+
isHtlc,
|
|
136
|
+
isSetEpoch,
|
|
137
|
+
isConsensusControl
|
|
138
|
+
}
|