Skip to content

Commit

Permalink
Lock runes commit output (ordinals#3504)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph authored Apr 15, 2024
1 parent 6cfd9d0 commit c9f793c
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 14 deletions.
6 changes: 3 additions & 3 deletions crates/mockcore/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -774,11 +774,12 @@ impl Api for Server {
}

fn list_lock_unspent(&self) -> Result<Vec<JsonOutPoint>, jsonrpc_core::Error> {
let state = self.state();
Ok(
self
.state()
state
.locked
.iter()
.filter(|outpoint| state.utxos.contains_key(outpoint))
.map(|outpoint| (*outpoint).into())
.collect(),
)
Expand Down Expand Up @@ -890,7 +891,6 @@ impl Api for Server {
vout: output.vout,
txid: output.txid,
};
assert!(state.utxos.contains_key(&output));
assert!(state.locked.insert(output));
}

Expand Down
7 changes: 7 additions & 0 deletions src/wallet/batch/plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ impl Plan {
) -> SubcommandResult {
let Transactions {
commit_tx,
commit_vout,
reveal_tx,
recovery_key_pair,
total_fees,
Expand Down Expand Up @@ -128,6 +129,11 @@ impl Plan {
.send_raw_transaction(&signed_commit_tx)?;

if let Some(ref rune_info) = rune {
wallet.bitcoin_client().lock_unspent(&[OutPoint {
txid: commit_txid,
vout: commit_vout.try_into().unwrap(),
}])?;

let commit = consensus::encode::deserialize::<Transaction>(&signed_commit_tx)?;
let reveal = consensus::encode::deserialize::<Transaction>(&signed_reveal_tx)?;

Expand Down Expand Up @@ -657,6 +663,7 @@ impl Plan {

Ok(Transactions {
commit_tx: unsigned_commit_tx,
commit_vout: vout,
recovery_key_pair,
reveal_tx,
rune,
Expand Down
1 change: 1 addition & 0 deletions src/wallet/batch/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::*;
pub(crate) struct Transactions {
pub(crate) rune: Option<RuneInfo>,
pub(crate) commit_tx: Transaction,
pub(crate) commit_vout: usize,
pub(crate) recovery_key_pair: TweakedKeyPair,
pub(crate) reveal_tx: Transaction,
pub(crate) total_fees: u64,
Expand Down
107 changes: 96 additions & 11 deletions tests/wallet/resume.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ fn wallet_resume() {
.read_line(&mut buffer)
.unwrap();

assert_regex_match!(buffer, "Waiting for rune commitment .* to mature…\n");
assert_regex_match!(
buffer,
"Waiting for rune commitment [[:xdigit:]]{64} to mature…\n"
);

core.mine_blocks(1);

Expand Down Expand Up @@ -87,12 +90,14 @@ fn wallet_resume() {
.spawn();

let mut buffer = String::new();
let mut reader = BufReader::new(spawn.child.stderr.as_mut().unwrap());

BufReader::new(spawn.child.stderr.as_mut().unwrap())
.read_line(&mut buffer)
.unwrap();
reader.read_line(&mut buffer).unwrap();

assert_regex_match!(buffer, "Waiting for rune commitment .* to mature…\n");
assert_regex_match!(
buffer,
"Waiting for rune commitment [[:xdigit:]]{64} to mature…\n"
);

let output = spawn.run_and_deserialize_output::<ord::subcommand::wallet::resume::ResumeOutput>();

Expand Down Expand Up @@ -160,7 +165,10 @@ fn resume_suspended() {
.read_line(&mut buffer)
.unwrap();

assert_regex_match!(buffer, "Waiting for rune commitment .* to mature…\n");
assert_regex_match!(
buffer,
"Waiting for rune commitment [[:xdigit:]]{64} to mature…\n"
);

core.mine_blocks(1);

Expand Down Expand Up @@ -206,15 +214,89 @@ fn resume_suspended() {
)
.unwrap();

let mut buffer = String::new();
let mut reader = BufReader::new(spawn.child.stderr.as_mut().unwrap());
reader.read_line(&mut buffer).unwrap();

assert_eq!(
buffer,
"Shutting down gracefully. Press <CTRL-C> again to shutdown immediately.\n"
);

buffer.clear();
reader.read_line(&mut buffer).unwrap();

assert_eq!(
buffer,
"Suspending batch. Run `ord wallet resume` to continue.\n"
);

let output = spawn.run_and_deserialize_output::<ord::subcommand::wallet::resume::ResumeOutput>();

assert!(!output.etchings.first().unwrap().reveal_broadcast);
}

#[test]
fn commitment_output_is_locked() {
let core = mockcore::builder().network(Network::Regtest).build();

let ord = TestServer::spawn_with_server_args(&core, &["--regtest", "--index-runes"], &[]);

create_wallet(&core, &ord);

core.mine_blocks(1);

let batchfile = batch::File {
etching: Some(batch::Etching {
divisibility: 0,
rune: SpacedRune {
rune: Rune(RUNE),
spacers: 0,
},
supply: "1000".parse().unwrap(),
premine: "1000".parse().unwrap(),
symbol: '¢',
..default()
}),
inscriptions: vec![batch::Entry {
file: Some("inscription.jpeg".into()),
..default()
}],
..default()
};

let tempdir = Arc::new(TempDir::new().unwrap());

let mut spawn =
CommandBuilder::new("--regtest --index-runes wallet batch --fee-rate 0 --batch batch.yaml")
.temp_dir(tempdir.clone())
.write("batch.yaml", serde_yaml::to_string(&batchfile).unwrap())
.write("inscription.jpeg", "inscription")
.core(&core)
.ord(&ord)
.expected_exit_code(1)
.spawn();

let mut buffer = String::new();
BufReader::new(spawn.child.stderr.as_mut().unwrap())
.read_line(&mut buffer)
.unwrap();

assert_eq!(
assert_regex_match!(
buffer,
"Shutting down gracefully. Press <CTRL-C> again to shutdown immediately.\n"
"Waiting for rune commitment [[:xdigit:]]{64} to mature…\n"
);

let commitment = core.mempool()[0].txid();

core.mine_blocks(1);

signal::kill(
Pid::from_raw(spawn.child.id().try_into().unwrap()),
Signal::SIGINT,
)
.unwrap();

buffer.clear();

BufReader::new(spawn.child.stderr.as_mut().unwrap())
Expand All @@ -223,10 +305,13 @@ fn resume_suspended() {

assert_eq!(
buffer,
"Suspending batch. Run `ord wallet resume` to continue.\n"
"Shutting down gracefully. Press <CTRL-C> again to shutdown immediately.\n"
);

let output = spawn.run_and_deserialize_output::<ord::subcommand::wallet::resume::ResumeOutput>();
spawn.child.wait().unwrap();

assert!(!output.etchings.first().unwrap().reveal_broadcast);
assert!(core.get_locked().contains(&OutPoint {
txid: commitment,
vout: 0
}));
}

0 comments on commit c9f793c

Please sign in to comment.