@keetanetwork/keetanet-client 0.14.9 → 0.14.10
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/client/index-browser.js +217 -75
- package/client/index.js +200 -70
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.BaseVoteBuilder.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.BlockOperation.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.ECDSAKeyPair.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256K1KeyPair.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.ECDSASECP256R1KeyPair.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.ED25519KeyPair.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.IdempotentKey.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.IdentifierKeyPair.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.KeetaNetError.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.KeetaNetLedgerError.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.KeyInterface.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.KeyStorage.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.PermissionSetHolder.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.SignatureStorage.html +1 -1
- package/docs/classes/KeetaNetSDK.Referenced.StatsPending.html +1 -1
- package/docs/hierarchy.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.ACLEntry.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.ACLUpdate.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.ASN1ExplicitContextTag.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.ASN1ImplicitContextTag.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.ASN1Object.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BaseExternalKeyPairFunctions.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BaseGenerationConfig.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BaseIdentifierCreateArguments.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperation.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationCREATE_IDENTIFIER.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationMANAGE_CERTIFICATE.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationMANAGE_CERTIFICATESerializable.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationMODIFY_PERMISSIONS.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationRECEIVE.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationSEND.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationSET_INFO.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationSET_REP.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationTOKEN_ADMIN_MODIFY_BALANCE.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.BlockJSONOperationTOKEN_ADMIN_SUPPLY.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.Constructor.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.DisposableTimingHandle.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.ExternalKeyPairFunctionsNoEncryption.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.ExternalKeyPairFunctionsSupportsEncryption.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.InitialConfigSupply.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.InstanceSet.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.KVGenericOptionsType.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.KVSetOptionsType.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.ModifyTokenBalanceEntry.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.MultiSigIdentifierCreateArguments.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.MultisigConfig.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.NumericValueEntry.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.P2PPeerBase.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.P2PPeerListener.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.P2PPeerRepBase.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.PublicKeyStorage.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.RequestTokenReceiveEntry.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.TokenNumericEntry.html +1 -1
- package/docs/interfaces/KeetaNetSDK.Referenced.WithIsInstance.html +1 -1
- package/docs/modules/KeetaNetSDK.Referenced.html +1 -1
- package/docs/types/KeetaNetSDK.Referenced.VoteOrQuoteOptions.html +3 -0
- package/docs/variables/KeetaNetSDK.Referenced.FullLedgerBaseErrorCode.html +1 -1
- package/docs/variables/KeetaNetSDK.Referenced.allFullErrorCodes.html +1 -1
- package/lib/error/index.d.ts +1 -1
- package/lib/error/ledger.d.ts +3 -3
- package/lib/ledger/db_spanner_helper.d.ts +1 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/version.d.ts +1 -1
package/client/index-browser.js
CHANGED
|
@@ -116912,9 +116912,9 @@ function client_ledger_toPrimitive(t, r) { if ("object" != typeof t || !t) retur
|
|
|
116912
116912
|
|
|
116913
116913
|
|
|
116914
116914
|
const client_LedgerErrorType = 'LEDGER';
|
|
116915
|
-
const client_LedgerBaseErrorCodes = ['BLOCK_ALREADY_EXISTS', 'TRANSACTION_ABORTED', 'INVALID_CHAIN', 'INVALID_NETWORK', 'INVALID_SUBNET', 'INVALID_PERMISSIONS', 'INVALID_OWNER_COUNT', 'INVALID_BALANCE', 'INVALID_SET_REP', 'OPERATION_NOT_SUPPORTED', 'NOT_EMPTY', 'PREVIOUS_ALREADY_USED', 'PREVIOUS_NOT_SEEN', 'SUCCESSOR_VOTE_EXISTS', 'INSUFFICIENT_VOTING_WEIGHT', 'INVALID_ACCOUNT_INFO_KEY', 'RECEIVE_NOT_MET', 'DUPLICATE_VOTE_FOUND', 'CANNOT_EXCHANGE_PERM_VOTE', 'BLOCKS_DIFFER_FROM_VOTED_ON', 'NO_PERM_WITHOUT_SELF_TEMP', 'DUPLICATE_VOTE_ISSUER_FOUND', 'OTHER', 'MISSING_BLOCKS',
|
|
116915
|
+
const client_LedgerBaseErrorCodes = ['BLOCK_ALREADY_EXISTS', 'BLOCK_EXPIRED', 'TRANSACTION_ABORTED', 'INVALID_CHAIN', 'INVALID_NETWORK', 'INVALID_SUBNET', 'INVALID_PERMISSIONS', 'INVALID_OWNER_COUNT', 'INVALID_BALANCE', 'INVALID_SET_REP', 'OPERATION_NOT_SUPPORTED', 'NOT_EMPTY', 'PREVIOUS_ALREADY_USED', 'PREVIOUS_NOT_SEEN', 'SUCCESSOR_VOTE_EXISTS', 'INSUFFICIENT_VOTING_WEIGHT', 'INVALID_ACCOUNT_INFO_KEY', 'RECEIVE_NOT_MET', 'DUPLICATE_VOTE_FOUND', 'CANNOT_EXCHANGE_PERM_VOTE', 'TEMP_VOTE_INCLUDES_SELF', 'BLOCKS_DIFFER_FROM_VOTED_ON', 'NO_PERM_WITHOUT_SELF_TEMP', 'DUPLICATE_VOTE_ISSUER_FOUND', 'OTHER', 'MISSING_BLOCKS',
|
|
116916
116916
|
// Fee Errors
|
|
116917
|
-
'FEE_AMOUNT_MISMATCH', 'FEE_TOKEN_MISMATCH', 'FEE_MISSING', 'MISSING_REQUIRED_FEE_BLOCK', '
|
|
116917
|
+
'FEE_AMOUNT_MISMATCH', 'FEE_TOKEN_MISMATCH', 'FEE_MISSING', 'MISSING_REQUIRED_FEE_BLOCK', 'VOTE_WITH_QUOTE', 'QUOTE_MISMATCH', 'REQUIRED_FEE_MISMATCH'];
|
|
116918
116918
|
|
|
116919
116919
|
// Errors that can trigger rep sync
|
|
116920
116920
|
const client_LedgerVoteErrorCodes = ['NOT_SUCCESSOR', 'NOT_OPENING'];
|
|
@@ -126409,6 +126409,7 @@ function client_lib_ledger_toPrimitive(t, r) { if ("object" != typeof t || !t) r
|
|
|
126409
126409
|
|
|
126410
126410
|
|
|
126411
126411
|
|
|
126412
|
+
|
|
126412
126413
|
/**
|
|
126413
126414
|
* Kind of ledger
|
|
126414
126415
|
*/
|
|
@@ -126487,6 +126488,10 @@ class client_LedgerStorageTransactionBase {
|
|
|
126487
126488
|
}
|
|
126488
126489
|
}
|
|
126489
126490
|
|
|
126491
|
+
/**
|
|
126492
|
+
* Options for the LedgerStorageAPI.voteOrQuoteWithFees function
|
|
126493
|
+
*/
|
|
126494
|
+
|
|
126490
126495
|
/**
|
|
126491
126496
|
* Each Ledger Storage backend must implement this interface
|
|
126492
126497
|
*/
|
|
@@ -126567,24 +126572,50 @@ class client_LedgerAtomicInterface {
|
|
|
126567
126572
|
}
|
|
126568
126573
|
const privateKey = client_ledger_classPrivateFieldGet(client_ledger_privateKey, this);
|
|
126569
126574
|
const ledgerPubKey = privateKey.publicKeyString.get();
|
|
126575
|
+
const transaction = client_ledger_assertClassBrand(client_LedgerAtomicInterface_brand, this, client_assertTransaction).call(this);
|
|
126576
|
+
|
|
126577
|
+
/**
|
|
126578
|
+
* If there are other votes, if all of them are permanent then
|
|
126579
|
+
* we are requesting a temporary vote with a minority of permanent
|
|
126580
|
+
* votes to disable the block timestamp checking; otherwise if
|
|
126581
|
+
* any are temporary we are requesting a permanent vote
|
|
126582
|
+
*
|
|
126583
|
+
* If there are no other votes, we need to produce a temporary
|
|
126584
|
+
* vote.
|
|
126585
|
+
*/
|
|
126586
|
+
let outcome = 'temporary';
|
|
126587
|
+
let requireBlockTimestampCheck = true;
|
|
126588
|
+
if (otherVotes !== undefined) {
|
|
126589
|
+
const foundTemporary = otherVotes.some(function (checkVote) {
|
|
126590
|
+
return !checkVote.$permanent;
|
|
126591
|
+
});
|
|
126592
|
+
if (foundTemporary) {
|
|
126593
|
+
outcome = 'permanent';
|
|
126594
|
+
} else {
|
|
126595
|
+
outcome = 'temporary';
|
|
126596
|
+
requireBlockTimestampCheck = false;
|
|
126597
|
+
}
|
|
126598
|
+
}
|
|
126599
|
+
|
|
126600
|
+
/*
|
|
126601
|
+
* If we have a quote, ensure it is valid for this ledger and outcome
|
|
126602
|
+
*/
|
|
126570
126603
|
if (quote !== undefined) {
|
|
126571
|
-
if (
|
|
126572
|
-
throw new client_ledger_KeetaNetLedgerError('
|
|
126604
|
+
if (outcome === 'permanent') {
|
|
126605
|
+
throw new client_ledger_KeetaNetLedgerError('LEDGER_VOTE_WITH_QUOTE', 'Quote should not be included when requesting permanent votes');
|
|
126573
126606
|
}
|
|
126574
126607
|
if (!quote.issuer.comparePublicKey(ledgerPubKey)) {
|
|
126575
126608
|
throw new client_ledger_KeetaNetLedgerError('LEDGER_QUOTE_MISMATCH', 'Provided quote does not match issuer public key');
|
|
126576
126609
|
}
|
|
126577
126610
|
}
|
|
126578
|
-
const transaction = client_ledger_assertClassBrand(client_LedgerAtomicInterface_brand, this, client_assertTransaction).call(this);
|
|
126579
126611
|
|
|
126580
126612
|
/**
|
|
126581
|
-
*
|
|
126582
|
-
* us and the blocks are in the same order as the set of
|
|
126583
|
-
* blocks we are voting on now
|
|
126613
|
+
* Verify some attributes about the other votes if they are provided
|
|
126584
126614
|
*/
|
|
126585
126615
|
let hasFeeBlock = false;
|
|
126586
|
-
|
|
126587
|
-
|
|
126616
|
+
let foundOurVote;
|
|
126617
|
+
if (otherVotes) {
|
|
126618
|
+
foundOurVote = false;
|
|
126588
126619
|
const seenVoteUIDs = new Set();
|
|
126589
126620
|
const seenVoteIssuers = new client_lib_account.Set();
|
|
126590
126621
|
let blockCount = blocks.length;
|
|
@@ -126596,7 +126627,7 @@ class client_LedgerAtomicInterface {
|
|
|
126596
126627
|
const requiredFees = new Map();
|
|
126597
126628
|
for (const checkVote of otherVotes) {
|
|
126598
126629
|
if (checkVote.quote === true) {
|
|
126599
|
-
throw new client_ledger_KeetaNetLedgerError('
|
|
126630
|
+
throw new client_ledger_KeetaNetLedgerError('LEDGER_VOTE_WITH_QUOTE', 'Cannot request votes with quote as supporting votes');
|
|
126600
126631
|
}
|
|
126601
126632
|
if (seenVoteUIDs.has(checkVote.$id)) {
|
|
126602
126633
|
throw new client_ledger_KeetaNetLedgerError('LEDGER_DUPLICATE_VOTE_FOUND', 'Duplicate vote UID found');
|
|
@@ -126609,13 +126640,22 @@ class client_LedgerAtomicInterface {
|
|
|
126609
126640
|
if (checkVote.fee !== undefined) {
|
|
126610
126641
|
requiredFees.set(checkVote.issuer, checkVote.fee);
|
|
126611
126642
|
}
|
|
126612
|
-
|
|
126613
|
-
|
|
126643
|
+
|
|
126644
|
+
/*
|
|
126645
|
+
* Handle errors specific to requesting a permanent vote
|
|
126646
|
+
*/
|
|
126647
|
+
if (outcome === 'permanent') {
|
|
126648
|
+
if (checkVote.$permanent && checkVote.issuer.comparePublicKey(ledgerPubKey)) {
|
|
126649
|
+
throw new client_ledger_KeetaNetLedgerError('LEDGER_CANNOT_EXCHANGE_PERM_VOTE', 'Asked to exchange a permanent vote from us for a permanent vote from us');
|
|
126650
|
+
}
|
|
126614
126651
|
}
|
|
126652
|
+
|
|
126653
|
+
/* XXX:TODO: Need to account for fee blocks if the input is a permanent vote */
|
|
126615
126654
|
let blocksDifferFromVoteBlocks = checkVote.blocks.length !== blockCount;
|
|
126616
126655
|
|
|
126617
126656
|
/* If they do not differ from length alone, compare block hashes */
|
|
126618
126657
|
if (!blocksDifferFromVoteBlocks) {
|
|
126658
|
+
/* XXX:TODO: Need to account for fee blocks if the input is a permanent vote */
|
|
126619
126659
|
for (let blockIndex = 0; blockIndex < blockCount; blockIndex++) {
|
|
126620
126660
|
if (!blocks[blockIndex].hash.compareHexString(checkVote.blocks[blockIndex])) {
|
|
126621
126661
|
blocksDifferFromVoteBlocks = true;
|
|
@@ -126630,38 +126670,82 @@ class client_LedgerAtomicInterface {
|
|
|
126630
126670
|
foundOurVote = true;
|
|
126631
126671
|
}
|
|
126632
126672
|
}
|
|
126633
|
-
|
|
126634
|
-
|
|
126635
|
-
|
|
126636
|
-
|
|
126637
|
-
|
|
126638
|
-
|
|
126673
|
+
|
|
126674
|
+
/*
|
|
126675
|
+
* We only care about fees if we are issuing a permanent vote,
|
|
126676
|
+
* if we are issuing a temporary vote the fees will be checked
|
|
126677
|
+
* when the permanent vote is requested
|
|
126678
|
+
*/
|
|
126679
|
+
if (outcome === 'permanent') {
|
|
126680
|
+
if (requiredFees.size > 0) {
|
|
126681
|
+
if (!hasFeeBlock) {
|
|
126682
|
+
throw new client_ledger_KeetaNetLedgerError('LEDGER_MISSING_REQUIRED_FEE_BLOCK', 'Missing fee block but votes require it');
|
|
126683
|
+
}
|
|
126684
|
+
if (requiredFees.size !== (possibleFeeBlock === null || possibleFeeBlock === void 0 ? void 0 : possibleFeeBlock.operations.length)) {
|
|
126685
|
+
throw new client_ledger_KeetaNetLedgerError('LEDGER_REQUIRED_FEE_MISMATCH', 'Fee Block Operations do not match required fees');
|
|
126686
|
+
}
|
|
126639
126687
|
}
|
|
126640
|
-
}
|
|
126641
126688
|
|
|
126642
|
-
|
|
126643
|
-
|
|
126644
|
-
|
|
126645
|
-
|
|
126646
|
-
|
|
126647
|
-
|
|
126648
|
-
|
|
126649
|
-
|
|
126650
|
-
|
|
126651
|
-
|
|
126652
|
-
|
|
126653
|
-
|
|
126689
|
+
// Verify that all required fees have been included in the fee block
|
|
126690
|
+
for (const [issuer, fee] of requiredFees) {
|
|
126691
|
+
const foundFee = possibleFeeBlock === null || possibleFeeBlock === void 0 ? void 0 : possibleFeeBlock.operations.find(operation => {
|
|
126692
|
+
var _fee$payTo, _fee$token;
|
|
126693
|
+
const expectedPayTo = (_fee$payTo = fee.payTo) !== null && _fee$payTo !== void 0 ? _fee$payTo : issuer;
|
|
126694
|
+
const expectedToken = (_fee$token = fee.token) !== null && _fee$token !== void 0 ? _fee$token : client_ledger_classPrivateFieldGet(client_ledger, this).baseToken;
|
|
126695
|
+
if (operation.type === client_OperationType.SEND && operation.to.comparePublicKey(expectedPayTo)) {
|
|
126696
|
+
if (operation.amount !== fee.amount) {
|
|
126697
|
+
throw new client_ledger_KeetaNetLedgerError('LEDGER_FEE_AMOUNT_MISMATCH', `Fee Amount Mismatch, found: ${operation.amount} expected: ${fee.amount}`);
|
|
126698
|
+
}
|
|
126699
|
+
if (!operation.token.comparePublicKey(expectedToken)) {
|
|
126700
|
+
throw new client_ledger_KeetaNetLedgerError('LEDGER_FEE_TOKEN_MISMATCH', `Fee Token Mismatch, found: ${operation.token.publicKeyString.get()} expected: ${expectedToken.publicKeyString.get()}`);
|
|
126701
|
+
}
|
|
126702
|
+
return true;
|
|
126654
126703
|
}
|
|
126655
|
-
return
|
|
126704
|
+
return false;
|
|
126705
|
+
});
|
|
126706
|
+
if (foundFee === undefined) {
|
|
126707
|
+
var _fee$payTo$publicKeyS, _fee$payTo2;
|
|
126708
|
+
throw new client_ledger_KeetaNetLedgerError('LEDGER_FEE_MISSING', `Missing Required Fee for ${(_fee$payTo$publicKeyS = (_fee$payTo2 = fee.payTo) === null || _fee$payTo2 === void 0 ? void 0 : _fee$payTo2.publicKeyString.get()) !== null && _fee$payTo$publicKeyS !== void 0 ? _fee$payTo$publicKeyS : issuer.publicKeyString.get()}`);
|
|
126656
126709
|
}
|
|
126657
|
-
return false;
|
|
126658
|
-
});
|
|
126659
|
-
if (foundFee === undefined) {
|
|
126660
|
-
var _fee$payTo$publicKeyS, _fee$payTo2;
|
|
126661
|
-
throw new client_ledger_KeetaNetLedgerError('LEDGER_FEE_MISSING', `Missing Required Fee for ${(_fee$payTo$publicKeyS = (_fee$payTo2 = fee.payTo) === null || _fee$payTo2 === void 0 ? void 0 : _fee$payTo2.publicKeyString.get()) !== null && _fee$payTo$publicKeyS !== void 0 ? _fee$payTo$publicKeyS : issuer.publicKeyString.get()}`);
|
|
126662
126710
|
}
|
|
126711
|
+
} else if (outcome === 'temporary') {
|
|
126712
|
+
if (foundOurVote) {
|
|
126713
|
+
throw new client_ledger_KeetaNetLedgerError('LEDGER_TEMP_VOTE_INCLUDES_SELF', 'Temporary vote request cannot include a vote from self');
|
|
126714
|
+
}
|
|
126715
|
+
/* XXX:TODO: We need to check the fee block to find out the fee paid to us and include that in our temporary vote so that it can be verified later */
|
|
126716
|
+
} else {
|
|
126717
|
+
client_assertNever(outcome);
|
|
126718
|
+
}
|
|
126719
|
+
}
|
|
126720
|
+
|
|
126721
|
+
/**
|
|
126722
|
+
* If the outcome is a temporary vote and the are other votes
|
|
126723
|
+
* ensure that the temporary votes represent a minority of
|
|
126724
|
+
* the voting weight and do not include a vote from us
|
|
126725
|
+
*/
|
|
126726
|
+
if (outcome === 'temporary' && otherVotes !== undefined) {
|
|
126727
|
+
const totalVotingPower = await this.votingPower();
|
|
126728
|
+
const minVotingWeight = totalVotingPower / 4n;
|
|
126729
|
+
const combinedVotingPower = (await Promise.all(otherVotes.map(async vote => {
|
|
126730
|
+
return await this.votingPower(vote.issuer);
|
|
126731
|
+
}))).reduce(function (sum, value) {
|
|
126732
|
+
return sum + value;
|
|
126733
|
+
}, 0n);
|
|
126734
|
+
if (combinedVotingPower <= minVotingWeight) {
|
|
126735
|
+
throw new client_ledger_KeetaNetLedgerError('LEDGER_INSUFFICIENT_VOTING_WEIGHT', 'Temporary vote must represent at least a minority of the voting weight');
|
|
126736
|
+
}
|
|
126737
|
+
}
|
|
126738
|
+
|
|
126739
|
+
/**
|
|
126740
|
+
* If there are other votes, ensure one of them was issued by
|
|
126741
|
+
* us and the blocks are in the same order as the set of
|
|
126742
|
+
* blocks we are voting on now
|
|
126743
|
+
*/
|
|
126744
|
+
if (outcome === 'permanent') {
|
|
126745
|
+
if (otherVotes === undefined) {
|
|
126746
|
+
throw new Error('internal error: Outcome permanent but otherVotes is undefined');
|
|
126663
126747
|
}
|
|
126664
|
-
if (
|
|
126748
|
+
if (foundOurVote !== true) {
|
|
126665
126749
|
throw new client_ledger_KeetaNetLedgerError('LEDGER_NO_PERM_WITHOUT_SELF_TEMP', 'Asked to give a permanent vote without a temporary vote from us');
|
|
126666
126750
|
}
|
|
126667
126751
|
}
|
|
@@ -126710,7 +126794,13 @@ class client_LedgerAtomicInterface {
|
|
|
126710
126794
|
*/
|
|
126711
126795
|
|
|
126712
126796
|
let mayReplace = false;
|
|
126713
|
-
if (previousVotes.length === 1 &&
|
|
126797
|
+
if (previousVotes.length === 1 && outcome === 'permanent') {
|
|
126798
|
+
var _otherVotes$length;
|
|
126799
|
+
const otherVotesCount = (_otherVotes$length = otherVotes === null || otherVotes === void 0 ? void 0 : otherVotes.length) !== null && _otherVotes$length !== void 0 ? _otherVotes$length : 0;
|
|
126800
|
+
if (otherVotesCount < 1) {
|
|
126801
|
+
throw new Error('internal error: outcome permanent but otherVotes is empty or undefined');
|
|
126802
|
+
}
|
|
126803
|
+
;
|
|
126714
126804
|
const ourVote = previousVotes[0];
|
|
126715
126805
|
mayReplace = !ourVote.$permanent && ourVote.issuer.comparePublicKey(ledgerPubKey);
|
|
126716
126806
|
}
|
|
@@ -126721,15 +126811,25 @@ class client_LedgerAtomicInterface {
|
|
|
126721
126811
|
}
|
|
126722
126812
|
|
|
126723
126813
|
/**
|
|
126724
|
-
* If
|
|
126814
|
+
* If we are producing a temporary vote, do it now and return
|
|
126725
126815
|
*/
|
|
126726
|
-
if (
|
|
126727
|
-
const vote = await client_ledger_assertClassBrand(client_LedgerAtomicInterface_brand, this, client_voteOrQuoteWithFees).call(this, blocks, 'VOTE', quote
|
|
126816
|
+
if (outcome === 'temporary') {
|
|
126817
|
+
const vote = await client_ledger_assertClassBrand(client_LedgerAtomicInterface_brand, this, client_voteOrQuoteWithFees).call(this, blocks, 'VOTE', quote, {
|
|
126818
|
+
requireBlockTimestampCheck
|
|
126819
|
+
});
|
|
126728
126820
|
const blocksAndVote = src_client_VoteStaple.fromVotesAndBlocks([vote], blocks);
|
|
126729
126821
|
await client_ledger_classPrivateFieldGet(client_ledger_storage, this).addPendingVote(transaction, blocksAndVote);
|
|
126730
126822
|
return vote;
|
|
126731
126823
|
}
|
|
126732
126824
|
|
|
126825
|
+
/**
|
|
126826
|
+
* From here on we are producing a permanent vote but we need
|
|
126827
|
+
* to narrow some types for TypeScript
|
|
126828
|
+
*/
|
|
126829
|
+
if (otherVotes === undefined) {
|
|
126830
|
+
throw new Error('internal error: Outcome permanent but otherVotes is undefined');
|
|
126831
|
+
}
|
|
126832
|
+
|
|
126733
126833
|
/**
|
|
126734
126834
|
* Validate ledger outcome again before permanent votes if blocks includes a fee block
|
|
126735
126835
|
*/
|
|
@@ -127540,8 +127640,8 @@ async function client_validateBlocksForVote(blocks) {
|
|
|
127540
127640
|
allLedgerIdempotentKeys
|
|
127541
127641
|
};
|
|
127542
127642
|
}
|
|
127543
|
-
async function client_voteOrQuoteWithFees(blocks, type, quote) {
|
|
127544
|
-
var _quote$fee;
|
|
127643
|
+
async function client_voteOrQuoteWithFees(blocks, type, quote, options) {
|
|
127644
|
+
var _options$requireBlock, _quote$fee;
|
|
127545
127645
|
if (client_ledger_classPrivateFieldGet(client_ledger, this).ledgerWriteMode !== 'read-write') {
|
|
127546
127646
|
throw new Error(`May not issue votes in read-only mode, in ${client_ledger_classPrivateFieldGet(client_ledger, this).ledgerWriteMode} mode`);
|
|
127547
127647
|
}
|
|
@@ -127550,16 +127650,26 @@ async function client_voteOrQuoteWithFees(blocks, type, quote) {
|
|
|
127550
127650
|
}
|
|
127551
127651
|
client_ledger_assertClassBrand(client_LedgerAtomicInterface_brand, this, client_assertTransaction).call(this);
|
|
127552
127652
|
const effects = await client_ledger_assertClassBrand(client_LedgerAtomicInterface_brand, this, client_validateLedgerOutcome).call(this, blocks);
|
|
127553
|
-
const now = Date.now();
|
|
127554
|
-
for (const block of blocks) {
|
|
127555
|
-
const blockDate = block.date.valueOf();
|
|
127556
|
-
const timeOffset = 5 /* m */ * 60 /* s */ * 1000 /* ms */;
|
|
127557
127653
|
|
|
127558
|
-
|
|
127559
|
-
|
|
127560
|
-
|
|
127561
|
-
|
|
127562
|
-
|
|
127654
|
+
/*
|
|
127655
|
+
* Ensure the block is relatively recent, otherwise a found
|
|
127656
|
+
* block for an account could be used to indefinitely delay voting
|
|
127657
|
+
* by continuously requesting votes on old blocks
|
|
127658
|
+
*/
|
|
127659
|
+
const requireBlockTimestampCheck = (_options$requireBlock = options === null || options === void 0 ? void 0 : options.requireBlockTimestampCheck) !== null && _options$requireBlock !== void 0 ? _options$requireBlock : true;
|
|
127660
|
+
if (requireBlockTimestampCheck) {
|
|
127661
|
+
var _classPrivateFieldGet0, _classPrivateFieldGet1;
|
|
127662
|
+
const now = (_classPrivateFieldGet0 = (_classPrivateFieldGet1 = client_ledger_classPrivateFieldGet(client_transaction, this)) === null || _classPrivateFieldGet1 === void 0 ? void 0 : _classPrivateFieldGet1.moment.valueOf()) !== null && _classPrivateFieldGet0 !== void 0 ? _classPrivateFieldGet0 : Date.now();
|
|
127663
|
+
for (const block of blocks) {
|
|
127664
|
+
const blockDate = block.date.valueOf();
|
|
127665
|
+
const timeOffset = 5 /* m */ * 60 /* s */ * 1000 /* ms */;
|
|
127666
|
+
|
|
127667
|
+
/**
|
|
127668
|
+
* Do not allow short votes on blocks from the distant past
|
|
127669
|
+
*/
|
|
127670
|
+
if (blockDate < now - timeOffset || blockDate > now + timeOffset) {
|
|
127671
|
+
throw new client_ledger_KeetaNetLedgerError('LEDGER_BLOCK_EXPIRED', `Refusing to issue vote for block dated ${block.date.toISOString()}`);
|
|
127672
|
+
}
|
|
127563
127673
|
}
|
|
127564
127674
|
}
|
|
127565
127675
|
|
|
@@ -128012,7 +128122,7 @@ client_lib_ledger_defineProperty(src_client_Ledger, "isInstance", client_checkab
|
|
|
128012
128122
|
// EXTERNAL MODULE: ws (ignored)
|
|
128013
128123
|
var client_ws_ignored_ = __webpack_require__(4708);
|
|
128014
128124
|
;// ./src/version.ts
|
|
128015
|
-
const client_version = '0.14.
|
|
128125
|
+
const client_version = '0.14.10+g915d941de2a9b7990a6a140496a0e142eafaa9b7';
|
|
128016
128126
|
/* harmony default export */ const client_src_version = ((/* unused pure expression or super */ null && (client_version)));
|
|
128017
128127
|
;// ./src/lib/p2p.ts
|
|
128018
128128
|
/* provided dependency */ var client_p2p_Buffer = __webpack_require__(8287)["Buffer"];
|
|
@@ -132800,21 +132910,31 @@ class src_client_Client {
|
|
|
132800
132910
|
if (!successorBlock) {
|
|
132801
132911
|
return null;
|
|
132802
132912
|
}
|
|
132803
|
-
const
|
|
132913
|
+
const getVote = async (rep, hash) => {
|
|
132914
|
+
var _votes$;
|
|
132804
132915
|
let votes = null;
|
|
132805
132916
|
try {
|
|
132806
132917
|
votes = await client_client_assertClassBrand(client_Client_brand, this, client_getVotes).call(this, hash, 'side', rep);
|
|
132807
132918
|
} catch {
|
|
132808
132919
|
/* Ignore */
|
|
132809
132920
|
}
|
|
132921
|
+
if (votes === null) {
|
|
132922
|
+
return {
|
|
132923
|
+
rep,
|
|
132924
|
+
vote: null
|
|
132925
|
+
};
|
|
132926
|
+
}
|
|
132927
|
+
|
|
132928
|
+
// Favor using permanent votes over short votes if the rep returns both
|
|
132929
|
+
votes.sort((voteA, voteB) => voteB.validityTo.valueOf() - voteA.validityTo.valueOf());
|
|
132810
132930
|
return {
|
|
132811
132931
|
rep: rep,
|
|
132812
|
-
votes:
|
|
132932
|
+
vote: (_votes$ = votes[0]) !== null && _votes$ !== void 0 ? _votes$ : null
|
|
132813
132933
|
};
|
|
132814
132934
|
};
|
|
132815
132935
|
const votePromises = [];
|
|
132816
132936
|
for (const rep of client_client_classPrivateFieldGet(client_reps, this)) {
|
|
132817
|
-
votePromises.push(
|
|
132937
|
+
votePromises.push(getVote(rep, successorBlock.hash));
|
|
132818
132938
|
}
|
|
132819
132939
|
const votesInfo = await Promise.all(votePromises);
|
|
132820
132940
|
if (votesInfo.length === 0) {
|
|
@@ -132832,18 +132952,16 @@ class src_client_Client {
|
|
|
132832
132952
|
/* Any reps that did not generate any vote */
|
|
132833
132953
|
const missingReps = [];
|
|
132834
132954
|
for (const repInfo of votesInfo) {
|
|
132835
|
-
const
|
|
132836
|
-
if (
|
|
132955
|
+
const repVote = repInfo.vote;
|
|
132956
|
+
if (repVote === null) {
|
|
132837
132957
|
missingReps.push(repInfo.rep);
|
|
132838
132958
|
} else {
|
|
132839
|
-
|
|
132840
|
-
|
|
132841
|
-
|
|
132842
|
-
|
|
132843
|
-
|
|
132844
|
-
|
|
132845
|
-
tempReps.push(repInfo.rep);
|
|
132846
|
-
}
|
|
132959
|
+
if (repVote.$permanent === true) {
|
|
132960
|
+
permVotes.push(repVote);
|
|
132961
|
+
permReps.push(repInfo.rep);
|
|
132962
|
+
} else {
|
|
132963
|
+
tempVotes.push(repVote);
|
|
132964
|
+
tempReps.push(repInfo.rep);
|
|
132847
132965
|
}
|
|
132848
132966
|
}
|
|
132849
132967
|
}
|
|
@@ -132893,7 +133011,12 @@ class src_client_Client {
|
|
|
132893
133011
|
let newTempVotes = [];
|
|
132894
133012
|
if (tempVotes.length !== client_client_classPrivateFieldGet(client_reps, this).length) {
|
|
132895
133013
|
try {
|
|
132896
|
-
|
|
133014
|
+
/**
|
|
133015
|
+
* If we are trying to recover an old block that has some permanent votes, send those votes in the request
|
|
133016
|
+
* Otherwise the rep will reject the old block and won't issue a vote
|
|
133017
|
+
*/
|
|
133018
|
+
const otherVotes = permVotes.length > 0 ? permVotes : undefined;
|
|
133019
|
+
newTempVotes = await client_client_assertClassBrand(client_Client_brand, this, client_requestVotes).call(this, votedOnBlocks, otherVotes, missingReps, options === null || options === void 0 ? void 0 : options.quotes);
|
|
132897
133020
|
} catch {
|
|
132898
133021
|
/* Ignore */
|
|
132899
133022
|
}
|
|
@@ -132918,7 +133041,7 @@ class src_client_Client {
|
|
|
132918
133041
|
votedOnBlocks.push(feeBlock);
|
|
132919
133042
|
}
|
|
132920
133043
|
try {
|
|
132921
|
-
const newPermVotes = await client_client_assertClassBrand(client_Client_brand, this, client_requestVotes).call(this, votedOnBlocks, tempVotes, missingPermReps);
|
|
133044
|
+
const newPermVotes = await client_client_assertClassBrand(client_Client_brand, this, client_requestVotes).call(this, votedOnBlocks, [...tempVotes, ...permVotes], missingPermReps);
|
|
132922
133045
|
permVotes = [...permVotes, ...newPermVotes];
|
|
132923
133046
|
} catch {
|
|
132924
133047
|
/* Ignore */
|
|
@@ -132945,7 +133068,7 @@ class src_client_Client {
|
|
|
132945
133068
|
* @param publish Publish the synced staple to the network (default is true)
|
|
132946
133069
|
*/
|
|
132947
133070
|
async syncAccount(account) {
|
|
132948
|
-
var _accountInfoSorted$
|
|
133071
|
+
var _accountInfoSorted$in, _accountInfoSorted$0$;
|
|
132949
133072
|
let publish = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
132950
133073
|
let reps = arguments.length > 2 ? arguments[2] : undefined;
|
|
132951
133074
|
await client_client_classPrivateFieldGet(client_updateRepsPromise, this);
|
|
@@ -132973,11 +133096,12 @@ class src_client_Client {
|
|
|
132973
133096
|
var _a$info$height, _a$info, _b$info$height, _b$info;
|
|
132974
133097
|
return Number(BigInt((_a$info$height = (_a$info = a.info) === null || _a$info === void 0 ? void 0 : _a$info.height) !== null && _a$info$height !== void 0 ? _a$info$height : -1) - BigInt((_b$info$height = (_b$info = b.info) === null || _b$info === void 0 ? void 0 : _b$info.height) !== null && _b$info$height !== void 0 ? _b$info$height : -1));
|
|
132975
133098
|
});
|
|
132976
|
-
|
|
133099
|
+
const lowestInfo = accountInfoSorted[0].info;
|
|
133100
|
+
if ((lowestInfo === null || lowestInfo === void 0 ? void 0 : lowestInfo.height) === ((_accountInfoSorted$in = accountInfoSorted[accountInfoSorted.length - 1].info) === null || _accountInfoSorted$in === void 0 ? void 0 : _accountInfoSorted$in.height)) {
|
|
132977
133101
|
// Block Heights match so return
|
|
132978
133102
|
return null;
|
|
132979
133103
|
}
|
|
132980
|
-
let lowestHead =
|
|
133104
|
+
let lowestHead = lowestInfo === null || lowestInfo === void 0 ? void 0 : lowestInfo.block.hash;
|
|
132981
133105
|
if (lowestHead === null || lowestHead === undefined) {
|
|
132982
133106
|
lowestHead = client_lib_block.getAccountOpeningHash(account);
|
|
132983
133107
|
}
|
|
@@ -132992,10 +133116,28 @@ class src_client_Client {
|
|
|
132992
133116
|
return null;
|
|
132993
133117
|
}
|
|
132994
133118
|
if (publish === true) {
|
|
132995
|
-
|
|
133119
|
+
const allLowestReps = [];
|
|
133120
|
+
for (const accountInfo of accountInfoSorted) {
|
|
133121
|
+
var _accountInfo$info;
|
|
133122
|
+
// All lowest reps could be missing the opening block and info would be null so make sure we send to all of them
|
|
133123
|
+
if (((_accountInfo$info = accountInfo.info) === null || _accountInfo$info === void 0 ? void 0 : _accountInfo$info.height) === (lowestInfo === null || lowestInfo === void 0 ? void 0 : lowestInfo.height)) {
|
|
133124
|
+
allLowestReps.push(accountInfo.rep);
|
|
133125
|
+
}
|
|
133126
|
+
}
|
|
133127
|
+
for (const rep of allLowestReps) {
|
|
133128
|
+
// we publish these serially to avoid transaction conflicts, but publish to all to ensure that every missing rep sees the staple
|
|
133129
|
+
try {
|
|
133130
|
+
await this.transmitStaple(successorStaple, [rep]);
|
|
133131
|
+
} catch {
|
|
133132
|
+
/**
|
|
133133
|
+
* Ignore transmit errors like LEDGER_BLOCK_ALREADY_EXISTS
|
|
133134
|
+
* We will check block heights after to see if sync was performed
|
|
133135
|
+
*/
|
|
133136
|
+
}
|
|
133137
|
+
}
|
|
132996
133138
|
}
|
|
132997
133139
|
const updatedAccountInfo = await this.getAccountHeadInfo(account, accountInfoSorted[0].rep);
|
|
132998
|
-
if ((updatedAccountInfo === null || updatedAccountInfo === void 0 ? void 0 : updatedAccountInfo.height) === ((_accountInfoSorted$0$
|
|
133140
|
+
if ((updatedAccountInfo === null || updatedAccountInfo === void 0 ? void 0 : updatedAccountInfo.height) === ((_accountInfoSorted$0$ = accountInfoSorted[0].info) === null || _accountInfoSorted$0$ === void 0 ? void 0 : _accountInfoSorted$0$.height)) {
|
|
132999
133141
|
throw new src_client_KeetaNetClientError('CLIENT_SYNC_PUBLISH_FAILED', `Client sync found a missing staple: ${successorStaple.blocksHash}, but it could not be published to rep: ${accountInfoSorted[0].rep.key.publicKeyString.get()}`);
|
|
133000
133142
|
}
|
|
133001
133143
|
return successorStaple;
|