Skip to content
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
99 changes: 99 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions libs/pillar_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ lz4_flex = "0.11.5"
bytemuck = {version="1.23.2", features=["derive"]}
bytes = "1.10.1"
byteorder = "1.5.0"
hex = "0.4.3"
tempfile = "3.23.0"
dirs = "6.0.0"
34 changes: 15 additions & 19 deletions libs/pillar_core/src/accounting/state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! State management built on a Merkle trie with optional reputation tracking.
use std::{collections::HashMap, fmt::Debug, sync::{Arc, Mutex}};
use std::{collections::HashMap, fmt::Debug};

use pillar_crypto::{merkle_trie::MerkleTrie, types::StdByteArray};

Expand All @@ -12,9 +12,9 @@ pub type ReputationMap = HashMap<StdByteArray, NodeHistory>;
#[derive(Clone, Default)]
pub struct StateManager{
// The mapping from address to account
pub state_trie: Arc<Mutex<MerkleTrie<StdByteArray, Account>>>,
pub state_trie: MerkleTrie<StdByteArray, Account>,
/// mapping of reputations for peers
pub reputations: Arc<Mutex<ReputationMap>>,
pub reputations: ReputationMap,
}

impl Debug for StateManager {
Expand All @@ -36,32 +36,29 @@ impl StateManager{
/// Create a new state manager with an empty trie and no reputations.
pub fn new() -> Self {
StateManager {
state_trie: Arc::new(Mutex::new(MerkleTrie::new())),
reputations: Arc::new(Mutex::new(HashMap::new())),
state_trie: MerkleTrie::new(),
reputations: HashMap::new(),
}
}

/// Get an account by address at a specific `state_root` (if present).
pub fn get_account(&self, address: &StdByteArray, state_root: StdByteArray) -> Option<Account> {
let state_trie = self.state_trie.lock().expect("Failed to lock state trie");
state_trie.get(address, state_root)
self.state_trie.get(address, state_root)
}

/// Get an account or a default zero-balance account for the given address.
pub fn get_account_or_default(&self, address: &StdByteArray, state_root: StdByteArray) -> Account {
let state_trie = self.state_trie.lock().expect("Failed to lock state trie");
state_trie.get(address, state_root).unwrap_or(Account::new(*address, 0))
self.state_trie.get(address, state_root).unwrap_or(Account::new(*address, 0))
}

/// Return all accounts reachable from `root`.
pub fn get_all_accounts(&self, root: StdByteArray) -> Vec<Account>{
self.state_trie.lock().unwrap().get_all(root)
self.state_trie.get_all(root)
}

/// Remove a branched root and decrement reference counts, pruning unique nodes.
pub fn remove_branch(&mut self, root: StdByteArray){
let mut state_trie = self.state_trie.lock().expect("Failed to lock state trie");
state_trie.trim_branch(root).expect("Failed to remove branch from state trie");
self.state_trie.trim_branch(root).expect("Failed to remove branch from state trie");
}

/// Apply a complete block to produce a new state root branch.
Expand Down Expand Up @@ -99,13 +96,12 @@ impl StateManager{
// Update the accounts from the block
let mut state_updates: HashMap<StdByteArray, Account> = HashMap::new();
let state_root = prev_header.completion.as_ref().expect("Previous block should be complete").state_root;
let mut state_trie = self.state_trie.lock().expect("Failed to lock state trie");
for transaction in &block.transactions {
let mut sender = match state_updates.get(&transaction.header.sender){
Some(account) => account.clone(),
None => {
// if the sender does not exist, we create a new account with 0 balance
let account = state_trie
let account = self.state_trie
.get(&transaction.header.sender, state_root)
.unwrap_or(Account::new(transaction.header.sender, 0));

Expand All @@ -124,7 +120,7 @@ impl StateManager{
let mut receiver = match state_updates.get(&transaction.header.receiver){
Some(account) => account.clone(),
None => {
state_trie.get(&transaction.header.receiver, state_root).unwrap_or(Account::new(transaction.header.receiver, 0))
self.state_trie.get(&transaction.header.receiver, state_root).unwrap_or(Account::new(transaction.header.receiver, 0))
},
};
// update balances
Expand All @@ -138,7 +134,7 @@ impl StateManager{
Some(account) => account.clone(),
None => {
// if the miner account does not exist, we create a new account with 0 balance
state_trie.get(miner_address, state_root).unwrap_or(Account::new(*miner_address, 0))
self.state_trie.get(miner_address, state_root).unwrap_or(Account::new(*miner_address, 0))
}
};
miner_account.balance += if !por_enabled {reward} else {div_up(reward, POR_MINER_SHARE_DIVISOR)};
Expand All @@ -161,7 +157,7 @@ impl StateManager{
let mut stamper_account = match state_updates.get(stamper) {
Some(account) => account.clone(),
None => {
state_trie.get(stamper, state_root).unwrap_or(Account::new(*stamper, 0))
self.state_trie.get(stamper, state_root).unwrap_or(Account::new(*stamper, 0))
}
};
stamper_account.balance += stamper_reward;
Expand All @@ -183,7 +179,7 @@ impl StateManager{
let mut stamper = match state_updates.get(stamper){
Some(account) => account.clone(),
None => {
state_trie.get(stamper, state_root).unwrap_or(Account::new(*stamper, 0))
self.state_trie.get(stamper, state_root).unwrap_or(Account::new(*stamper, 0))
}
};
if stamper.history.is_none(){
Expand All @@ -194,6 +190,6 @@ impl StateManager{
state_updates.insert(stamper.address, stamper);
}
// branch the state trie with the updates
state_trie.branch(Some(state_root), state_updates).expect("Issue with branching state trie")
self.state_trie.branch(Some(state_root), state_updates).expect("Issue with branching state trie")
}
}
1 change: 0 additions & 1 deletion libs/pillar_core/src/accounting/wallet.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! Wallet wrapper around an ed25519 keypair with convenience methods.
use bytemuck::{Pod, Zeroable};
use pillar_crypto::{signing::{DefaultSigner, DefaultVerifier, SigFunction, SigVerFunction, Signable}, types::{StdByteArray, STANDARD_ARRAY_LENGTH}};
use pillar_serialize::PillarSerialize;

Expand Down
Loading
Loading