Skip to content

Commit

Permalink
Basic Djed Implementation
Browse files Browse the repository at this point in the history
- Implemented an interface for fetching information from oracles.
- Developed a transaction selector logic based on the ReserveRatioState.
- Enhanced transaction payloads to store detailed information about asset conversions.
- Added validation for transaction payloads.
- Refactored other functions and unit tests for improved efficiency and clarity.
  • Loading branch information
KashProtocol committed Jan 24, 2024
1 parent 58be95e commit 9b81376
Show file tree
Hide file tree
Showing 46 changed files with 977 additions and 71 deletions.
207 changes: 172 additions & 35 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ members = [
"metrics/perf_monitor",
"metrics/core",
"utils/alloc",
"oracle",
]

[workspace.package]
Expand Down Expand Up @@ -126,6 +127,7 @@ kash-wrpc-server = { version = "0.13.3", path = "rpc/wrpc/server" }
kash-wrpc-wasm = { version = "0.13.3", path = "rpc/wrpc/wasm" }
kashd = { version = "0.13.3", path = "kashd" }
kash-alloc = { version = "0.13.3", path = "utils/alloc" }
kash-oracle = { version = "0.13.3", path = "oracle" }

# external
aes = "0.8.3"
Expand Down
1 change: 1 addition & 0 deletions consensus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ kash-math.workspace = true
kash-merkle.workspace = true
kash-muhash.workspace = true
kash-notify.workspace = true
kash-oracle.workspace = true
kash-pow.workspace = true
kash-txscript.workspace = true
kash-utils.workspace = true
Expand Down
2 changes: 2 additions & 0 deletions consensus/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ kash-hashes.workspace = true
kash-math.workspace = true
kash-merkle.workspace = true
kash-muhash.workspace = true
kash-oracle.workspace = true
kash-txscript-errors.workspace = true
kash-utils.workspace = true
rand.workspace = true
Expand All @@ -35,6 +36,7 @@ wasm-bindgen.workspace = true
workflow-core.workspace = true
workflow-log.workspace = true
workflow-wasm.workspace = true
serde_cbor = "0.11.2"

[dev-dependencies]
criterion.workspace = true
Expand Down
1 change: 1 addition & 0 deletions consensus/core/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub trait ConsensusApi: Send + Sync {
miner_data: MinerData,
tx_selector: Box<dyn TemplateTransactionSelector>,
build_mode: TemplateBuildMode,
target_block_time: u64,
) -> Result<BlockTemplate, RuleError> {
unimplemented!()
}
Expand Down
3 changes: 2 additions & 1 deletion consensus/core/src/block.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::sync::Arc;

use crate::tx::reserve_state::ReserveRatioState;
use crate::{
coinbase::MinerData,
header::Header,
Expand Down Expand Up @@ -74,7 +75,7 @@ pub trait TemplateTransactionSelector {
/// Expected to return a batch of transactions which were not previously selected.
/// The batch will typically contain sufficient transactions to fill the block
/// mass (along with the previously unrejected txs), or will drain the selector
fn select_transactions(&mut self) -> Vec<Transaction>;
fn select_transactions(&mut self, rs: ReserveRatioState) -> Vec<Transaction>;

/// Should be used to report invalid transactions obtained from the *most recent*
/// `select_transactions` call. Implementors should use this call to internally
Expand Down
2 changes: 2 additions & 0 deletions consensus/core/src/config/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::tx::TransactionAction;
use crate::{block::Block, header::Header, subnets::SUBNETWORK_ID_COINBASE, tx::Transaction};
use kash_hashes::{Hash, ZERO_HASH};
use kash_muhash::EMPTY_MUHASH;
use kash_oracle::pricing_record::PricingRecord;

/// The constants uniquely representing the genesis block
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -47,6 +48,7 @@ impl From<&GenesisBlock> for Header {
0.into(),
0,
ZERO_HASH,
PricingRecord::default(),
)
}
}
Expand Down
6 changes: 6 additions & 0 deletions consensus/core/src/errors/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ pub enum TxRuleError {
#[error("a non coinbase transaction has a payload")]
NonCoinbaseTxHasPayload,

#[error("Invalid asset conversion types")]
InvalidAssetConversionTypes,

#[error("Invalid asset conversion amount")]
InvalidAssetConversionAmount,

#[error("transaction version {0} is unknown")]
UnknownTxVersion(u16),

Expand Down
2 changes: 2 additions & 0 deletions consensus/core/src/hashing/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub fn hash(header: &Header) -> Hash {
mod tests {
use super::*;
use crate::{blockhash, BlueWorkType};
use kash_oracle::pricing_record::PricingRecord;

#[test]
fn test_header_hashing() {
Expand All @@ -54,6 +55,7 @@ mod tests {
0.into(),
0,
Default::default(),
PricingRecord::default(),
);
assert_ne!(blockhash::NONE, header.hash);
}
Expand Down
14 changes: 14 additions & 0 deletions consensus/core/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ use crate::{hashing, BlueWorkType};
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
use js_sys::{Array, Object};
use kash_hashes::Hash;
use kash_oracle::pricing_record::create_random_pricing_record;
use kash_oracle::pricing_record::PricingRecord;
use kash_utils::hex::ToHex;
use rand::rngs::SmallRng;
use rand::SeedableRng;
use serde::{Deserialize, Serialize};
use serde_wasm_bindgen::*;
use wasm_bindgen::prelude::*;
Expand Down Expand Up @@ -34,6 +38,8 @@ pub struct Header {
pub blue_score: u64,
#[wasm_bindgen(skip)]
pub pruning_point: Hash,
#[wasm_bindgen(skip)]
pub pricing_record: PricingRecord,
}

impl Header {
Expand All @@ -51,6 +57,7 @@ impl Header {
blue_work: BlueWorkType,
blue_score: u64,
pruning_point: Hash,
pricing_record: PricingRecord,
) -> Self {
let mut header = Self {
hash: Default::default(), // Temp init before the finalize below
Expand All @@ -66,6 +73,7 @@ impl Header {
blue_work,
blue_score,
pruning_point,
pricing_record,
};
header.finalize();
header
Expand Down Expand Up @@ -100,6 +108,7 @@ impl Header {
blue_work: 0.into(),
blue_score: 0,
pruning_point: Default::default(),
pricing_record: create_random_pricing_record(&mut SmallRng::seed_from_u64(0)),
}
}
}
Expand Down Expand Up @@ -249,6 +258,9 @@ impl TryFrom<JsValue> for Header {
})
.collect::<std::result::Result<Vec<Vec<Hash>>, Error>>()?;

let pricing_record: PricingRecord =
object.get_value("pricingRecord")?.try_into().map_err(|err| Error::convert("pricingRecord", err))?;

let header = Self {
hash: object.get_value("hash")?.try_into().unwrap_or_default(),
version: object.get_u16("version")?,
Expand All @@ -272,6 +284,7 @@ impl TryFrom<JsValue> for Header {
blue_work: object.get_value("blueWork")?.try_into().map_err(|err| Error::convert("blueWork", err))?,
blue_score: object.get_u64("blueScore")?,
pruning_point: object.get_value("pruningPoint")?.try_into().map_err(|err| Error::convert("pruningPoint", err))?,
pricing_record,
};

Ok(header)
Expand Down Expand Up @@ -302,6 +315,7 @@ mod tests {
Uint192([0x1234567890abcfed, 0xc0dec0ffeec0ffee, 0x1234567890abcdef]),
u64::MAX,
Default::default(),
create_random_pricing_record(&mut SmallRng::seed_from_u64(0)),
);
let json = serde_json::to_string(&header).unwrap();
println!("{}", json);
Expand Down
33 changes: 26 additions & 7 deletions consensus/core/src/tx.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod asset_conversion;
pub mod reserve_state;
mod script_public_key;

use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
Expand Down Expand Up @@ -146,8 +148,10 @@ pub enum TransactionAction {
MintKUSD,
/// Staking KSH to get KRV: KSH -> KRV
StakeKSH,
/// Redeeming KSH using KUSD: KUSD -> KSH
RedeemViaKUSD,
/// Redeeming KSH using KRV: KRV -> KSH
RedeemKSH,
RedeemViaKRV,
}

impl TransactionAction {
Expand All @@ -160,7 +164,17 @@ impl TransactionAction {
TransactionAction::TransferKRV => (AssetType::KRV, AssetType::KRV),
TransactionAction::MintKUSD => (AssetType::KSH, AssetType::KUSD),
TransactionAction::StakeKSH => (AssetType::KSH, AssetType::KRV),
TransactionAction::RedeemKSH => (AssetType::KRV, AssetType::KSH),
TransactionAction::RedeemViaKUSD => (AssetType::KUSD, AssetType::KSH),
TransactionAction::RedeemViaKRV => (AssetType::KRV, AssetType::KSH),
}
}

pub fn is_transfer(&self) -> bool {
match self {
TransactionAction::TransferKSH => true,
TransactionAction::TransferKUSD => true,
TransactionAction::TransferKRV => true,
_ => false,
}
}
}
Expand All @@ -174,7 +188,8 @@ impl From<TransactionAction> for u32 {
TransactionAction::TransferKRV => 2,
TransactionAction::MintKUSD => 3,
TransactionAction::StakeKSH => 4,
TransactionAction::RedeemKSH => 5,
TransactionAction::RedeemViaKUSD => 5,
TransactionAction::RedeemViaKRV => 6,
}
}
}
Expand All @@ -188,7 +203,8 @@ impl From<u32> for TransactionAction {
2 => TransactionAction::TransferKRV,
3 => TransactionAction::MintKUSD,
4 => TransactionAction::StakeKSH,
5 => TransactionAction::RedeemKSH,
5 => TransactionAction::RedeemViaKUSD,
6 => TransactionAction::RedeemViaKRV,
_ => TransactionAction::TransferKSH, // Handle unknown values gracefully
}
}
Expand All @@ -203,7 +219,8 @@ impl From<String> for TransactionAction {
"TransferKRV" => TransactionAction::TransferKRV,
"MintKUSD" => TransactionAction::MintKUSD,
"StakeKSH" => TransactionAction::StakeKSH,
"RedeemKSH" => TransactionAction::RedeemKSH,
"RedeemViaKUSD" => TransactionAction::RedeemViaKUSD,
"RedeemViaKRV" => TransactionAction::RedeemViaKRV,
_ => TransactionAction::TransferKSH, // Handle unknown values gracefully
}
}
Expand All @@ -219,7 +236,8 @@ impl TryFrom<&String> for TransactionAction {
"TransferKRV" => Ok(TransactionAction::TransferKRV),
"MintKUSD" => Ok(TransactionAction::MintKUSD),
"StakeKSH" => Ok(TransactionAction::StakeKSH),
"RedeemKSH" => Ok(TransactionAction::RedeemKSH),
"RedeemViaKUSD" => Ok(TransactionAction::RedeemViaKUSD),
"RedeemViaKRV" => Ok(TransactionAction::RedeemViaKRV),
_ => Err(TxRuleError::InvalidTransactionType(value.clone())),
}
}
Expand All @@ -237,7 +255,8 @@ impl TryFrom<JsValue> for TransactionAction {
2 => Ok(TransactionAction::TransferKRV),
3 => Ok(TransactionAction::MintKUSD),
4 => Ok(TransactionAction::StakeKSH),
5 => Ok(TransactionAction::RedeemKSH),
5 => Ok(TransactionAction::RedeemViaKUSD),
6 => Ok(TransactionAction::RedeemViaKRV),
_ => Err(JsValue::from_str("Invalid TransactionAction value")),
}
} else {
Expand Down
23 changes: 23 additions & 0 deletions consensus/core/src/tx/asset_conversion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use crate::asset_type::AssetType;
use serde::{Deserialize, Serialize};
use serde_cbor;

#[derive(Serialize, Deserialize)]
pub struct AssetConversionDetails {
pub to_asset_type: AssetType,
pub from_asset_type: AssetType,
pub to_amount: u64,
pub from_amount: u64,
}

pub struct AssetConversionSerializer;

impl AssetConversionSerializer {
pub fn serialize(details: &AssetConversionDetails) -> Vec<u8> {
serde_cbor::to_vec(details).expect("Serialization failed")
}

pub fn deserialize(data: &[u8]) -> AssetConversionDetails {
serde_cbor::from_slice(data).expect("Deserialization failed")
}
}
Loading

0 comments on commit 9b81376

Please sign in to comment.