diff --git a/packages/fast-usdc/test/fast-usdc.contract.test.ts b/packages/fast-usdc/test/fast-usdc.contract.test.ts index 05196c6890f..6e339ee0cfa 100644 --- a/packages/fast-usdc/test/fast-usdc.contract.test.ts +++ b/packages/fast-usdc/test/fast-usdc.contract.test.ts @@ -6,7 +6,6 @@ import { encodeAddressHook, } from '@agoric/cosmic-proto/address-hooks.js'; import { AmountMath } from '@agoric/ertp/src/amountMath.js'; -import type { makeFakeStorageKit } from '@agoric/internal/src/storage-test-utils.js'; import { eventLoopIteration, inspectMapStore, @@ -141,6 +140,8 @@ const makeTestContext = async (t: ExecutionContext) => { const { settlementAccount, poolAccount } = JSON.parse( JSON.parse(accountsData!).values[0], ); + t.is(settlementAccount, 'agoric1qyqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc09z0g'); + t.is(poolAccount, 'agoric1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqp7zqht'); const mint = async (e: CctpTxEvidence) => { const rxd = await receiveUSDCAt(settlementAccount, e.tx.amount); await VE(transferBridge).fromBridge( @@ -362,13 +363,17 @@ const makeLP = async ( const makeEVM = (template = MockCctpTxEvidences.AGORIC_PLUS_OSMO()) => { let nonce = 0; - const makeTx = (amount: bigint, recipientAddress: string): CctpTxEvidence => { + const makeTx = ( + amount: bigint, + recipientAddress: string, + nonceOverride?: number, + ): CctpTxEvidence => { nonce += 1; const tx: CctpTxEvidence = harden({ ...template, - txHash: `0x00000${nonce}`, - blockNumber: template.blockNumber + BigInt(nonce), + txHash: `0x00000${nonceOverride || nonce}`, + blockNumber: template.blockNumber + BigInt(nonceOverride || nonce), tx: { ...template.tx, amount }, // KLUDGE: CCTP doesn't know about aux; it would be added by OCW aux: { ...template.aux, recipientAddress }, @@ -407,6 +412,7 @@ const makeCustomer = ( t: ExecutionContext, amount: bigint, EUD: string, + nonceOverride?: number, ) => { const { storage } = t.context.common.bootstrap; const accountsData = storage.data.get('fun'); @@ -416,7 +422,7 @@ const makeCustomer = ( const recipientAddress = encodeAddressHook(settlementAccount, { EUD }); // KLUDGE: UI would ask noble for a forwardingAddress // "cctp" here has some noble stuff mixed in. - const tx = cctp.makeTx(amount, recipientAddress); + const tx = cctp.makeTx(amount, recipientAddress, nonceOverride); t.log(who, 'signs CCTP for', amount, 'uusdc w/EUD:', EUD); txPublisher.publish(tx); sent.push(tx); @@ -782,8 +788,7 @@ test.serial('C20 - Contract MUST function with an empty pool', async t => { test.todo('C18 - forward - MUST log and alert these incidents'); -// FIXME; passes but causes the next test to fail -test.skip('Settlement for unknown transaction (operator down)', async t => { +test.serial('Settlement for unknown transaction (operator down)', async t => { const { sync, bridges: { snapshot, since }, @@ -791,6 +796,7 @@ test.skip('Settlement for unknown transaction (operator down)', async t => { common: { bootstrap: { storage }, commonPrivateArgs: { feeConfig }, + mocks: { transferBridge }, utils: { transmitTransferAck }, }, mint, @@ -805,7 +811,7 @@ test.skip('Settlement for unknown transaction (operator down)', async t => { const opDown = makeCustomer('Otto', cctp, txPub.publisher, feeConfig); const bridgePos = snapshot(); - const EUD = 'osmo12345'; + const EUD = 'osmo10tt0'; const mintAmt = 5_000_000n; const sent = await opDown.sendFast(t, mintAmt, EUD); await mint(sent); @@ -835,9 +841,13 @@ test.skip('Settlement for unknown transaction (operator down)', async t => { // 'C12 - Contract MUST only pay back the Pool (fees) only if they started the advance before USDC is minted', operators[0].setActive(true); operators[1].setActive(true); - await opDown.sendFast(t, mintAmt, EUD); + // set the 3rd operator to inactive so it doesn't report a 2nd time + operators[2].setActive(false); + + // compute nonce from initial report so a new txId is not generated by `sendFast` helper + const nonce = Number(sent.txHash.slice(2)); + await opDown.sendFast(t, mintAmt, EUD, nonce); - await transmitTransferAck(); const [outgoingForward] = since(bridgePos).local; t.like(outgoingForward, { type: 'VLOCALCHAIN_EXECUTE_TX', @@ -848,7 +858,6 @@ test.skip('Settlement for unknown transaction (operator down)', async t => { }, ], }); - const [outgoingForwardMessage] = outgoingForward.messages; t.is( outgoingForwardMessage.token.amount, @@ -857,14 +866,26 @@ test.skip('Settlement for unknown transaction (operator down)', async t => { ); const forwardInfo = JSON.parse(outgoingForwardMessage.memo).forward; - t.is(forwardInfo.receiver, EUD, 'receiver is osmo12345'); - - // t.deepEqual(storage.getDeserialized(`fun.txns.${sent.txHash}`), [ - // // { evidence: sent, status: 'OBSERVED' }, // no OBSERVED state recorded - // { status: 'FORWARDED' }, - // ]); + t.is(forwardInfo.receiver, EUD, 'receiver is osmo10tt0'); + + // in lieu of transmitTransferAck so we can set a nonce that matches our initial Advance + await E(transferBridge).fromBridge( + buildVTransferEvent({ + receiver: outgoingForwardMessage.receiver, + sender: outgoingForwardMessage.sender, + target: outgoingForwardMessage.sender, + sourceChannel: outgoingForwardMessage.sourceChannel, + sequence: BigInt(nonce), + denom: outgoingForwardMessage.token.denom, + amount: BigInt(outgoingForwardMessage.token.amount), + }), + ); + await eventLoopIteration(); - // await transmitTransferAck(); // ??? + t.deepEqual(storage.getDeserialized(`fun.txns.${sent.txHash}`), [ + // { evidence: sent, status: 'OBSERVED' }, // no OBSERVED state recorded + { status: 'FORWARDED' }, + ]); }); test.serial('mint received why ADVANCING', async t => {