fix(txbuilder): sign transactions using Conway era (#531)

This commit is contained in:
Santiago Carmuega 2024-10-24 16:17:34 -03:00 committed by GitHub
parent 698d7a4933
commit 211674d81c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 45 additions and 21 deletions

View file

@ -6,8 +6,8 @@ use pallas_primitives::{
conway::{
DatumOption, ExUnits as PallasExUnits, NativeScript, NetworkId, NonZeroInt, PlutusData,
PlutusScript, PostAlonzoTransactionOutput, PseudoScript as PallasScript,
PseudoTransactionOutput, Redeemer, RedeemerTag, TransactionBody, TransactionInput,
Tx as BabbageTx, Value, WitnessSet,
PseudoTransactionOutput, Redeemer, RedeemerTag, TransactionBody, TransactionInput, Tx,
Value, WitnessSet,
},
Fragment, NonEmptyKeyValuePairs, NonEmptySet, PositiveCoin,
};
@ -25,15 +25,15 @@ use crate::{
TxBuilderError,
};
pub trait BuildBabbage {
fn build_babbage_raw(self) -> Result<BuiltTransaction, TxBuilderError>;
pub trait BuildConway {
fn build_conway_raw(self) -> Result<BuiltTransaction, TxBuilderError>;
// fn build_babbage(staging_tx: StagingTransaction, resolver: (), params: ()) ->
// Result<BuiltTransaction, TxBuilderError>;
}
impl BuildBabbage for StagingTransaction {
fn build_babbage_raw(self) -> Result<BuiltTransaction, TxBuilderError> {
impl BuildConway for StagingTransaction {
fn build_conway_raw(self) -> Result<BuiltTransaction, TxBuilderError> {
let mut inputs = self
.inputs
.unwrap_or_default()
@ -220,15 +220,21 @@ impl BuildBabbage for StagingTransaction {
);
let script_data_hash = self.language_view.map(|language_view| {
scriptdata::ScriptData {
let dta = scriptdata::ScriptData {
redeemers: witness_set_redeemers.clone(),
datums: Some(plutus_data.clone()),
datums: if !plutus_data.is_empty() {
Some(plutus_data.clone())
} else {
None
},
language_view,
}
.hash()
};
dbg!(&dta);
dta.hash()
});
let mut pallas_tx = BabbageTx {
let mut pallas_tx = Tx {
transaction_body: TransactionBody {
inputs: pallas_primitives::Set::from(inputs),
outputs,
@ -274,7 +280,7 @@ impl BuildBabbage for StagingTransaction {
Ok(BuiltTransaction {
version: self.version,
era: BuilderEra::Babbage,
era: BuilderEra::Conway,
status: TransactionStatus::Built,
tx_hash: Bytes32(*pallas_tx.transaction_body.compute_hash()),
tx_bytes: Bytes(pallas_tx.encode_fragment().unwrap()),

View file

@ -1,8 +1,8 @@
mod babbage;
mod conway;
mod scriptdata;
mod transaction;
pub use babbage::BuildBabbage;
pub use conway::BuildConway;
pub use transaction::model::{
BuiltTransaction, ExUnits, Input, Output, ScriptKind, StagingTransaction,
};
@ -34,4 +34,7 @@ pub enum TxBuilderError {
/// Asset name is too long, it must be 32 bytes or less
#[error("Asset name must be 32 bytes or less")]
AssetNameTooLong,
/// Unsupported era
#[error("Unsupported era")]
UnsupportedEra,
}

View file

@ -39,6 +39,7 @@ impl<C> Encode<C> for LanguageView {
}
}
#[derive(Debug, Clone)]
pub struct ScriptData {
pub redeemers: Redeemers,
pub datums: Option<Vec<PlutusData>>,
@ -112,6 +113,10 @@ mod tests {
hex::decode(include_str!("../../test_data/conway2.tx")).unwrap(),
LanguageView(0, COST_MODEL_PLUTUS_V1.clone()),
),
(
hex::decode(include_str!("../../test_data/hydra-init.tx")).unwrap(),
LanguageView(1, COST_MODEL_PLUTUS_V2.clone()),
),
]
});

View file

@ -3,7 +3,7 @@ use pallas_crypto::{
hash::{Hash, Hasher},
key::ed25519,
};
use pallas_primitives::{babbage, Fragment};
use pallas_primitives::{babbage, conway, Fragment, NonEmptySet};
use pallas_wallet::PrivateKey;
use std::{collections::HashMap, ops::Deref};
@ -599,6 +599,7 @@ impl From<PallasAddress> for Address {
#[serde(rename_all = "snake_case")]
pub enum BuilderEra {
Babbage,
Conway,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
@ -626,7 +627,7 @@ impl BuiltTransaction {
.unwrap();
match self.era {
BuilderEra::Babbage => {
BuilderEra::Conway => {
let mut new_sigs = self.signatures.unwrap_or_default();
new_sigs.insert(Bytes32(pubkey), Bytes64(signature));
@ -634,20 +635,26 @@ impl BuiltTransaction {
self.signatures = Some(new_sigs);
// TODO: chance for serialisation round trip issues?
let mut tx = babbage::Tx::decode_fragment(&self.tx_bytes.0)
let mut tx = conway::Tx::decode_fragment(&self.tx_bytes.0)
.map_err(|_| TxBuilderError::CorruptedTxBytes)?;
let mut vkey_witnesses = tx.transaction_witness_set.vkeywitness.unwrap_or_default();
let mut vkey_witnesses = tx
.transaction_witness_set
.vkeywitness
.map(|x| x.to_vec())
.unwrap_or_default();
vkey_witnesses.push(babbage::VKeyWitness {
vkey: Vec::from(pubkey.as_ref()).into(),
signature: Vec::from(signature.as_ref()).into(),
});
tx.transaction_witness_set.vkeywitness = Some(vkey_witnesses);
tx.transaction_witness_set.vkeywitness =
Some(NonEmptySet::from_vec(vkey_witnesses).unwrap());
self.tx_bytes = tx.encode_fragment().unwrap().into();
}
_ => return Err(TxBuilderError::UnsupportedEra),
}
Ok(self)
@ -659,7 +666,7 @@ impl BuiltTransaction {
signature: [u8; 64],
) -> Result<Self, TxBuilderError> {
match self.era {
BuilderEra::Babbage => {
BuilderEra::Conway => {
let mut new_sigs = self.signatures.unwrap_or_default();
new_sigs.insert(
@ -689,6 +696,7 @@ impl BuiltTransaction {
self.tx_bytes = tx.encode_fragment().unwrap().into();
}
_ => return Err(TxBuilderError::UnsupportedEra),
}
Ok(self)
@ -696,7 +704,7 @@ impl BuiltTransaction {
pub fn remove_signature(mut self, pub_key: ed25519::PublicKey) -> Result<Self, TxBuilderError> {
match self.era {
BuilderEra::Babbage => {
BuilderEra::Conway => {
let mut new_sigs = self.signatures.unwrap_or_default();
let pk = Bytes32(
@ -722,6 +730,7 @@ impl BuiltTransaction {
self.tx_bytes = tx.encode_fragment().unwrap().into();
}
_ => return Err(TxBuilderError::UnsupportedEra),
}
Ok(self)