using legacy signing payload in CLI and verifying both variants in contract

This commit is contained in:
Jędrzej Stuczyński
2024-08-28 15:19:55 +01:00
parent a6ad6c7d49
commit 7ae56b08b3
7 changed files with 128 additions and 19 deletions
@@ -6,7 +6,7 @@ use crate::utils::{account_id_to_cw_addr, DataWrapper};
use clap::Parser;
use cosmwasm_std::Coin;
use nym_bin_common::output_format::OutputFormat;
use nym_mixnet_contract_common::construct_gateway_bonding_sign_payload;
use nym_mixnet_contract_common::construct_legacy_gateway_bonding_sign_payload;
use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
use nym_validator_client::nyxd::contract_traits::MixnetQueryClient;
@@ -71,7 +71,7 @@ pub async fn create_payload(args: Args, client: SigningClient) {
let address = account_id_to_cw_addr(&client.address());
let payload = construct_gateway_bonding_sign_payload(nonce, address, coin, gateway);
let payload = construct_legacy_gateway_bonding_sign_payload(nonce, address, coin, gateway);
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
println!("{}", args.output.format(&wrapper))
}
@@ -7,7 +7,9 @@ use clap::Parser;
use cosmwasm_std::{Coin, Uint128};
use nym_bin_common::output_format::OutputFormat;
use nym_contracts_common::Percent;
use nym_mixnet_contract_common::{construct_mixnode_bonding_sign_payload, MixNodeCostParams};
use nym_mixnet_contract_common::{
construct_legacy_mixnode_bonding_sign_payload, MixNodeCostParams,
};
use nym_network_defaults::{
DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT,
};
@@ -98,7 +100,7 @@ pub async fn create_payload(args: Args, client: SigningClient) {
let address = account_id_to_cw_addr(&client.address());
let payload =
construct_mixnode_bonding_sign_payload(nonce, address, coin, mixnode, cost_params);
construct_legacy_mixnode_bonding_sign_payload(nonce, address, coin, mixnode, cost_params);
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
println!("{}", args.output.format(&wrapper))
}
@@ -248,3 +248,31 @@ impl<T> ContractMessageContent<T> {
}
}
}
impl<T> From<ContractMessageContent<T>> for LegacyContractMessageContent<T> {
fn from(value: ContractMessageContent<T>) -> Self {
LegacyContractMessageContent {
sender: value.sender,
proxy: None,
funds: value.funds,
data: value.data,
}
}
}
#[derive(Serialize)]
pub struct LegacyContractMessageContent<T> {
pub sender: Addr,
pub proxy: Option<Addr>,
pub funds: Vec<Coin>,
pub data: T,
}
impl<T> SigningPurpose for LegacyContractMessageContent<T>
where
T: SigningPurpose,
{
fn message_type() -> MessageType {
T::message_type()
}
}
@@ -4,13 +4,18 @@
use crate::families::FamilyHead;
use crate::{Gateway, IdentityKey, MixNode, MixNodeCostParams};
use contracts_common::signing::{
ContractMessageContent, MessageType, Nonce, SignableMessage, SigningPurpose,
ContractMessageContent, LegacyContractMessageContent, MessageType, Nonce, SignableMessage,
SigningPurpose,
};
use cosmwasm_std::{Addr, Coin};
use serde::Serialize;
pub type SignableMixNodeBondingMsg = SignableMessage<ContractMessageContent<MixnodeBondingPayload>>;
pub type SignableGatewayBondingMsg = SignableMessage<ContractMessageContent<GatewayBondingPayload>>;
pub type SignableLegacyMixNodeBondingMsg =
SignableMessage<LegacyContractMessageContent<MixnodeBondingPayload>>;
pub type SignableLegacyGatewayBondingMsg =
SignableMessage<LegacyContractMessageContent<GatewayBondingPayload>>;
pub type SignableFamilyJoinPermitMsg = SignableMessage<FamilyJoinPermit>;
#[derive(Serialize)]
@@ -47,6 +52,20 @@ pub fn construct_mixnode_bonding_sign_payload(
SignableMessage::new(nonce, content)
}
pub fn construct_legacy_mixnode_bonding_sign_payload(
nonce: Nonce,
sender: Addr,
pledge: Coin,
mix_node: MixNode,
cost_params: MixNodeCostParams,
) -> SignableLegacyMixNodeBondingMsg {
let payload = MixnodeBondingPayload::new(mix_node, cost_params);
let content: LegacyContractMessageContent<_> =
ContractMessageContent::new(sender, vec![pledge], payload).into();
SignableMessage::new(nonce, content)
}
#[derive(Serialize)]
pub struct GatewayBondingPayload {
gateway: Gateway,
@@ -76,6 +95,19 @@ pub fn construct_gateway_bonding_sign_payload(
SignableMessage::new(nonce, content)
}
pub fn construct_legacy_gateway_bonding_sign_payload(
nonce: Nonce,
sender: Addr,
pledge: Coin,
gateway: Gateway,
) -> SignableLegacyGatewayBondingMsg {
let payload = GatewayBondingPayload::new(gateway);
let content: LegacyContractMessageContent<_> =
ContractMessageContent::new(sender, vec![pledge], payload).into();
SignableMessage::new(nonce, content)
}
#[derive(Serialize)]
pub struct FamilyJoinPermit {
// the granter of this permit
@@ -5,7 +5,9 @@ use crate::signing::storage as signing_storage;
use crate::support::helpers::decode_ed25519_identity_key;
use cosmwasm_std::{Addr, Coin, Deps};
use mixnet_contract_common::error::MixnetContractError;
use mixnet_contract_common::{construct_gateway_bonding_sign_payload, Gateway};
use mixnet_contract_common::{
construct_gateway_bonding_sign_payload, construct_legacy_gateway_bonding_sign_payload, Gateway,
};
use nym_contracts_common::signing::MessageSignature;
use nym_contracts_common::signing::Verifier;
@@ -19,13 +21,31 @@ pub(crate) fn verify_gateway_bonding_signature(
// recover the public key
let public_key = decode_ed25519_identity_key(&gateway.identity_key)?;
// reconstruct the payload
// reconstruct the payload, first try the current format, then attempt legacy
let nonce = signing_storage::get_signing_nonce(deps.storage, sender.clone())?;
let msg = construct_gateway_bonding_sign_payload(nonce, sender, pledge, gateway);
let msg = construct_gateway_bonding_sign_payload(
nonce,
sender.clone(),
pledge.clone(),
gateway.clone(),
);
if deps.api.verify_message(msg, signature, &public_key)? {
if deps
.api
.verify_message(msg, signature.clone(), &public_key)?
{
Ok(())
} else {
Err(MixnetContractError::InvalidEd25519Signature)
// attempt to use legacy
let msg_legacy =
construct_legacy_gateway_bonding_sign_payload(nonce, sender, pledge, gateway);
if deps
.api
.verify_message(msg_legacy, signature, &public_key)?
{
Ok(())
} else {
Err(MixnetContractError::InvalidEd25519Signature)
}
}
}
@@ -5,7 +5,10 @@ use crate::signing::storage as signing_storage;
use crate::support::helpers::decode_ed25519_identity_key;
use cosmwasm_std::{Addr, Coin, Deps};
use mixnet_contract_common::error::MixnetContractError;
use mixnet_contract_common::{construct_mixnode_bonding_sign_payload, MixNode, MixNodeCostParams};
use mixnet_contract_common::{
construct_legacy_mixnode_bonding_sign_payload, construct_mixnode_bonding_sign_payload, MixNode,
MixNodeCostParams,
};
use nym_contracts_common::signing::MessageSignature;
use nym_contracts_common::signing::Verifier;
@@ -20,13 +23,37 @@ pub(crate) fn verify_mixnode_bonding_signature(
// recover the public key
let public_key = decode_ed25519_identity_key(&mixnode.identity_key)?;
// reconstruct the payload
// reconstruct the payload, first try the current format, then attempt legacy
let nonce = signing_storage::get_signing_nonce(deps.storage, sender.clone())?;
let msg = construct_mixnode_bonding_sign_payload(nonce, sender, pledge, mixnode, cost_params);
let msg = construct_mixnode_bonding_sign_payload(
nonce,
sender.clone(),
pledge.clone(),
mixnode.clone(),
cost_params.clone(),
);
if deps.api.verify_message(msg, signature, &public_key)? {
if deps
.api
.verify_message(msg, signature.clone(), &public_key)?
{
Ok(())
} else {
Err(MixnetContractError::InvalidEd25519Signature)
// attempt to use legacy
let msg_legacy = construct_legacy_mixnode_bonding_sign_payload(
nonce,
sender,
pledge,
mixnode,
cost_params,
);
if deps
.api
.verify_message(msg_legacy, signature, &public_key)?
{
Ok(())
} else {
Err(MixnetContractError::InvalidEd25519Signature)
}
}
}
@@ -9,8 +9,8 @@ use nym_contracts_common::signing::{
};
use nym_crypto::asymmetric::identity;
use nym_mixnet_contract_common::{
construct_mixnode_bonding_sign_payload, Gateway, GatewayBondingPayload, MixNode,
MixNodeCostParams, SignableGatewayBondingMsg, SignableMixNodeBondingMsg,
construct_legacy_mixnode_bonding_sign_payload, Gateway, GatewayBondingPayload, MixNode,
MixNodeCostParams, SignableGatewayBondingMsg, SignableLegacyMixNodeBondingMsg,
};
use nym_validator_client::nyxd::contract_traits::MixnetQueryClient;
use nym_validator_client::nyxd::error::NyxdError;
@@ -42,14 +42,14 @@ pub(crate) async fn create_mixnode_bonding_sign_payload<P: AddressAndNonceProvid
cost_params: MixNodeCostParams,
pledge: Coin,
vesting: bool,
) -> Result<SignableMixNodeBondingMsg, BackendError> {
) -> Result<SignableLegacyMixNodeBondingMsg, BackendError> {
if vesting {
return Err(BackendError::UnsupportedVestingOperation);
}
let sender = client.cw_address();
let nonce = client.get_signing_nonce().await?;
Ok(construct_mixnode_bonding_sign_payload(
Ok(construct_legacy_mixnode_bonding_sign_payload(
nonce,
sender,
pledge.into(),