Skip to content

Commit

Permalink
[Cosmos] Add MsgWithdrawDelegationRewardsAll (#763)
Browse files Browse the repository at this point in the history
* Add MsgWithdrawDelegationRewardsAll
* renaming type prefixes
  • Loading branch information
hewigovens authored and optout21 committed Dec 8, 2019
1 parent f64adb5 commit cfbde7b
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 46 deletions.
1 change: 1 addition & 0 deletions include/TrustWalletCore/TWCosmosProto.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ typedef TWData *_Nonnull TW_Cosmos_Proto_SendCoinsMessage;
typedef TWData *_Nonnull TW_Cosmos_Proto_StakeMessage;
typedef TWData *_Nonnull TW_Cosmos_Proto_ReStakeMessage;
typedef TWData *_Nonnull TW_Cosmos_Proto_WithdrawStakeRewardMessage;
typedef TWData *_Nonnull TW_Cosmos_Proto_WithdrawStakeRewardsAllMessage;
typedef TWData *_Nonnull TW_Cosmos_Proto_Signature;
typedef TWData *_Nonnull TW_Cosmos_Proto_Transaction;
typedef TWData *_Nonnull TW_Cosmos_Proto_SigningInput;
Expand Down
75 changes: 46 additions & 29 deletions src/Cosmos/Serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ using namespace TW::Cosmos::Proto;
using json = nlohmann::json;
using string = std::string;

const string AMINO_PREFIX_SEND_COIN_MESSAGE = "cosmos-sdk/MsgSend";
const string AMINO_PREFIX_STAKE_MESSAGE = "cosmos-sdk/MsgDelegate";
const string AMINO_PREFIX_UNSTAKE_MESSAGE = "cosmos-sdk/MsgUndelegate";
const string AMINO_PREFIX_RESTAKE_MESSAGE = "cosmos-sdk/MsgBeginRedelegate";
const string AMINO_PREFIX_WITHDRAW_STAKE_MESSAGE = "cosmos-sdk/MsgWithdrawDelegationReward";
const string AMINO_PREFIX_PUBLIC_KEY = "tendermint/PubKeySecp256k1";
const string TYPE_PREFIX_MSG_SEND = "cosmos-sdk/MsgSend";
const string TYPE_PREFIX_MSG_DELEGATE = "cosmos-sdk/MsgDelegate";
const string TYPE_PREFIX_MSG_UNDELEGATE = "cosmos-sdk/MsgUndelegate";
const string TYPE_PREFIX_MSG_REDELEGATE = "cosmos-sdk/MsgBeginRedelegate";
const string TYPE_PREFIX_MSG_WITHDRAW_REWARD = "cosmos-sdk/MsgWithdrawDelegationReward";
const string TYPE_PREFIX_MSG_WITHDRAW_REWARDS_ALL = "cosmos-sdk/MsgWithdrawDelegationRewardsAll";
const string TYPE_PREFIX_PUBLIC_KEY = "tendermint/PubKeySecp256k1";

static json broadcastJSON(json& jsonObj) {
json jsonMsgWrapper;
Expand Down Expand Up @@ -66,7 +67,7 @@ static json feeJSON(const Fee& fee) {
return jsonFee;
}

static json sendCoinsMessageJSON(json& amounts, const string& from_address, const string& to_address, const string& type_prefix) {
static json sendCoinsMessage(json& amounts, const string& from_address, const string& to_address, const string& type_prefix) {
json jsonMsg;

jsonMsg["amount"] = amounts;
Expand All @@ -76,7 +77,7 @@ static json sendCoinsMessageJSON(json& amounts, const string& from_address, cons
return wrapperJSON(type_prefix, jsonMsg);
}

static json stakeMessageJSON(json& amount, const string& delegator_address, const string& validator_address, const string& type_prefix) {
static json stakeMessage(json& amount, const string& delegator_address, const string& validator_address, const string& type_prefix) {
json jsonMsg;

jsonMsg["amount"] = amount;
Expand All @@ -86,7 +87,7 @@ static json stakeMessageJSON(json& amount, const string& delegator_address, cons
return wrapperJSON(type_prefix, jsonMsg);
}

static json restakeMessageJSON(json& amount, const string& delegator_address, const string& validator_src_address, const string& validator_dst_address, const string& type_prefix) {
static json restakeMessage(json& amount, const string& delegator_address, const string& validator_src_address, const string& validator_dst_address, const string& type_prefix) {
json jsonMsg;

jsonMsg["amount"] = amount;
Expand All @@ -97,7 +98,7 @@ static json restakeMessageJSON(json& amount, const string& delegator_address, co
return wrapperJSON(type_prefix, jsonMsg);
}

static json withdrawStakeRewardMessageJSON(const string& delegator_address, const string& validator_address, const string& type_prefix) {
static json withdrawStakeRewardMessage(const string& delegator_address, const string& validator_address, const string& type_prefix) {
json jsonMsg;

jsonMsg["delegator_address"] = delegator_address;
Expand All @@ -106,64 +107,80 @@ static json withdrawStakeRewardMessageJSON(const string& delegator_address, cons
return wrapperJSON(type_prefix, jsonMsg);
}

static json sendCoinsMessageJSON(const SendCoinsMessage& message) {
static json withdrawStakeRewardsAllMessage(const string& delegator_address, const string& type_prefix) {
json jsonMsg;

jsonMsg["delegator_address"] = delegator_address;

return wrapperJSON(type_prefix, jsonMsg);
}

static json sendCoinsMessage(const SendCoinsMessage& message) {
json jsonAmounts = json::array();

for (auto& amount : message.amounts()) {
jsonAmounts.push_back(amountJSON(std::to_string(amount.amount()), amount.denom()));
}

return sendCoinsMessageJSON(jsonAmounts, message.from_address(), message.to_address(), message.type_prefix());
return sendCoinsMessage(jsonAmounts, message.from_address(), message.to_address(), message.type_prefix());
}


static json stakeMessageJSON(const StakeMessage& message) {
static json stakeMessage(const StakeMessage& message) {
auto amount = message.amount();
json jsonAmount = amountJSON(std::to_string(amount.amount()), amount.denom());

return stakeMessageJSON(jsonAmount, message.delegator_address(), message.validator_address(), message.type_prefix());
return stakeMessage(jsonAmount, message.delegator_address(), message.validator_address(), message.type_prefix());
}

static json restakeMessageJSON(const ReStakeMessage& message) {
static json restakeMessage(const ReStakeMessage& message) {
auto amount = message.amount();
json jsonAmount = amountJSON(std::to_string(amount.amount()), amount.denom());

return restakeMessageJSON(jsonAmount, message.delegator_address(), message.validator_src_address(),
return restakeMessage(jsonAmount, message.delegator_address(), message.validator_src_address(),
message.validator_dst_address(), message.type_prefix());
}


static json withdrawStakeRewardMessageJSON(const WithdrawStakeRewardMessage& message) {
return withdrawStakeRewardMessageJSON(message.delegator_address(), message.validator_address(), message.type_prefix());
static json withdrawStakeRewardMessage(const WithdrawStakeRewardMessage& message) {
return withdrawStakeRewardMessage(message.delegator_address(), message.validator_address(), message.type_prefix());
}

static json withdrawStakeRewardsAllMessage(const WithdrawStakeRewardsAllMessage& message) {
return withdrawStakeRewardsAllMessage(message.delegator_address(), message.type_prefix());
}

static json messageJSON(const SigningInput& input) {
if (input.has_send_coins_message()) {
return sendCoinsMessageJSON(input.send_coins_message());
return sendCoinsMessage(input.send_coins_message());
} else if (input.has_stake_message()) {
return stakeMessageJSON(input.stake_message());
return stakeMessage(input.stake_message());
} else if (input.has_unstake_message()) {
return stakeMessageJSON(input.unstake_message());
return stakeMessage(input.unstake_message());
} else if (input.has_restake_message()) {
return restakeMessageJSON(input.restake_message());
return restakeMessage(input.restake_message());
} else if (input.has_withdraw_stake_reward_message()) {
return withdrawStakeRewardMessageJSON(input.withdraw_stake_reward_message());
return withdrawStakeRewardMessage(input.withdraw_stake_reward_message());
} else if (input.has_withdraw_stake_rewards_all_message()) {
return withdrawStakeRewardsAllMessage(input.withdraw_stake_rewards_all_message());
}

return nullptr;
}

static json messageJSON(const Transaction& transaction) {
if (transaction.has_send_coins_message()) {
return sendCoinsMessageJSON(transaction.send_coins_message());
return sendCoinsMessage(transaction.send_coins_message());
} else if (transaction.has_stake_message()) {
return stakeMessageJSON(transaction.stake_message());
return stakeMessage(transaction.stake_message());
} else if (transaction.has_unstake_message()) {
return stakeMessageJSON(transaction.unstake_message());
return stakeMessage(transaction.unstake_message());
} else if (transaction.has_restake_message()) {
return restakeMessageJSON(transaction.restake_message());
return restakeMessage(transaction.restake_message());
} else if (transaction.has_withdraw_stake_reward_message()) {
return withdrawStakeRewardMessageJSON(transaction.withdraw_stake_reward_message());
return withdrawStakeRewardMessage(transaction.withdraw_stake_reward_message());
} else if (transaction.has_withdraw_stake_rewards_all_message()) {
return withdrawStakeRewardsAllMessage(transaction.withdraw_stake_rewards_all_message());
}

return nullptr;
Expand All @@ -172,7 +189,7 @@ static json messageJSON(const Transaction& transaction) {
static json signatureJSON(const Signature& signature) {
json jsonSignature;

jsonSignature["pub_key"]["type"] = AMINO_PREFIX_PUBLIC_KEY;
jsonSignature["pub_key"]["type"] = TYPE_PREFIX_PUBLIC_KEY;
jsonSignature["pub_key"]["value"] = Base64::encode(Data(signature.public_key().begin(), signature.public_key().end()));
jsonSignature["signature"] = Base64::encode(Data(signature.signature().begin(), signature.signature().end()));

Expand Down
17 changes: 10 additions & 7 deletions src/Cosmos/Serialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@
#include "../proto/Cosmos.pb.h"
#include <nlohmann/json.hpp>

extern const std::string AMINO_PREFIX_SEND_COIN_MESSAGE;
extern const std::string AMINO_PREFIX_STAKE_MESSAGE;
extern const std::string AMINO_PREFIX_UNSTAKE_MESSAGE;
extern const std::string AMINO_PREFIX_RESTAKE_MESSAGE;
extern const std::string AMINO_PREFIX_WITHDRAW_STAKE_MESSAGE;
extern const std::string AMINO_PREFIX_PUBLIC_KEY;
using string = std::string;

extern const string TYPE_PREFIX_MSG_SEND;
extern const string TYPE_PREFIX_MSG_DELEGATE;
extern const string TYPE_PREFIX_MSG_UNDELEGATE;
extern const string TYPE_PREFIX_MSG_REDELEGATE;
extern const string TYPE_PREFIX_MSG_WITHDRAW_REWARD;
extern const string TYPE_PREFIX_MSG_WITHDRAW_REWARDS_ALL;
extern const string TYPE_PREFIX_PUBLIC_KEY;

namespace TW::Cosmos {

nlohmann::json signaturePreimageJSON(const Proto::SigningInput& input);
nlohmann::json transactionJSON(const Proto::Transaction& transaction, const std::string& type_prefix);
nlohmann::json transactionJSON(const Proto::Transaction& transaction, const string& type_prefix);

} // namespace
20 changes: 14 additions & 6 deletions src/Cosmos/Signer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,45 @@ using json = nlohmann::json;

Signer::Signer(Proto::SigningInput&& input) {
if (input.type_prefix().empty()) {
input.set_type_prefix(AMINO_PREFIX_SEND_COIN_MESSAGE);
input.set_type_prefix(TYPE_PREFIX_MSG_SEND);
}

if (input.has_send_coins_message()) {
auto message = input.send_coins_message();
if (message.type_prefix().empty()) {
message.set_type_prefix(AMINO_PREFIX_SEND_COIN_MESSAGE);
message.set_type_prefix(TYPE_PREFIX_MSG_SEND);
}
*input.mutable_send_coins_message() = message;
} else if (input.has_stake_message()) {
auto message = input.stake_message();
if (message.type_prefix().empty()) {
message.set_type_prefix(AMINO_PREFIX_STAKE_MESSAGE);
message.set_type_prefix(TYPE_PREFIX_MSG_DELEGATE);
}
*input.mutable_stake_message() = message;
} else if(input.has_unstake_message()) {
auto message = input.unstake_message();
if (message.type_prefix().empty()) {
message.set_type_prefix(AMINO_PREFIX_UNSTAKE_MESSAGE);
message.set_type_prefix(TYPE_PREFIX_MSG_UNDELEGATE);
}
*input.mutable_unstake_message() = message;
} else if(input.has_withdraw_stake_reward_message()) {
auto message = input.withdraw_stake_reward_message();
if (message.type_prefix().empty()) {
message.set_type_prefix(AMINO_PREFIX_WITHDRAW_STAKE_MESSAGE);
message.set_type_prefix(TYPE_PREFIX_MSG_WITHDRAW_REWARD);
}
*input.mutable_withdraw_stake_reward_message() = message;
} else if(input.has_restake_message()) {
auto message = input.restake_message();
if (message.type_prefix().empty()) {
message.set_type_prefix(AMINO_PREFIX_RESTAKE_MESSAGE);
message.set_type_prefix(TYPE_PREFIX_MSG_REDELEGATE);
}
*input.mutable_restake_message() = message;
} else if (input.has_withdraw_stake_rewards_all_message()) {
auto message = input.withdraw_stake_rewards_all_message();
if (message.type_prefix().empty()) {
message.set_type_prefix(TYPE_PREFIX_MSG_WITHDRAW_REWARDS_ALL);
}
*input.mutable_withdraw_stake_rewards_all_message() = message;
}

this->input = input;
Expand Down Expand Up @@ -91,6 +97,8 @@ json Signer::buildTransactionJSON(const Data& signature) const {
*transaction.mutable_restake_message() = input.restake_message();
} else if (input.has_withdraw_stake_reward_message()) {
*transaction.mutable_withdraw_stake_reward_message() = input.withdraw_stake_reward_message();
} else if (input.has_withdraw_stake_rewards_all_message()) {
*transaction.mutable_withdraw_stake_rewards_all_message() = input.withdraw_stake_rewards_all_message();
}

*transaction.mutable_signature() = sig;
Expand Down
10 changes: 9 additions & 1 deletion src/proto/Cosmos.proto
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ message WithdrawStakeRewardMessage {
string type_prefix = 3;
}

message WithdrawStakeRewardsAllMessage {
string delegator_address = 1;
// cosmos-sdk/MsgWithdrawDelegationRewardsAll
string type_prefix = 2;
}

// Signature
message Signature {
bytes public_key = 1;
Expand All @@ -69,6 +75,7 @@ message Transaction {
StakeMessage unstake_message = 6;
ReStakeMessage restake_message = 7;
WithdrawStakeRewardMessage withdraw_stake_reward_message = 8;
WithdrawStakeRewardsAllMessage withdraw_stake_rewards_all_message = 9;
}
}

Expand All @@ -88,9 +95,10 @@ message SigningInput {
StakeMessage unstake_message = 9;
ReStakeMessage restake_message = 10;
WithdrawStakeRewardMessage withdraw_stake_reward_message = 11;
WithdrawStakeRewardsAllMessage withdraw_stake_rewards_all_message = 12;
}
// default is cosmos-sdk/MsgSend
string type_prefix = 12;
string type_prefix = 20;
}

// Transaction signing output.
Expand Down
35 changes: 33 additions & 2 deletions tests/Cosmos/StakingTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
#include <TrustWalletCore/TWHRP.h>
#include <gtest/gtest.h>

namespace TW::Cosmos {
using namespace TW;
using namespace TW::Cosmos;

TEST(CosmosStaking, Staking) {
auto input = Proto::SigningInput();
Expand Down Expand Up @@ -159,6 +160,36 @@ TEST(CosmosStaking, Withdraw) {
ASSERT_EQ("{\"mode\":\"block\",\"tx\":{\"fee\":{\"amount\":[{\"amount\":\"1018\",\"denom\":\"muon\"}],\"gas\":\"101721\"},\"memo\":\"\",\"msg\":[{\"type\":\"cosmos-sdk/MsgWithdrawDelegationReward\",\"value\":{\"delegator_address\":\"cosmos1hsk6jryyqjfhp5dhc55tc9jtckygx0eph6dd02\",\"validator_address\":\"cosmosvaloper1zkupr83hrzkn3up5elktzcq3tuft8nxsmwdqgp\"}}],\"signatures\":[{\"pub_key\":{\"type\":\"tendermint/PubKeySecp256k1\",\"value\":\"AlcobsPzfTNVe7uqAAsndErJAjqplnyudaGB0f+R+p3F\"},\"signature\":\"VG8NZzVvavlM+1qyK5dOSZwzEj8sLCkvTw5kh44Oco9GQxBf13FVC+s/I3HwiICqo4+o8jNMEDp3nx2C0tuY1g==\"}],\"type\":\"cosmos-sdk/MsgSend\"}}", output.json());

ASSERT_EQ(hex(output.signature()), "546f0d67356f6af94cfb5ab22b974e499c33123f2c2c292f4f0e64878e0e728f4643105fd771550beb3f2371f08880aaa38fa8f2334c103a779f1d82d2db98d6");
}
}

TEST(CosmosStaking, WithdrawAll) {
auto input = Proto::SigningInput();
input.set_account_number(1037);
input.set_chain_id("gaia-13003");
input.set_memo("");
input.set_sequence(7);

auto& message = *input.mutable_withdraw_stake_rewards_all_message();
message.set_delegator_address("cosmos1hsk6jryyqjfhp5dhc55tc9jtckygx0eph6dd02");

auto &fee = *input.mutable_fee();
fee.set_gas(101721);
auto amountOfFee = fee.add_amounts();
amountOfFee->set_denom("muon");
amountOfFee->set_amount(1018);

auto privateKey = parse_hex("80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005");
input.set_private_key(privateKey.data(), privateKey.size());

auto signer = Cosmos::Signer(std::move(input));
auto signature = signer.sign();
auto signatureInBase64 = Base64::encode(signature);

ASSERT_EQ("ImvsgnfbjebxzeBCUPeOcMoOJWMV3IhWM1apV20WiS4K11iA50fe0uXr4Xf/RTxUDXTm56cne/OjOr77BG99Aw==", signatureInBase64);

auto output = signer.build();

ASSERT_EQ("{\"mode\":\"block\",\"tx\":{\"fee\":{\"amount\":[{\"amount\":\"1018\",\"denom\":\"muon\"}],\"gas\":\"101721\"},\"memo\":\"\",\"msg\":[{\"type\":\"cosmos-sdk/MsgWithdrawDelegationRewardsAll\",\"value\":{\"delegator_address\":\"cosmos1hsk6jryyqjfhp5dhc55tc9jtckygx0eph6dd02\"}}],\"signatures\":[{\"pub_key\":{\"type\":\"tendermint/PubKeySecp256k1\",\"value\":\"AlcobsPzfTNVe7uqAAsndErJAjqplnyudaGB0f+R+p3F\"},\"signature\":\"ImvsgnfbjebxzeBCUPeOcMoOJWMV3IhWM1apV20WiS4K11iA50fe0uXr4Xf/RTxUDXTm56cne/OjOr77BG99Aw==\"}],\"type\":\"cosmos-sdk/MsgSend\"}}", output.json());

ASSERT_EQ(hex(output.signature()), "226bec8277db8de6f1cde04250f78e70ca0e256315dc88563356a9576d16892e0ad75880e747ded2e5ebe177ff453c540d74e6e7a7277bf3a33abefb046f7d03");
}
1 change: 0 additions & 1 deletion tools/tests
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,3 @@ build/tests/tests tests

tools/ios-test
tools/android-test
tools/js-test

0 comments on commit cfbde7b

Please sign in to comment.