get genesis timestamp from bitcoind

This commit is contained in:
pythcoiner 2024-02-03 06:38:39 +01:00
parent 3fcbb0b67d
commit f2c418f79a
4 changed files with 29 additions and 9 deletions

View File

@ -40,6 +40,8 @@ impl fmt::Display for BlockChainTip {
/// Our Bitcoin backend.
pub trait BitcoinInterface: Send {
fn genesis_block_timestamp(&self) -> u32;
fn genesis_block(&self) -> BlockChainTip;
/// Get the progress of the block chain synchronization.
@ -119,6 +121,15 @@ pub trait BitcoinInterface: Send {
}
impl BitcoinInterface for d::BitcoinD {
fn genesis_block_timestamp(&self) -> u32 {
self.get_block_stats(
self.get_block_hash(0)
.expect("Genesis block hash must always be there"),
)
.expect("Genesis block must always be there")
.time
}
fn genesis_block(&self) -> BlockChainTip {
let height = 0;
let hash = self
@ -370,6 +381,10 @@ impl BitcoinInterface for d::BitcoinD {
// FIXME: do we need to repeat the entire trait implemenation? Isn't there a nicer way?
impl BitcoinInterface for sync::Arc<sync::Mutex<dyn BitcoinInterface + 'static>> {
fn genesis_block_timestamp(&self) -> u32 {
self.lock().unwrap().genesis_block_timestamp()
}
fn genesis_block(&self) -> BlockChainTip {
self.lock().unwrap().genesis_block()
}

View File

@ -33,9 +33,6 @@ use miniscript::{
};
use serde::{Deserialize, Serialize};
// Timestamp in the header of the genesis block. Used for sanity checks.
const MAINNET_GENESIS_TIME: u32 = 1231006505;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CommandError {
NoOutpointForSelfSend,
@ -888,13 +885,14 @@ impl DaemonControl {
/// The date must be after the genesis block time and before the current tip blocktime.
pub fn start_rescan(&self, timestamp: u32) -> Result<(), CommandError> {
let mut db_conn = self.db.connection();
let genesis_timestamp = self.bitcoin.genesis_block_timestamp();
let future_timestamp = self
.bitcoin
.tip_time()
.map(|t| timestamp >= t)
.unwrap_or(false);
if timestamp < MAINNET_GENESIS_TIME || future_timestamp {
if timestamp < genesis_timestamp || future_timestamp {
return Err(CommandError::InsaneRescanTimestamp(timestamp));
}
if db_conn.rescan_timestamp().is_some() || self.bitcoin.rescan_progress().is_some() {

View File

@ -34,6 +34,10 @@ impl DummyBitcoind {
}
impl BitcoinInterface for DummyBitcoind {
fn genesis_block_timestamp(&self) -> u32 {
1231006505
}
fn genesis_block(&self) -> BlockChainTip {
let hash = bitcoin::BlockHash::from_str(
"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",

View File

@ -22,7 +22,7 @@ from test_framework.utils import (
def test_getinfo(lianad):
res = lianad.rpc.getinfo()
assert 'timestamp' in res.keys()
assert "timestamp" in res.keys()
assert res["version"] == "4.0.0-dev"
assert res["network"] == "regtest"
wait_for(lambda: lianad.rpc.getinfo()["block_height"] == 101)
@ -599,10 +599,15 @@ def test_start_rescan(lianad, bitcoind):
with pytest.raises(RpcError, match="Insane timestamp.*"):
lianad.rpc.startrescan(future_timestamp)
assert lianad.rpc.getinfo()["rescan_progress"] is None
prebitcoin_timestamp = 1231006505 - 1
block_hash = bitcoind.rpc.getblockhash(0)
genesis_timestamp = bitcoind.rpc.getblock(block_hash)["time"]
prebitcoin_timestamp = genesis_timestamp - 1
with pytest.raises(RpcError, match="Insane timestamp."):
lianad.rpc.startrescan(prebitcoin_timestamp)
assert lianad.rpc.getinfo()["rescan_progress"] is None
# we can rescan from genesis block
lianad.rpc.startrescan(genesis_timestamp)
wait_for(lambda: lianad.rpc.getinfo()["rescan_progress"] is None)
# First, get some coins
for _ in range(10):
@ -1232,9 +1237,7 @@ def test_rbfpsbt_cancel(lianad, bitcoind):
# But we can't set the feerate explicitly.
with pytest.raises(
RpcError,
match=re.escape(
"A feerate must not be provided if creating a cancel."
),
match=re.escape("A feerate must not be provided if creating a cancel."),
):
rbf_1_res = lianad.rpc.rbfpsbt(first_txid, True, 2)
rbf_1_psbt = PSBT.from_base64(rbf_1_res["psbt"])