Skip to content

Commit 3eef53d

Browse files
author
pythcoiner
committed
get genesis timestamp from bitcoind
1 parent 3fcbb0b commit 3eef53d

File tree

4 files changed

+26
-9
lines changed

4 files changed

+26
-9
lines changed

src/bitcoin/mod.rs

+15
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ impl fmt::Display for BlockChainTip {
4040

4141
/// Our Bitcoin backend.
4242
pub trait BitcoinInterface: Send {
43+
fn genesis_block_timestamp(&self) -> u32;
44+
4345
fn genesis_block(&self) -> BlockChainTip;
4446

4547
/// Get the progress of the block chain synchronization.
@@ -119,6 +121,15 @@ pub trait BitcoinInterface: Send {
119121
}
120122

121123
impl BitcoinInterface for d::BitcoinD {
124+
fn genesis_block_timestamp(&self) -> u32 {
125+
self.get_block_stats(
126+
self.get_block_hash(0)
127+
.expect("Genesis block hash must always be there"),
128+
)
129+
.expect("Genesis block must always be there")
130+
.time
131+
}
132+
122133
fn genesis_block(&self) -> BlockChainTip {
123134
let height = 0;
124135
let hash = self
@@ -370,6 +381,10 @@ impl BitcoinInterface for d::BitcoinD {
370381

371382
// FIXME: do we need to repeat the entire trait implemenation? Isn't there a nicer way?
372383
impl BitcoinInterface for sync::Arc<sync::Mutex<dyn BitcoinInterface + 'static>> {
384+
fn genesis_block_timestamp(&self) -> u32 {
385+
self.lock().unwrap().genesis_block_timestamp()
386+
}
387+
373388
fn genesis_block(&self) -> BlockChainTip {
374389
self.lock().unwrap().genesis_block()
375390
}

src/commands/mod.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ use miniscript::{
3333
};
3434
use serde::{Deserialize, Serialize};
3535

36-
// Timestamp in the header of the genesis block. Used for sanity checks.
37-
const MAINNET_GENESIS_TIME: u32 = 1231006505;
38-
3936
#[derive(Debug, Clone, PartialEq, Eq)]
4037
pub enum CommandError {
4138
NoOutpointForSelfSend,
@@ -888,13 +885,14 @@ impl DaemonControl {
888885
/// The date must be after the genesis block time and before the current tip blocktime.
889886
pub fn start_rescan(&self, timestamp: u32) -> Result<(), CommandError> {
890887
let mut db_conn = self.db.connection();
888+
let genesis_timestamp = self.bitcoin.genesis_block_timestamp();
891889

892890
let future_timestamp = self
893891
.bitcoin
894892
.tip_time()
895893
.map(|t| timestamp >= t)
896894
.unwrap_or(false);
897-
if timestamp < MAINNET_GENESIS_TIME || future_timestamp {
895+
if timestamp < genesis_timestamp || future_timestamp {
898896
return Err(CommandError::InsaneRescanTimestamp(timestamp));
899897
}
900898
if db_conn.rescan_timestamp().is_some() || self.bitcoin.rescan_progress().is_some() {

src/testutils.rs

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ impl DummyBitcoind {
3434
}
3535

3636
impl BitcoinInterface for DummyBitcoind {
37+
fn genesis_block_timestamp(&self) -> u32 {
38+
1231006505
39+
}
40+
3741
fn genesis_block(&self) -> BlockChainTip {
3842
let hash = bitcoin::BlockHash::from_str(
3943
"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",

tests/test_rpc.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
def test_getinfo(lianad):
2424
res = lianad.rpc.getinfo()
25-
assert 'timestamp' in res.keys()
25+
assert "timestamp" in res.keys()
2626
assert res["version"] == "4.0.0-dev"
2727
assert res["network"] == "regtest"
2828
wait_for(lambda: lianad.rpc.getinfo()["block_height"] == 101)
@@ -599,7 +599,9 @@ def all_spent(coins):
599599
with pytest.raises(RpcError, match="Insane timestamp.*"):
600600
lianad.rpc.startrescan(future_timestamp)
601601
assert lianad.rpc.getinfo()["rescan_progress"] is None
602-
prebitcoin_timestamp = 1231006505 - 1
602+
block_hash = bitcoind.rpc.getblockhash(0)
603+
genesis_timestamp = bitcoind.rpc.getblock(block_hash)["time"]
604+
prebitcoin_timestamp = genesis_timestamp - 1
603605
with pytest.raises(RpcError, match="Insane timestamp."):
604606
lianad.rpc.startrescan(prebitcoin_timestamp)
605607
assert lianad.rpc.getinfo()["rescan_progress"] is None
@@ -1232,9 +1234,7 @@ def test_rbfpsbt_cancel(lianad, bitcoind):
12321234
# But we can't set the feerate explicitly.
12331235
with pytest.raises(
12341236
RpcError,
1235-
match=re.escape(
1236-
"A feerate must not be provided if creating a cancel."
1237-
),
1237+
match=re.escape("A feerate must not be provided if creating a cancel."),
12381238
):
12391239
rbf_1_res = lianad.rpc.rbfpsbt(first_txid, True, 2)
12401240
rbf_1_psbt = PSBT.from_base64(rbf_1_res["psbt"])

0 commit comments

Comments
 (0)