pshenmic-dpp 2.0.0-dev.25 → 2.0.0-dev.27
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/binaries/bindingsTypes.d.ts +51 -1
- package/dist/binaries/bindingsTypes.js +1 -0
- package/dist/binaries/native/aarch64-apple-darwin/pshenmic_dpp.node +0 -0
- package/dist/binaries/native/aarch64-pc-windows-msvc/pshenmic_dpp.node +0 -0
- package/dist/binaries/native/aarch64-unknown-linux-gnu/pshenmic_dpp.node +0 -0
- package/dist/binaries/native/aarch64-unknown-linux-musl/pshenmic_dpp.node +0 -0
- package/dist/binaries/native/x86_64-apple-darwin/pshenmic_dpp.node +0 -0
- package/dist/binaries/native/x86_64-pc-windows-msvc/pshenmic_dpp.node +0 -0
- package/dist/binaries/native/x86_64-unknown-linux-gnu/pshenmic_dpp.node +0 -0
- package/dist/binaries/native/x86_64-unknown-linux-musl/pshenmic_dpp.node +0 -0
- package/dist/binaries/node.cjs +42 -21
- package/dist/binaries/node.d.cts +2 -2
- package/dist/binaries/pshenmic_dpp.android.node/arm64-v8a/libpshenmic_dpp.so +0 -0
- package/dist/binaries/pshenmic_dpp.apple.node/ios-arm64-simulator/libpshenmic_dpp.framework/libpshenmic_dpp +0 -0
- package/dist/binaries/wasm/wasmBytes.cjs +1 -1
- package/dist/src/dpp/structs/AddressTransitions/AddressCreditWithdrawalTransition.d.ts +3 -1
- package/dist/src/dpp/structs/AddressTransitions/AddressCreditWithdrawalTransition.js +6 -0
- package/dist/src/dpp/structs/AddressTransitions/AddressFundingFromAssetLockTransition.d.ts +2 -1
- package/dist/src/dpp/structs/AddressTransitions/AddressFundingFromAssetLockTransition.js +3 -0
- package/dist/src/dpp/structs/AddressTransitions/AddressFundsTransferTransition.d.ts +3 -1
- package/dist/src/dpp/structs/AddressTransitions/AddressFundsTransferTransition.js +6 -0
- package/dist/src/dpp/structs/AddressTransitions/IdentityCreateFromAddressesTransition.d.ts +2 -1
- package/dist/src/dpp/structs/AddressTransitions/IdentityCreateFromAddressesTransition.js +3 -0
- package/dist/src/dpp/structs/AddressTransitions/IdentityCreditTransferToAddressesTransition.d.ts +2 -1
- package/dist/src/dpp/structs/AddressTransitions/IdentityCreditTransferToAddressesTransition.js +3 -0
- package/dist/src/dpp/structs/AddressTransitions/IdentityTopUpFromAddressesTransition.d.ts +2 -1
- package/dist/src/dpp/structs/AddressTransitions/IdentityTopUpFromAddressesTransition.js +3 -0
- package/dist/src/dpp/structs/Batch/BatchTransition.d.ts +2 -1
- package/dist/src/dpp/structs/Batch/BatchTransition.js +3 -0
- package/dist/src/dpp/structs/DataContractTransitions/DataContractCreateTransition.d.ts +2 -1
- package/dist/src/dpp/structs/DataContractTransitions/DataContractCreateTransition.js +3 -0
- package/dist/src/dpp/structs/DataContractTransitions/DataContractUpdateTransition.d.ts +2 -1
- package/dist/src/dpp/structs/DataContractTransitions/DataContractUpdateTransition.js +3 -0
- package/dist/src/dpp/structs/IdentityTransitions/IdentityCreateTransition.d.ts +2 -1
- package/dist/src/dpp/structs/IdentityTransitions/IdentityCreateTransition.js +3 -0
- package/dist/src/dpp/structs/IdentityTransitions/IdentityCreditTransfer.d.ts +2 -1
- package/dist/src/dpp/structs/IdentityTransitions/IdentityCreditTransfer.js +3 -0
- package/dist/src/dpp/structs/IdentityTransitions/IdentityCreditWithdrawalTransition.d.ts +2 -1
- package/dist/src/dpp/structs/IdentityTransitions/IdentityCreditWithdrawalTransition.js +3 -0
- package/dist/src/dpp/structs/IdentityTransitions/IdentityTopUpTransition.d.ts +2 -1
- package/dist/src/dpp/structs/IdentityTransitions/IdentityTopUpTransition.js +3 -0
- package/dist/src/dpp/structs/IdentityTransitions/IdentityUpdateTransition.d.ts +2 -1
- package/dist/src/dpp/structs/IdentityTransitions/IdentityUpdateTransition.js +3 -0
- package/dist/src/dpp/structs/MasternodeVote/MasternodeVoteTransition.d.ts +2 -1
- package/dist/src/dpp/structs/MasternodeVote/MasternodeVoteTransition.js +3 -0
- package/dist/src/dpp/structs/Orchard/RecoveredNote.d.ts +1 -0
- package/dist/src/dpp/structs/Orchard/RecoveredNote.js +3 -0
- package/dist/src/dpp/structs/PlatformAddress/PlatformAddress.d.ts +9 -1
- package/dist/src/dpp/structs/PlatformAddress/PlatformAddress.js +10 -0
- package/dist/src/dpp/structs/ShieldedTransitions/IdentityCreateFromShieldedPoolTransition.d.ts +2 -1
- package/dist/src/dpp/structs/ShieldedTransitions/IdentityCreateFromShieldedPoolTransition.js +3 -0
- package/dist/src/dpp/structs/ShieldedTransitions/ShieldFromAssetLockTransition.d.ts +2 -1
- package/dist/src/dpp/structs/ShieldedTransitions/ShieldFromAssetLockTransition.js +3 -0
- package/dist/src/dpp/structs/ShieldedTransitions/ShieldTransition.d.ts +2 -1
- package/dist/src/dpp/structs/ShieldedTransitions/ShieldTransition.js +3 -0
- package/dist/src/dpp/structs/ShieldedTransitions/ShieldedTransferTransition.d.ts +2 -1
- package/dist/src/dpp/structs/ShieldedTransitions/ShieldedTransferTransition.js +3 -0
- package/dist/src/dpp/structs/ShieldedTransitions/ShieldedWithdrawalTransition.d.ts +2 -1
- package/dist/src/dpp/structs/ShieldedTransitions/ShieldedWithdrawalTransition.js +3 -0
- package/dist/src/dpp/structs/ShieldedTransitions/UnshieldTransition.d.ts +2 -1
- package/dist/src/dpp/structs/ShieldedTransitions/UnshieldTransition.js +3 -0
- package/dist/src/dpp/structs/StateTransition.d.ts +2 -1
- package/dist/src/dpp/structs/StateTransition.js +3 -0
- package/dist/src/dpp/types.d.ts +6 -0
- package/dist/src/dpp/verify/StateTransition/verifyStateTransitionResult.js +2 -1
- package/package.json +1 -1
- package/tests/unit/AddressTransitionsFees.spec.ts +274 -0
- package/tests/unit/Shielded.spec.ts +37 -4
- package/tests/unit/ShieldedTransitions.spec.ts +168 -0
- package/tests/unit/StateTransitionFees.spec.ts +177 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { StateTransitionNAPI } from '../../../binaries/bindingsTypes.js';
|
|
1
|
+
import type { StateTransitionNAPI, PlatformVersionNAPI } from '../../../binaries/bindingsTypes.js';
|
|
2
2
|
import { PrivateKeyWASM } from './PrivateKey.js';
|
|
3
3
|
import { IdentityPublicKeyWASM } from './IdentityPublicKey.js';
|
|
4
4
|
import { IdentifierLike, KeyTypeLike, PurposeLike } from '../types.js';
|
|
@@ -29,6 +29,7 @@ export declare class StateTransitionWASM {
|
|
|
29
29
|
setIdentityContractNonce(nonce: bigint): void;
|
|
30
30
|
setIdentityNonce(nonce: bigint): void;
|
|
31
31
|
getSignableBytes(): Uint8Array;
|
|
32
|
+
calculateMinRequiredFee(platformVersion?: PlatformVersionNAPI): bigint;
|
|
32
33
|
bytes(): Uint8Array;
|
|
33
34
|
hex(): string;
|
|
34
35
|
base64(): string;
|
|
@@ -79,6 +79,9 @@ export class StateTransitionWASM {
|
|
|
79
79
|
getSignableBytes() {
|
|
80
80
|
return this._rawStateTransition.getSignableBytes();
|
|
81
81
|
}
|
|
82
|
+
calculateMinRequiredFee(platformVersion) {
|
|
83
|
+
return BigInt(this._rawStateTransition.calculateMinRequiredFee(platformVersion));
|
|
84
|
+
}
|
|
82
85
|
bytes() {
|
|
83
86
|
return this._rawStateTransition.bytes();
|
|
84
87
|
}
|
package/dist/src/dpp/types.d.ts
CHANGED
|
@@ -250,6 +250,12 @@ export type VerifiedStateTransitionResultVariantsRAW = protocol.DataContractNAPI
|
|
|
250
250
|
export interface VerifiedStateTransitionResult {
|
|
251
251
|
rootHash: Uint8Array;
|
|
252
252
|
result: VerifiedStateTransitionResultVariants;
|
|
253
|
+
/**
|
|
254
|
+
* Whether the proof binds the execution of this specific state transition.
|
|
255
|
+
* When false, the result is a height-pinned snapshot of the state the
|
|
256
|
+
* transition affects, not evidence that the transition executed.
|
|
257
|
+
*/
|
|
258
|
+
isExecutionProved: boolean;
|
|
253
259
|
}
|
|
254
260
|
export type WhereOperator = '=' | '==' | '>' | '>=' | '<' | '<=' | 'Between' | 'between' | 'BetweenExcludeBounds' | 'betweenExcludeBounds' | 'betweenexcludebounds' | 'between_exclude_bounds' | 'BetweenExcludeLeft' | 'betweenExcludeLeft' | 'betweenexcludeleft' | 'between_exclude_left' | 'BetweenExcludeRight' | 'betweenExcludeRight' | 'betweenexcluderight' | 'between_exclude_right' | 'In' | 'in' | 'StartsWith' | 'startsWith' | 'startswith' | 'starts_with';
|
|
255
261
|
export type WhereClause = [
|
|
@@ -5,6 +5,7 @@ export function verifyStateTransitionResult(proof, stateTransition, blockInfo, k
|
|
|
5
5
|
const verified = dppProvider.dpp.verifyStateTransitionResult(proof, stateTransition._rawStateTransition, new dppProvider.dpp.BlockInfoNAPI(blockInfo.timeMs.toString(), blockInfo.height.toString(), blockInfo.coreHeight, blockInfo.epoch), knownContractsArray.map(contract => contract._rawDataContract), valueToDynamicValue(platformVersion));
|
|
6
6
|
return {
|
|
7
7
|
rootHash: verified.rootHash,
|
|
8
|
-
result: convertResult(verified.result)
|
|
8
|
+
result: convertResult(verified.result),
|
|
9
|
+
isExecutionProved: verified.isExecutionProved
|
|
9
10
|
};
|
|
10
11
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AddressCreditWithdrawalTransitionWASM,
|
|
3
|
+
AddressFundingFromAssetLockTransitionWASM,
|
|
4
|
+
AddressFundsFeeStrategyStepWASM,
|
|
5
|
+
AddressFundsTransferTransitionWASM,
|
|
6
|
+
AddressWitnessWASM,
|
|
7
|
+
AssetLockProofWASM,
|
|
8
|
+
CoreScriptWASM,
|
|
9
|
+
IdentityCreateFromAddressesTransitionWASM,
|
|
10
|
+
IdentityCreditTransferToAddressesTransitionWASM,
|
|
11
|
+
IdentityPublicKeyInCreationWASM,
|
|
12
|
+
IdentityTopUpFromAddressesTransitionWASM,
|
|
13
|
+
InputAddressWASM,
|
|
14
|
+
KeyType,
|
|
15
|
+
OutPointWASM,
|
|
16
|
+
OutputAddressNullableCreditsWASM,
|
|
17
|
+
OutputAddressWASM,
|
|
18
|
+
PlatformAddressWASM,
|
|
19
|
+
PlatformVersionWASM,
|
|
20
|
+
Purpose,
|
|
21
|
+
SecurityLevel
|
|
22
|
+
} from 'pshenmic-dpp'
|
|
23
|
+
|
|
24
|
+
// Min fee components from the platform fee version (STATE_TRANSITION_MIN_FEES_VERSION1)
|
|
25
|
+
// Storage charged by the node for one address balance entry that does not exist yet,
|
|
26
|
+
// as pinned by platform's own fee regression suite.
|
|
27
|
+
const NEW_ADDRESS_STORAGE_FEE = BigInt(6075000)
|
|
28
|
+
const INPUT_COST = BigInt(500000)
|
|
29
|
+
const OUTPUT_COST = BigInt(6000000)
|
|
30
|
+
const ADDRESS_CREDIT_WITHDRAWAL_COST = BigInt(400000000)
|
|
31
|
+
const IDENTITY_CREATE_BASE_COST = BigInt(2000000)
|
|
32
|
+
const IDENTITY_KEY_IN_CREATION_COST = BigInt(6500000)
|
|
33
|
+
const IDENTITY_TOPUP_BASE_COST = BigInt(500000)
|
|
34
|
+
const CREDIT_TRANSFER_TO_ADDRESSES_COST = BigInt(500000)
|
|
35
|
+
|
|
36
|
+
function randomBytes (length: number): Uint8Array {
|
|
37
|
+
const bytes = new Uint8Array(length)
|
|
38
|
+
for (let i = 0; i < length; i++) {
|
|
39
|
+
bytes[i] = Math.floor(Math.random() * 256)
|
|
40
|
+
}
|
|
41
|
+
return bytes
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function createTestAddress (): PlatformAddressWASM {
|
|
45
|
+
const addressBytes = new Uint8Array(21)
|
|
46
|
+
addressBytes[0] = 0x00
|
|
47
|
+
addressBytes.set(randomBytes(20), 1)
|
|
48
|
+
return PlatformAddressWASM.fromBytes(addressBytes)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function createTestInputs (count: number): InputAddressWASM[] {
|
|
52
|
+
return Array.from(
|
|
53
|
+
{ length: count },
|
|
54
|
+
() => new InputAddressWASM(createTestAddress(), 0, BigInt(500000000))
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function createTestOutputs (count: number): OutputAddressWASM[] {
|
|
59
|
+
return Array.from(
|
|
60
|
+
{ length: count },
|
|
61
|
+
() => new OutputAddressWASM(createTestAddress(), BigInt(100000))
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function createTestWitnesses (count: number): AddressWitnessWASM[] {
|
|
66
|
+
return Array.from({ length: count }, () => AddressWitnessWASM.P2PKH(randomBytes(65)))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const feeStrategy = (): AddressFundsFeeStrategyStepWASM[] =>
|
|
70
|
+
[AddressFundsFeeStrategyStepWASM.DeductFromInput(0)]
|
|
71
|
+
|
|
72
|
+
describe('AddressFundsTransferTransition fees', function () {
|
|
73
|
+
describe('estimateMinFee', function () {
|
|
74
|
+
test('should price inputs and outputs', function () {
|
|
75
|
+
expect(AddressFundsTransferTransitionWASM.estimateMinFee(1, 1))
|
|
76
|
+
.toEqual(INPUT_COST + OUTPUT_COST)
|
|
77
|
+
|
|
78
|
+
expect(AddressFundsTransferTransitionWASM.estimateMinFee(2, 3))
|
|
79
|
+
.toEqual(INPUT_COST * BigInt(2) + OUTPUT_COST * BigInt(3))
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
test('should charge at least one output', function () {
|
|
83
|
+
expect(AddressFundsTransferTransitionWASM.estimateMinFee(1, 0))
|
|
84
|
+
.toEqual(AddressFundsTransferTransitionWASM.estimateMinFee(1, 1))
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
test('should grow with the input and output counts', function () {
|
|
88
|
+
const one = AddressFundsTransferTransitionWASM.estimateMinFee(1, 1)
|
|
89
|
+
const two = AddressFundsTransferTransitionWASM.estimateMinFee(2, 2)
|
|
90
|
+
|
|
91
|
+
expect(two).toBeGreaterThan(one)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
test('should default to the latest platform version', function () {
|
|
95
|
+
expect(AddressFundsTransferTransitionWASM.estimateMinFee(1, 1))
|
|
96
|
+
.toEqual(AddressFundsTransferTransitionWASM.estimateMinFee(1, 1, PlatformVersionWASM.PLATFORM_V13))
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
describe('calculateMinRequiredFee', function () {
|
|
101
|
+
test('should match the estimate for the transition inputs and outputs', function () {
|
|
102
|
+
const transition = new AddressFundsTransferTransitionWASM(
|
|
103
|
+
createTestInputs(2),
|
|
104
|
+
feeStrategy(),
|
|
105
|
+
0,
|
|
106
|
+
createTestWitnesses(2),
|
|
107
|
+
createTestOutputs(1)
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
expect(transition.calculateMinRequiredFee())
|
|
111
|
+
.toEqual(AddressFundsTransferTransitionWASM.estimateMinFee(2, 1))
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
describe('AddressCreditWithdrawalTransition fees', function () {
|
|
117
|
+
const outputScript = (): CoreScriptWASM => CoreScriptWASM.newP2PKH(randomBytes(20))
|
|
118
|
+
|
|
119
|
+
describe('estimateMinFee', function () {
|
|
120
|
+
test('should price the withdrawal, its inputs and its change output', function () {
|
|
121
|
+
expect(AddressCreditWithdrawalTransitionWASM.estimateMinFee(1, false))
|
|
122
|
+
.toEqual(ADDRESS_CREDIT_WITHDRAWAL_COST + INPUT_COST)
|
|
123
|
+
|
|
124
|
+
expect(AddressCreditWithdrawalTransitionWASM.estimateMinFee(1, true))
|
|
125
|
+
.toEqual(ADDRESS_CREDIT_WITHDRAWAL_COST + INPUT_COST + OUTPUT_COST)
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
test('should grow with the input count', function () {
|
|
129
|
+
expect(AddressCreditWithdrawalTransitionWASM.estimateMinFee(2, false))
|
|
130
|
+
.toBeGreaterThan(AddressCreditWithdrawalTransitionWASM.estimateMinFee(1, false))
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
describe('calculateMinRequiredFee', function () {
|
|
135
|
+
test('should match the estimate without a change output', function () {
|
|
136
|
+
const transition = new AddressCreditWithdrawalTransitionWASM(
|
|
137
|
+
createTestInputs(1),
|
|
138
|
+
feeStrategy(),
|
|
139
|
+
1,
|
|
140
|
+
'Standard',
|
|
141
|
+
outputScript(),
|
|
142
|
+
0,
|
|
143
|
+
createTestWitnesses(1)
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
expect(transition.calculateMinRequiredFee())
|
|
147
|
+
.toEqual(AddressCreditWithdrawalTransitionWASM.estimateMinFee(1, false))
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
test('should match the estimate with a change output', function () {
|
|
151
|
+
const transition = new AddressCreditWithdrawalTransitionWASM(
|
|
152
|
+
createTestInputs(1),
|
|
153
|
+
feeStrategy(),
|
|
154
|
+
1,
|
|
155
|
+
'Standard',
|
|
156
|
+
outputScript(),
|
|
157
|
+
0,
|
|
158
|
+
createTestWitnesses(1),
|
|
159
|
+
createTestOutputs(1)[0]
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
expect(transition.calculateMinRequiredFee())
|
|
163
|
+
.toEqual(AddressCreditWithdrawalTransitionWASM.estimateMinFee(1, true))
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
describe('IdentityCreateFromAddressesTransition fees', function () {
|
|
169
|
+
test('calculateMinRequiredFee should price the base cost, inputs, output and keys', function () {
|
|
170
|
+
const publicKeys = [
|
|
171
|
+
new IdentityPublicKeyInCreationWASM(
|
|
172
|
+
0,
|
|
173
|
+
Purpose.AUTHENTICATION,
|
|
174
|
+
SecurityLevel.MASTER,
|
|
175
|
+
KeyType.ECDSA_SECP256K1,
|
|
176
|
+
false,
|
|
177
|
+
randomBytes(33)
|
|
178
|
+
)
|
|
179
|
+
]
|
|
180
|
+
|
|
181
|
+
const transition = new IdentityCreateFromAddressesTransitionWASM(
|
|
182
|
+
publicKeys,
|
|
183
|
+
createTestInputs(1),
|
|
184
|
+
feeStrategy(),
|
|
185
|
+
0,
|
|
186
|
+
createTestWitnesses(1),
|
|
187
|
+
createTestOutputs(1)[0]
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
expect(transition.calculateMinRequiredFee()).toEqual(
|
|
191
|
+
IDENTITY_CREATE_BASE_COST + INPUT_COST + OUTPUT_COST + IDENTITY_KEY_IN_CREATION_COST
|
|
192
|
+
)
|
|
193
|
+
})
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
describe('IdentityTopUpFromAddressesTransition fees', function () {
|
|
197
|
+
test('calculateMinRequiredFee should price the base cost, inputs and output', function () {
|
|
198
|
+
const transition = new IdentityTopUpFromAddressesTransitionWASM(
|
|
199
|
+
randomBytes(32),
|
|
200
|
+
createTestInputs(1),
|
|
201
|
+
feeStrategy(),
|
|
202
|
+
0,
|
|
203
|
+
createTestWitnesses(1),
|
|
204
|
+
createTestOutputs(1)[0]
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
expect(transition.calculateMinRequiredFee())
|
|
208
|
+
.toEqual(IDENTITY_TOPUP_BASE_COST + INPUT_COST + OUTPUT_COST)
|
|
209
|
+
})
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
describe('IdentityCreditTransferToAddressesTransition fees', function () {
|
|
213
|
+
test('calculateMinRequiredFee should price the base cost and each recipient', function () {
|
|
214
|
+
const transition = new IdentityCreditTransferToAddressesTransitionWASM(
|
|
215
|
+
randomBytes(32),
|
|
216
|
+
createTestOutputs(2),
|
|
217
|
+
BigInt(1),
|
|
218
|
+
0
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
expect(transition.calculateMinRequiredFee())
|
|
222
|
+
.toEqual(CREDIT_TRANSFER_TO_ADDRESSES_COST + OUTPUT_COST * BigInt(2))
|
|
223
|
+
})
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
describe('AddressFundingFromAssetLockTransition fees', function () {
|
|
227
|
+
test('calculateMinRequiredFee should include the asset lock base cost', function () {
|
|
228
|
+
const outPoint = new OutPointWASM('a'.repeat(64), 0)
|
|
229
|
+
const assetLockProof = AssetLockProofWASM.createChainAssetLockProof(100, outPoint)
|
|
230
|
+
|
|
231
|
+
const transition = new AddressFundingFromAssetLockTransitionWASM(
|
|
232
|
+
assetLockProof,
|
|
233
|
+
createTestInputs(1),
|
|
234
|
+
feeStrategy(),
|
|
235
|
+
0,
|
|
236
|
+
createTestWitnesses(1),
|
|
237
|
+
[new OutputAddressNullableCreditsWASM(createTestAddress(), BigInt(100000))]
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
const fee = transition.calculateMinRequiredFee()
|
|
241
|
+
|
|
242
|
+
expect(typeof fee).toEqual('bigint')
|
|
243
|
+
expect(fee).toBeGreaterThan(INPUT_COST + OUTPUT_COST)
|
|
244
|
+
})
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
describe('new address storage fee', function () {
|
|
248
|
+
test('should match the storage the node charges for one created address', function () {
|
|
249
|
+
expect(PlatformAddressWASM.estimateStorageFeeForNewAddresses(1))
|
|
250
|
+
.toEqual(NEW_ADDRESS_STORAGE_FEE)
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
test('should scale with the number of created addresses', function () {
|
|
254
|
+
expect(PlatformAddressWASM.estimateStorageFeeForNewAddresses(0)).toEqual(BigInt(0))
|
|
255
|
+
expect(PlatformAddressWASM.estimateStorageFeeForNewAddresses(3))
|
|
256
|
+
.toEqual(NEW_ADDRESS_STORAGE_FEE * BigInt(3))
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
test('should default to the latest platform version', function () {
|
|
260
|
+
expect(PlatformAddressWASM.estimateStorageFeeForNewAddresses(1))
|
|
261
|
+
.toEqual(PlatformAddressWASM.estimateStorageFeeForNewAddresses(1, PlatformVersionWASM.PLATFORM_V13))
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
test('should exceed the per output component of the min fee', function () {
|
|
265
|
+
const perOutput =
|
|
266
|
+
AddressFundsTransferTransitionWASM.estimateMinFee(1, 2) -
|
|
267
|
+
AddressFundsTransferTransitionWASM.estimateMinFee(1, 1)
|
|
268
|
+
|
|
269
|
+
// The min fee prices an output slightly below what a created address costs in storage,
|
|
270
|
+
// which is why a transfer paying a brand new address is charged a little more than its
|
|
271
|
+
// minimum required fee.
|
|
272
|
+
expect(NEW_ADDRESS_STORAGE_FEE).toBeGreaterThan(perOutput)
|
|
273
|
+
})
|
|
274
|
+
})
|
|
@@ -27,7 +27,9 @@ const ACCOUNT = 0
|
|
|
27
27
|
// A funded testnet WIF reused across the builder/deposit tests.
|
|
28
28
|
const WIF = 'cUy4wbim4y9NDwC24omx8oWY5WqfmjSU2gdcZtTXza2xDCAkQXRP'
|
|
29
29
|
|
|
30
|
-
//
|
|
30
|
+
// The memo payload field is a fixed 32 bytes (MEMO_PAYLOAD_SIZE) on the wire.
|
|
31
|
+
// Text memos may be shorter and are zero-padded to it; `other` payloads are
|
|
32
|
+
// taken verbatim and so must match it exactly.
|
|
31
33
|
const MEMO_PAYLOAD_SIZE = 32
|
|
32
34
|
|
|
33
35
|
const DASH = 100_000_000_000n
|
|
@@ -62,6 +64,7 @@ describe('ShieldedMemo', function () {
|
|
|
62
64
|
|
|
63
65
|
expect(memo).toBeInstanceOf(ShieldedMemoWASM)
|
|
64
66
|
expect(memo.toBytes().length).toEqual(36) // on-wire memo size
|
|
67
|
+
expect(memo.toString()).toEqual('')
|
|
65
68
|
})
|
|
66
69
|
})
|
|
67
70
|
|
|
@@ -72,11 +75,41 @@ describe('ShieldedMemo', function () {
|
|
|
72
75
|
|
|
73
76
|
expect(memo).toBeInstanceOf(ShieldedMemoWASM)
|
|
74
77
|
expect(memo.toBytes().length).toEqual(36)
|
|
75
|
-
expect(memo.toString().
|
|
78
|
+
expect(memo.toString()).toEqual(text)
|
|
76
79
|
})
|
|
77
80
|
|
|
78
|
-
test('should
|
|
79
|
-
|
|
81
|
+
test('should accept text shorter than the payload', function () {
|
|
82
|
+
const text = 'thanks for lunch' // 16 bytes, half the payload
|
|
83
|
+
const memo = ShieldedMemoWASM.fromString(text)
|
|
84
|
+
const bytes = memo.toBytes()
|
|
85
|
+
|
|
86
|
+
// The wire memo stays a fixed 36 bytes: a 4-byte little-endian kind tag
|
|
87
|
+
// (1 = text), the utf-8 text, then zero padding out to the 32-byte
|
|
88
|
+
// payload. The padding is not part of the decoded text.
|
|
89
|
+
expect(bytes.length).toEqual(36)
|
|
90
|
+
expect(Array.from(bytes.slice(0, 4))).toEqual([1, 0, 0, 0])
|
|
91
|
+
expect(new TextDecoder().decode(bytes.slice(4, 4 + text.length))).toEqual(text)
|
|
92
|
+
expect(bytes.slice(4 + text.length).every((byte) => byte === 0)).toBe(true)
|
|
93
|
+
expect(memo.toString()).toEqual(text)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
test('should accept an empty string', function () {
|
|
97
|
+
const memo = ShieldedMemoWASM.fromString('')
|
|
98
|
+
|
|
99
|
+
expect(memo.toBytes().length).toEqual(36)
|
|
100
|
+
expect(memo.toString()).toEqual('')
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
test('should count multi-byte characters by their utf-8 byte length', function () {
|
|
104
|
+
// 8 x U+1F355 = 32 bytes, exactly the payload; 9 would be 36 bytes.
|
|
105
|
+
const memo = ShieldedMemoWASM.fromString('🍕'.repeat(8))
|
|
106
|
+
|
|
107
|
+
expect(memo.toString()).toEqual('🍕'.repeat(8))
|
|
108
|
+
expect(() => ShieldedMemoWASM.fromString('🍕'.repeat(9))).toThrow()
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
test('should reject text longer than 32 bytes', function () {
|
|
112
|
+
expect(() => ShieldedMemoWASM.fromString('A'.repeat(MEMO_PAYLOAD_SIZE + 1))).toThrow()
|
|
80
113
|
})
|
|
81
114
|
})
|
|
82
115
|
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
Purpose,
|
|
19
19
|
SecurityLevel,
|
|
20
20
|
KeyType,
|
|
21
|
+
PlatformVersionWASM,
|
|
21
22
|
StateTransitionWASM
|
|
22
23
|
} from 'pshenmic-dpp'
|
|
23
24
|
|
|
@@ -190,6 +191,27 @@ describe('ShieldedTransferTransition', function () {
|
|
|
190
191
|
expect(restored.actions.length).toEqual(1)
|
|
191
192
|
})
|
|
192
193
|
})
|
|
194
|
+
|
|
195
|
+
describe('computeMinimumFee', function () {
|
|
196
|
+
test('should return a positive fee', function () {
|
|
197
|
+
const fee = ShieldedTransferTransitionWASM.computeMinimumFee(2)
|
|
198
|
+
|
|
199
|
+
expect(typeof fee).toEqual('bigint')
|
|
200
|
+
expect(fee).toBeGreaterThan(BigInt(0))
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
test('should grow with the action count', function () {
|
|
204
|
+
const oneAction = ShieldedTransferTransitionWASM.computeMinimumFee(1)
|
|
205
|
+
const twoActions = ShieldedTransferTransitionWASM.computeMinimumFee(2)
|
|
206
|
+
|
|
207
|
+
expect(twoActions).toBeGreaterThan(oneAction)
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
test('should default to the latest platform version', function () {
|
|
211
|
+
expect(ShieldedTransferTransitionWASM.computeMinimumFee(2))
|
|
212
|
+
.toEqual(ShieldedTransferTransitionWASM.computeMinimumFee(2, PlatformVersionWASM.PLATFORM_V12))
|
|
213
|
+
})
|
|
214
|
+
})
|
|
193
215
|
})
|
|
194
216
|
|
|
195
217
|
describe('ShieldTransition', function () {
|
|
@@ -291,6 +313,27 @@ describe('ShieldTransition', function () {
|
|
|
291
313
|
expect(restored.actions.length).toEqual(1)
|
|
292
314
|
})
|
|
293
315
|
})
|
|
316
|
+
|
|
317
|
+
describe('computeMinimumFee', function () {
|
|
318
|
+
test('should return a positive fee', function () {
|
|
319
|
+
const fee = ShieldTransitionWASM.computeMinimumFee(2)
|
|
320
|
+
|
|
321
|
+
expect(typeof fee).toEqual('bigint')
|
|
322
|
+
expect(fee).toBeGreaterThan(BigInt(0))
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
test('should grow with the action count', function () {
|
|
326
|
+
const oneAction = ShieldTransitionWASM.computeMinimumFee(1)
|
|
327
|
+
const twoActions = ShieldTransitionWASM.computeMinimumFee(2)
|
|
328
|
+
|
|
329
|
+
expect(twoActions).toBeGreaterThan(oneAction)
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
test('should default to the latest platform version', function () {
|
|
333
|
+
expect(ShieldTransitionWASM.computeMinimumFee(2))
|
|
334
|
+
.toEqual(ShieldTransitionWASM.computeMinimumFee(2, PlatformVersionWASM.PLATFORM_V12))
|
|
335
|
+
})
|
|
336
|
+
})
|
|
294
337
|
})
|
|
295
338
|
|
|
296
339
|
describe('UnshieldTransition', function () {
|
|
@@ -381,6 +424,27 @@ describe('UnshieldTransition', function () {
|
|
|
381
424
|
expect(restored.bindingsSignature).toEqual(bindingsSignature)
|
|
382
425
|
})
|
|
383
426
|
})
|
|
427
|
+
|
|
428
|
+
describe('computeMinimumFee', function () {
|
|
429
|
+
test('should return a positive fee', function () {
|
|
430
|
+
const fee = UnshieldTransitionWASM.computeMinimumFee(2)
|
|
431
|
+
|
|
432
|
+
expect(typeof fee).toEqual('bigint')
|
|
433
|
+
expect(fee).toBeGreaterThan(BigInt(0))
|
|
434
|
+
})
|
|
435
|
+
|
|
436
|
+
test('should grow with the action count', function () {
|
|
437
|
+
const oneAction = UnshieldTransitionWASM.computeMinimumFee(1)
|
|
438
|
+
const twoActions = UnshieldTransitionWASM.computeMinimumFee(2)
|
|
439
|
+
|
|
440
|
+
expect(twoActions).toBeGreaterThan(oneAction)
|
|
441
|
+
})
|
|
442
|
+
|
|
443
|
+
test('should default to the latest platform version', function () {
|
|
444
|
+
expect(UnshieldTransitionWASM.computeMinimumFee(2))
|
|
445
|
+
.toEqual(UnshieldTransitionWASM.computeMinimumFee(2, PlatformVersionWASM.PLATFORM_V12))
|
|
446
|
+
})
|
|
447
|
+
})
|
|
384
448
|
})
|
|
385
449
|
|
|
386
450
|
describe('ShieldFromAssetLockTransition', function () {
|
|
@@ -491,6 +555,27 @@ describe('ShieldFromAssetLockTransition', function () {
|
|
|
491
555
|
expect(restored.actions.length).toEqual(1)
|
|
492
556
|
})
|
|
493
557
|
})
|
|
558
|
+
|
|
559
|
+
describe('computeMinimumFee', function () {
|
|
560
|
+
test('should return a positive fee', function () {
|
|
561
|
+
const fee = ShieldFromAssetLockTransitionWASM.computeMinimumFee(2)
|
|
562
|
+
|
|
563
|
+
expect(typeof fee).toEqual('bigint')
|
|
564
|
+
expect(fee).toBeGreaterThan(BigInt(0))
|
|
565
|
+
})
|
|
566
|
+
|
|
567
|
+
test('should grow with the action count', function () {
|
|
568
|
+
const oneAction = ShieldFromAssetLockTransitionWASM.computeMinimumFee(1)
|
|
569
|
+
const twoActions = ShieldFromAssetLockTransitionWASM.computeMinimumFee(2)
|
|
570
|
+
|
|
571
|
+
expect(twoActions).toBeGreaterThan(oneAction)
|
|
572
|
+
})
|
|
573
|
+
|
|
574
|
+
test('should default to the latest platform version', function () {
|
|
575
|
+
expect(ShieldFromAssetLockTransitionWASM.computeMinimumFee(2))
|
|
576
|
+
.toEqual(ShieldFromAssetLockTransitionWASM.computeMinimumFee(2, PlatformVersionWASM.PLATFORM_V12))
|
|
577
|
+
})
|
|
578
|
+
})
|
|
494
579
|
})
|
|
495
580
|
|
|
496
581
|
describe('ShieldedWithdrawalTransition', function () {
|
|
@@ -590,6 +675,27 @@ describe('ShieldedWithdrawalTransition', function () {
|
|
|
590
675
|
expect(restored.pooling).toEqual('Never')
|
|
591
676
|
})
|
|
592
677
|
})
|
|
678
|
+
|
|
679
|
+
describe('computeMinimumFee', function () {
|
|
680
|
+
test('should return a positive fee', function () {
|
|
681
|
+
const fee = ShieldedWithdrawalTransitionWASM.computeMinimumFee(2)
|
|
682
|
+
|
|
683
|
+
expect(typeof fee).toEqual('bigint')
|
|
684
|
+
expect(fee).toBeGreaterThan(BigInt(0))
|
|
685
|
+
})
|
|
686
|
+
|
|
687
|
+
test('should grow with the action count', function () {
|
|
688
|
+
const oneAction = ShieldedWithdrawalTransitionWASM.computeMinimumFee(1)
|
|
689
|
+
const twoActions = ShieldedWithdrawalTransitionWASM.computeMinimumFee(2)
|
|
690
|
+
|
|
691
|
+
expect(twoActions).toBeGreaterThan(oneAction)
|
|
692
|
+
})
|
|
693
|
+
|
|
694
|
+
test('should default to the latest platform version', function () {
|
|
695
|
+
expect(ShieldedWithdrawalTransitionWASM.computeMinimumFee(2))
|
|
696
|
+
.toEqual(ShieldedWithdrawalTransitionWASM.computeMinimumFee(2, PlatformVersionWASM.PLATFORM_V12))
|
|
697
|
+
})
|
|
698
|
+
})
|
|
593
699
|
})
|
|
594
700
|
|
|
595
701
|
describe('IdentityCreateFromShieldedPoolTransition', function () {
|
|
@@ -706,4 +812,66 @@ describe('IdentityCreateFromShieldedPoolTransition', function () {
|
|
|
706
812
|
expect(restored.identityId.bytes()).toEqual(identityId.bytes())
|
|
707
813
|
})
|
|
708
814
|
})
|
|
815
|
+
|
|
816
|
+
describe('computeMinimumFee', function () {
|
|
817
|
+
test('should return a positive fee', function () {
|
|
818
|
+
const fee = IdentityCreateFromShieldedPoolTransitionWASM.computeMinimumFee(2, 3)
|
|
819
|
+
|
|
820
|
+
expect(typeof fee).toEqual('bigint')
|
|
821
|
+
expect(fee).toBeGreaterThan(BigInt(0))
|
|
822
|
+
})
|
|
823
|
+
|
|
824
|
+
test('should grow with the action count', function () {
|
|
825
|
+
const oneAction = IdentityCreateFromShieldedPoolTransitionWASM.computeMinimumFee(1, 3)
|
|
826
|
+
const twoActions = IdentityCreateFromShieldedPoolTransitionWASM.computeMinimumFee(2, 3)
|
|
827
|
+
|
|
828
|
+
expect(twoActions).toBeGreaterThan(oneAction)
|
|
829
|
+
})
|
|
830
|
+
|
|
831
|
+
test('should grow with the key count', function () {
|
|
832
|
+
const oneKey = IdentityCreateFromShieldedPoolTransitionWASM.computeMinimumFee(2, 1)
|
|
833
|
+
const threeKeys = IdentityCreateFromShieldedPoolTransitionWASM.computeMinimumFee(2, 3)
|
|
834
|
+
|
|
835
|
+
expect(threeKeys).toBeGreaterThan(oneKey)
|
|
836
|
+
})
|
|
837
|
+
|
|
838
|
+
test('should default to the latest platform version', function () {
|
|
839
|
+
expect(IdentityCreateFromShieldedPoolTransitionWASM.computeMinimumFee(2, 3))
|
|
840
|
+
.toEqual(IdentityCreateFromShieldedPoolTransitionWASM.computeMinimumFee(2, 3, PlatformVersionWASM.PLATFORM_V12))
|
|
841
|
+
})
|
|
842
|
+
})
|
|
843
|
+
})
|
|
844
|
+
|
|
845
|
+
describe('computeMinimumFee across shielded transitions', function () {
|
|
846
|
+
const numActions = 2
|
|
847
|
+
|
|
848
|
+
test('Shield should be the compute-only fee, without the per-action storage term', function () {
|
|
849
|
+
expect(ShieldTransitionWASM.computeMinimumFee(numActions))
|
|
850
|
+
.toBeLessThan(ShieldedTransferTransitionWASM.computeMinimumFee(numActions))
|
|
851
|
+
})
|
|
852
|
+
|
|
853
|
+
test('Shield and ShieldedTransfer should agree with no actions', function () {
|
|
854
|
+
expect(ShieldTransitionWASM.computeMinimumFee(0))
|
|
855
|
+
.toEqual(ShieldedTransferTransitionWASM.computeMinimumFee(0))
|
|
856
|
+
})
|
|
857
|
+
|
|
858
|
+
test('ShieldFromAssetLock should match ShieldedTransfer', function () {
|
|
859
|
+
expect(ShieldFromAssetLockTransitionWASM.computeMinimumFee(numActions))
|
|
860
|
+
.toEqual(ShieldedTransferTransitionWASM.computeMinimumFee(numActions))
|
|
861
|
+
})
|
|
862
|
+
|
|
863
|
+
test('Unshield should add the output address write on top of ShieldedTransfer', function () {
|
|
864
|
+
expect(UnshieldTransitionWASM.computeMinimumFee(numActions))
|
|
865
|
+
.toBeGreaterThan(ShieldedTransferTransitionWASM.computeMinimumFee(numActions))
|
|
866
|
+
})
|
|
867
|
+
|
|
868
|
+
test('ShieldedWithdrawal should add the withdrawal document write on top of Unshield', function () {
|
|
869
|
+
expect(ShieldedWithdrawalTransitionWASM.computeMinimumFee(numActions))
|
|
870
|
+
.toBeGreaterThan(UnshieldTransitionWASM.computeMinimumFee(numActions))
|
|
871
|
+
})
|
|
872
|
+
|
|
873
|
+
test('IdentityCreateFromShieldedPool should add the identity create floor on top of ShieldedTransfer', function () {
|
|
874
|
+
expect(IdentityCreateFromShieldedPoolTransitionWASM.computeMinimumFee(numActions, 1))
|
|
875
|
+
.toBeGreaterThan(ShieldedTransferTransitionWASM.computeMinimumFee(numActions))
|
|
876
|
+
})
|
|
709
877
|
})
|