Skip to content

Commit

Permalink
Add ability to specify sat to batch inscribe (ordinals#2770)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph authored Nov 29, 2023
1 parent 9281108 commit 37a7b34
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 23 deletions.
3 changes: 3 additions & 0 deletions batch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ parent: 6ac5cacb768794f4fd7a78bf00f2074891fce68bd65c4ff36e77177237aacacai0
# postage for each inscription:
postage: 12345

# sat to inscribe on, can only be used with `same-sat`:
# sat: 5000000000

# inscriptions to inscribe
#
# each inscription has the following fields:
Expand Down
37 changes: 23 additions & 14 deletions src/subcommand/wallet/inscribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,20 +117,6 @@ impl Inscribe {
let index = Index::open(&options)?;
index.update()?;

let satpoint = if let Some(sat) = self.sat {
if !index.has_sat_index() {
return Err(anyhow!(
"index must be built with `--index-sats` to use `--sat`"
));
}
match index.find(sat)? {
Some(satpoint) => Some(satpoint),
None => return Err(anyhow!(format!("could not find sat {}", sat))),
}
} else {
self.satpoint
};

let utxos = index.get_unspent_outputs(Wallet::load(&options)?)?;

let locked_utxos = index.get_locked_outputs(Wallet::load(&options)?)?;
Expand All @@ -144,6 +130,7 @@ impl Inscribe {
let inscriptions;
let mode;
let parent_info;
let sat;

match (self.file, self.batch) {
(Some(file), None) => {
Expand All @@ -163,6 +150,8 @@ impl Inscribe {

mode = Mode::SeparateOutputs;

sat = self.sat;

destinations = vec![match self.destination.clone() {
Some(destination) => destination.require_network(chain.network())?,
None => get_change_address(&client, chain)?,
Expand All @@ -188,10 +177,30 @@ impl Inscribe {
)?;

mode = batchfile.mode;

if batchfile.sat.is_some() && mode != Mode::SameSat {
return Err(anyhow!("`sat` can only be set in `same-sat` mode"));
}

sat = batchfile.sat;
}
_ => unreachable!(),
}

let satpoint = if let Some(sat) = sat {
if !index.has_sat_index() {
return Err(anyhow!(
"index must be built with `--index-sats` to use `--sat`"
));
}
match index.find(sat)? {
Some(satpoint) => Some(satpoint),
None => return Err(anyhow!(format!("could not find sat `{sat}`"))),
}
} else {
self.satpoint
};

Batch {
commit_fee_rate: self.commit_fee_rate.unwrap_or(self.fee_rate),
destinations,
Expand Down
9 changes: 1 addition & 8 deletions src/subcommand/wallet/inscribe/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,6 @@ impl Batch {
.all(|inscription| inscription.parent().unwrap() == parent_info.id))
}

if self.satpoint.is_some() {
assert_eq!(
self.inscriptions.len(),
1,
"invariant: satpoint may only be specified when making a single inscription",
);
}

match self.mode {
Mode::SameSat => assert_eq!(
self.destinations.len(),
Expand Down Expand Up @@ -563,6 +555,7 @@ pub(crate) struct Batchfile {
pub(crate) mode: Mode,
pub(crate) parent: Option<InscriptionId>,
pub(crate) postage: Option<u64>,
pub(crate) sat: Option<Sat>,
}

impl Batchfile {
Expand Down
65 changes: 64 additions & 1 deletion tests/wallet/inscribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1620,6 +1620,69 @@ fn inscribe_with_sat_arg_fails_if_no_index_or_not_found() {
.write("foo.txt", "FOO")
.rpc_server(&rpc_server)
.expected_exit_code(1)
.expected_stderr("error: could not find sat 5000000000\n")
.expected_stderr("error: could not find sat `5000000000`\n")
.run_and_extract_stdout();
}

#[test]
fn batch_inscribe_with_sat_argument_with_parent() {
let rpc_server = test_bitcoincore_rpc::spawn();
rpc_server.mine_blocks(1);

assert_eq!(rpc_server.descriptors().len(), 0);

create_wallet(&rpc_server);

let parent_output =
CommandBuilder::new("--index-sats wallet inscribe --fee-rate 5.0 --file parent.png")
.write("parent.png", [1; 520])
.rpc_server(&rpc_server)
.run_and_deserialize_output::<Inscribe>();

rpc_server.mine_blocks(1);

assert_eq!(rpc_server.descriptors().len(), 3);

let parent_id = parent_output.inscriptions[0].id;

let output = CommandBuilder::new("--index-sats wallet inscribe --fee-rate 1 --batch batch.yaml")
.write("inscription.txt", "Hello World")
.write("tulip.png", [0; 555])
.write("meow.wav", [0; 2048])
.write(
"batch.yaml",
format!("parent: {parent_id}\nmode: same-sat\nsat: 5000111111\ninscriptions:\n- file: inscription.txt\n- file: tulip.png\n- file: meow.wav\n")
)
.rpc_server(&rpc_server)
.run_and_deserialize_output::<Inscribe>();

rpc_server.mine_blocks(1);

TestServer::spawn_with_args(&rpc_server, &["--index-sats"]).assert_response_regex(
"/sat/5000111111",
format!(
".*<a href=/inscription/{}>.*<a href=/inscription/{}>.*<a href=/inscription/{}>.*",
output.inscriptions[0].id, output.inscriptions[1].id, output.inscriptions[2].id
),
);
}

#[test]
fn batch_inscribe_with_sat_arg_fails_if_wrong_mode() {
let rpc_server = test_bitcoincore_rpc::spawn();
create_wallet(&rpc_server);
rpc_server.mine_blocks(1);

CommandBuilder::new("wallet inscribe --fee-rate 1 --batch batch.yaml")
.write("inscription.txt", "Hello World")
.write("tulip.png", [0; 555])
.write("meow.wav", [0; 2048])
.write(
"batch.yaml",
"mode: shared-output\nsat: 5000111111\ninscriptions:\n- file: inscription.txt\n- file: tulip.png\n- file: meow.wav\n"
)
.rpc_server(&rpc_server)
.expected_exit_code(1)
.expected_stderr("error: `sat` can only be set in `same-sat` mode\n")
.run_and_extract_stdout();
}

0 comments on commit 37a7b34

Please sign in to comment.