Skip to content

Commit

Permalink
feat(ibc): reimplement relativeTimeoutNs, per ibc-go
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfig committed Feb 4, 2022
1 parent 08f9a44 commit 4673493
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 26 deletions.
32 changes: 16 additions & 16 deletions golang/cosmos/x/vibc/ibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ type portHandler struct {
}

type portMessage struct { // comes from swingset's IBC handler
Type string `json:"type"` // IBC_METHOD
Method string `json:"method"`
Packet channeltypes.Packet `json:"packet"`
RelativeTimeout uint64 `json:"relativeTimeout"`
Order string `json:"order"`
Hops []string `json:"hops"`
Version string `json:"version"`
Ack []byte `json:"ack"`
Type string `json:"type"` // IBC_METHOD
Method string `json:"method"`
Packet channeltypes.Packet `json:"packet"`
RelativeTimeoutNs uint64 `json:"relativeTimeoutNs,string"`
Order string `json:"order"`
Hops []string `json:"hops"`
Version string `json:"version"`
Ack []byte `json:"ack"`
}

func stringToOrder(order string) channeltypes.Order {
Expand All @@ -54,12 +54,6 @@ func orderToString(order channeltypes.Order) string {
}
}

// DefaultRouter is a temporary hack until cosmos-sdk implements its features FIXME.
type DefaultRouter struct {
*porttypes.Router
defaultRoute porttypes.IBCModule
}

func NewPortHandler(ibcModule porttypes.IBCModule, keeper Keeper) portHandler {
return portHandler{
ibcModule: ibcModule,
Expand All @@ -78,7 +72,7 @@ func (ch portHandler) Receive(ctx *vm.ControllerContext, str string) (ret string
}

if msg.Type != "IBC_METHOD" {
return "", fmt.Errorf(`Channel handler only accepts messages of "type": "IBC_METHOD"`)
return "", fmt.Errorf(`channel handler only accepts messages of "type": "IBC_METHOD"`)
}

switch msg.Method {
Expand All @@ -92,11 +86,17 @@ func (ch portHandler) Receive(ctx *vm.ControllerContext, str string) (ret string
return "", fmt.Errorf("unknown sequence number")
}

timeoutTimestamp := msg.Packet.TimeoutTimestamp
if msg.Packet.TimeoutHeight.IsZero() && msg.Packet.TimeoutTimestamp == 0 {
// Use the relative timeout if no absolute timeout is specifiied.
timeoutTimestamp = uint64(ctx.Context.BlockTime().UnixNano()) + msg.RelativeTimeoutNs
}

packet := channeltypes.NewPacket(
msg.Packet.Data, seq,
msg.Packet.SourcePort, msg.Packet.SourceChannel,
msg.Packet.DestinationPort, msg.Packet.DestinationChannel,
msg.Packet.TimeoutHeight, msg.Packet.TimeoutTimestamp,
msg.Packet.TimeoutHeight, timeoutTimestamp,
)
err = keeper.SendPacket(ctx.Context, packet)
if err == nil {
Expand Down
7 changes: 6 additions & 1 deletion packages/SwingSet/src/devices/bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,12 @@ function sanitize(data) {
if (data instanceof Error) {
data = data.stack;
}
return JSON.parse(JSON.stringify(data));
// Golang likes to have its bigints as strings.
return JSON.parse(
JSON.stringify(data, (key, value) =>
typeof value === 'bigint' ? value.toString() : value,
),
);
}

export function buildBridge(outboundCallback) {
Expand Down
4 changes: 2 additions & 2 deletions packages/SwingSet/src/vats/network/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const makeConnection = (
.onClose(connection, undefined, handler)
.catch(rethrowUnlessMissing);
},
async send(data) {
async send(data, opts) {
// console.log('send', data, local === srcHandler);
if (closed) {
throw closed;
Expand All @@ -81,7 +81,7 @@ export const makeConnection = (
const ackDeferred = makePromiseKit();
pendingAcks.add(ackDeferred);
E(handler)
.onReceive(connection, bytes, handler)
.onReceive(connection, bytes, handler, opts)
.catch(err => {
rethrowUnlessMissing(err);
return '';
Expand Down
4 changes: 2 additions & 2 deletions packages/SwingSet/src/vats/network/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

/**
* @typedef {Object} Connection
* @property {(packetBytes: Data) => Promise<Bytes>} send Send a packet on the connection
* @property {(packetBytes: Data, opts?: Record<string, any>) => Promise<Bytes>} send Send a packet on the connection
* @property {() => Promise<void>} close Close both ends of the connection
* @property {() => Endpoint} getLocalAddress Get the locally bound name of this connection
* @property {() => Endpoint} getRemoteAddress Get the name of the counterparty
Expand All @@ -49,7 +49,7 @@
/**
* @typedef {Object} ConnectionHandler A handler for a given Connection
* @property {(connection: Connection, localAddr: Endpoint, remoteAddr: Endpoint, c: ConnectionHandler) => void} [onOpen] The connection has been opened
* @property {(connection: Connection, packetBytes: Bytes, c: ConnectionHandler) => Promise<Data>} [onReceive] The connection received a packet
* @property {(connection: Connection, packetBytes: Bytes, c: ConnectionHandler, opts?: Record<string, any>) => Promise<Data>} [onReceive] The connection received a packet
* @property {(connection: Connection, reason?: CloseReason, c?: ConnectionHandler) => Promise<void>} [onClose] The connection has been closed
*
* @typedef {any?} CloseReason The reason a connection was closed
Expand Down
26 changes: 21 additions & 5 deletions packages/vats/src/ibc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import { makeWithQueue } from './queue.js';
// empty acknowledgements as distinct from unacknowledged packets.
const DEFAULT_ACKNOWLEDGEMENT = '\x00';

// Default timeout after 10 minutes.
const DEFAULT_PACKET_TIMEOUT_NS = 10n * 60n * 1_000_000_000n;

/**
* @typedef {import('./bridge').BridgeHandler} BridgeHandler
*/
Expand Down Expand Up @@ -105,11 +108,17 @@ export function makeIBCProtocolHandler(E, rawCallIBCDevice) {
*
* @param {IBCPacket} packet
* @param {LegacyMap<number, PromiseRecord<Bytes>>} seqToAck
* @param {bigint} [relativeTimeoutNs]
*/
async function ibcSendPacket(packet, seqToAck) {
async function ibcSendPacket(
packet,
seqToAck,
relativeTimeoutNs = DEFAULT_PACKET_TIMEOUT_NS,
) {
// Make a kernel call to do the send.
const fullPacket = await callIBCDevice('sendPacket', {
packet,
relativeTimeoutNs,
});

// Extract the actual sequence number from the return.
Expand Down Expand Up @@ -149,9 +158,16 @@ export function makeIBCProtocolHandler(E, rawCallIBCDevice) {
* @param {Connection} _conn
* @param {Bytes} packetBytes
* @param {ConnectionHandler} _handler
* @param {Object} root0
* @param {bigint} [root0.relativeTimeoutNs]
* @returns {Promise<Bytes>} Acknowledgement data
*/
let onReceive = async (_conn, packetBytes, _handler) => {
let onReceive = async (
_conn,
packetBytes,
_handler,
{ relativeTimeoutNs } = {},
) => {
// console.error(`Remote IBC Handler ${portID} ${channelID}`);
const packet = {
source_port: portID,
Expand All @@ -160,7 +176,7 @@ export function makeIBCProtocolHandler(E, rawCallIBCDevice) {
destination_channel: rChannelID,
data: dataToBase64(packetBytes),
};
return ibcSendPacket(packet, seqToAck);
return ibcSendPacket(packet, seqToAck, relativeTimeoutNs);
};

if (order === 'ORDERED') {
Expand Down Expand Up @@ -552,11 +568,11 @@ export function makeIBCProtocolHandler(E, rawCallIBCDevice) {
}

case 'sendPacket': {
const { packet } = obj;
const { packet, relativeTimeoutNs } = obj;
const { source_port: portID, source_channel: channelID } = packet;
const channelKey = `${channelID}:${portID}`;
const seqToAck = channelKeyToSeqAck.get(channelKey);
ibcSendPacket(packet, seqToAck).then(
ibcSendPacket(packet, seqToAck, relativeTimeoutNs).then(
ack => console.info('Manual packet', packet, 'acked:', ack),
e => console.warn('Manual packet', packet, 'failed:', e),
);
Expand Down
1 change: 1 addition & 0 deletions packages/vats/test/test-network.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ test('network - ibc', async t => {
source_channel: 'channel-1',
source_port: 'port-1',
},
relativeTimeoutNs: 600_000_000_000n, // 10 minutes in nanoseconds.
},
]);

Expand Down

0 comments on commit 4673493

Please sign in to comment.