@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.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, TestBitcoinCli, 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 };
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, TestBitcoinCli, 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 };
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 child_process4 from "child_process";
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 Path5 from "path";
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 ?? Path5.join(projectRoot(), "target/debug/argon-oracle");
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 = child_process4.spawn(binPath, execArgs, {
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 Path6 from "path";
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(Path6.join(os.tmpdir(), "argon-ethereum-devnet-"));
712
- const argsFile = Path6.join(this.#argsDir, "network-params.yaml");
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 Path7 from "path";
1091
+ import * as Path6 from "path";
1113
1092
  async function startNetwork(testName, options) {
1114
- const config = Path7.join(__dirname, `dev.docker-compose.yml`);
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
- if (!await queueEntryIsReady(
1413
- client,
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 = payloadHashFromActivationPayload(hashContext, target);
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 { payload, signatures } = validateDeactivationEntry(
1505
- hashContext,
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
- entry,
1508
- approvingCouncilHash
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
- const signedWeight = [...entry.signatures.entries()].reduce((total, [signer]) => {
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
- return total + member.weight;
1547
- }, 0n);
1548
- return signedWeight * 2n > council.totalWeight;
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 approvingCouncil = await loadCouncilByHash(client, approvingCouncilHash, councilCache);
1556
- return queueEntryHasQuorum(entry, approvingCouncil);
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 payloadHashFromActivationPayload(hashContext, target) {
1565
- return hashMintingGatewayActivateMintingAuthority(hashContext, target);
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,