Skip to content
This repository has been archived by the owner on Jul 27, 2022. It is now read-only.

Commit

Permalink
Problem: nowhere to pay fees to (CRO-94) (#72)
Browse files Browse the repository at this point in the history
Solution: added a basic definition for rewards pool state representation + refactor around BlockHeight opaque type
* extended InitConfig to contain the dedicated ERC20 addresses that will form the rewards pool at genesis
* fixed chain-core dependencies
* changed dev-utils to allow a more flexible config generation
* extracted out app_hash computation into chain-core's `computer_app_hash` and extended InitChain handling to persist rewards pool state
* added a basic modified calculation mechanism from https://github.com/input-output-hk/rust-cardano
* removed error-prone deref in coin
* removed ABCI  app sanity checks, as they should be done in the ABCI library (added a link to the issue tendermint/rust-abci#49 )
* removed .iter() calls where possible
  • Loading branch information
tomtau committed May 6, 2019
1 parent 0031c1e commit dd9cd13
Show file tree
Hide file tree
Showing 19 changed files with 564 additions and 144 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions chain-abci/benches/hashes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ impl<D: Digest> GenericMerkleNode<D> {
let a = GenericMerkleNode::make_tree(&xs[0..i]);
let b = GenericMerkleNode::make_tree(&xs[i..]);
let mut bs = vec![1u8];
bs.extend(a.get_root_hash().as_bytes().iter());
bs.extend(b.get_root_hash().as_bytes().iter());
bs.extend(a.get_root_hash().as_bytes());
bs.extend(b.get_root_hash().as_bytes());
GenericMerkleNode::Branch(hash256::<D>(&bs), Box::new(a), Box::new(b))
}
}
Expand Down
53 changes: 33 additions & 20 deletions chain-abci/src/app/app_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use bit_vec::BitVec;
use chain_core::common::merkle::MerkleTree;
use chain_core::common::Timespec;
use chain_core::common::{H256, HASH_SIZE_256};
use chain_core::compute_app_hash;
use chain_core::init::config::InitConfig;
use chain_core::state::{BlockHeight, RewardsPoolState};
use chain_core::tx::{
data::{attribute::TxAttributes, Tx, TxId},
TxAux,
Expand All @@ -12,7 +14,7 @@ use hex::decode;
use integer_encoding::VarInt;
use log::info;
use protobuf::Message;
use rlp::{Encodable, RlpStream};
use rlp::{Decodable, Encodable, Rlp, RlpStream};

use crate::storage::*;

Expand All @@ -21,11 +23,9 @@ pub struct ChainNodeApp {
/// the underlying key-value storage (+ possibly some info in the future)
pub storage: Storage,
/// last processed block height
pub last_block_height: i64,
pub last_block_height: BlockHeight,
/// next block height
pub uncommitted_block_height: i64,
/// sanity check -- TODO: remove when this is checked in the ABCI lib
pub uncommitted_block: bool,
pub uncommitted_block_height: BlockHeight,
/// valid transactions after DeliverTx before EndBlock/Commit
pub delivered_txs: Vec<TxAux>,
/// a reference to genesis (used when there is no committed state)
Expand All @@ -36,6 +36,8 @@ pub struct ChainNodeApp {
pub chain_hex_id: u8,
/// time in previous block's header or genesis time
pub block_time: Option<Timespec>,
/// last rewards pool state
pub rewards_pool: Option<RewardsPoolState>,
}

impl ChainNodeApp {
Expand Down Expand Up @@ -68,14 +70,14 @@ impl ChainNodeApp {
.expect("genesis app hash should be stored");
ChainNodeApp {
storage,
last_block_height: 0,
uncommitted_block_height: 0,
uncommitted_block: false,
last_block_height: 0.into(),
uncommitted_block_height: 0.into(),
delivered_txs: Vec::new(),
last_apphash: None,
chain_hex_id,
genesis_app_hash: genesis_app_hash.into(),
block_time: None,
rewards_pool: None,
}
} else {
info!("last app hash stored");
Expand All @@ -94,7 +96,7 @@ impl ChainNodeApp {
.db
.get(COL_EXTRA, CHAIN_ID_KEY)
.unwrap()
.expect("last app hash found, but chain id stored");
.expect("last app hash found, but no chain id stored");
if stored_chain_id != chain_id.as_bytes() {
panic!(
"stored chain id: {:?} does not match the provided chain id: {:?}",
Expand All @@ -110,23 +112,30 @@ impl ChainNodeApp {
.to_vec(),
)
.0;
let block_time: Option<Timespec> = storage
.db
.get(COL_NODE_INFO, BLOCK_TIME_KEY)
.expect("Error while fetching value")
.map(|bytes| -> Timespec { i64::decode_var_vec(&bytes.to_vec()).0.into() });

let rewards_pool = RewardsPoolState::decode(&Rlp::new(
&storage
.db
.get(COL_NODE_INFO, REWARDS_POOL_STATE_KEY)
.unwrap()
.expect("last app hash found, but no rewards pool state stored"),
))
.expect(
"failed to decode stored
rewards pool state",
);
let mut app_hash = [0u8; HASH_SIZE_256];
app_hash.copy_from_slice(&last_app_hash.unwrap()[..]);
ChainNodeApp {
storage,
last_block_height,
uncommitted_block_height: 0,
uncommitted_block: false,
last_block_height: last_block_height.into(),
uncommitted_block_height: 0.into(),
delivered_txs: Vec::new(),
last_apphash: Some(app_hash.into()),
chain_hex_id,
genesis_app_hash: genesis_app_hash.into(),
block_time,
block_time: None,
rewards_pool: Some(rewards_pool),
}
}
}
Expand Down Expand Up @@ -164,7 +173,9 @@ impl ChainNodeApp {
let utxos = conf.generate_utxos(&TxAttributes::new(self.chain_hex_id));
let ids: Vec<TxId> = utxos.iter().map(Tx::id).collect();
let tree = MerkleTree::new(&ids);
let genesis_app_hash = tree.get_root_hash();
let rp = conf.get_genesis_rewards_pool();

let genesis_app_hash = compute_app_hash(&tree, &rp);
if self.genesis_app_hash != genesis_app_hash {
panic!("initchain resulting genesis app hash: {:?} does not match the expected genesis app hash: {:?}", genesis_app_hash, self.genesis_app_hash);
}
Expand Down Expand Up @@ -224,6 +235,7 @@ impl ChainNodeApp {
&BitVec::from_elem(1, false).to_bytes(),
);
}
inittx.put(COL_NODE_INFO, REWARDS_POOL_STATE_KEY, &rp.rlp_bytes());
inittx.put(
COL_NODE_INFO,
LAST_APP_HASH_KEY,
Expand All @@ -232,7 +244,7 @@ impl ChainNodeApp {
inittx.put(
COL_NODE_INFO,
LAST_BLOCK_HEIGHT_KEY,
&i64::encode_var_vec(self.last_block_height),
&i64::encode_var_vec(self.last_block_height.into()),
);
inittx.put(
COL_MERKLE_PROOFS,
Expand All @@ -245,6 +257,7 @@ impl ChainNodeApp {
// TODO: panic?
println!("db write error: {}", wr.err().unwrap());
} else {
self.rewards_pool = Some(rp);
self.last_apphash = Some(genesis_app_hash);
}

Expand Down
13 changes: 7 additions & 6 deletions chain-abci/src/app/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::storage::tx::update_utxos_commit;
use crate::storage::*;
use abci::*;
use chain_core::common::merkle::MerkleTree;
use chain_core::compute_app_hash;
use chain_core::tx::data::TxId;
use chain_core::tx::TxAux;
use integer_encoding::VarInt;
Expand All @@ -28,12 +29,14 @@ impl ChainNodeApp {
inittx.put(COL_WITNESS, &txid.as_bytes(), &witness.rlp_bytes());
update_utxos_commit(&tx, self.storage.db.clone(), &mut inittx);
}
let app_hash = tree.get_root_hash();
let rp = self.rewards_pool.clone().unwrap();
let app_hash = compute_app_hash(&tree, &rp);
inittx.put(COL_NODE_INFO, REWARDS_POOL_STATE_KEY, &rp.rlp_bytes());
inittx.put(COL_NODE_INFO, LAST_APP_HASH_KEY, &app_hash.as_bytes());
inittx.put(
COL_NODE_INFO,
LAST_BLOCK_HEIGHT_KEY,
&i64::encode_var_vec(self.uncommitted_block_height),
&i64::encode_var_vec(self.uncommitted_block_height.into()),
);
inittx.put(COL_MERKLE_PROOFS, &app_hash.as_bytes(), &tree.rlp_bytes());
Some(app_hash)
Expand All @@ -44,17 +47,15 @@ impl ChainNodeApp {
if app_hash.is_some() {
inittx.put(
COL_APP_STATES,
&i64::encode_var_vec(self.uncommitted_block_height),
&i64::encode_var_vec(self.uncommitted_block_height.into()),
&app_hash.unwrap().as_bytes(),
);
let wr = self.storage.db.write(inittx);
if wr.is_err() {
// TODO: panic?
println!("db write error: {}", wr.err().unwrap());
panic!("db write error: {}", wr.err().unwrap());
} else {
self.last_block_height = self.uncommitted_block_height;
self.last_apphash = app_hash;
self.uncommitted_block = false;
resp.data = app_hash.unwrap().as_bytes().to_vec();
}
}
Expand Down
Loading

0 comments on commit dd9cd13

Please sign in to comment.