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

Set fee #1150

Merged
merged 28 commits into from
Jan 12, 2023
Merged

Set fee #1150

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
94caf99
stash
raphjaph Dec 30, 2022
5570580
Merge branch 'master' of https://github.com/casey/ord into set-fee
raphjaph Dec 30, 2022
4def8a5
stash
raphjaph Jan 2, 2023
9cb6ba2
stash
raphjaph Jan 2, 2023
724526e
allow setting fee in inscribe and send
raphjaph Jan 2, 2023
e80e787
Merge remote-tracking branch 'upstream/master' into set-fee
raphjaph Jan 2, 2023
1e9fbb5
tweak
raphjaph Jan 2, 2023
539a201
stuck on test failing
raphjaph Jan 3, 2023
f66b024
stash
raphjaph Jan 3, 2023
3ebbd1e
trying and failing to merge properly
raphjaph Jan 6, 2023
8d14d16
Merge branch 'master' of https://github.com/casey/ord into set-fee
raphjaph Jan 9, 2023
b387fca
merging
raphjaph Jan 9, 2023
0b38ca6
merging
raphjaph Jan 9, 2023
360bfb8
up to date
raphjaph Jan 9, 2023
3f6d103
stash
raphjaph Jan 9, 2023
7696ee0
stash
raphjaph Jan 10, 2023
482eac7
Merge branch 'master' of https://github.com/casey/ord into set-fee
raphjaph Jan 10, 2023
b33f076
use taproot inputs for exact fee estimation
raphjaph Jan 10, 2023
d8e0d6c
placate clippy and fmt
raphjaph Jan 10, 2023
181b889
Merge remote-tracking branch 'upstream/master' into set-fee
raphjaph Jan 10, 2023
1ecb918
fixed tests
raphjaph Jan 10, 2023
b8d8659
stuff
raphjaph Jan 12, 2023
4386939
added fee rate test to integration tests
raphjaph Jan 12, 2023
17f5732
Merge remote-tracking branch 'upstream/master' into set-fee
raphjaph Jan 12, 2023
7e19e32
Merge remote-tracking branch 'upstream/master' into set-fee
raphjaph Jan 12, 2023
77f7cea
some more tests
raphjaph Jan 12, 2023
51ef0bd
small stuff
raphjaph Jan 12, 2023
70b3d59
merging
raphjaph Jan 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions src/fee_rate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use super::*;

#[derive(Debug, PartialEq, Clone, Copy)]
pub(crate) struct FeeRate(f64);

impl FromStr for FeeRate {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::try_from(f64::from_str(s)?)
}
}

impl TryFrom<f64> for FeeRate {
type Error = Error;

fn try_from(rate: f64) -> Result<Self, Self::Error> {
if rate.is_sign_negative() | rate.is_nan() | rate.is_infinite() {
bail!("invalid fee rate: {rate}")
}
Ok(Self(rate))
}
}

impl FeeRate {
pub(crate) fn fee(&self, vsize: usize) -> Amount {
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_sign_loss)]
Amount::from_sat((self.0 * vsize as f64).round() as u64)
}
}

raphjaph marked this conversation as resolved.
Show resolved Hide resolved
#[cfg(test)]
mod tests {
use super::*;

#[test]
fn parse() {
assert_eq!("1.1".parse::<FeeRate>().unwrap().0, 1.1);
assert_eq!("11.19".parse::<FeeRate>().unwrap().0, 11.19);
assert_eq!("11.1111".parse::<FeeRate>().unwrap().0, 11.1111);
assert!("-4.2".parse::<FeeRate>().is_err());
assert!(FeeRate::try_from(f64::INFINITY).is_err());
assert!(FeeRate::try_from(f64::NAN).is_err());
}

#[test]
fn fee() {
assert_eq!(
"2.5".parse::<FeeRate>().unwrap().fee(100),
Amount::from_sat(250)
);
assert_eq!(
"2.0".parse::<FeeRate>().unwrap().fee(1024),
Amount::from_sat(2048)
);
assert_eq!(
"1.1".parse::<FeeRate>().unwrap().fee(100),
Amount::from_sat(110)
);
assert_eq!(
"1.0".parse::<FeeRate>().unwrap().fee(123456789),
Amount::from_sat(123456789)
);
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ mod content;
mod decimal;
mod degree;
mod epoch;
mod fee_rate;
mod height;
mod index;
mod inscription;
Expand Down
3 changes: 2 additions & 1 deletion src/subcommand/preview.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::*;
use {super::*, fee_rate::FeeRate};

#[derive(Debug, Parser)]
pub(crate) struct Preview {
Expand Down Expand Up @@ -77,6 +77,7 @@ impl Preview {
options: options.clone(),
subcommand: Subcommand::Wallet(super::wallet::Wallet::Inscribe(
super::wallet::inscribe::Inscribe {
fee_rate: FeeRate::try_from(1.0).unwrap(),
file,
no_backup: true,
satpoint: None,
Expand Down
2 changes: 1 addition & 1 deletion src/subcommand/wallet.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use {super::*, transaction_builder::TransactionBuilder};
use {super::*, fee_rate::FeeRate, transaction_builder::TransactionBuilder};

mod balance;
pub(crate) mod create;
Expand Down
67 changes: 64 additions & 3 deletions src/subcommand/wallet/inscribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ use {
pub(crate) struct Inscribe {
#[clap(long, help = "Inscribe <SATPOINT>")]
pub(crate) satpoint: Option<SatPoint>,
#[clap(
long,
default_value = "1.0",
help = "Use fee rate of <FEE_RATE> sats/vB"
)]
pub(crate) fee_rate: FeeRate,
#[clap(help = "Inscribe sat with contents of <FILE>")]
pub(crate) file: PathBuf,
#[clap(long, help = "Do not back up recovery key.")]
Expand Down Expand Up @@ -52,6 +58,7 @@ impl Inscribe {
utxos,
commit_tx_change,
reveal_tx_destination,
self.fee_rate,
)?;

if !self.no_backup {
Expand Down Expand Up @@ -83,6 +90,7 @@ impl Inscribe {
utxos: BTreeMap<OutPoint, Amount>,
change: Vec<Address>,
destination: Address,
fee_rate: FeeRate,
) -> Result<(Transaction, Transaction, TweakedKeyPair)> {
let satpoint = if let Some(satpoint) = satpoint {
satpoint
Expand Down Expand Up @@ -143,6 +151,7 @@ impl Inscribe {
utxos,
commit_tx_address.clone(),
change,
fee_rate,
)?;

let (vout, output) = unsigned_commit_tx
Expand Down Expand Up @@ -181,7 +190,7 @@ impl Inscribe {
reveal_tx.input[0].witness.push(&reveal_script);
reveal_tx.input[0].witness.push(&control_block.serialize());

TransactionBuilder::TARGET_FEE_RATE * reveal_tx.vsize().try_into().unwrap()
fee_rate.fee(reveal_tx.vsize())
};

reveal_tx.output[0].value = reveal_tx.output[0]
Expand Down Expand Up @@ -279,10 +288,13 @@ mod tests {
utxos.into_iter().collect(),
vec![commit_address, change(1)],
reveal_address,
FeeRate::try_from(1.0).unwrap(),
)
.unwrap();

let fee = TransactionBuilder::TARGET_FEE_RATE * reveal_tx.vsize().try_into().unwrap();
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_sign_loss)]
let fee = Amount::from_sat((1.0 * (reveal_tx.vsize() as f64)).ceil() as u64);
raphjaph marked this conversation as resolved.
Show resolved Hide resolved

assert_eq!(
reveal_tx.output[0].value,
Expand All @@ -306,6 +318,7 @@ mod tests {
utxos.into_iter().collect(),
vec![commit_address, change(1)],
reveal_address,
FeeRate::try_from(1.0).unwrap(),
)
.unwrap_err()
.to_string()
Expand All @@ -314,7 +327,7 @@ mod tests {

#[test]
fn reveal_transaction_would_create_dust() {
let utxos = vec![(outpoint(1), Amount::from_sat(600))];
let utxos = vec![(outpoint(1), Amount::from_sat(500))];
let inscription = inscription("text/plain", "ord");
let satpoint = Some(satpoint(1, 0));
let commit_address = change(0);
Expand All @@ -328,6 +341,7 @@ mod tests {
utxos.into_iter().collect(),
vec![commit_address, change(1)],
reveal_address,
FeeRate::try_from(1.0).unwrap(),
)
.unwrap_err()
.to_string();
Expand All @@ -354,6 +368,7 @@ mod tests {
utxos.into_iter().collect(),
vec![commit_address, change(1)],
reveal_address,
FeeRate::try_from(1.0).unwrap(),
)
.unwrap();

Expand Down Expand Up @@ -386,6 +401,7 @@ mod tests {
utxos.into_iter().collect(),
vec![commit_address, change(1)],
reveal_address,
FeeRate::try_from(1.0).unwrap(),
)
.unwrap_err()
.to_string();
Expand Down Expand Up @@ -425,7 +441,52 @@ mod tests {
utxos.into_iter().collect(),
vec![commit_address, change(1)],
reveal_address,
FeeRate::try_from(1.0).unwrap(),
)
.is_ok())
}

#[test]
fn inscribe_with_custom_fee_rate() {
let utxos = vec![
(outpoint(1), Amount::from_sat(10_000)),
(outpoint(2), Amount::from_sat(10_000)),
];
let mut inscriptions = BTreeMap::new();
inscriptions.insert(
SatPoint {
outpoint: outpoint(1),
offset: 0,
},
Txid::from_str("06413a3ef4232f0485df2bc7c912c13c05c69f967c19639344753e05edb64bd5").unwrap(),
);

let inscription = inscription("text/plain", "ord");
let satpoint = None;
let commit_address = change(0);
let reveal_address = recipient();
let fee_rate = 3.3;

let (commit_tx, reveal_tx, _private_key) = Inscribe::create_inscription_transactions(
satpoint,
inscription,
inscriptions,
bitcoin::Network::Signet,
utxos.into_iter().collect(),
vec![commit_address, change(1)],
reveal_address,
FeeRate::try_from(fee_rate).unwrap(),
)
.unwrap();

let fee = FeeRate::try_from(fee_rate)
.unwrap()
.fee(reveal_tx.vsize())
.to_sat();

assert_eq!(
reveal_tx.output[0].value,
10_000 - fee - (10_000 - commit_tx.output[0].value),
);
}
}
7 changes: 7 additions & 0 deletions src/subcommand/wallet/send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ use super::*;
pub(crate) struct Send {
address: Address,
outgoing: Outgoing,
#[clap(
long,
default_value = "1.0",
help = "Use fee rate of <FEE_RATE> sats/vB"
)]
fee_rate: FeeRate,
}

impl Send {
Expand Down Expand Up @@ -70,6 +76,7 @@ impl Send {
unspent_outputs,
self.address,
change,
self.fee_rate,
)?;

let signed_tx = client
Expand Down
Loading