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

Make better use of the type system #6

Merged
merged 8 commits into from
Nov 17, 2020

Conversation

thomaseizinger
Copy link
Contributor

@thomaseizinger thomaseizinger commented Nov 17, 2020

See commit messages.

This is helpful because we sometimes need to peek at the next value
to deserialize the right thing.
The previous model was to flexible in that it allowed to express
states that were not actually possible (like explicit value but
confidential asset).
Copy link
Collaborator

@luckysori luckysori left a comment

Choose a reason for hiding this comment

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

Half-review

elements-fun/src/confidential.rs Show resolved Hide resolved
elements-fun/src/confidential.rs Show resolved Hide resolved
elements-fun/src/confidential.rs Show resolved Hide resolved
tx: &crate::Transaction,
index: usize,
script_code: &bitcoin::Script,
value: &crate::confidential::Value,
value: &V, // TODO: Is this really the best way to do it?
Copy link
Collaborator

Choose a reason for hiding this comment

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

❓ Should we introduce a ValueCommitment type?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It actually exists. Should we use it here?

Copy link
Contributor Author

@thomaseizinger thomaseizinger Nov 17, 2020

Choose a reason for hiding this comment

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

Well, you can use this function for confidential and non-confidential values. The new model system doesn't (yet) offer anything here.

elements-fun/src/wally.rs Show resolved Hide resolved
use crate::issuance::AssetId;

// TODO: Is `Default` really useful here?
Copy link
Collaborator

Choose a reason for hiding this comment

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

❓ Why not? A null asset issuance is what I would expect when I need the rest of a transaction to be default.


impl ExplicitAssetIssuance {
pub fn encoded_length(&self) -> usize {
32 + 32 + self.amount.encoded_length() + self.inflation_keys.encoded_length()
Copy link
Collaborator

Choose a reason for hiding this comment

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

❓ Should we use a SECRET_KEY_LENGTH sort of constant (that may already exist) instead of magic numbers?

Comment on lines +91 to +99
pub struct NullAssetIssuance {
/// Zero for a new asset issuance; otherwise a blinding factor for the input
pub asset_blinding_nonce: [u8; 32],
/// Freeform entropy field
pub asset_entropy: [u8; 32],
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

❓ Can you explain why a null asset issuance has any fields at all? Doesn't make sense to me given the name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, the data is still there I think, like I need to deserialize it. Will have to do some testing to see if this can be improved!

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's just weird that there has to be any data at all if the transaction does not issue an asset. Unless this data is unrelated to asset issuances?

)]
pub struct ConfidentialAssetIssuance {
/// Zero for a new asset issuance; otherwise a blinding factor for the input
pub asset_blinding_nonce: [u8; 32],
Copy link
Collaborator

Choose a reason for hiding this comment

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

❓ Have you thought about using SecretKey for some of these fields? Would it make sense?

Copy link
Contributor Author

@thomaseizinger thomaseizinger Nov 17, 2020

Choose a reason for hiding this comment

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

Haven't yet thought about it, wanted to get the big refactoring in first!

@luckysori luckysori merged commit 084661a into comit-network:master Nov 17, 2020
Copy link
Collaborator

@luckysori luckysori left a comment

Choose a reason for hiding this comment

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

This looks really good to me! I would consider upstreaming this. The worst that can happen is that they say no and we just continue with our own version of it.

pub struct PeginData<'tx> {
/// Reference to the pegin output on the mainchain
pub outpoint: bitcoin::OutPoint,
/// The value, in satoshis, of the pegin
pub value: u64,
/// Asset type being pegged in
pub asset: confidential::Asset,
pub asset: AssetId,
Copy link
Collaborator

Choose a reason for hiding this comment

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

❓ Does this mean that this struct is always explicit?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes from my understanding yes!

derive(serde::Serialize, serde::Deserialize),
serde(crate = "serde_crate")
)]
pub struct NullTxOut {
Copy link
Collaborator

Choose a reason for hiding this comment

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

❓ When does elements use null txouts? Just curious.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't fully understand this yet :D

derive(serde::Serialize, serde::Deserialize),
serde(crate = "serde_crate", transparent)
)]
pub struct ExplicitValue(pub u64);
Copy link
Collaborator

Choose a reason for hiding this comment

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

❓ Should we be using bitcoin::Amount under the hood? Is that a horrible idea?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not a horrible idea because all tokens have the same decimal points :)

Comment on lines +728 to +751
pub fn unblind(&self, blinding_key: SecretKey) -> Result<UnblindedTxOut, UnblindError> {
let sender_ephemeral_pk = self.nonce.ok_or(UnblindError::MissingNonce)?.commitment();
let sender_ephemeral_pk = PublicKey::from_slice(&sender_ephemeral_pk)
.map_err(|_| UnblindError::InvalidPublicKey)?;

let (unblinded_asset, abf, vbf, value_out) = asset_unblind(
sender_ephemeral_pk,
blinding_key,
&self.witness.rangeproof,
self.value,
&self.script_pubkey,
self.asset,
)
.map_err(|_| UnblindError::Wally)?;

Ok(UnblindedTxOut {
asset: AssetId::from_slice(&unblinded_asset).unwrap(),
original_asset: self.asset,
asset_blinding_factor: abf,
value_blinding_factor: vbf,
value: value_out,
})
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

🎉 This makes it all worth it! Awesome work.

elements-fun/src/transaction.rs Show resolved Hide resolved

if !has_min {
min_value
} else if has_nonzero_range {
bitcoin::consensus::deserialize::<u64>(&self.witness.rangeproof[2..10])
bitcoin::consensus::deserialize::<u64>(&witness.rangeproof[2..10])
Copy link
Collaborator

Choose a reason for hiding this comment

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

🤔 Imagine if we had a rangeproof struct.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is all possible :D

Comment on lines +2096 to +2111
// assert_eq!(
// tx.input[0].asset_issuance,
// AssetIssuance {
// asset_blinding_nonce: [0; 32],
// asset_entropy: [0; 32],
// amount: confidential::Value::Confidential(
// 9,
// [
// 0x81, 0x65, 0x4e, 0xb5, 0xcc, 0xd9, 0x92, 0x7b, 0x8b, 0xea, 0x94, 0x99,
// 0x7d, 0xce, 0x4a, 0xe8, 0x5b, 0x3d, 0x95, 0xa2, 0x07, 0x00, 0x38, 0x4f,
// 0x0b, 0x8c, 0x1f, 0xe9, 0x95, 0x18, 0x06, 0x38
// ],
// ),
// inflation_keys: confidential::Value::Null,
// }
// );
Copy link
Collaborator

Choose a reason for hiding this comment

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

🔧 I guess you meant to remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ups, no I didn't!

Will put it back!

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.

2 participants