Skip to content

Commit

Permalink
Now support the Become Validator transaction that replaces the InitVa…
Browse files Browse the repository at this point in the history
…lidator command.
  • Loading branch information
murisi committed Dec 8, 2023
1 parent 3e7c30b commit f76aaaf
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 603 deletions.
6 changes: 0 additions & 6 deletions app/src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,6 @@ static zxerr_t crypto_addTxnHashes(const parser_tx_t *txObj, concatenated_hashes
hashes->hashesLen++;
break;

case InitValidator:
MEMCPY(hashes->hashes.ptr + hashes->hashesLen * HASH_LEN, txObj->initValidator.vp_type_sechash.ptr, HASH_LEN);
hashes->indices.ptr[hashes->hashesLen] = txObj->initValidator.vp_type_secidx;
hashes->hashesLen++;
break;

case UpdateVP:
MEMCPY(hashes->hashes.ptr + hashes->hashesLen * HASH_LEN, txObj->updateVp.vp_type_sechash.ptr, HASH_LEN);
hashes->indices.ptr[hashes->hashesLen] = txObj->updateVp.vp_type_secidx;
Expand Down
11 changes: 5 additions & 6 deletions app/src/parser_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,15 @@ parser_error_t getNumItems(const parser_context_t *ctx, uint8_t *numItems) {
*numItems = (app_mode_expert() ? COMMISSION_CHANGE_EXPERT_PARAMS : COMMISSION_CHANGE_NORMAL_PARAMS);
break;

case InitValidator: {
const uint32_t accounts = ctx->tx_obj->initValidator.number_of_account_keys;
*numItems = (uint8_t) ((app_mode_expert() ? INIT_VALIDATOR_EXPERT_PARAMS : INIT_VALIDATOR_NORMAL_PARAMS) + accounts);
if(ctx->tx_obj->initValidator.description.ptr) {
case BecomeValidator: {
*numItems = (app_mode_expert() ? BECOME_VALIDATOR_EXPERT_PARAMS : BECOME_VALIDATOR_NORMAL_PARAMS);
if(ctx->tx_obj->becomeValidator.description.ptr) {
(*numItems)++;
}
if(ctx->tx_obj->initValidator.discord_handle.ptr) {
if(ctx->tx_obj->becomeValidator.discord_handle.ptr) {
(*numItems)++;
}
if(ctx->tx_obj->initValidator.website.ptr) {
if(ctx->tx_obj->becomeValidator.website.ptr) {
(*numItems)++;
}
break;
Expand Down
4 changes: 2 additions & 2 deletions app/src/parser_impl_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ extern "C" {
#define VOTE_PROPOSAL_NORMAL_PARAMS 4
#define VOTE_PROPOSAL_EXPERT_PARAMS 9

#define INIT_VALIDATOR_NORMAL_PARAMS 10
#define INIT_VALIDATOR_EXPERT_PARAMS 15
#define BECOME_VALIDATOR_NORMAL_PARAMS 9
#define BECOME_VALIDATOR_EXPERT_PARAMS 14

#define REVEAL_PUBKEY_NORMAL_PARAMS 2
#define REVEAL_PUBKEY_EXPERT_PARAMS 7
Expand Down
105 changes: 31 additions & 74 deletions app/src/parser_impl_txn.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static const txn_types_t allowed_txn[] = {
{"tx_init_account.wasm", InitAccount},
{"tx_init_proposal.wasm", InitProposal},
{"tx_vote_proposal.wasm", VoteProposal},
{"tx_init_validator.wasm", InitValidator},
{"tx_become_validator.wasm", BecomeValidator},
{"tx_reveal_pk.wasm", RevealPubkey},
{"tx_transfer.wasm", Transfer},
{"tx_update_account.wasm", UpdateVP},
Expand Down Expand Up @@ -173,111 +173,68 @@ static parser_error_t readTransactionType(bytes_t *codeTag, transaction_type_e *
return parser_ok;
}

static parser_error_t readInitValidatorTxn(bytes_t *data, const section_t *extra_data, const uint32_t extraDataLen, parser_tx_t *v) {
static parser_error_t readBecomeValidatorTxn(bytes_t *data, const section_t *extra_data, const uint32_t extraDataLen, parser_tx_t *v) {
if (data == NULL || extra_data == NULL || v == NULL || extraDataLen >= MAX_EXTRA_DATA_SECS) {
return parser_unexpected_value;
}
parser_context_t ctx = {.buffer = data->ptr, .bufferLen = data->len, .offset = 0, .tx_obj = NULL};

v->initValidator.number_of_account_keys = 0;
CHECK_ERROR(readUint32(&ctx, &v->initValidator.number_of_account_keys))
if (v->initValidator.number_of_account_keys == 0) {
return parser_unexpected_number_items;
}
v->initValidator.account_keys.len = PK_LEN_25519_PLUS_TAG * v->initValidator.number_of_account_keys;
CHECK_ERROR(readBytes(&ctx, &v->initValidator.account_keys.ptr, v->initValidator.account_keys.len))

CHECK_ERROR(readByte(&ctx, &v->initValidator.threshold))
v->becomeValidator.address.len = ADDRESS_LEN_BYTES;
CHECK_ERROR(readBytes(&ctx, &v->becomeValidator.address.ptr, v->becomeValidator.address.len))

v->initValidator.consensus_key.len = PK_LEN_25519_PLUS_TAG;
CHECK_ERROR(readBytes(&ctx, &v->initValidator.consensus_key.ptr, v->initValidator.consensus_key.len))
v->becomeValidator.consensus_key.len = PK_LEN_25519_PLUS_TAG;
CHECK_ERROR(readBytes(&ctx, &v->becomeValidator.consensus_key.ptr, v->becomeValidator.consensus_key.len))

v->initValidator.eth_cold_key.len = PK_LEN_25519_PLUS_TAG;
CHECK_ERROR(readBytes(&ctx, &v->initValidator.eth_cold_key.ptr, v->initValidator.eth_cold_key.len))
v->becomeValidator.eth_cold_key.len = PK_LEN_25519_PLUS_TAG;
CHECK_ERROR(readBytes(&ctx, &v->becomeValidator.eth_cold_key.ptr, v->becomeValidator.eth_cold_key.len))

v->initValidator.eth_hot_key.len = PK_LEN_25519_PLUS_TAG;
CHECK_ERROR(readBytes(&ctx, &v->initValidator.eth_hot_key.ptr, v->initValidator.eth_hot_key.len))
v->becomeValidator.eth_hot_key.len = PK_LEN_25519_PLUS_TAG;
CHECK_ERROR(readBytes(&ctx, &v->becomeValidator.eth_hot_key.ptr, v->becomeValidator.eth_hot_key.len))

v->initValidator.protocol_key.len = PK_LEN_25519_PLUS_TAG;
CHECK_ERROR(readBytes(&ctx, &v->initValidator.protocol_key.ptr, v->initValidator.protocol_key.len))
v->becomeValidator.protocol_key.len = PK_LEN_25519_PLUS_TAG;
CHECK_ERROR(readBytes(&ctx, &v->becomeValidator.protocol_key.ptr, v->becomeValidator.protocol_key.len))

// Commission rate
CHECK_ERROR(readUint256(&ctx, &v->initValidator.commission_rate));
CHECK_ERROR(readUint256(&ctx, &v->becomeValidator.commission_rate));

// Max commission rate change
CHECK_ERROR(readUint256(&ctx, &v->initValidator.max_commission_rate_change));
CHECK_ERROR(readUint256(&ctx, &v->becomeValidator.max_commission_rate_change));

// The validator email
CHECK_ERROR(readUint32(&ctx, &v->initValidator.email.len))
CHECK_ERROR(readBytes(&ctx, &v->initValidator.email.ptr, v->initValidator.email.len))
CHECK_ERROR(readUint32(&ctx, &v->becomeValidator.email.len))
CHECK_ERROR(readBytes(&ctx, &v->becomeValidator.email.ptr, v->becomeValidator.email.len))

/// The validator description
v->initValidator.description.ptr = NULL;
v->initValidator.description.len = 0;
v->becomeValidator.description.ptr = NULL;
v->becomeValidator.description.len = 0;
uint8_t has_description = 0;
CHECK_ERROR(readByte(&ctx, &has_description))
if (has_description) {
CHECK_ERROR(readUint32(&ctx, &v->initValidator.description.len))
CHECK_ERROR(readBytes(&ctx, &v->initValidator.description.ptr, v->initValidator.description.len))
CHECK_ERROR(readUint32(&ctx, &v->becomeValidator.description.len))
CHECK_ERROR(readBytes(&ctx, &v->becomeValidator.description.ptr, v->becomeValidator.description.len))
}

/// The validator website
v->initValidator.website.ptr = NULL;
v->initValidator.website.len = 0;
v->becomeValidator.website.ptr = NULL;
v->becomeValidator.website.len = 0;
uint8_t has_website;
CHECK_ERROR(readByte(&ctx, &has_website))
if (has_website) {
CHECK_ERROR(readUint32(&ctx, &v->initValidator.website.len))
CHECK_ERROR(readBytes(&ctx, &v->initValidator.website.ptr, v->initValidator.website.len))
CHECK_ERROR(readUint32(&ctx, &v->becomeValidator.website.len))
CHECK_ERROR(readBytes(&ctx, &v->becomeValidator.website.ptr, v->becomeValidator.website.len))
}

/// The validator's discord handle
v->initValidator.discord_handle.ptr = NULL;
v->initValidator.discord_handle.len = 0;
v->becomeValidator.discord_handle.ptr = NULL;
v->becomeValidator.discord_handle.len = 0;
uint8_t has_discord_handle;
CHECK_ERROR(readByte(&ctx, &has_discord_handle))
if (has_discord_handle) {
CHECK_ERROR(readUint32(&ctx, &v->initValidator.discord_handle.len))
CHECK_ERROR(readBytes(&ctx, &v->initValidator.discord_handle.ptr, v->initValidator.discord_handle.len))
}

// VP code hash
v->initValidator.vp_type_sechash.len = HASH_LEN;
CHECK_ERROR(readBytes(&ctx, &v->initValidator.vp_type_sechash.ptr, v->initValidator.vp_type_sechash.len))

bool found_vp_code = false;
// Load the linked to data from the extra data sections
for (uint32_t i = 0; i < extraDataLen; i++) {
parser_context_t extra_data_ctx = {
.buffer = extra_data[i].bytes.ptr,
.bufferLen = extra_data[i].bytes.len,
.offset = 0,
.tx_obj = NULL};

// Read the hash inside the extra data section
bytes_t commitment = { .ptr = NULL, .len = HASH_LEN };
CHECK_ERROR(readBytes(&extra_data_ctx, &commitment.ptr, commitment.len))

uint8_t extraDataHash[HASH_LEN] = {0};
if (crypto_hashExtraDataSection(&extra_data[i], extraDataHash, sizeof(extraDataHash)) != zxerr_ok) {
return parser_unexpected_error;
}

if (!memcmp(extraDataHash, v->initValidator.vp_type_sechash.ptr, HASH_LEN)) {
// If this section contains the VP code hash
v->initValidator.vp_type_secidx = extra_data[i].idx;
v->initValidator.vp_type_hash = commitment;
CHECK_ERROR(readVPType(&extra_data[i].tag, &v->initValidator.vp_type_text))
found_vp_code = true;
}
if (extra_data_ctx.offset != extra_data_ctx.bufferLen) {
return parser_unexpected_characters;
}
CHECK_ERROR(readUint32(&ctx, &v->becomeValidator.discord_handle.len))
CHECK_ERROR(readBytes(&ctx, &v->becomeValidator.discord_handle.ptr, v->becomeValidator.discord_handle.len))
}

if (!found_vp_code) {
return parser_missing_field;
} else if (ctx.offset != ctx.bufferLen) {
if (ctx.offset != ctx.bufferLen) {
return parser_unexpected_characters;
}
return parser_ok;
Expand Down Expand Up @@ -1177,8 +1134,8 @@ parser_error_t validateTransactionParams(parser_tx_t *txObj) {
case CommissionChange:
CHECK_ERROR(readCommissionChangeTxn(&txObj->transaction.sections.data.bytes, txObj))
break;
case InitValidator:
CHECK_ERROR(readInitValidatorTxn(&txObj->transaction.sections.data.bytes, txObj->transaction.sections.extraData, txObj->transaction.sections.extraDataLen, txObj))
case BecomeValidator:
CHECK_ERROR(readBecomeValidatorTxn(&txObj->transaction.sections.data.bytes, txObj->transaction.sections.extraData, txObj->transaction.sections.extraDataLen, txObj))
break;
case UpdateVP:
CHECK_ERROR(readUpdateVPTxn(&txObj->transaction.sections.data.bytes, txObj->transaction.sections.extraData, txObj->transaction.sections.extraDataLen, txObj))
Expand Down
99 changes: 32 additions & 67 deletions app/src/parser_print_txn.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,30 +548,23 @@ static parser_error_t printUpdateVPTxn(const parser_context_t *ctx,
return parser_ok;
}

static parser_error_t printInitValidatorTxn( const parser_context_t *ctx,
static parser_error_t printBecomeValidatorTxn( const parser_context_t *ctx,
uint8_t displayIdx,
char *outKey, uint16_t outKeyLen,
char *outVal, uint16_t outValLen,
uint8_t pageIdx, uint8_t *pageCount) {


const tx_init_validator_t *initValidator = &ctx->tx_obj->initValidator;
const uint32_t account_keys = initValidator->number_of_account_keys;

uint8_t adjustedDisplayIdx = (displayIdx == 0) ? displayIdx : \
(displayIdx < account_keys + 1) ? 1 : displayIdx - account_keys + 1;

if(adjustedDisplayIdx >= 10 && ctx->tx_obj->initValidator.description.ptr == NULL) {
adjustedDisplayIdx++;
if(displayIdx >= 9 && ctx->tx_obj->becomeValidator.description.ptr == NULL) {
displayIdx++;
}
if(adjustedDisplayIdx >= 11 && ctx->tx_obj->initValidator.website.ptr == NULL) {
adjustedDisplayIdx++;
if(displayIdx >= 10 && ctx->tx_obj->becomeValidator.website.ptr == NULL) {
displayIdx++;
}
if(adjustedDisplayIdx >= 12 && ctx->tx_obj->initValidator.discord_handle.ptr == NULL) {
adjustedDisplayIdx++;
if(displayIdx >= 11 && ctx->tx_obj->becomeValidator.discord_handle.ptr == NULL) {
displayIdx++;
}

switch (adjustedDisplayIdx) {
switch (displayIdx) {
case 0:
snprintf(outKey, outKeyLen, "Type");
snprintf(outVal, outValLen, "Init Validator");
Expand All @@ -581,97 +574,69 @@ static parser_error_t printInitValidatorTxn( const parser_context_t *ctx,
}
break;
case 1: {
snprintf(outKey, outKeyLen, "Account key");
const uint8_t key_index = displayIdx - 1;
const bytes_t key = {
.ptr = initValidator->account_keys.ptr + PK_LEN_25519_PLUS_TAG * key_index,
.len = PK_LEN_25519_PLUS_TAG
};
CHECK_ERROR(printPublicKey(&key, outVal, outValLen, pageIdx, pageCount));
snprintf(outKey, outKeyLen, "Address");
CHECK_ERROR(printAddress(ctx->tx_obj->becomeValidator.address, outVal, outValLen, pageIdx, pageCount))
break;
}
case 2: {
*pageCount = 1;
snprintf(outKey, outKeyLen, "Threshold");
snprintf(outVal, outValLen, "%d", initValidator->threshold);
break;
}
case 3: {
snprintf(outKey, outKeyLen, "Consensus key");
const bytes_t *consensusKey = &ctx->tx_obj->initValidator.consensus_key;
const bytes_t *consensusKey = &ctx->tx_obj->becomeValidator.consensus_key;
CHECK_ERROR(printPublicKey(consensusKey, outVal, outValLen, pageIdx, pageCount));
break;
}
case 4: {
case 3: {
snprintf(outKey, outKeyLen, "Ethereum cold key");
const bytes_t *ethColdKey = &ctx->tx_obj->initValidator.eth_cold_key;
const bytes_t *ethColdKey = &ctx->tx_obj->becomeValidator.eth_cold_key;
pageStringHex(outVal, outValLen, (const char*) ethColdKey->ptr, ethColdKey->len, pageIdx, pageCount);
break;
}
case 5: {
case 4: {
snprintf(outKey, outKeyLen, "Ethereum hot key");
const bytes_t *ethHotKey = &ctx->tx_obj->initValidator.eth_hot_key;
const bytes_t *ethHotKey = &ctx->tx_obj->becomeValidator.eth_hot_key;
pageStringHex(outVal, outValLen, (const char*) ethHotKey->ptr, ethHotKey->len, pageIdx, pageCount);
break;
}
case 6: {
case 5: {
snprintf(outKey, outKeyLen, "Protocol key");
const bytes_t *protocolKey = &ctx->tx_obj->initValidator.protocol_key;
const bytes_t *protocolKey = &ctx->tx_obj->becomeValidator.protocol_key;
CHECK_ERROR(printPublicKey(protocolKey, outVal, outValLen, pageIdx, pageCount));
break;
}
case 7: {
case 6: {
snprintf(outKey, outKeyLen, "Commission rate");
CHECK_ERROR(printAmount(&ctx->tx_obj->initValidator.commission_rate, POS_DECIMAL_PRECISION, "", outVal, outValLen, pageIdx, pageCount))
CHECK_ERROR(printAmount(&ctx->tx_obj->becomeValidator.commission_rate, POS_DECIMAL_PRECISION, "", outVal, outValLen, pageIdx, pageCount))
break;
}
case 8: {
case 7: {
snprintf(outKey, outKeyLen, "Maximum commission rate change");
CHECK_ERROR(printAmount(&ctx->tx_obj->initValidator.max_commission_rate_change, POS_DECIMAL_PRECISION, "", outVal, outValLen, pageIdx, pageCount))
CHECK_ERROR(printAmount(&ctx->tx_obj->becomeValidator.max_commission_rate_change, POS_DECIMAL_PRECISION, "", outVal, outValLen, pageIdx, pageCount))
break;
}
case 9: {
case 8: {
snprintf(outKey, outKeyLen, "Email");
pageStringExt(outVal, outValLen, (const char*)ctx->tx_obj->initValidator.email.ptr, ctx->tx_obj->initValidator.email.len, pageIdx, pageCount);
pageStringExt(outVal, outValLen, (const char*)ctx->tx_obj->becomeValidator.email.ptr, ctx->tx_obj->becomeValidator.email.len, pageIdx, pageCount);
break;
}
case 10: {
case 9: {
snprintf(outKey, outKeyLen, "Description");
pageStringExt(outVal, outValLen, (const char*)ctx->tx_obj->initValidator.description.ptr, ctx->tx_obj->initValidator.description.len, pageIdx, pageCount);
pageStringExt(outVal, outValLen, (const char*)ctx->tx_obj->becomeValidator.description.ptr, ctx->tx_obj->becomeValidator.description.len, pageIdx, pageCount);
break;
}
case 11: {
case 10: {
snprintf(outKey, outKeyLen, "Website");
pageStringExt(outVal, outValLen, (const char*)ctx->tx_obj->initValidator.website.ptr, ctx->tx_obj->initValidator.website.len, pageIdx, pageCount);
pageStringExt(outVal, outValLen, (const char*)ctx->tx_obj->becomeValidator.website.ptr, ctx->tx_obj->becomeValidator.website.len, pageIdx, pageCount);
break;
}
case 12: {
case 11: {
snprintf(outKey, outKeyLen, "Discord handle");
pageStringExt(outVal, outValLen, (const char*)ctx->tx_obj->initValidator.discord_handle.ptr, ctx->tx_obj->initValidator.discord_handle.len, pageIdx, pageCount);
break;
}
case 13: {
snprintf(outKey, outKeyLen, "Validator VP type");
pageString(outVal, outValLen,ctx->tx_obj->initValidator.vp_type_text, pageIdx, pageCount);
if (app_mode_expert()) {
pageStringHex(outVal, outValLen, (const char*)ctx->tx_obj->initValidator.vp_type_hash.ptr, ctx->tx_obj->initValidator.vp_type_hash.len, pageIdx, pageCount);
}
pageStringExt(outVal, outValLen, (const char*)ctx->tx_obj->becomeValidator.discord_handle.ptr, ctx->tx_obj->becomeValidator.discord_handle.len, pageIdx, pageCount);
break;
}
default: {
if (!app_mode_expert()) {
return parser_display_idx_out_of_range;
}
displayIdx -= INIT_VALIDATOR_NORMAL_PARAMS + account_keys;
if (initValidator->description.ptr != NULL) {
displayIdx--;
}
if (initValidator->discord_handle.ptr != NULL) {
displayIdx--;
}
if (initValidator->website.ptr != NULL) {
displayIdx--;
}
displayIdx -= 12;
return printExpert(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount);
}
}
Expand Down Expand Up @@ -868,8 +833,8 @@ parser_error_t printTxnFields(const parser_context_t *ctx,
case CommissionChange:
return printCommissionChangeTxn(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount);

case InitValidator:
return printInitValidatorTxn(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount);
case BecomeValidator:
return printBecomeValidatorTxn(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount);

case UpdateVP:
return printUpdateVPTxn(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount);
Expand Down
2 changes: 1 addition & 1 deletion app/src/parser_txdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ typedef struct{
tx_unjail_validator_t unjailValidator;
tx_withdraw_t withdraw;
tx_commission_change_t commissionChange;
tx_init_validator_t initValidator;
tx_become_validator_t becomeValidator;
tx_update_vp_t updateVp;
tx_ibc_t ibc;
};
Expand Down
Loading

0 comments on commit f76aaaf

Please sign in to comment.