Skip to content

Commit e7c5cbe

Browse files
committed
Replaced redundand fields in tx-builder with one config field
1 parent 32008de commit e7c5cbe

File tree

2 files changed

+71
-61
lines changed

2 files changed

+71
-61
lines changed

rust/Cargo.lock

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/src/tx_builder.rs

Lines changed: 71 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ fn fake_full_tx(tx_builder: &TransactionBuilder, body: TransactionBody) -> Resul
129129

130130
fn min_fee(tx_builder: &TransactionBuilder) -> Result<Coin, JsError> {
131131
let full_tx = fake_full_tx(tx_builder, tx_builder.build()?)?;
132-
fees::min_fee(&full_tx, &tx_builder.fee_algo)
132+
fees::min_fee(&full_tx, &tx_builder.config.fee_algo)
133133
}
134134

135135

@@ -153,15 +153,23 @@ pub enum CoinSelectionStrategyCIP2 {
153153
RandomImprove,
154154
}
155155

156+
#[wasm_bindgen]
157+
#[derive(Clone, Builder, Debug)]
158+
pub struct TransactionBuilderConfig {
159+
fee_algo: fees::LinearFee,
160+
pool_deposit: BigNum, // protocol parameter
161+
key_deposit: BigNum, // protocol parameter
162+
max_value_size: u32, // protocol parameter
163+
max_tx_size: u32, // protocol parameter
164+
coins_per_utxo_word: Coin, // protocol parameter
165+
#[builder(default = "false")]
166+
prefer_pure_change: bool,
167+
}
168+
156169
#[wasm_bindgen]
157170
#[derive(Clone, Debug)]
158171
pub struct TransactionBuilder {
159-
coins_per_utxo_word: BigNum,
160-
pool_deposit: BigNum,
161-
key_deposit: BigNum,
162-
max_value_size: u32,
163-
max_tx_size: u32,
164-
fee_algo: fees::LinearFee,
172+
config: TransactionBuilderConfig,
165173
inputs: Vec<TxBuilderInput>,
166174
outputs: TransactionOutputs,
167175
fee: Option<Coin>,
@@ -173,20 +181,6 @@ pub struct TransactionBuilder {
173181
input_types: MockWitnessSet,
174182
mint: Option<Mint>,
175183
inputs_auto_added: bool,
176-
prefer_pure_change: bool,
177-
}
178-
179-
#[wasm_bindgen]
180-
#[derive(Clone, Builder, Debug)]
181-
pub struct TransactionBuilderConfig {
182-
linear_fee: fees::LinearFee,
183-
pool_deposit: BigNum, // protocol parameter
184-
key_deposit: BigNum, // protocol parameter
185-
max_value_size: u32, // protocol parameter
186-
max_tx_size: u32, // protocol parameter
187-
coins_per_utxo_word: Coin, // protocol parameter
188-
#[builder(default = "false")]
189-
prefer_pure_change: bool,
190184
}
191185

192186
#[wasm_bindgen]
@@ -430,25 +424,32 @@ impl TransactionBuilder {
430424
address: &Address,
431425
multiasset: &MultiAsset,
432426
) -> Result<(), JsError> {
433-
let min_possible_coin = min_pure_ada(&self.coins_per_utxo_word)?;
427+
let min_possible_coin = min_pure_ada(&self.config.coins_per_utxo_word)?;
434428
let mut value = Value::new(&min_possible_coin);
435429
value.set_multiasset(multiasset);
436-
let required_coin =
437-
min_ada_required(&value, false, &self.coins_per_utxo_word)?;
430+
let required_coin = min_ada_required(
431+
&value,
432+
false,
433+
&self.config.coins_per_utxo_word,
434+
)?;
438435
self.add_output_coin_and_asset(address, &required_coin, multiasset)
439436
}
440437

441438
/// Add explicit output via a TransactionOutput object
442439
pub fn add_output(&mut self, output: &TransactionOutput) -> Result<(), JsError> {
443440
let value_size = output.amount.to_bytes().len();
444-
if value_size > self.max_value_size as usize {
441+
if value_size > self.config.max_value_size as usize {
445442
return Err(JsError::from_str(&format!(
446443
"Maximum value size of {} exceeded. Found: {}",
447-
self.max_value_size,
444+
self.config.max_value_size,
448445
value_size
449446
)));
450447
}
451-
let min_ada = min_ada_required(&output.amount(), false, &self.coins_per_utxo_word)?;
448+
let min_ada = min_ada_required(
449+
&output.amount(),
450+
false,
451+
&self.config.coins_per_utxo_word,
452+
)?;
452453
if output.amount().coin() < min_ada {
453454
Err(JsError::from_str(&format!(
454455
"Value {} less than the minimum UTXO value {}",
@@ -628,20 +629,9 @@ impl TransactionBuilder {
628629
self.add_output_asset_and_min_required_coin(address, &multiasset)
629630
}
630631

631-
/// If set to true, add_change_if_needed will try
632-
/// to put pure Coin in a separate output from assets
633-
pub fn set_prefer_pure_change(&mut self, prefer_pure_change: bool) {
634-
self.prefer_pure_change = prefer_pure_change;
635-
}
636-
637632
pub fn new(cfg: &TransactionBuilderConfig) -> Self {
638633
Self {
639-
coins_per_utxo_word: cfg.coins_per_utxo_word.clone(),
640-
key_deposit: cfg.key_deposit.clone(),
641-
pool_deposit: cfg.pool_deposit.clone(),
642-
max_value_size: cfg.max_value_size,
643-
max_tx_size: cfg.max_tx_size,
644-
fee_algo: cfg.linear_fee.clone(),
634+
config: cfg.clone(),
645635
inputs: Vec::new(),
646636
outputs: TransactionOutputs::new(),
647637
fee: None,
@@ -657,7 +647,6 @@ impl TransactionBuilder {
657647
validity_start_interval: None,
658648
mint: None,
659649
inputs_auto_added: false,
660-
prefer_pure_change: cfg.prefer_pure_change,
661650
}
662651
}
663652

@@ -675,8 +664,8 @@ impl TransactionBuilder {
675664
internal_get_implicit_input(
676665
&self.withdrawals,
677666
&self.certs,
678-
&self.pool_deposit,
679-
&self.key_deposit,
667+
&self.config.pool_deposit,
668+
&self.config.key_deposit,
680669
)
681670
}
682671

@@ -709,8 +698,8 @@ impl TransactionBuilder {
709698
pub fn get_deposit(&self) -> Result<Coin, JsError> {
710699
internal_get_deposit(
711700
&self.certs,
712-
&self.pool_deposit,
713-
&self.key_deposit,
701+
&self.config.pool_deposit,
702+
&self.config.key_deposit,
714703
)
715704
}
716705

@@ -800,17 +789,25 @@ impl TransactionBuilder {
800789
let mut new_fee = fee.clone();
801790
// we might need multiple change outputs for cases where the change has many asset types
802791
// which surpass the max UTXO size limit
803-
let minimum_utxo_val = min_pure_ada(&self.coins_per_utxo_word)?;
792+
let minimum_utxo_val = min_pure_ada(&self.config.coins_per_utxo_word)?;
804793
while let Some(Ordering::Greater) = change_left.multiasset.as_ref().map_or_else(|| None, |ma| ma.partial_cmp(&MultiAsset::new())) {
805-
let nft_change = pack_nfts_for_change(self.max_value_size, address, &change_left)?;
794+
let nft_change = pack_nfts_for_change(
795+
self.config.max_value_size,
796+
address,
797+
&change_left,
798+
)?;
806799
if nft_change.len() == 0 {
807800
// this likely should never happen
808801
return Err(JsError::from_str("NFTs too large for change output"));
809802
}
810803
// we only add the minimum needed (for now) to cover this output
811804
let mut change_value = Value::new(&Coin::zero());
812805
change_value.set_multiasset(&nft_change);
813-
let min_ada = min_ada_required(&change_value, false, &self.coins_per_utxo_word)?;
806+
let min_ada = min_ada_required(
807+
&change_value,
808+
false,
809+
&self.config.coins_per_utxo_word,
810+
)?;
814811
change_value.set_coin(&min_ada);
815812
let change_output = TransactionOutput::new(address, &change_value);
816813
// increase fee
@@ -825,7 +822,7 @@ impl TransactionBuilder {
825822
change_left = change_left.checked_sub(&Value::new(&new_fee))?;
826823
// add potentially a separate pure ADA change output
827824
let left_above_minimum = change_left.coin.compare(&minimum_utxo_val) > 0;
828-
if self.prefer_pure_change && left_above_minimum {
825+
if self.config.prefer_pure_change && left_above_minimum {
829826
let pure_output = TransactionOutput::new(address, &change_left);
830827
let additional_fee = self.fee_for_output(&pure_output)?;
831828
let potential_pure_value = change_left.checked_sub(&Value::new(&additional_fee))?;
@@ -843,7 +840,11 @@ impl TransactionBuilder {
843840
}
844841
Ok(true)
845842
} else {
846-
let min_ada = min_ada_required(&change_estimator, false, &self.coins_per_utxo_word)?;
843+
let min_ada = min_ada_required(
844+
&change_estimator,
845+
false,
846+
&self.config.coins_per_utxo_word,
847+
)?;
847848
// no-asset case so we have no problem burning the rest if there is no other option
848849
fn burn_extra(builder: &mut TransactionBuilder, burn_amount: &BigNum) -> Result<bool, JsError> {
849850
// recall: min_fee assumed the fee was the maximum possible so we definitely have enough input to cover whatever fee it ends up being
@@ -926,10 +927,10 @@ impl TransactionBuilder {
926927
/// You can use `get_auxiliary_date` or `build_tx`
927928
pub fn build(&self) -> Result<TransactionBody, JsError> {
928929
let (body, full_tx_size) = self.build_and_size()?;
929-
if full_tx_size > self.max_tx_size as usize {
930+
if full_tx_size > self.config.max_tx_size as usize {
930931
Err(JsError::from_str(&format!(
931932
"Maximum transaction size of {} exceeded. Found: {}",
932-
self.max_tx_size,
933+
self.config.max_tx_size,
933934
full_tx_size
934935
)))
935936
} else {
@@ -1016,7 +1017,7 @@ mod tests {
10161017
coins_per_utxo_word: u64,
10171018
) -> TransactionBuilder {
10181019
let cfg = TransactionBuilderConfigBuilder::default()
1019-
.linear_fee(linear_fee.clone())
1020+
.fee_algo(linear_fee.clone())
10201021
.pool_deposit(to_bignum(pool_deposit))
10211022
.key_deposit(to_bignum(key_deposit))
10221023
.max_value_size(max_val_size)
@@ -1053,6 +1054,19 @@ mod tests {
10531054
create_tx_builder(linear_fee, 1, 1, 1)
10541055
}
10551056

1057+
fn create_tx_builder_with_fee_and_pure_change(linear_fee: &LinearFee) -> TransactionBuilder {
1058+
TransactionBuilder::new(&TransactionBuilderConfigBuilder::default()
1059+
.fee_algo(linear_fee.clone())
1060+
.pool_deposit(to_bignum(1))
1061+
.key_deposit(to_bignum(1))
1062+
.max_value_size(MAX_VALUE_SIZE)
1063+
.max_tx_size(MAX_TX_SIZE)
1064+
.coins_per_utxo_word(to_bignum(1))
1065+
.prefer_pure_change(true)
1066+
.build()
1067+
.unwrap())
1068+
}
1069+
10561070
fn create_tx_builder_with_key_deposit(deposit: u64) -> TransactionBuilder {
10571071
create_tx_builder(&create_default_linear_fee(), 1, 1, deposit)
10581072
}
@@ -1760,9 +1774,8 @@ mod tests {
17601774
fn build_tx_with_native_assets_change_and_purification() {
17611775
let minimum_utxo_value = to_bignum(1);
17621776
let coin_per_utxo_word = to_bignum(1);
1763-
let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(0, 1));
17641777
// Prefer pure change!
1765-
tx_builder.set_prefer_pure_change(true);
1778+
let mut tx_builder = create_tx_builder_with_fee_and_pure_change(&create_linear_fee(0, 1));
17661779
let spend = root_key_15()
17671780
.derive(harden(1852))
17681781
.derive(harden(1815))
@@ -1888,9 +1901,8 @@ mod tests {
18881901
#[test]
18891902
fn build_tx_with_native_assets_change_and_no_purification_cuz_not_enough_pure_coin() {
18901903
let minimum_utxo_value = to_bignum(10);
1891-
let mut tx_builder = create_tx_builder_with_fee(&create_linear_fee(1, 1));
18921904
// Prefer pure change!
1893-
tx_builder.set_prefer_pure_change(true);
1905+
let mut tx_builder = create_tx_builder_with_fee_and_pure_change(&create_linear_fee(1, 1));
18941906
let spend = root_key_15()
18951907
.derive(harden(1852))
18961908
.derive(harden(1815))
@@ -2464,7 +2476,7 @@ mod tests {
24642476
// we have a = 1 to test increasing fees when more inputs are added
24652477
let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0));
24662478
let cfg = TransactionBuilderConfigBuilder::default()
2467-
.linear_fee(linear_fee)
2479+
.fee_algo(linear_fee)
24682480
.pool_deposit(to_bignum(0))
24692481
.key_deposit(to_bignum(0))
24702482
.max_value_size(9999)
@@ -2491,7 +2503,7 @@ mod tests {
24912503
// we have a = 1 to test increasing fees when more inputs are added
24922504
let linear_fee = LinearFee::new(&to_bignum(1), &to_bignum(0));
24932505
let cfg = TransactionBuilderConfigBuilder::default()
2494-
.linear_fee(linear_fee)
2506+
.fee_algo(linear_fee)
24952507
.pool_deposit(to_bignum(0))
24962508
.key_deposit(to_bignum(0))
24972509
.max_value_size(9999)
@@ -3181,7 +3193,7 @@ mod tests {
31813193
mint.insert(&policy_id3, &mass);
31823194

31833195
let mint_len = mint.to_bytes().len();
3184-
let fee_coefficient = tx_builder.fee_algo.coefficient();
3196+
let fee_coefficient = tx_builder.config.fee_algo.coefficient();
31853197

31863198
let raw_mint_fee = fee_coefficient
31873199
.checked_mul(&to_bignum(mint_len as u64))

0 commit comments

Comments
 (0)