Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor test api #82

Merged
merged 11 commits into from
Feb 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,17 +258,21 @@ impl Index {
let rtx = self.database.begin_read()?;
let outpoint_to_ordinal_ranges: ReadOnlyTable<[u8], [u8]> =
rtx.open_table(Self::OUTPOINT_TO_ORDINAL_RANGES)?;

let mut key = Vec::new();
outpoint.consensus_encode(&mut key)?;

let ordinal_ranges = outpoint_to_ordinal_ranges
.get(key.as_slice())?
.ok_or("Could not find outpoint in index")?;

let mut output = Vec::new();
for chunk in ordinal_ranges.to_value().chunks_exact(16) {
let start = u64::from_le_bytes(chunk[0..8].try_into().unwrap());
let end = u64::from_le_bytes(chunk[8..16].try_into().unwrap());
output.push((start, end));
}

Ok(output)
}
}
18 changes: 16 additions & 2 deletions tests/find.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ fn first_satoshi() -> Result {
Test::new()?
.command("find --blocksdir blocks 0 --as-of-height 0")
.expected_stdout("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0:0\n")
.block()
.run()
}

Expand All @@ -13,6 +14,7 @@ fn first_satoshi_slot() -> Result {
Test::new()?
.command("find --blocksdir blocks 0 --as-of-height 0 --slot")
.expected_stdout("0.0.0.0\n")
.block()
.run()
}

Expand All @@ -21,6 +23,7 @@ fn second_satoshi() -> Result {
Test::new()?
.command("find --blocksdir blocks 1 --as-of-height 0")
.expected_stdout("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0:1\n")
.block()
.run()
}

Expand All @@ -29,14 +32,17 @@ fn second_satoshi_slot() -> Result {
Test::new()?
.command("find --blocksdir blocks 1 --as-of-height 0 --slot")
.expected_stdout("0.0.0.1\n")
.block()
.run()
}

#[test]
fn first_satoshi_of_second_block() -> Result {
Test::new()?
.command("find --blocksdir blocks 5000000000 --as-of-height 1")
.expected_stdout("e5fb252959bdc7727c80296dbc53e1583121503bb2e266a609ebc49cf2a74c1d:0:0\n")
.expected_stdout("9068a11b8769174363376b606af9a4b8b29dd7b13d013f4b0cbbd457db3c3ce5:0:0\n")
.block()
.block()
.run()
}

Expand All @@ -45,14 +51,19 @@ fn first_satoshi_of_second_block_slot() -> Result {
Test::new()?
.command("find --blocksdir blocks 5000000000 --as-of-height 1 --slot")
.expected_stdout("1.0.0.0\n")
.block()
.block()
.run()
}

#[test]
fn first_satoshi_spent_in_second_block() -> Result {
Test::new()?
.command("find --blocksdir blocks 0 --as-of-height 1")
.expected_stdout("1e8149c3be0dd66b1cbcb4652d15bea04a9bc8d515c4f544e71bb35a9cba1ed0:0:0\n")
.expected_stdout("72e60639a1dcc6263ed214a1db0dc9545bf65d9327e5a60e84bd3db7fbb4c2fa:0:0\n")
.block()
.block()
.transaction(&[(0, 0, 0)], 1)
.run()
}

Expand All @@ -61,5 +72,8 @@ fn first_satoshi_spent_in_second_block_slot() -> Result {
Test::new()?
.command("find --blocksdir blocks 0 --as-of-height 1 --slot")
.expected_stdout("1.1.0.0\n")
.block()
.block()
.transaction(&[(0, 0, 0)], 1)
.run()
}
104 changes: 66 additions & 38 deletions tests/integration.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use {
bitcoin::{
blockdata::constants::{genesis_block, COIN_VALUE, MAX_SEQUENCE},
blockdata::constants::{genesis_block, COIN_VALUE},
blockdata::script,
consensus::Encodable,
{Block, BlockHeader, Network, OutPoint, Transaction, TxIn, TxOut},
Expand Down Expand Up @@ -35,6 +35,7 @@ struct Test {
expected_status: i32,
ignore_stdout: bool,
tempdir: TempDir,
blocks: Vec<Block>,
}

impl Test {
Expand All @@ -46,6 +47,7 @@ impl Test {
expected_status: 0,
ignore_stdout: false,
tempdir: TempDir::new()?,
blocks: Vec::new(),
})
}

Expand Down Expand Up @@ -124,63 +126,89 @@ impl Test {
Ok(stdout.to_owned())
}

fn populate_blocksdir(&self) -> io::Result<()> {
let mut blocks = vec![genesis_block(Network::Bitcoin)];

blocks.push(Block {
header: BlockHeader {
version: 0,
prev_blockhash: blocks.last().unwrap().block_hash(),
merkle_root: Default::default(),
time: 0,
bits: 0,
nonce: 0,
},
txdata: vec![
Transaction {
version: 1,
lock_time: 0,
input: vec![TxIn {
previous_output: OutPoint::null(),
script_sig: script::Builder::new().push_scriptint(1).into_script(),
sequence: MAX_SEQUENCE,
witness: vec![],
}],
output: vec![TxOut {
value: 50 * COIN_VALUE,
script_pubkey: script::Builder::new().into_script(),
}],
fn block(mut self) -> Self {
if self.blocks.is_empty() {
self.blocks.push(genesis_block(Network::Bitcoin));
} else {
self.blocks.push(Block {
header: BlockHeader {
version: 0,
prev_blockhash: self.blocks.last().unwrap().block_hash(),
merkle_root: Default::default(),
time: 0,
bits: 0,
nonce: 0,
},
Transaction {
version: 1,
txdata: vec![Transaction {
version: 0,
lock_time: 0,
input: vec![TxIn {
script_sig: script::Builder::new().into_script(),
sequence: MAX_SEQUENCE,
previous_output: OutPoint::null(),
script_sig: script::Builder::new()
.push_scriptint(self.blocks.len().try_into().unwrap())
.into_script(),
sequence: 0,
witness: vec![],
previous_output: OutPoint {
txid: blocks.last().unwrap().txdata[0].txid(),
vout: 0,
},
}],
output: vec![TxOut {
value: 50 * COIN_VALUE,
script_pubkey: script::Builder::new().into_script(),
}],
},
}],
});
}
self
}

fn transaction(mut self, slots: &[(usize, usize, u32)], output_count: u64) -> Self {
let value = slots
.iter()
.map(|slot| self.blocks[slot.0].txdata[slot.1].output[slot.2 as usize].value)
.sum::<u64>();

let tx = Transaction {
version: 0,
lock_time: 0,
input: slots
.iter()
.map(|slot| TxIn {
previous_output: OutPoint {
txid: self.blocks[slot.0].txdata[slot.1].txid(),
vout: slot.2,
},
script_sig: script::Builder::new().into_script(),
sequence: 0,
witness: vec![],
})
.collect(),
output: vec![
TxOut {
value: value / output_count,
script_pubkey: script::Builder::new().into_script(),
};
output_count.try_into().unwrap()
],
});
};

self.blocks.last_mut().unwrap().txdata.push(tx);

self
}

fn populate_blocksdir(&self) -> io::Result<()> {
let blocksdir = self.tempdir.path().join("blocks");
fs::create_dir(&blocksdir)?;
let mut blockfile = File::create(blocksdir.join("blk00000.dat"))?;

for block in blocks {
for block in &self.blocks {
let mut encoded = Vec::new();
block.consensus_encode(&mut encoded)?;
blockfile.write_all(&[0xf9, 0xbe, 0xb4, 0xd9])?;
blockfile.write_all(&(encoded.len() as u32).to_le_bytes())?;
blockfile.write_all(&encoded)?;
for tx in &block.txdata {
eprintln!("{}", tx.txid());
}
}

Ok(())
Expand Down
56 changes: 55 additions & 1 deletion tests/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ fn first_coinbase_transaction() -> Result {
.command(
"list --blocksdir blocks 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0",
)
.block()
.expected_stdout("[0,5000000000)\n")
.run()
}
Expand All @@ -14,8 +15,61 @@ fn first_coinbase_transaction() -> Result {
fn second_coinbase_transaction() -> Result {
Test::new()?
.command(
"list --blocksdir blocks e5fb252959bdc7727c80296dbc53e1583121503bb2e266a609ebc49cf2a74c1d:0",
"list --blocksdir blocks 9068a11b8769174363376b606af9a4b8b29dd7b13d013f4b0cbbd457db3c3ce5:0",
)
.block()
.block()
.expected_stdout("[5000000000,10000000000)\n")
.run()
}

#[test]
fn third_coinbase_transaction_is_not_duplicate() -> Result {
Test::new()?
.command(
"list --blocksdir blocks 8aa5103b13b5b233ac417ee31f21820c9284af2b7a2080a142c2d20e1697b0f4:0",
)
.block()
.block()
.block()
.expected_stdout("[10000000000,15000000000)\n")
.run()
}

#[test]
fn split_ranges_are_tracked_correctly() -> Result {
Test::new()?
.command(
"list --blocksdir blocks 7ab338c0e46c95c119ba8ff0a3f6cf64f56f35ba5553a399fdd38169cca00be3:0",
)
.block()
.block()
.transaction(&[(0, 0, 0)], 2)
.expected_stdout("[0,2500000000)\n")
.run()?;

Test::new()?
.command(
"list --blocksdir blocks 7ab338c0e46c95c119ba8ff0a3f6cf64f56f35ba5553a399fdd38169cca00be3:1",
)
.block()
.block()
.transaction(&[(0, 0, 0)], 2)
.expected_stdout("[2500000000,5000000000)\n")
.run()
}

#[test]
fn merge_ranges_are_tracked_correctly() -> Result {
Test::new()?
.command(
"list --blocksdir blocks fe283c08e46269a7bbe36b629bc2be55d604152419818e94330477c9c3487eec:0",
)
.block()
.block()
.transaction(&[(0, 0, 0)], 2)
.block()
.transaction(&[(1, 1, 0), (1, 1, 1)], 1)
.expected_stdout("[0,2500000000)\n[2500000000,5000000000)\n")
.run()
}