Skip to content

Commit

Permalink
support for new transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
ftheirs committed Feb 7, 2024
1 parent b3dfabd commit c021078
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 31 deletions.
1 change: 1 addition & 0 deletions app/src/allowed_transactions.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ static const txn_types_t allowed_txn[] = {
{"tx_change_consensus_key.wasm", ChangeConsensusKey},
{"tx_update_steward_commission.wasm", UpdateStewardCommission},
{"tx_change_validator_metadata.wasm", ChangeValidatorMetadata},
{"tx_bridge_pool.wasm", BridgePoolTransfer},
};

static const uint32_t allowed_txn_len = sizeof(allowed_txn) / sizeof(allowed_txn[0]);
Expand Down
1 change: 1 addition & 0 deletions app/src/coin.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extern "C" {
#define COMPRESSED_SECP256K1_PK_LEN 33u
#define SECP256K1_SK_LEN 32u
#define SCALAR_LEN_SECP256K1 32u
#define ETH_ADDRESS_LEN 20u

#define SK_LEN_25519 32u
#define SCALAR_LEN_ED25519 32u
Expand Down
4 changes: 4 additions & 0 deletions app/src/parser_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ parser_error_t getNumItems(const parser_context_t *ctx, uint8_t *numItems) {
break;
}

case BridgePoolTransfer:
*numItems = app_mode_expert() ? BRIDGE_POOL_TRANSFER_EXPERT_PARAMS : BRIDGE_POOL_TRANSFER_NORMAL_PARAMS;
break;

default:
break;
}
Expand Down
15 changes: 15 additions & 0 deletions app/src/parser_impl_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ parser_error_t readFieldSize(parser_context_t *ctx, uint32_t *size) {
return parser_ok;
}

parser_error_t readFieldSizeU16(parser_context_t *ctx, uint16_t *size) {
uint8_t consumed = 0;
uint64_t tmpSize = 0;

decodeLEB128(ctx->buffer + ctx->offset, 10, &consumed, &tmpSize);
ctx->offset += consumed;

if (tmpSize > UINT16_MAX) {
return parser_value_out_of_range;
}
*size = (uint16_t)tmpSize;

return parser_ok;
}

parser_error_t checkTag(parser_context_t *ctx, uint8_t expectedTag) {
uint8_t tmpTag = 0;
CHECK_ERROR(readByte(ctx, &tmpTag))
Expand Down
4 changes: 4 additions & 0 deletions app/src/parser_impl_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,17 @@ extern "C" {
#define CHANGE_VALIDATOR_METADATA_NORMAL_PARAMS 2
#define CHANGE_VALIDATOR_METADATA_EXPERT_PARAMS 7

#define BRIDGE_POOL_TRANSFER_NORMAL_PARAMS 9
#define BRIDGE_POOL_TRANSFER_EXPERT_PARAMS 14

parser_error_t readByte(parser_context_t *ctx, uint8_t *byte);
parser_error_t readBytes(parser_context_t *ctx, const uint8_t **output, uint16_t outputLen);
parser_error_t readUint16(parser_context_t *ctx, uint16_t *value);
parser_error_t readUint32(parser_context_t *ctx, uint32_t *value);
parser_error_t readUint64(parser_context_t *ctx, uint64_t *value);

parser_error_t readFieldSize(parser_context_t *ctx, uint32_t *size);
parser_error_t readFieldSizeU16(parser_context_t *ctx, uint16_t *size);
parser_error_t checkTag(parser_context_t *ctx, uint8_t expectedTag);
parser_error_t readPubkey(parser_context_t *ctx, bytes_t *pubkey);

Expand Down
111 changes: 89 additions & 22 deletions app/src/parser_impl_txn.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,41 @@ static parser_error_t readChangeValidatorMetadata(bytes_t *buffer, tx_metadata_c
return parser_ok;
}

static parser_error_t readBridgePoolTransfer(const bytes_t *data, tx_bridge_pool_transfer_t *bridgePoolTransfer) {
parser_context_t ctx = {.buffer = data->ptr, .bufferLen = data->len, .offset = 0, .tx_obj = NULL};

CHECK_ERROR(readByte(&ctx, &bridgePoolTransfer->kind))
if (bridgePoolTransfer->kind > Nut) {
return parser_value_out_of_range;
}

bridgePoolTransfer->asset.len = ETH_ADDRESS_LEN;
CHECK_ERROR(readBytes(&ctx, &bridgePoolTransfer->asset.ptr, bridgePoolTransfer->asset.len))

bridgePoolTransfer->recipient.len = ETH_ADDRESS_LEN;
CHECK_ERROR(readBytes(&ctx, &bridgePoolTransfer->recipient.ptr, bridgePoolTransfer->recipient.len))

bridgePoolTransfer->sender.len = ADDRESS_LEN_BYTES;
CHECK_ERROR(readBytes(&ctx, &bridgePoolTransfer->sender.ptr, bridgePoolTransfer->sender.len))

bridgePoolTransfer->amount.len = 32;
CHECK_ERROR(readBytes(&ctx, &bridgePoolTransfer->amount.ptr, bridgePoolTransfer->amount.len))

bridgePoolTransfer->gasAmount.len = 32;
CHECK_ERROR(readBytes(&ctx, &bridgePoolTransfer->gasAmount.ptr, bridgePoolTransfer->gasAmount.len))

bridgePoolTransfer->gasPayer.len = ADDRESS_LEN_BYTES;
CHECK_ERROR(readBytes(&ctx, &bridgePoolTransfer->gasPayer.ptr, bridgePoolTransfer->gasPayer.len))

bridgePoolTransfer->gasToken.len = ADDRESS_LEN_BYTES;
CHECK_ERROR(readBytes(&ctx, &bridgePoolTransfer->gasToken.ptr, bridgePoolTransfer->gasToken.len))

if (ctx.offset != ctx.bufferLen) {
return parser_unexpected_characters;
}
return parser_ok;
}

__Z_INLINE parser_error_t readTimestamp(parser_context_t *ctx, timestamp_t *timestamp) {
uint8_t consumed = 0;
uint64_t tmp = 0;
Expand All @@ -749,60 +784,88 @@ static parser_error_t readIBCTxn(const bytes_t *data, parser_tx_t *v) {
// Read tag
CHECK_ERROR(checkTag(&ctx, 0x0A))
// Skip URL: /ibc.applications.transfer.v1.MsgTransfer
uint8_t tmp = 0;
CHECK_ERROR(readByte(&ctx, &tmp))
ctx.offset += tmp;
uint16_t tmpFieldLen = 0;
CHECK_ERROR(readFieldSizeU16(&ctx, &tmpFieldLen))
bytes_t tmpUrl = {.ptr = NULL, .len = (uint16_t)tmpFieldLen};
CHECK_ERROR(readBytes(&ctx, &tmpUrl.ptr, tmpUrl.len))

// Check value field (expect vector and check size)
CHECK_ERROR(checkTag(&ctx, 0x12))
// Missing bytes
CHECK_ERROR(readByte(&ctx, &tmp))
CHECK_ERROR(readByte(&ctx, &tmp))
CHECK_ERROR(readFieldSizeU16(&ctx, &tmpFieldLen))

if (tmpFieldLen != ctx.bufferLen - ctx.offset) {
return parser_unexpected_buffer_end;
}

// Read port id
CHECK_ERROR(checkTag(&ctx, 0x0A))
CHECK_ERROR(readByte(&ctx, &tmp))
v->ibc.port_id.len = tmp;
CHECK_ERROR(readFieldSizeU16(&ctx, &v->ibc.port_id.len))
CHECK_ERROR(readBytes(&ctx, &v->ibc.port_id.ptr, v->ibc.port_id.len))

// Read channel id
CHECK_ERROR(checkTag(&ctx, 0x12))
CHECK_ERROR(readByte(&ctx, &tmp))
v->ibc.channel_id.len = tmp;
CHECK_ERROR(readFieldSizeU16(&ctx, &v->ibc.channel_id.len))
CHECK_ERROR(readBytes(&ctx, &v->ibc.channel_id.ptr, v->ibc.channel_id.len))

////// Packed data
// Read token address
CHECK_ERROR(checkTag(&ctx, 0x1A))
CHECK_ERROR(readByte(&ctx, &tmp))
CHECK_ERROR(readFieldSizeU16(&ctx, &tmpFieldLen))

CHECK_ERROR(checkTag(&ctx, 0x0A))
CHECK_ERROR(readByte(&ctx, &tmp))
v->ibc.token_address.len = tmp;
CHECK_ERROR(readFieldSizeU16(&ctx, &v->ibc.token_address.len))
CHECK_ERROR(readBytes(&ctx, &v->ibc.token_address.ptr, v->ibc.token_address.len))

// Read token amount
CHECK_ERROR(checkTag(&ctx, 0x12))
CHECK_ERROR(readByte(&ctx, &tmp))
v->ibc.token_amount.len = tmp;
CHECK_ERROR(readFieldSizeU16(&ctx, &v->ibc.token_amount.len))
CHECK_ERROR(readBytes(&ctx, &v->ibc.token_amount.ptr, v->ibc.token_amount.len))

// Read sender
CHECK_ERROR(checkTag(&ctx, 0x22))
CHECK_ERROR(readByte(&ctx, &tmp))
v->ibc.sender_address.len = tmp;
CHECK_ERROR(readBytes(&ctx, &v->ibc.sender_address.ptr, v->ibc.sender_address.len))
if (*(ctx.buffer + ctx.offset) == 0x22) {
CHECK_ERROR(checkTag(&ctx, 0x22))
CHECK_ERROR(readFieldSizeU16(&ctx, &v->ibc.sender_address.len))
CHECK_ERROR(readBytes(&ctx, &v->ibc.sender_address.ptr, v->ibc.sender_address.len))
}

// Read receiver
CHECK_ERROR(checkTag(&ctx, 0x2A))
CHECK_ERROR(readByte(&ctx, &tmp))
v->ibc.receiver.len = tmp;
CHECK_ERROR(readFieldSizeU16(&ctx, &v->ibc.receiver.len))
CHECK_ERROR(readBytes(&ctx, &v->ibc.receiver.ptr, v->ibc.receiver.len))
////////////////

// Read timeout height
CHECK_ERROR(checkTag(&ctx, 0x32))
CHECK_ERROR(readByte(&ctx, &v->ibc.timeout_height))
CHECK_ERROR(readByte(&ctx, &v->ibc.timeout_height_type))

if (v->ibc.timeout_height_type > 0) {
uint8_t consumed = 0;
uint64_t tmp = 0;

// Read 0x08
CHECK_ERROR(checkTag(&ctx, 0x08))
const uint64_t remainingBytes = ctx.bufferLen - ctx.offset;
decodeLEB128(ctx.buffer + ctx.offset, remainingBytes, &consumed, &tmp);
v->ibc.revision_number = tmp;
ctx.offset += consumed;

CHECK_ERROR(checkTag(&ctx, 0x10))
const uint64_t remainingBytes2 = ctx.bufferLen - ctx.offset;
decodeLEB128(ctx.buffer + ctx.offset, remainingBytes2, &consumed, &tmp);
v->ibc.revision_height = tmp;
ctx.offset += consumed;
}
// Read timeout timestamp
CHECK_ERROR(readTimestamp(&ctx, &v->ibc.timeout_timestamp))

CHECK_ERROR(checkTag(&ctx, 0x42))
bytes_t tmpBytes = {0};
CHECK_ERROR(readFieldSizeU16(&ctx, &tmpBytes.len))
CHECK_ERROR(readBytes(&ctx, &tmpBytes.ptr, tmpBytes.len))

if (ctx.offset != ctx.bufferLen) {
return parser_unexpected_characters;
}
return parser_ok;
}

Expand Down Expand Up @@ -1245,6 +1308,10 @@ parser_error_t validateTransactionParams(parser_tx_t *txObj) {
CHECK_ERROR(readChangeValidatorMetadata(&data->bytes, &txObj->metadataChange))
break;

case BridgePoolTransfer:
CHECK_ERROR(readBridgePoolTransfer(&data->bytes, &txObj->bridgePoolTransfer))
break;

default:
return parser_unexpected_method;
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/parser_print_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ parser_error_t printAmount( const bytes_t *amount, bool isSigned, uint8_t amount
if (insertDecimalPoint(strAmount + isNegative, sizeof(strAmount) - isNegative, amountDenom) != zxerr_ok) {
return parser_unexpected_error;
}

// const char *suffix = (amountDenom == 0) ? ".0" : "";
z_str3join(strAmount, sizeof(strAmount), symbol, "");
number_inplace_trimming(strAmount, 1);
pageString(outVal, outValLen, strAmount, pageIdx, pageCount);
Expand Down
Loading

0 comments on commit c021078

Please sign in to comment.