Remove height as a term

Unbeknowst to me, height doesn't have a universal definition of the 
chain length.

Bitcoin defines height as the block number, with getblockcount existing 
for the chain length.

Ethereum uses the unambiguous term "block number".

Monero defines height as both the block number and the chain length.

Instead of arguing about who's right, it's agreed it referring to both 
isn't productive. While we could provide our own definition, taking a 
side, moving to the unambiguous block number prevents future hiccups.

height is now only a term in the Monero code, where it takes its 
Monero-specific definition, as documented in the processor.
This commit is contained in:
Luke Parker
2022-10-15 21:39:06 -04:00
parent a245ee28c1
commit 514563cef0
5 changed files with 82 additions and 84 deletions

View File

@@ -18,12 +18,12 @@ use crate::{
pub struct WalletKeys<C: Curve> {
keys: FrostKeys<C>,
creation_height: usize,
creation_block: usize,
}
impl<C: Curve> WalletKeys<C> {
pub fn new(keys: FrostKeys<C>, creation_height: usize) -> WalletKeys<C> {
WalletKeys { keys, creation_height }
pub fn new(keys: FrostKeys<C>, creation_block: usize) -> WalletKeys<C> {
WalletKeys { keys, creation_block }
}
// Bind this key to a specific network by applying an additive offset
@@ -45,42 +45,42 @@ impl<C: Curve> WalletKeys<C> {
}
pub trait CoinDb {
// Set a height as scanned to
fn scanned_to_height(&mut self, height: usize);
// Acknowledge a given coin height for a canonical height
fn acknowledge_height(&mut self, canonical: usize, height: usize);
// Set a block as scanned to
fn scanned_to_block(&mut self, block: usize);
// Acknowledge a specific block number as part of a canonical block
fn acknowledge_block(&mut self, canonical: usize, block: usize);
// Adds an output to the DB. Returns false if the output was already added
fn add_output<O: Output>(&mut self, output: &O) -> bool;
// Height this coin has been scanned to
fn scanned_height(&self) -> usize;
// Acknowledged height for a given canonical height
fn acknowledged_height(&self, canonical: usize) -> usize;
// Block this coin has been scanned to (inclusive)
fn scanned_block(&self) -> usize;
// Acknowledged block for a given canonical block
fn acknowledged_block(&self, canonical: usize) -> usize;
}
pub struct MemCoinDb {
// Height this coin has been scanned to
scanned_height: usize,
// Acknowledged height for a given canonical height
acknowledged_heights: HashMap<usize, usize>,
scanned_block: usize,
// Acknowledged block for a given canonical block
acknowledged_blocks: HashMap<usize, usize>,
outputs: HashMap<Vec<u8>, Vec<u8>>,
}
impl MemCoinDb {
pub fn new() -> MemCoinDb {
MemCoinDb { scanned_height: 0, acknowledged_heights: HashMap::new(), outputs: HashMap::new() }
MemCoinDb { scanned_block: 0, acknowledged_blocks: HashMap::new(), outputs: HashMap::new() }
}
}
impl CoinDb for MemCoinDb {
fn scanned_to_height(&mut self, height: usize) {
self.scanned_height = height;
fn scanned_to_block(&mut self, block: usize) {
self.scanned_block = block;
}
fn acknowledge_height(&mut self, canonical: usize, height: usize) {
debug_assert!(!self.acknowledged_heights.contains_key(&canonical));
self.acknowledged_heights.insert(canonical, height);
fn acknowledge_block(&mut self, canonical: usize, block: usize) {
debug_assert!(!self.acknowledged_blocks.contains_key(&canonical));
self.acknowledged_blocks.insert(canonical, block);
}
fn add_output<O: Output>(&mut self, output: &O) -> bool {
@@ -96,12 +96,12 @@ impl CoinDb for MemCoinDb {
true
}
fn scanned_height(&self) -> usize {
self.scanned_height
fn scanned_block(&self) -> usize {
self.scanned_block
}
fn acknowledged_height(&self, canonical: usize) -> usize {
self.acknowledged_heights[&canonical]
fn acknowledged_block(&self, canonical: usize) -> usize {
self.acknowledged_blocks[&canonical]
}
}
@@ -212,22 +212,18 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
Wallet { db, coin, keys: vec![], pending: vec![] }
}
pub fn scanned_height(&self) -> usize {
self.db.scanned_height()
pub fn scanned_block(&self) -> usize {
self.db.scanned_block()
}
pub fn acknowledge_height(&mut self, canonical: usize, height: usize) {
self.db.acknowledge_height(canonical, height);
if height > self.db.scanned_height() {
self.db.scanned_to_height(height);
}
pub fn acknowledge_block(&mut self, canonical: usize, block: usize) {
self.db.acknowledge_block(canonical, block);
}
pub fn acknowledged_height(&self, canonical: usize) -> usize {
self.db.acknowledged_height(canonical)
pub fn acknowledged_block(&self, canonical: usize) -> usize {
self.db.acknowledged_block(canonical)
}
pub fn add_keys(&mut self, keys: &WalletKeys<C::Curve>) {
// Doesn't use +1 as this is height, not block index, and poll moves by block index
self.pending.push((self.acknowledged_height(keys.creation_height), keys.bind(C::ID)));
self.pending.push((self.acknowledged_block(keys.creation_block), keys.bind(C::ID)));
}
pub fn address(&self) -> C::Address {
@@ -236,17 +232,18 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
// TODO: Remove
pub async fn is_confirmed(&mut self, tx: &[u8]) -> Result<bool, CoinError> {
self.coin.is_confirmed(tx, self.scanned_height() + C::CONFIRMATIONS).await
self.coin.is_confirmed(tx).await
}
pub async fn poll(&mut self) -> Result<(), CoinError> {
if self.coin.get_height().await? < C::CONFIRMATIONS {
if self.coin.get_latest_block_number().await? < (C::CONFIRMATIONS - 1) {
return Ok(());
}
let confirmed_block = self.coin.get_height().await? - C::CONFIRMATIONS;
let confirmed_block = self.coin.get_latest_block_number().await? - (C::CONFIRMATIONS - 1);
for b in self.scanned_height() ..= confirmed_block {
// If any keys activated at this height, shift them over
// Will never scan the genesis block, which shouldn't be an issue
for b in (self.scanned_block() + 1) ..= confirmed_block {
// If any keys activated at this block, shift them over
{
let mut k = 0;
while k < self.pending.len() {
@@ -274,8 +271,7 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
);
}
// Blocks are zero-indexed while heights aren't
self.db.scanned_to_height(b + 1);
self.db.scanned_to_block(b);
}
Ok(())
@@ -296,7 +292,7 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
return Ok((vec![], vec![]));
}
let acknowledged_height = self.acknowledged_height(canonical);
let acknowledged_block = self.acknowledged_block(canonical);
// TODO: Log schedule outputs when MAX_OUTPUTS is lower than payments.len()
// Payments is the first set of TXs in the schedule
@@ -318,16 +314,16 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
// Create the transcript for this transaction
let mut transcript = RecommendedTranscript::new(b"Serai Processor Wallet Send");
transcript
.append_message(b"canonical_height", &u64::try_from(canonical).unwrap().to_le_bytes());
.append_message(b"canonical_block", &u64::try_from(canonical).unwrap().to_le_bytes());
transcript.append_message(
b"acknowledged_height",
&u64::try_from(acknowledged_height).unwrap().to_le_bytes(),
b"acknowledged_block",
&u64::try_from(acknowledged_block).unwrap().to_le_bytes(),
);
transcript.append_message(b"index", &u64::try_from(txs.len()).unwrap().to_le_bytes());
let tx = self
.coin
.prepare_send(keys.clone(), transcript, acknowledged_height, inputs, &outputs, fee)
.prepare_send(keys.clone(), transcript, acknowledged_block, inputs, &outputs, fee)
.await?;
// self.db.save_tx(tx) // TODO
txs.push(tx);