Skip to content

Commit

Permalink
Merge pull request #4615 from Agoric/mfig-4614-ics20-trace-and-result
Browse files Browse the repository at this point in the history
feat(pegasus): implement correct result and denom trace handling
  • Loading branch information
mergify[bot] authored Feb 20, 2022
2 parents ae98f61 + f1801f6 commit a5de8dd
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 66 deletions.
6 changes: 3 additions & 3 deletions packages/pegasus/src/courier.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const getCourierPK = (key, keyToCourierPK) => {
* @property {ContractFacet} zcf
* @property {ERef<BoardDepositFacet>} board
* @property {ERef<NameHub>} namesByAddress
* @property {Denom} remoteDenom
* @property {Denom} sendDenom
* @property {Brand} localBrand
* @property {(zcfSeat: ZCFSeat, amounts: AmountKeywordRecord) => void} retain
* @property {(zcfSeat: ZCFSeat, amounts: AmountKeywordRecord) => void} redeem
Expand All @@ -47,7 +47,7 @@ export const makeCourierMaker =
zcf,
board,
namesByAddress,
remoteDenom,
sendDenom,
localBrand,
retain,
redeem,
Expand All @@ -59,7 +59,7 @@ export const makeCourierMaker =
const amount = zcfSeat.getAmountAllocated('Transfer', localBrand);
const transferPacket = await E(transferProtocol).makeTransferPacket({
value: amount.value,
remoteDenom,
remoteDenom: sendDenom,
depositAddress,
});

Expand Down
44 changes: 44 additions & 0 deletions packages/pegasus/src/ibc-trace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// @ts-check
import { Far } from '@endo/marshal';
import { assert, details as X } from '@agoric/assert';

import { parse } from '@agoric/swingset-vat/src/vats/network/multiaddr.js';

/**
* Return a source-prefixed version of the denomination, as specified in
* ICS20-1.
*
* @param {Address} addr
* @param {Denom} denom
*/
const sourcePrefixedDenom = (addr, denom) => {
const ma = parse(addr);

const ibcPort = ma.find(([protocol]) => protocol === 'ibc-port');
assert(ibcPort, X`${addr} does not contain an IBC port`);
const ibcChannel = ma.find(([protocol]) => protocol === 'ibc-channel');
assert(ibcChannel, X`${addr} does not contain an IBC channel`);

return `${ibcPort[1]}/${ibcChannel[1]}/${denom}`;
};

/** @type {DenomTransformer} */
const transformer = {
getDenomsForLocalPeg: async (denom, _localAddress, remoteAddress) => {
return {
sendDenom: denom,
receiveDenom: sourcePrefixedDenom(remoteAddress, denom),
};
},
getDenomsForRemotePeg: async (denom, localAddress, _remoteAddress) => {
return {
sendDenom: sourcePrefixedDenom(localAddress, denom),
receiveDenom: denom,
};
},
};

export const IBCSourceTraceDenomTransformer = Far(
'IBC source trace denom transformer',
transformer,
);
17 changes: 13 additions & 4 deletions packages/pegasus/src/ics20.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import { assert, details as X } from '@agoric/assert';
* @property {DepositAddress} receiver The receiver deposit address
*/

// As specified in ICS20, the success result is a base64-encoded '\0x1' byte.
const ICS20_TRANSFER_SUCCESS_RESULT = 'AQ==';

// ibc-go as late as v3 requires the `sender` to be nonempty, but doesn't
// actually use it on the receiving side. We don't need it on the sending side,
// either, so we can just omit it.
Expand Down Expand Up @@ -96,8 +99,14 @@ export const makeICS20TransferPacket = async ({
* @returns {Promise<void>}
*/
export const assertICS20TransferPacketAck = async ack => {
const { success, error } = safeJSONParseObject(ack);
assert(success, X`ICS20 transfer error ${error}`);
const { result, error } = safeJSONParseObject(ack);
assert(error === undefined, X`ICS20 transfer error ${error}`);
assert(result !== undefined, X`ICS20 transfer missing result in ${ack}`);
if (result !== ICS20_TRANSFER_SUCCESS_RESULT) {
// We don't want to throw an error here, because we want only to be able to
// differentiate between a transfer that failed and a transfer that succeeded.
console.warn(`ICS20 transfer succeeded with unexpected result: ${result}`);
}
};

/**
Expand All @@ -110,10 +119,10 @@ export const assertICS20TransferPacketAck = async ack => {
*/
export const makeICS20TransferPacketAck = async (success, error) => {
if (success) {
const ack = { success: true };
const ack = { result: ICS20_TRANSFER_SUCCESS_RESULT };
return JSON.stringify(ack);
}
const nack = { success: false, error: `${error}` };
const nack = { error: `${error}` };
return JSON.stringify(nack);
};

Expand Down
Loading

0 comments on commit a5de8dd

Please sign in to comment.