@arcium-hq/client 0.10.4 → 0.11.1
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/README.md +1 -2
- package/build/index.cjs +1493 -279
- package/build/index.mjs +1492 -282
- package/build/types/constants.d.ts +55 -0
- package/build/types/constants.d.ts.map +1 -1
- package/build/types/idl/arcium.d.ts +1338 -209
- package/build/types/idl/arcium.d.ts.map +1 -1
- package/build/types/idl/arcium_staking.d.ts +4583 -2032
- package/build/types/idl/arcium_staking.d.ts.map +1 -1
- package/build/types/idlAccounts.d.ts +14 -0
- package/build/types/idlAccounts.d.ts.map +1 -0
- package/build/types/onchain.d.ts +17 -4
- package/build/types/onchain.d.ts.map +1 -1
- package/build/types/pda.d.ts +29 -1
- package/build/types/pda.d.ts.map +1 -1
- package/build/types/rawCircuit.d.ts +5 -0
- package/build/types/rawCircuit.d.ts.map +1 -0
- package/build/types/recoveryPeers.d.ts +8 -0
- package/build/types/recoveryPeers.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/constants.ts +55 -0
- package/src/idl/arcium.json +1340 -211
- package/src/idl/arcium.ts +1340 -211
- package/src/idl/arcium_staking.json +4411 -1820
- package/src/idl/arcium_staking.ts +4375 -1824
- package/src/idlAccounts.ts +79 -0
- package/src/onchain.ts +62 -177
- package/src/pda.ts +103 -64
- package/src/rawCircuit.ts +41 -0
- package/src/recoveryPeers.ts +46 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { BorshCoder, convertIdlToCamelCase } from '@anchor-lang/core';
|
|
2
|
+
import { DISCRIMINATOR_SIZE } from './constants.js';
|
|
3
|
+
import { ARCIUM_IDL } from './idl/index.js';
|
|
4
|
+
import type { ArciumIdlType } from './idl/index.js';
|
|
5
|
+
|
|
6
|
+
type IdlAccountName = ArciumIdlType['accounts'][number]['name'];
|
|
7
|
+
|
|
8
|
+
// Names are validated against the IDL account-name union at compile time, so a
|
|
9
|
+
// typo or stale tier fails `tsc` rather than only throwing at load.
|
|
10
|
+
const MEMPOOL_DECODER_ACCOUNT_NAMES = [
|
|
11
|
+
'tinyMempool',
|
|
12
|
+
'smallMempool',
|
|
13
|
+
'mediumMempool',
|
|
14
|
+
'largeMempool',
|
|
15
|
+
] as const satisfies readonly IdlAccountName[];
|
|
16
|
+
const EXECUTING_POOL_DECODER_ACCOUNT_NAMES = [
|
|
17
|
+
'tinyExecPool',
|
|
18
|
+
'smallExecPool',
|
|
19
|
+
'mediumExecPool',
|
|
20
|
+
'largeExecPool',
|
|
21
|
+
] as const satisfies readonly IdlAccountName[];
|
|
22
|
+
|
|
23
|
+
/** @internal */
|
|
24
|
+
export type MempoolDecoderAccountName = typeof MEMPOOL_DECODER_ACCOUNT_NAMES[number];
|
|
25
|
+
/** @internal */
|
|
26
|
+
export type ExecutingPoolDecoderAccountName = typeof EXECUTING_POOL_DECODER_ACCOUNT_NAMES[number];
|
|
27
|
+
/** @internal */
|
|
28
|
+
export type PoolDecoderAccountName = MempoolDecoderAccountName | ExecutingPoolDecoderAccountName;
|
|
29
|
+
|
|
30
|
+
type PoolAccountKind = 'mempool' | 'executing pool';
|
|
31
|
+
|
|
32
|
+
function discriminatorKey(discriminator: ArrayLike<number>): string {
|
|
33
|
+
return Buffer.from(discriminator).toString('hex');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Discriminator bytes are read from the IDL at load time rather than pinned, so the
|
|
37
|
+
// decoder tracks the program's account layout as the single source of truth; a
|
|
38
|
+
// missing or renamed tier throws here instead of silently misrouting at runtime.
|
|
39
|
+
const accountDiscriminatorCoder = new BorshCoder(convertIdlToCamelCase(ARCIUM_IDL)).accounts;
|
|
40
|
+
|
|
41
|
+
function buildPoolAccountMap<const AccountNames extends readonly IdlAccountName[]>(
|
|
42
|
+
accountNames: AccountNames,
|
|
43
|
+
): ReadonlyMap<string, AccountNames[number]> {
|
|
44
|
+
return new Map<string, AccountNames[number]>(accountNames.map((name): [string, AccountNames[number]] => [
|
|
45
|
+
discriminatorKey(accountDiscriminatorCoder.accountDiscriminator(name)),
|
|
46
|
+
name,
|
|
47
|
+
]));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const MEMPOOL_ACCOUNT_BY_DISCRIMINATOR = buildPoolAccountMap(MEMPOOL_DECODER_ACCOUNT_NAMES);
|
|
51
|
+
const EXECUTING_POOL_ACCOUNT_BY_DISCRIMINATOR = buildPoolAccountMap(EXECUTING_POOL_DECODER_ACCOUNT_NAMES);
|
|
52
|
+
|
|
53
|
+
function getPoolAccountNameByDiscriminator<AccountName extends PoolDecoderAccountName>(
|
|
54
|
+
accountData: Uint8Array,
|
|
55
|
+
accountsByDiscriminator: ReadonlyMap<string, AccountName>,
|
|
56
|
+
kind: PoolAccountKind,
|
|
57
|
+
): AccountName {
|
|
58
|
+
if (accountData.length < DISCRIMINATOR_SIZE) {
|
|
59
|
+
throw new Error(`${kind} account data is shorter than discriminator size`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const key = discriminatorKey(accountData.subarray(0, DISCRIMINATOR_SIZE));
|
|
63
|
+
const accountName = accountsByDiscriminator.get(key);
|
|
64
|
+
if (accountName === undefined) {
|
|
65
|
+
throw new Error(`Unknown ${kind} account discriminator: ${key}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return accountName;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** @internal */
|
|
72
|
+
export function getMempoolAccountNameByDiscriminator(accountData: Uint8Array): MempoolDecoderAccountName {
|
|
73
|
+
return getPoolAccountNameByDiscriminator(accountData, MEMPOOL_ACCOUNT_BY_DISCRIMINATOR, 'mempool');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** @internal */
|
|
77
|
+
export function getExecutingPoolAccountNameByDiscriminator(accountData: Uint8Array): ExecutingPoolDecoderAccountName {
|
|
78
|
+
return getPoolAccountNameByDiscriminator(accountData, EXECUTING_POOL_ACCOUNT_BY_DISCRIMINATOR, 'executing pool');
|
|
79
|
+
}
|
package/src/onchain.ts
CHANGED
|
@@ -1,137 +1,35 @@
|
|
|
1
|
-
import { Program, AnchorProvider } from '@anchor-lang/core';
|
|
1
|
+
import anchorPkg, { Program, AnchorProvider } from '@anchor-lang/core';
|
|
2
2
|
import * as anchor from '@anchor-lang/core';
|
|
3
|
-
import { ConfirmOptions, PublicKey } from '@solana/web3.js';
|
|
3
|
+
import type { AccountInfo, ConfirmOptions, PublicKey } from '@solana/web3.js';
|
|
4
4
|
import { ARCIUM_IDL, ArciumIdlType } from './idl/index.js';
|
|
5
5
|
import { sha256 } from './cryptography/cryptography.js';
|
|
6
6
|
import { Arcium } from './idl/arcium.js';
|
|
7
7
|
import {
|
|
8
|
-
COMP_DEF_ACC_SEED,
|
|
9
8
|
COMP_DEF_OFFSET_SIZE,
|
|
10
|
-
|
|
11
|
-
MAX_ACCOUNT_SIZE,
|
|
9
|
+
DEFAULT_UPLOAD_TX_BATCH_SIZE,
|
|
12
10
|
MAX_EMBIGGEN_IX_PER_TX,
|
|
11
|
+
MAX_RAW_CIRCUIT_BYTES_PER_ACC,
|
|
13
12
|
MAX_REALLOC_PER_IX,
|
|
14
13
|
MAX_UPLOAD_PER_TX_BYTES,
|
|
15
|
-
|
|
14
|
+
RAW_CIRCUIT_ACCOUNT_HEADER_SIZE,
|
|
16
15
|
} from './constants.js';
|
|
17
16
|
import {
|
|
18
|
-
getArciumProgramId,
|
|
19
17
|
getMXEAccAddress,
|
|
20
18
|
getComputationAccAddress,
|
|
19
|
+
getCompDefAccAddress,
|
|
21
20
|
getFeePoolAccAddress,
|
|
22
21
|
getRawCircuitAccAddress,
|
|
23
22
|
getLookupTableAddress,
|
|
24
23
|
} from './pda.js';
|
|
25
24
|
import { ComputationReference, isNullRef, optionalLog } from './utils.js';
|
|
25
|
+
import {
|
|
26
|
+
getExecutingPoolAccountNameByDiscriminator,
|
|
27
|
+
getMempoolAccountNameByDiscriminator,
|
|
28
|
+
} from './idlAccounts.js';
|
|
29
|
+
import { normalizeRecoveryPeers } from './recoveryPeers.js';
|
|
30
|
+
import { assertRawCircuitUploadLength, getRawCircuitAccountCount } from './rawCircuit.js';
|
|
26
31
|
|
|
27
|
-
const
|
|
28
|
-
const TINY_MEMPOOL_DISCRIMINATOR: Arcium['accounts']['21']['discriminator'] = [
|
|
29
|
-
176,
|
|
30
|
-
33,
|
|
31
|
-
67,
|
|
32
|
-
108,
|
|
33
|
-
73,
|
|
34
|
-
135,
|
|
35
|
-
110,
|
|
36
|
-
166,
|
|
37
|
-
];
|
|
38
|
-
|
|
39
|
-
const TINY_EXECPOOL_ACC_NAME: Arcium['accounts']['20']['name'] = 'tinyExecPool';
|
|
40
|
-
const TINY_EXECPOOL_DISCRIMINATOR: Arcium['accounts']['20']['discriminator'] = [
|
|
41
|
-
80,
|
|
42
|
-
245,
|
|
43
|
-
5,
|
|
44
|
-
90,
|
|
45
|
-
154,
|
|
46
|
-
189,
|
|
47
|
-
190,
|
|
48
|
-
172,
|
|
49
|
-
];
|
|
50
|
-
|
|
51
|
-
const SMALL_MEMPOOL_ACC_NAME: Arcium['accounts']['19']['name'] = 'smallMempool';
|
|
52
|
-
const SMALL_MEMPOOL_DISCRIMINATOR: Arcium['accounts']['19']['discriminator'] = [
|
|
53
|
-
123,
|
|
54
|
-
153,
|
|
55
|
-
151,
|
|
56
|
-
118,
|
|
57
|
-
126,
|
|
58
|
-
71,
|
|
59
|
-
73,
|
|
60
|
-
92,
|
|
61
|
-
];
|
|
62
|
-
|
|
63
|
-
const SMALL_EXECPOOL_ACC_NAME: Arcium['accounts']['18']['name'] = 'smallExecPool';
|
|
64
|
-
const SMALL_EXECPOOL_DISCRIMINATOR: Arcium['accounts']['18']['discriminator'] = [
|
|
65
|
-
37,
|
|
66
|
-
147,
|
|
67
|
-
249,
|
|
68
|
-
253,
|
|
69
|
-
217,
|
|
70
|
-
136,
|
|
71
|
-
3,
|
|
72
|
-
87,
|
|
73
|
-
];
|
|
74
|
-
const MEDIUM_MEMPOOL_ACC_NAME: Arcium['accounts']['12']['name'] = 'mediumMempool';
|
|
75
|
-
const MEDIUM_MEMPOOL_DISCRIMINATOR: Arcium['accounts']['12']['discriminator'] = [
|
|
76
|
-
10,
|
|
77
|
-
249,
|
|
78
|
-
58,
|
|
79
|
-
39,
|
|
80
|
-
255,
|
|
81
|
-
231,
|
|
82
|
-
199,
|
|
83
|
-
168,
|
|
84
|
-
];
|
|
85
|
-
|
|
86
|
-
const MEDIUM_EXECPOOL_ACC_NAME: Arcium['accounts']['11']['name'] = 'mediumExecPool';
|
|
87
|
-
const MEDIUM_EXECPOOL_DISCRIMINATOR: Arcium['accounts']['11']['discriminator'] = [
|
|
88
|
-
97,
|
|
89
|
-
117,
|
|
90
|
-
128,
|
|
91
|
-
202,
|
|
92
|
-
213,
|
|
93
|
-
76,
|
|
94
|
-
5,
|
|
95
|
-
163,
|
|
96
|
-
];
|
|
97
|
-
|
|
98
|
-
const LARGE_MEMPOOL_ACC_NAME: Arcium['accounts']['9']['name'] = 'largeMempool';
|
|
99
|
-
const LARGE_MEMPOOL_DISCRIMINATOR: Arcium['accounts']['9']['discriminator'] = [
|
|
100
|
-
16,
|
|
101
|
-
168,
|
|
102
|
-
90,
|
|
103
|
-
235,
|
|
104
|
-
249,
|
|
105
|
-
207,
|
|
106
|
-
73,
|
|
107
|
-
223,
|
|
108
|
-
];
|
|
109
|
-
|
|
110
|
-
const LARGE_EXECPOOL_ACC_NAME: Arcium['accounts']['8']['name'] = 'largeExecPool';
|
|
111
|
-
const LARGE_EXECPOOL_DISCRIMINATOR: Arcium['accounts']['8']['discriminator'] = [
|
|
112
|
-
147,
|
|
113
|
-
145,
|
|
114
|
-
148,
|
|
115
|
-
170,
|
|
116
|
-
30,
|
|
117
|
-
13,
|
|
118
|
-
43,
|
|
119
|
-
216,
|
|
120
|
-
];
|
|
121
|
-
|
|
122
|
-
const MEMPOOL_DISCRIMINATOR_MAP = {
|
|
123
|
-
[TINY_MEMPOOL_DISCRIMINATOR.toString()]: TINY_MEMPOOL_ACC_NAME,
|
|
124
|
-
[SMALL_MEMPOOL_DISCRIMINATOR.toString()]: SMALL_MEMPOOL_ACC_NAME,
|
|
125
|
-
[MEDIUM_MEMPOOL_DISCRIMINATOR.toString()]: MEDIUM_MEMPOOL_ACC_NAME,
|
|
126
|
-
[LARGE_MEMPOOL_DISCRIMINATOR.toString()]: LARGE_MEMPOOL_ACC_NAME,
|
|
127
|
-
} as const;
|
|
128
|
-
|
|
129
|
-
const EXECPOOL_DISCRIMINATOR_MAP = {
|
|
130
|
-
[TINY_EXECPOOL_DISCRIMINATOR.toString()]: TINY_EXECPOOL_ACC_NAME,
|
|
131
|
-
[SMALL_EXECPOOL_DISCRIMINATOR.toString()]: SMALL_EXECPOOL_ACC_NAME,
|
|
132
|
-
[MEDIUM_EXECPOOL_DISCRIMINATOR.toString()]: MEDIUM_EXECPOOL_ACC_NAME,
|
|
133
|
-
[LARGE_EXECPOOL_DISCRIMINATOR.toString()]: LARGE_EXECPOOL_ACC_NAME,
|
|
134
|
-
} as const;
|
|
32
|
+
const { BN } = anchorPkg;
|
|
135
33
|
|
|
136
34
|
/**
|
|
137
35
|
* Represents a mempool account of any size (tiny, small, medium, or large).
|
|
@@ -169,17 +67,8 @@ export type CircuitSource = anchor.IdlTypes<ArciumIdlType>['circuitSource'];
|
|
|
169
67
|
* @throws Error if the account cannot be fetched or the discriminator is unknown.
|
|
170
68
|
*/
|
|
171
69
|
export async function getMempoolAccInfo(provider: AnchorProvider, mempoolAccPubkey: anchor.web3.PublicKey): Promise<MempoolAccount> {
|
|
172
|
-
const accData = await provider.connection.getAccountInfo(mempoolAccPubkey);
|
|
173
|
-
|
|
174
|
-
throw new Error(`Failed to fetch mempool account ${mempoolAccPubkey.toBase58()}`);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const discriminator = Array.from(accData.data.subarray(0, DISCRIMINATOR_SIZE)).toString();
|
|
178
|
-
const accName = MEMPOOL_DISCRIMINATOR_MAP[discriminator];
|
|
179
|
-
|
|
180
|
-
if (accName === undefined) {
|
|
181
|
-
throw new Error(`Unknown mempool account discriminator: ${discriminator}`);
|
|
182
|
-
}
|
|
70
|
+
const accData = requireAccountInfo(await provider.connection.getAccountInfo(mempoolAccPubkey), mempoolAccPubkey, 'mempool');
|
|
71
|
+
const accName = getMempoolAccountNameByDiscriminator(accData.data);
|
|
183
72
|
const program = getArciumProgram(provider);
|
|
184
73
|
return program.coder.accounts.decode(accName, accData.data);
|
|
185
74
|
}
|
|
@@ -192,21 +81,24 @@ export async function getMempoolAccInfo(provider: AnchorProvider, mempoolAccPubk
|
|
|
192
81
|
* @throws Error if the account cannot be fetched or the discriminator is unknown.
|
|
193
82
|
*/
|
|
194
83
|
export async function getExecutingPoolAccInfo(provider: AnchorProvider, executingPoolAccPubkey: anchor.web3.PublicKey): Promise<ExecutingPoolAccount> {
|
|
195
|
-
const accData = await provider.connection.getAccountInfo(executingPoolAccPubkey);
|
|
196
|
-
|
|
197
|
-
throw new Error(`Failed to fetch executing pool account ${executingPoolAccPubkey.toBase58()}`);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const discriminator = Array.from(accData.data.subarray(0, DISCRIMINATOR_SIZE)).toString();
|
|
201
|
-
const accName = EXECPOOL_DISCRIMINATOR_MAP[discriminator];
|
|
202
|
-
|
|
203
|
-
if (accName === undefined) {
|
|
204
|
-
throw new Error(`Unknown executing pool account discriminator: ${discriminator}`);
|
|
205
|
-
}
|
|
84
|
+
const accData = requireAccountInfo(await provider.connection.getAccountInfo(executingPoolAccPubkey), executingPoolAccPubkey, 'executing pool');
|
|
85
|
+
const accName = getExecutingPoolAccountNameByDiscriminator(accData.data);
|
|
206
86
|
const program = getArciumProgram(provider);
|
|
207
87
|
return program.coder.accounts.decode(accName, accData.data);
|
|
208
88
|
}
|
|
209
89
|
|
|
90
|
+
function requireAccountInfo(
|
|
91
|
+
accountInfo: AccountInfo<Buffer> | null,
|
|
92
|
+
pubkey: PublicKey,
|
|
93
|
+
label: 'mempool' | 'executing pool',
|
|
94
|
+
): AccountInfo<Buffer> {
|
|
95
|
+
if (accountInfo === null) {
|
|
96
|
+
throw new Error(`Failed to fetch ${label} account ${pubkey.toBase58()}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return accountInfo;
|
|
100
|
+
}
|
|
101
|
+
|
|
210
102
|
/**
|
|
211
103
|
* Return all computation references in the mempool for a given account.
|
|
212
104
|
* Only non-stake computations are included.
|
|
@@ -286,18 +178,18 @@ export async function getMempoolPriorityFeeStats(
|
|
|
286
178
|
const refs = await getComputationsInMempool(arciumProgram, mempoolAddress);
|
|
287
179
|
|
|
288
180
|
if (refs.length === 0) {
|
|
289
|
-
const zero = new
|
|
181
|
+
const zero = new BN(0);
|
|
290
182
|
return { mean: zero, median: zero, min: zero, max: zero, count: 0 };
|
|
291
183
|
}
|
|
292
184
|
|
|
293
185
|
const fees = refs.map(ref => ref.priorityFee).sort((a, b) => a.cmp(b));
|
|
294
186
|
|
|
295
|
-
const sum = fees.reduce((acc, fee) => acc.add(fee), new
|
|
296
|
-
const mean = sum.div(new
|
|
187
|
+
const sum = fees.reduce((acc, fee) => acc.add(fee), new BN(0));
|
|
188
|
+
const mean = sum.div(new BN(fees.length));
|
|
297
189
|
|
|
298
190
|
const mid = Math.floor(fees.length / 2);
|
|
299
191
|
const median = fees.length % 2 === 0
|
|
300
|
-
? fees[mid - 1].add(fees[mid]).div(new
|
|
192
|
+
? fees[mid - 1].add(fees[mid]).div(new BN(2))
|
|
301
193
|
: fees[mid];
|
|
302
194
|
|
|
303
195
|
return {
|
|
@@ -408,7 +300,8 @@ export function getCircuitState(circuitSource: CircuitSource): CircuitState {
|
|
|
408
300
|
* @param mxeProgramId - Public key of the MXE program.
|
|
409
301
|
* @param rawCircuit - Raw circuit data as a Uint8Array.
|
|
410
302
|
* @param logging - Whether to log progress (default: true).
|
|
411
|
-
* @param chunkSize - Number of upload transactions to send in parallel
|
|
303
|
+
* @param chunkSize - Number of upload transactions to send in parallel. Defaults to
|
|
304
|
+
* {@link DEFAULT_UPLOAD_TX_BATCH_SIZE}.
|
|
412
305
|
* @param confirmOptions - Transaction confirmation options.
|
|
413
306
|
* @returns Array of transaction signatures for all upload and finalize transactions.
|
|
414
307
|
*/
|
|
@@ -418,7 +311,7 @@ export async function uploadCircuit(
|
|
|
418
311
|
mxeProgramId: anchor.web3.PublicKey,
|
|
419
312
|
rawCircuit: Uint8Array,
|
|
420
313
|
logging: boolean = true,
|
|
421
|
-
chunkSize: number =
|
|
314
|
+
chunkSize: number = DEFAULT_UPLOAD_TX_BATCH_SIZE,
|
|
422
315
|
confirmOptions?: ConfirmOptions,
|
|
423
316
|
): Promise<string[]> {
|
|
424
317
|
const compDefAccInfo = getCompDefAccInfo(circuitName, mxeProgramId);
|
|
@@ -432,8 +325,8 @@ export async function uploadCircuit(
|
|
|
432
325
|
return [];
|
|
433
326
|
}
|
|
434
327
|
|
|
435
|
-
|
|
436
|
-
const numAccs =
|
|
328
|
+
assertRawCircuitUploadLength(rawCircuit.length, compDefAcc.definition.circuitLen, circuitName);
|
|
329
|
+
const numAccs = getRawCircuitAccountCount(rawCircuit.length);
|
|
437
330
|
const sigs: string[] = [];
|
|
438
331
|
const uploadPromises = [];
|
|
439
332
|
for (let i = 0; i < numAccs; i++) {
|
|
@@ -442,8 +335,8 @@ export async function uploadCircuit(
|
|
|
442
335
|
provider,
|
|
443
336
|
program,
|
|
444
337
|
rawCircuit.subarray(
|
|
445
|
-
i *
|
|
446
|
-
(i + 1) *
|
|
338
|
+
i * MAX_RAW_CIRCUIT_BYTES_PER_ACC,
|
|
339
|
+
(i + 1) * MAX_RAW_CIRCUIT_BYTES_PER_ACC,
|
|
447
340
|
),
|
|
448
341
|
i,
|
|
449
342
|
compDefAccInfo,
|
|
@@ -476,8 +369,6 @@ export async function buildFinalizeCompDefTx(
|
|
|
476
369
|
mxeProgramId: anchor.web3.PublicKey,
|
|
477
370
|
): Promise<anchor.web3.Transaction> {
|
|
478
371
|
const program = getArciumProgram(provider);
|
|
479
|
-
const compDefOffsetBuffer = Buffer.alloc(OFFSET_BUFFER_SIZE);
|
|
480
|
-
compDefOffsetBuffer.writeUInt32LE(compDefOffset, 0);
|
|
481
372
|
return program.methods
|
|
482
373
|
.finalizeComputationDefinition(compDefOffset, mxeProgramId)
|
|
483
374
|
.accounts({
|
|
@@ -494,15 +385,14 @@ async function uploadToCircuitAcc(
|
|
|
494
385
|
compDefAccInfo: { pubkey: anchor.web3.PublicKey; offset: number },
|
|
495
386
|
mxeProgramId: anchor.web3.PublicKey,
|
|
496
387
|
shouldLog: boolean = true,
|
|
497
|
-
chunkSize: number =
|
|
388
|
+
chunkSize: number = DEFAULT_UPLOAD_TX_BATCH_SIZE,
|
|
498
389
|
confirmOptions?: ConfirmOptions,
|
|
499
390
|
): Promise<string[]> {
|
|
500
391
|
const rawCircuitPda = getRawCircuitAccAddress(compDefAccInfo.pubkey, rawCircuitIndex);
|
|
501
392
|
const existingAcc = await provider.connection.getAccountInfo(rawCircuitPda);
|
|
502
393
|
|
|
503
394
|
// Skip entirely if account exists with correct size (pre-seeded at genesis or already uploaded)
|
|
504
|
-
|
|
505
|
-
const requiredAccountSize = rawCircuitPart.length + 9;
|
|
395
|
+
const requiredAccountSize = rawCircuitPart.length + RAW_CIRCUIT_ACCOUNT_HEADER_SIZE;
|
|
506
396
|
if (existingAcc !== null && existingAcc.data.length >= requiredAccountSize) {
|
|
507
397
|
optionalLog(
|
|
508
398
|
shouldLog,
|
|
@@ -725,19 +615,8 @@ export function getArciumProgram(provider: AnchorProvider): Program<Arcium> {
|
|
|
725
615
|
*/
|
|
726
616
|
function getCompDefAccInfo(circuitName: string, mxeProgramId: anchor.web3.PublicKey): { pubkey: anchor.web3.PublicKey; offset: number } {
|
|
727
617
|
const offset = getCompDefAccOffset(circuitName);
|
|
728
|
-
const
|
|
729
|
-
return { pubkey:
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
/**
|
|
733
|
-
* Return the PDA for a computation definition account, given the program ID, MXE program ID, and offset.
|
|
734
|
-
* @param arciumProgramId - Public key of the Arcium program.
|
|
735
|
-
* @param mxeProgramId - Public key of the MXE program.
|
|
736
|
-
* @param offset - Offset as a Uint8Array.
|
|
737
|
-
* @returns PDA for the computation definition account.
|
|
738
|
-
*/
|
|
739
|
-
function getCompDefAccPDA(arciumProgramId: anchor.web3.PublicKey, mxeProgramId: anchor.web3.PublicKey, offset: Uint8Array): anchor.web3.PublicKey {
|
|
740
|
-
return anchor.web3.PublicKey.findProgramAddressSync([Buffer.from(COMP_DEF_ACC_SEED, 'utf-8'), mxeProgramId.toBuffer(), offset], arciumProgramId)[0];
|
|
618
|
+
const offsetNumber = Buffer.from(offset).readUInt32LE(0);
|
|
619
|
+
return { pubkey: getCompDefAccAddress(mxeProgramId, offsetNumber), offset: offsetNumber };
|
|
741
620
|
}
|
|
742
621
|
|
|
743
622
|
/**
|
|
@@ -746,17 +625,22 @@ function getCompDefAccPDA(arciumProgramId: anchor.web3.PublicKey, mxeProgramId:
|
|
|
746
625
|
* Call initMxePart2 afterwards to finish allocation and add keygen to mempool.
|
|
747
626
|
* @param provider - Anchor provider to use for transactions.
|
|
748
627
|
* @param mxeProgramId - Public key to use as the MXE program ID.
|
|
628
|
+
* @param recoveryPeers - Array of 100 node offsets for recovery peers (0 for unused slots).
|
|
749
629
|
* @param confirmOptions - Transaction confirmation options.
|
|
750
630
|
* @returns Transaction signature.
|
|
751
631
|
*/
|
|
752
632
|
export async function initMxePart1(
|
|
753
633
|
provider: AnchorProvider,
|
|
754
634
|
mxeProgramId: anchor.web3.PublicKey,
|
|
635
|
+
recoveryPeers: number[],
|
|
755
636
|
confirmOptions?: ConfirmOptions,
|
|
756
637
|
): Promise<string> {
|
|
757
638
|
const program = getArciumProgram(provider);
|
|
639
|
+
const paddedRecoveryPeers = normalizeRecoveryPeers(recoveryPeers);
|
|
758
640
|
const tx = await program.methods
|
|
759
|
-
.initMxePart1(
|
|
641
|
+
.initMxePart1(
|
|
642
|
+
paddedRecoveryPeers
|
|
643
|
+
)
|
|
760
644
|
.accountsPartial({
|
|
761
645
|
signer: provider.publicKey,
|
|
762
646
|
mxeProgram: mxeProgramId,
|
|
@@ -772,9 +656,12 @@ export async function initMxePart1(
|
|
|
772
656
|
* @param provider - Anchor provider to use for transactions.
|
|
773
657
|
* @param clusterOffset - Cluster offset to associate with the MXE.
|
|
774
658
|
* @param mxeProgramId - Public key to use as the MXE program ID.
|
|
775
|
-
* @param recoveryPeers - Array of 100 node offsets for recovery peers (0 for unused slots).
|
|
776
659
|
* @param keygenOffset - Computation offset for the keygen computation.
|
|
777
660
|
* @param keyRecoveryInitOffset - Computation offset for the key_recovery_init computation.
|
|
661
|
+
* @param recoveryPeers - Recovery peer node offsets. Slots set to 0 are treated as unused.
|
|
662
|
+
* The non-zero count must be either 0 (recovery disabled) or at least
|
|
663
|
+
* `MIN_RECOVERY_PEERS` (4). The array is padded with zeros up to
|
|
664
|
+
* `MAX_RECOVERY_PEERS` (100); passing more than that throws.
|
|
778
665
|
* @param lutOffset - Lookup table offset for the MXE's address lookup table.
|
|
779
666
|
* @param mxeAuthority - Optional authority for the MXE (defaults to provider.publicKey).
|
|
780
667
|
* @param confirmOptions - Transaction confirmation options.
|
|
@@ -792,20 +679,10 @@ export async function initMxePart2(
|
|
|
792
679
|
confirmOptions?: ConfirmOptions,
|
|
793
680
|
): Promise<string> {
|
|
794
681
|
const program = getArciumProgram(provider);
|
|
795
|
-
// Ensure recoveryPeers has exactly 100 elements
|
|
796
|
-
const paddedRecoveryPeers = [...recoveryPeers];
|
|
797
|
-
while (paddedRecoveryPeers.length < 100) {
|
|
798
|
-
paddedRecoveryPeers.push(0);
|
|
799
|
-
}
|
|
800
|
-
if (paddedRecoveryPeers.length > 100) {
|
|
801
|
-
throw new Error('recoveryPeers must have at most 100 elements');
|
|
802
|
-
}
|
|
803
682
|
|
|
804
683
|
const tx = await program.methods
|
|
805
684
|
.initMxePart2(
|
|
806
685
|
clusterOffset,
|
|
807
|
-
mxeProgramId,
|
|
808
|
-
paddedRecoveryPeers,
|
|
809
686
|
keygenOffset,
|
|
810
687
|
keyRecoveryInitOffset,
|
|
811
688
|
lutOffset,
|
|
@@ -821,6 +698,14 @@ export async function initMxePart2(
|
|
|
821
698
|
return signAndSendWithBlockhash(provider, tx, await provider.connection.getLatestBlockhash({ commitment: confirmOptions?.commitment || 'confirmed' }), confirmOptions);
|
|
822
699
|
}
|
|
823
700
|
|
|
701
|
+
/**
|
|
702
|
+
* Reclaim the rent locked in a finished computation account.
|
|
703
|
+
* @param provider - Anchor provider to use for transactions.
|
|
704
|
+
* @param clusterOffset - Offset of the cluster that ran the computation.
|
|
705
|
+
* @param computationOffset - Offset of the computation whose rent is being claimed.
|
|
706
|
+
* @param confirmOptions - Transaction confirmation options.
|
|
707
|
+
* @returns Transaction signature.
|
|
708
|
+
*/
|
|
824
709
|
export async function claimComputationRent(
|
|
825
710
|
provider: AnchorProvider,
|
|
826
711
|
clusterOffset: number,
|