Repository: ordinals/ord (rust)

Issue:
Minting Off By 1 Error
If a mint starts on block 40, ord will not let you mint until that block has already passed. Meaning the first block ord allows you to mint in is actually block 41.

Pull request description:
Allow minting when mint begins next block
Fixes #3643.

Patch:
diff --git a/src/subcommand/wallet/mint.rs b/src/subcommand/wallet/mint.rs
index 1dd70a0e..281bdf5f 100644
--- a/src/subcommand/wallet/mint.rs
+++ b/src/subcommand/wallet/mint.rs
@@ -42,7 +42,7 @@ impl Mint {
     let postage = self.postage.unwrap_or(TARGET_POSTAGE);
 
     let amount = rune_entry
-      .mintable(block_height)
+      .mintable(block_height + 1)
       .map_err(|err| anyhow!("rune {rune} {err}"))?;
 
     let chain = wallet.chain();


Test patch:
diff --git a/tests/wallet/mint.rs b/tests/wallet/mint.rs
index 40f148c8..b3541613 100644
--- a/tests/wallet/mint.rs
+++ b/tests/wallet/mint.rs
@@ -489,3 +489,90 @@ fn minting_rune_with_postage_dust() {
   .expected_stderr("error: postage below dust limit of 330sat\n")
   .run_and_extract_stdout();
 }
+
+#[test]
+fn minting_is_allowed_when_mint_begins_next_block() {
+  let core = mockcore::builder().network(Network::Regtest).build();
+
+  let ord = TestServer::spawn_with_server_args(&core, &["--index-runes", "--regtest"], &[]);
+
+  core.mine_blocks(1);
+
+  create_wallet(&core, &ord);
+
+  batch(
+    &core,
+    &ord,
+    batch::File {
+      etching: Some(batch::Etching {
+        divisibility: 1,
+        rune: SpacedRune {
+          rune: Rune(RUNE),
+          spacers: 0,
+        },
+        premine: "0".parse().unwrap(),
+        symbol: '¢',
+        supply: "111.1".parse().unwrap(),
+        terms: Some(batch::Terms {
+          cap: 1,
+          offset: Some(batch::Range {
+            end: None,
+            start: Some(1),
+          }),
+          amount: "111.1".parse().unwrap(),
+          height: None,
+        }),
+        turbo: false,
+      }),
+      inscriptions: vec![batch::Entry {
+        file: Some("inscription.jpeg".into()),
+        ..default()
+      }],
+      ..default()
+    },
+  );
+
+  let output = CommandBuilder::new(format!(
+    "--chain regtest --index-runes wallet mint --fee-rate 1 --rune {}",
+    Rune(RUNE)
+  ))
+  .core(&core)
+  .ord(&ord)
+  .run_and_deserialize_output::<mint::Output>();
+
+  core.mine_blocks(1);
+
+  let balances = CommandBuilder::new("--regtest --index-runes balances")
+    .core(&core)
+    .ord(&ord)
+    .run_and_deserialize_output::<ord::subcommand::balances::Output>();
+
+  pretty_assert_eq!(
+    output.pile,
+    Pile {
+      amount: 1111,
+      divisibility: 1,
+      symbol: Some('¢'),
+    }
+  );
+
+  pretty_assert_eq!(
+    balances,
+    ord::subcommand::balances::Output {
+      runes: vec![(
+        output.rune,
+        vec![(
+          OutPoint {
+            txid: output.mint,
+            vout: 1
+          },
+          output.pile,
+        )]
+        .into_iter()
+        .collect()
+      ),]
+      .into_iter()
+      .collect(),
+    }
+  );
+}