@argonprotocol/testing 1.4.6 → 1.4.7-dev.6244465b
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/lib/index.cjs +48 -103
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +1 -9
- package/lib/index.d.ts +1 -9
- package/lib/index.js +48 -102
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
package/lib/index.d.cts
CHANGED
|
@@ -120,13 +120,6 @@ type BitcoinRawTransactionResult = {
|
|
|
120
120
|
txid: string;
|
|
121
121
|
};
|
|
122
122
|
|
|
123
|
-
declare class TestBitcoinCli {
|
|
124
|
-
/**
|
|
125
|
-
* Returns the localhost address of the notary (NOTE: not accessible from containers)
|
|
126
|
-
*/
|
|
127
|
-
static run(command: string): string;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
123
|
declare class TestOracle implements ITeardownable {
|
|
131
124
|
#private;
|
|
132
125
|
static BitcoinOperator: string;
|
|
@@ -234,7 +227,6 @@ type EthereumGatewayUpdateBatch = {
|
|
|
234
227
|
argonApprovalsNonce: bigint;
|
|
235
228
|
argonApprovalsHash: Hex;
|
|
236
229
|
paused: boolean;
|
|
237
|
-
pendingClearOutQueueNonces: bigint[];
|
|
238
230
|
firstQueueNonce?: bigint;
|
|
239
231
|
lastQueueNonce?: bigint;
|
|
240
232
|
updates: MintingGatewayGatewayUpdate[];
|
|
@@ -426,4 +418,4 @@ declare function stringifyExt(obj: any): any;
|
|
|
426
418
|
declare function sudo(): KeyringPair;
|
|
427
419
|
declare function activateNotary(sudo: KeyringPair, client: ArgonClient, notary: TestNotary): Promise<void>;
|
|
428
420
|
|
|
429
|
-
export { type EthereumGatewayUpdateBatch, EthereumProofE2eHarness, type ITeardownable, SKIP_E2E,
|
|
421
|
+
export { type EthereumGatewayUpdateBatch, EthereumProofE2eHarness, type ITeardownable, SKIP_E2E, TestEthereum, TestMainchain, TestMintingAuthorityActor, TestMintingGateway, TestNotary, TestOracle, activateNotary, addTeardown, cleanHostForDocker, closeOnTeardown, disconnectOnTeardown, getDockerPortMapping, getProxy, getReadyEthereumGatewayUpdates, mineLaterExecutionAnchorReceipt, projectRoot, runOnTeardown, runTestScript, signGatewayPermit, startNetwork, stringifyExt, sudo, syncEthereumVerifierUntilAnchorCovers, teardown, toArgonKeccakSignature, toEvmRecoverableSignature, waitForExecutionReceipt, waitForFinalizedBeaconExecutionAtOrAbove };
|
package/lib/index.d.ts
CHANGED
|
@@ -120,13 +120,6 @@ type BitcoinRawTransactionResult = {
|
|
|
120
120
|
txid: string;
|
|
121
121
|
};
|
|
122
122
|
|
|
123
|
-
declare class TestBitcoinCli {
|
|
124
|
-
/**
|
|
125
|
-
* Returns the localhost address of the notary (NOTE: not accessible from containers)
|
|
126
|
-
*/
|
|
127
|
-
static run(command: string): string;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
123
|
declare class TestOracle implements ITeardownable {
|
|
131
124
|
#private;
|
|
132
125
|
static BitcoinOperator: string;
|
|
@@ -234,7 +227,6 @@ type EthereumGatewayUpdateBatch = {
|
|
|
234
227
|
argonApprovalsNonce: bigint;
|
|
235
228
|
argonApprovalsHash: Hex;
|
|
236
229
|
paused: boolean;
|
|
237
|
-
pendingClearOutQueueNonces: bigint[];
|
|
238
230
|
firstQueueNonce?: bigint;
|
|
239
231
|
lastQueueNonce?: bigint;
|
|
240
232
|
updates: MintingGatewayGatewayUpdate[];
|
|
@@ -426,4 +418,4 @@ declare function stringifyExt(obj: any): any;
|
|
|
426
418
|
declare function sudo(): KeyringPair;
|
|
427
419
|
declare function activateNotary(sudo: KeyringPair, client: ArgonClient, notary: TestNotary): Promise<void>;
|
|
428
420
|
|
|
429
|
-
export { type EthereumGatewayUpdateBatch, EthereumProofE2eHarness, type ITeardownable, SKIP_E2E,
|
|
421
|
+
export { type EthereumGatewayUpdateBatch, EthereumProofE2eHarness, type ITeardownable, SKIP_E2E, TestEthereum, TestMainchain, TestMintingAuthorityActor, TestMintingGateway, TestNotary, TestOracle, activateNotary, addTeardown, cleanHostForDocker, closeOnTeardown, disconnectOnTeardown, getDockerPortMapping, getProxy, getReadyEthereumGatewayUpdates, mineLaterExecutionAnchorReceipt, projectRoot, runOnTeardown, runTestScript, signGatewayPermit, startNetwork, stringifyExt, sudo, syncEthereumVerifierUntilAnchorCovers, teardown, toArgonKeccakSignature, toEvmRecoverableSignature, waitForExecutionReceipt, waitForFinalizedBeaconExecutionAtOrAbove };
|
package/lib/index.js
CHANGED
|
@@ -567,34 +567,13 @@ var BitcoinRpcClient = class {
|
|
|
567
567
|
}
|
|
568
568
|
};
|
|
569
569
|
|
|
570
|
-
// src/TestBitcoinCli.ts
|
|
571
|
-
import * as child_process3 from "child_process";
|
|
572
|
-
import * as Path4 from "path";
|
|
573
|
-
var TestBitcoinCli = class {
|
|
574
|
-
/**
|
|
575
|
-
* Returns the localhost address of the notary (NOTE: not accessible from containers)
|
|
576
|
-
*/
|
|
577
|
-
static run(command) {
|
|
578
|
-
const binPath = Path4.join(`${projectRoot()}`, "target/debug/argon-bitcoin-cli");
|
|
579
|
-
try {
|
|
580
|
-
return child_process3.execSync(`${binPath} ${command}`, {
|
|
581
|
-
encoding: "utf8"
|
|
582
|
-
}).trim();
|
|
583
|
-
} catch (e) {
|
|
584
|
-
console.error(`Error running command: ${command}`);
|
|
585
|
-
console.error(e.stdout);
|
|
586
|
-
throw e;
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
};
|
|
590
|
-
|
|
591
570
|
// src/TestOracle.ts
|
|
592
|
-
import * as
|
|
571
|
+
import * as child_process3 from "child_process";
|
|
593
572
|
import { Keyring as Keyring2 } from "@argonprotocol/mainchain";
|
|
594
573
|
import * as fs3 from "fs";
|
|
595
574
|
import * as readline3 from "readline";
|
|
596
575
|
import * as process4 from "process";
|
|
597
|
-
import * as
|
|
576
|
+
import * as Path4 from "path";
|
|
598
577
|
var TestOracle = class _TestOracle {
|
|
599
578
|
static BitcoinOperator = "//Dave";
|
|
600
579
|
static PriceIndexOperator = "//Eve";
|
|
@@ -609,7 +588,7 @@ var TestOracle = class _TestOracle {
|
|
|
609
588
|
const { pathToBin, mainchainUrl, bitcoinRpcUrl } = options;
|
|
610
589
|
const operatorSuri = service == "bitcoin" ? _TestOracle.BitcoinOperator : _TestOracle.PriceIndexOperator;
|
|
611
590
|
this.operator = new Keyring2({ type: "sr25519" }).createFromUri(operatorSuri);
|
|
612
|
-
const binPath = pathToBin ??
|
|
591
|
+
const binPath = pathToBin ?? Path4.join(projectRoot(), "target/debug/argon-oracle");
|
|
613
592
|
if (!fs3.existsSync(binPath)) {
|
|
614
593
|
throw new Error(`Oracle binary not found at ${binPath}`);
|
|
615
594
|
}
|
|
@@ -621,7 +600,7 @@ var TestOracle = class _TestOracle {
|
|
|
621
600
|
}
|
|
622
601
|
execArgs.push("--bitcoin-rpc-url", bitcoinRpcUrl);
|
|
623
602
|
}
|
|
624
|
-
this.#childProcess =
|
|
603
|
+
this.#childProcess = child_process3.spawn(binPath, execArgs, {
|
|
625
604
|
stdio: ["ignore", "pipe", "pipe"],
|
|
626
605
|
env: { ...process4.env, RUST_LOG: "info", ...options.env }
|
|
627
606
|
});
|
|
@@ -646,7 +625,7 @@ var TestOracle = class _TestOracle {
|
|
|
646
625
|
// src/TestEthereum.ts
|
|
647
626
|
import * as fs4 from "fs/promises";
|
|
648
627
|
import * as os from "os";
|
|
649
|
-
import * as
|
|
628
|
+
import * as Path5 from "path";
|
|
650
629
|
import { spawn as spawn4, spawnSync } from "child_process";
|
|
651
630
|
import { detectPort as detectPort2 } from "detect-port";
|
|
652
631
|
import { EvmContracts } from "@argonprotocol/mainchain";
|
|
@@ -708,8 +687,8 @@ var TestEthereum = class {
|
|
|
708
687
|
} = options ?? {};
|
|
709
688
|
const elPublicPortStart = await findFreePortRange(DEFAULT_EL_PORT_START, PORT_RANGE_SIZE);
|
|
710
689
|
const clPublicPortStart = await findFreePortRange(DEFAULT_CL_PORT_START, PORT_RANGE_SIZE);
|
|
711
|
-
this.#argsDir = await fs4.mkdtemp(
|
|
712
|
-
const argsFile =
|
|
690
|
+
this.#argsDir = await fs4.mkdtemp(Path5.join(os.tmpdir(), "argon-ethereum-devnet-"));
|
|
691
|
+
const argsFile = Path5.join(this.#argsDir, "network-params.yaml");
|
|
713
692
|
await fs4.writeFile(
|
|
714
693
|
argsFile,
|
|
715
694
|
renderEthereumArgs(
|
|
@@ -1109,9 +1088,9 @@ async function delay(ms) {
|
|
|
1109
1088
|
|
|
1110
1089
|
// src/TestNetwork.ts
|
|
1111
1090
|
import * as docker from "docker-compose";
|
|
1112
|
-
import * as
|
|
1091
|
+
import * as Path6 from "path";
|
|
1113
1092
|
async function startNetwork(testName, options) {
|
|
1114
|
-
const config =
|
|
1093
|
+
const config = Path6.join(__dirname, `dev.docker-compose.yml`);
|
|
1115
1094
|
const env4 = {
|
|
1116
1095
|
VERSION: "dev",
|
|
1117
1096
|
ARGON_CHAIN: "dev-docker",
|
|
@@ -1342,7 +1321,6 @@ var {
|
|
|
1342
1321
|
encodeMintingGatewayMintingAuthorityDeactivateTarget,
|
|
1343
1322
|
hashMintingGatewayActivateMintingAuthority,
|
|
1344
1323
|
hashMintingGatewayGatewayUpdateApproval,
|
|
1345
|
-
hashMintingGatewayMintingAuthorityDeactivation,
|
|
1346
1324
|
mintingGatewayAbi,
|
|
1347
1325
|
MINTING_GATEWAY_UPDATE_KINDS
|
|
1348
1326
|
} = EvmContracts2;
|
|
@@ -1394,7 +1372,6 @@ async function getReadyEthereumGatewayUpdates(client, gatewayClient, options = {
|
|
|
1394
1372
|
const argonApprovalsNonce = rawArgonApprovalsNonce;
|
|
1395
1373
|
const argonApprovalsHash = rawArgonApprovalsHash;
|
|
1396
1374
|
const paused = rawPaused;
|
|
1397
|
-
const pendingClearOutQueueNonces = [];
|
|
1398
1375
|
const candidateUpdates = [];
|
|
1399
1376
|
let expectedPreviousApprovalHash = argonApprovalsHash;
|
|
1400
1377
|
let readyQueueEntriesScanned = 0;
|
|
@@ -1409,14 +1386,8 @@ async function getReadyEthereumGatewayUpdates(client, gatewayClient, options = {
|
|
|
1409
1386
|
}
|
|
1410
1387
|
const entry = entryOption.unwrap();
|
|
1411
1388
|
const approvingCouncilHash = toHexValue(entry.approvingCouncilHash);
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
entry,
|
|
1415
|
-
approvingCouncilHash,
|
|
1416
|
-
councilCache,
|
|
1417
|
-
hashContext,
|
|
1418
|
-
queueNonce
|
|
1419
|
-
)) {
|
|
1389
|
+
const approvingCouncil = await loadCouncilByHash(client, approvingCouncilHash, councilCache);
|
|
1390
|
+
if (!queueEntryHasQuorum(entry, approvingCouncil)) {
|
|
1420
1391
|
break;
|
|
1421
1392
|
}
|
|
1422
1393
|
readyQueueEntriesScanned += 1;
|
|
@@ -1433,10 +1404,15 @@ async function getReadyEthereumGatewayUpdates(client, gatewayClient, options = {
|
|
|
1433
1404
|
expectedPreviousApprovalHash = toHexValue(entry.approvalHash);
|
|
1434
1405
|
}
|
|
1435
1406
|
}
|
|
1436
|
-
while (candidateUpdates.length > 0 && candidateUpdates[candidateUpdates.length - 1]?.kind === MINTING_GATEWAY_UPDATE_KINDS.mintingAuthorityDeactivate) {
|
|
1437
|
-
pendingClearOutQueueNonces.unshift(candidateUpdates.pop().queueNonce);
|
|
1438
|
-
}
|
|
1439
1407
|
const updates = candidateUpdates;
|
|
1408
|
+
for (let index = 0; index < updates.length; index += 1) {
|
|
1409
|
+
const isBorder = updates[index].kind === MINTING_GATEWAY_UPDATE_KINDS.globalIssuanceCouncilRotate || index === updates.length - 1;
|
|
1410
|
+
if (isBorder || updates[index].signatures.length === 0) continue;
|
|
1411
|
+
updates[index] = {
|
|
1412
|
+
...updates[index],
|
|
1413
|
+
signatures: []
|
|
1414
|
+
};
|
|
1415
|
+
}
|
|
1440
1416
|
const firstQueueNonce = updates[0]?.queueNonce;
|
|
1441
1417
|
const lastQueueNonce = updates[updates.length - 1]?.queueNonce;
|
|
1442
1418
|
return {
|
|
@@ -1448,7 +1424,6 @@ async function getReadyEthereumGatewayUpdates(client, gatewayClient, options = {
|
|
|
1448
1424
|
argonApprovalsNonce,
|
|
1449
1425
|
argonApprovalsHash,
|
|
1450
1426
|
paused,
|
|
1451
|
-
pendingClearOutQueueNonces,
|
|
1452
1427
|
...firstQueueNonce !== void 0 ? { firstQueueNonce, lastQueueNonce } : {},
|
|
1453
1428
|
updates
|
|
1454
1429
|
};
|
|
@@ -1476,7 +1451,7 @@ async function buildGatewayUpdate(client, destinationChain, hashContext, queueNo
|
|
|
1476
1451
|
signingKey
|
|
1477
1452
|
};
|
|
1478
1453
|
const payload = encodeMintingGatewayMintingAuthorityActivationTarget(target);
|
|
1479
|
-
const targetPayloadHash =
|
|
1454
|
+
const targetPayloadHash = hashMintingGatewayActivateMintingAuthority(hashContext, target);
|
|
1480
1455
|
const approvalHash = hashMintingGatewayGatewayUpdateApproval(hashContext, {
|
|
1481
1456
|
queueNonce,
|
|
1482
1457
|
approvingCouncilHash,
|
|
@@ -1501,17 +1476,30 @@ async function buildGatewayUpdate(client, destinationChain, hashContext, queueNo
|
|
|
1501
1476
|
};
|
|
1502
1477
|
}
|
|
1503
1478
|
if (entry.target.isMintingAuthorityDeactivation) {
|
|
1504
|
-
const
|
|
1505
|
-
|
|
1479
|
+
const signingKey = getAddress2(toHexValue(entry.target.asMintingAuthorityDeactivation));
|
|
1480
|
+
const payload = encodeMintingGatewayMintingAuthorityDeactivateTarget({ signingKey });
|
|
1481
|
+
const targetPayloadHash = keccak256(payload);
|
|
1482
|
+
const approvalHash = hashMintingGatewayGatewayUpdateApproval(hashContext, {
|
|
1506
1483
|
queueNonce,
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1484
|
+
approvingCouncilHash,
|
|
1485
|
+
kind: MINTING_GATEWAY_UPDATE_KINDS.mintingAuthorityDeactivate,
|
|
1486
|
+
targetId: signingKeyTargetId(signingKey),
|
|
1487
|
+
targetPayloadHash,
|
|
1488
|
+
previousUpdateHash: toHexValue(entry.previousApprovalHash)
|
|
1489
|
+
});
|
|
1490
|
+
if (toHexValue(entry.targetPayloadHash) !== targetPayloadHash) {
|
|
1491
|
+
throw new Error(`Queue nonce ${queueNonce} target payload hash does not match deactivation`);
|
|
1492
|
+
}
|
|
1493
|
+
if (toHexValue(entry.approvalHash) !== approvalHash) {
|
|
1494
|
+
throw new Error(
|
|
1495
|
+
`Queue nonce ${queueNonce} approval hash does not match deactivation: actual=${toHexValue(entry.approvalHash)} expected=${approvalHash} previous=${toHexValue(entry.previousApprovalHash)} council=${approvingCouncilHash}`
|
|
1496
|
+
);
|
|
1497
|
+
}
|
|
1510
1498
|
return {
|
|
1511
1499
|
queueNonce,
|
|
1512
1500
|
kind: MINTING_GATEWAY_UPDATE_KINDS.mintingAuthorityDeactivate,
|
|
1513
1501
|
payload,
|
|
1514
|
-
signatures
|
|
1502
|
+
signatures: getSortedSignatures(entry.signatures)
|
|
1515
1503
|
};
|
|
1516
1504
|
}
|
|
1517
1505
|
throw new Error(`Unsupported approval queue target ${entry.target.type}`);
|
|
@@ -1537,23 +1525,20 @@ async function loadCouncilByHash(client, councilHash, cache) {
|
|
|
1537
1525
|
return loaded;
|
|
1538
1526
|
}
|
|
1539
1527
|
function queueEntryHasQuorum(entry, council) {
|
|
1540
|
-
|
|
1528
|
+
let signedWeight = 0n;
|
|
1529
|
+
for (const [signer] of entry.signatures.entries()) {
|
|
1541
1530
|
const signerAddress = getAddress2(toHexValue(signer));
|
|
1542
1531
|
const member = council.members.find((x) => x.signer === signerAddress);
|
|
1543
1532
|
if (!member) {
|
|
1544
1533
|
throw new Error(`Signature submitted by ${signerAddress}, which is not in the council`);
|
|
1545
1534
|
}
|
|
1546
|
-
|
|
1547
|
-
}
|
|
1548
|
-
|
|
1549
|
-
}
|
|
1550
|
-
async function queueEntryIsReady(client, entry, approvingCouncilHash, councilCache, hashContext, queueNonce) {
|
|
1551
|
-
if (entry.target.isMintingAuthorityDeactivation) {
|
|
1552
|
-
validateDeactivationEntry(hashContext, queueNonce, entry, approvingCouncilHash);
|
|
1535
|
+
signedWeight += member.weight;
|
|
1536
|
+
}
|
|
1537
|
+
if (signedWeight * 100n >= council.totalWeight * 90n) {
|
|
1553
1538
|
return true;
|
|
1554
1539
|
}
|
|
1555
|
-
const
|
|
1556
|
-
return
|
|
1540
|
+
const unsignedMemberCount = council.members.length - entry.signatures.size;
|
|
1541
|
+
return unsignedMemberCount <= 2 && signedWeight * 100n >= council.totalWeight * 80n;
|
|
1557
1542
|
}
|
|
1558
1543
|
function councilToSnapshot(council) {
|
|
1559
1544
|
return {
|
|
@@ -1561,46 +1546,8 @@ function councilToSnapshot(council) {
|
|
|
1561
1546
|
weights: council.members.map((member) => member.weight)
|
|
1562
1547
|
};
|
|
1563
1548
|
}
|
|
1564
|
-
function
|
|
1565
|
-
return
|
|
1566
|
-
}
|
|
1567
|
-
function payloadHashFromDeactivationPayload(target) {
|
|
1568
|
-
return keccak256(encodeMintingGatewayMintingAuthorityDeactivateTarget(target));
|
|
1569
|
-
}
|
|
1570
|
-
function validateDeactivationEntry(hashContext, queueNonce, entry, approvingCouncilHash) {
|
|
1571
|
-
const signingKey = getAddress2(toHexValue(entry.target.asMintingAuthorityDeactivation));
|
|
1572
|
-
const target = { signingKey };
|
|
1573
|
-
const payload = encodeMintingGatewayMintingAuthorityDeactivateTarget(target);
|
|
1574
|
-
const targetPayloadHash = payloadHashFromDeactivationPayload(target);
|
|
1575
|
-
const approvalHash = hashMintingGatewayMintingAuthorityDeactivation(hashContext, {
|
|
1576
|
-
queueNonce,
|
|
1577
|
-
target,
|
|
1578
|
-
previousUpdateHash: toHexValue(entry.previousApprovalHash)
|
|
1579
|
-
});
|
|
1580
|
-
if (toHexValue(entry.targetPayloadHash) !== targetPayloadHash) {
|
|
1581
|
-
throw new Error(`Queue nonce ${queueNonce} target payload hash does not match deactivation`);
|
|
1582
|
-
}
|
|
1583
|
-
if (toHexValue(entry.approvalHash) !== approvalHash) {
|
|
1584
|
-
throw new Error(
|
|
1585
|
-
`Queue nonce ${queueNonce} approval hash does not match deactivation: actual=${toHexValue(entry.approvalHash)} expected=${approvalHash} previous=${toHexValue(entry.previousApprovalHash)} council=${approvingCouncilHash}`
|
|
1586
|
-
);
|
|
1587
|
-
}
|
|
1588
|
-
const deactivationSignatures = [...entry.signatures.entries()];
|
|
1589
|
-
if (deactivationSignatures.length !== 1) {
|
|
1590
|
-
throw new Error(
|
|
1591
|
-
`Queue nonce ${queueNonce} expected exactly one deactivation signature, received ${deactivationSignatures.length}`
|
|
1592
|
-
);
|
|
1593
|
-
}
|
|
1594
|
-
const [signer] = deactivationSignatures[0];
|
|
1595
|
-
if (getAddress2(toHexValue(signer)) !== signingKey) {
|
|
1596
|
-
throw new Error(
|
|
1597
|
-
`Queue nonce ${queueNonce} deactivation signature was submitted by ${getAddress2(toHexValue(signer))}, expected ${signingKey}`
|
|
1598
|
-
);
|
|
1599
|
-
}
|
|
1600
|
-
return {
|
|
1601
|
-
payload,
|
|
1602
|
-
signatures: getSortedSignatures(entry.signatures)
|
|
1603
|
-
};
|
|
1549
|
+
function signingKeyTargetId(signingKey) {
|
|
1550
|
+
return `0x${signingKey.slice(2).padStart(64, "0").toLowerCase()}`;
|
|
1604
1551
|
}
|
|
1605
1552
|
function getSortedSignatures(signatures) {
|
|
1606
1553
|
return [...signatures.entries()].sort(
|
|
@@ -2248,7 +2195,6 @@ async function activateNotary(sudo2, client, notary) {
|
|
|
2248
2195
|
export {
|
|
2249
2196
|
EthereumProofE2eHarness,
|
|
2250
2197
|
SKIP_E2E,
|
|
2251
|
-
TestBitcoinCli,
|
|
2252
2198
|
TestEthereum,
|
|
2253
2199
|
TestMainchain,
|
|
2254
2200
|
TestMintingAuthorityActor,
|