Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/trezor common #1838

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Feature/trezor common #1838

wants to merge 2 commits into from

Conversation

OBorce
Copy link
Contributor

@OBorce OBorce commented Nov 14, 2024

Move the simplified no-std types used by Trezor firmware to keep it in sync with the core types.
Add randomized tests to check the encodings match between the types.

@OBorce OBorce force-pushed the feature/trezor-common branch from c2c31bb to a99237c Compare November 14, 2024 09:19
Cargo.toml Outdated Show resolved Hide resolved
trezor-common/Cargo.toml Outdated Show resolved Hide resolved
@OBorce OBorce force-pushed the feature/trezor-common branch from a99237c to 00f5576 Compare November 14, 2024 17:12
@OBorce OBorce force-pushed the feature/trezor-common branch from 00f5576 to 44b17f9 Compare November 14, 2024 17:34
Comment on lines +314 to +328
fn make_random_destination(rng: &mut (impl Rng + CryptoRng)) -> chain::Destination {
match rng.gen_range(0..=4) {
0 => chain::Destination::AnyoneCanSpend,
1 => chain::Destination::PublicKey(
crypto::key::PrivateKey::new_from_rng(rng, KeyKind::Secp256k1Schnorr).1,
),
2 => chain::Destination::ScriptHash(primitives::H256(rng.gen()).into()),
3 => chain::Destination::ClassicMultisig(
(&crypto::key::PrivateKey::new_from_rng(rng, KeyKind::Secp256k1Schnorr).1).into(),
),
_ => chain::Destination::PublicKeyHash(
(&crypto::key::PrivateKey::new_from_rng(rng, KeyKind::Secp256k1Schnorr).1).into(),
),
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest deriving strum::EnumDiscriminants for the existing enum types, like I did in 1832 for Destination:

#[derive(..., EnumDiscriminants)]
#[strum_discriminants(name(DestinationTag), derive(EnumIter))]
pub enum Destination {
...

This will define an additional enum called DestinationTag, which will be like Destination but without the data. And this DestinationTag will implement EnumIter, so it'll be possible to iterate over its values.
Then you'd be able to write:

let dest_tag = DestinationTag::iter().choose(rng).unwrap();
match dest_tag {
    DestinationTag::PublicKey => {
        chain::Destination::PublicKey(
            crypto::key::PrivateKey::new_from_rng(rng, KeyKind::Secp256k1Schnorr).1,
        )
    },
    ...
}

So, if/when a new variant is added to the enum, we'll get a compilation failure here.

Comment on lines +30 to +40
impl From<chain::OutPointSourceId> for crate::OutPointSourceId {
fn from(value: chain::OutPointSourceId) -> Self {
match value {
chain::OutPointSourceId::Transaction(tx) => Self::Transaction(tx.to_hash().into()),
chain::OutPointSourceId::BlockReward(tx) => Self::BlockReward(tx.to_hash().into()),
}
}
}

impl From<chain::UtxoOutPoint> for crate::UtxoOutPoint {
fn from(value: chain::UtxoOutPoint) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though I don't insist on this, I'd suggest to make the make_random... functions return a pair of values that are supposed to be encoded to the same bytes, and remove these From implementations (which look somewhat fragile to me).

Comment on lines +529 to +539
let mut rng = make_seedable_rng(seed);

let inp = make_random_input(&mut rng);

let simple_inp: crate::TxInput = inp.clone().into();

assert_eq!(inp.encode(), simple_inp.encode());

let decoded_simple_inp =
chain::TxInput::decode_all(&mut simple_inp.encode().as_slice()).unwrap();
assert_eq!(decoded_simple_inp, inp);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to perform the checks multiple times (e.g. 100 or 1000) in a loop, to increase the chance of failure if things get broken.
Same for the other test.

Comment on lines +374 to +385
#[derive(FromPrimitive)]
pub enum AccountCommandIndex {
MintTokens = 0,
UnmintTokens = 1,
LockTokenSupply = 2,
FreezeToken = 3,
UnfreezeToken = 4,
ChangeTokenAuthority = 5,
ConcludeOrder = 6,
FillOrder = 7,
ChangeTokenMetadataUri = 8,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this enum needed here? As I can see, it's only used in the trezor firmware repo in encode_token_account_command_input but only on the rust side. And its values are not tied to anything, they just have to be the same in rust and python. So probably it should go to messages-mintlayer.proto in the trezor repo, so that named constants can be used on the python side too.

Comment on lines +289 to +293
#[derive(FromPrimitive)]
pub enum OutPointSourceIdIndex {
Transaction = 0,
BlockReward = 1,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I can see, this is similar to AccountCommandIndex, but the difference is that there is already MintlayerUtxoType in the protobuf config which this enum should be consistent with. Remove it and use MintlayerUtxoType instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants