mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-02 13:23:10 +00:00
Merge branch 'main' into Pravdyvy/usability-updates
This commit is contained in:
commit
5c6c7d1c3e
@ -28,7 +28,6 @@ env_logger = "0.10"
|
||||
log = "0.4.28"
|
||||
lru = "0.7.8"
|
||||
thiserror = "2.0.12"
|
||||
rs_merkle = "1.4"
|
||||
sha2 = "0.10.8"
|
||||
hex = "0.4.3"
|
||||
aes-gcm = "0.10.3"
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
set -e
|
||||
curl -L https://risczero.com/install | bash
|
||||
/Users/runner/.risc0/bin/rzup install
|
||||
source env.sh
|
||||
RUSTFLAGS="-D warnings" cargo build
|
||||
RUSTFLAGS="-D warnings" cargo build
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
set -e
|
||||
curl -L https://risczero.com/install | bash
|
||||
/home/runner/.risc0/bin/rzup install
|
||||
source env.sh
|
||||
RUSTFLAGS="-D warnings" cargo build
|
||||
RUSTFLAGS="-D warnings" cargo build
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
set -e
|
||||
|
||||
source env.sh
|
||||
cargo install taplo-cli --locked
|
||||
|
||||
cargo fmt -- --check
|
||||
|
||||
@ -2,7 +2,6 @@ set -e
|
||||
|
||||
curl -L https://risczero.com/install | bash
|
||||
/home/runner/.risc0/bin/rzup install
|
||||
source env.sh
|
||||
|
||||
RISC0_DEV_MODE=1 cargo test --release --features no_docker
|
||||
|
||||
|
||||
@ -9,19 +9,12 @@ thiserror.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde.workspace = true
|
||||
reqwest.workspace = true
|
||||
k256.workspace = true
|
||||
|
||||
rs_merkle.workspace = true
|
||||
sha2.workspace = true
|
||||
log.workspace = true
|
||||
elliptic-curve.workspace = true
|
||||
hex.workspace = true
|
||||
nssa-core = { path = "../nssa/core", features = ["host"] }
|
||||
borsh.workspace = true
|
||||
|
||||
[dependencies.generic-array]
|
||||
version = "1.3.3"
|
||||
features = ["zeroize"]
|
||||
|
||||
[dependencies.nssa]
|
||||
path = "../nssa"
|
||||
|
||||
@ -1,7 +1,23 @@
|
||||
use borsh::{BorshDeserialize, BorshSerialize};
|
||||
use rs_merkle::Hasher;
|
||||
use sha2::{Digest, Sha256, digest::FixedOutput};
|
||||
|
||||
use crate::{OwnHasher, transaction::EncodedTransaction};
|
||||
use crate::transaction::EncodedTransaction;
|
||||
|
||||
pub type HashType = [u8; 32];
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
///Our own hasher.
|
||||
/// Currently it is SHA256 hasher wrapper. May change in a future.
|
||||
pub struct OwnHasher {}
|
||||
|
||||
impl OwnHasher {
|
||||
fn hash(data: &[u8]) -> HashType {
|
||||
let mut hasher = Sha256::new();
|
||||
|
||||
hasher.update(data);
|
||||
<HashType>::from(hasher.finalize_fixed())
|
||||
}
|
||||
}
|
||||
|
||||
pub type BlockHash = [u8; 32];
|
||||
pub type BlockId = u64;
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::CommitmentHashType;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq)]
|
||||
pub struct Commitment {
|
||||
pub commitment_hash: CommitmentHashType,
|
||||
}
|
||||
52
common/src/error.rs
Normal file
52
common/src/error.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::rpc_primitives::errors::RpcError;
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct SequencerRpcError {
|
||||
pub jsonrpc: String,
|
||||
pub error: RpcError,
|
||||
pub id: u64,
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum SequencerClientError {
|
||||
#[error("HTTP error")]
|
||||
HTTPError(reqwest::Error),
|
||||
#[error("Serde error")]
|
||||
SerdeError(serde_json::Error),
|
||||
#[error("Internal error")]
|
||||
InternalError(SequencerRpcError),
|
||||
}
|
||||
|
||||
impl From<reqwest::Error> for SequencerClientError {
|
||||
fn from(value: reqwest::Error) -> Self {
|
||||
SequencerClientError::HTTPError(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for SequencerClientError {
|
||||
fn from(value: serde_json::Error) -> Self {
|
||||
SequencerClientError::SerdeError(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SequencerRpcError> for SequencerClientError {
|
||||
fn from(value: SequencerRpcError) -> Self {
|
||||
SequencerClientError::InternalError(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ExecutionFailureKind {
|
||||
#[error("Failed to get account data from sequencer")]
|
||||
SequencerError,
|
||||
#[error("Inputs amounts does not match outputs")]
|
||||
AmountMismatchError,
|
||||
#[error("Accounts key not found")]
|
||||
KeyNotFoundError,
|
||||
#[error("Sequencer client error: {0:?}")]
|
||||
SequencerClientError(#[from] SequencerClientError),
|
||||
#[error("Can not pay for operation")]
|
||||
InsufficientFundsError,
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::TreeHashType;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PublicNativeTokenSend {
|
||||
pub from: TreeHashType,
|
||||
pub nonce: u64,
|
||||
pub to: TreeHashType,
|
||||
pub balance_to_move: u64,
|
||||
}
|
||||
@ -1,124 +1,10 @@
|
||||
use rs_merkle::Hasher;
|
||||
use serde::Deserialize;
|
||||
use sha2::{Digest, Sha256, digest::FixedOutput};
|
||||
|
||||
pub mod block;
|
||||
pub mod commitment;
|
||||
pub mod execution_input;
|
||||
pub mod nullifier;
|
||||
pub mod error;
|
||||
pub mod rpc_primitives;
|
||||
pub mod sequencer_client;
|
||||
pub mod transaction;
|
||||
pub mod utxo_commitment;
|
||||
|
||||
//Module for tests utility functions
|
||||
//TODO: Compile only for tests
|
||||
pub mod test_utils;
|
||||
|
||||
use rpc_primitives::errors::RpcError;
|
||||
|
||||
pub type TreeHashType = [u8; 32];
|
||||
pub type CommitmentHashType = Vec<u8>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
///Our own hasher.
|
||||
/// Currently it is SHA256 hasher wrapper. May change in a future.
|
||||
pub struct OwnHasher {}
|
||||
|
||||
impl Hasher for OwnHasher {
|
||||
type Hash = TreeHashType;
|
||||
|
||||
fn hash(data: &[u8]) -> TreeHashType {
|
||||
let mut hasher = Sha256::new();
|
||||
|
||||
hasher.update(data);
|
||||
<TreeHashType>::from(hasher.finalize_fixed())
|
||||
}
|
||||
}
|
||||
|
||||
///Account id on blockchain
|
||||
pub type AccountId = TreeHashType;
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct SequencerRpcError {
|
||||
pub jsonrpc: String,
|
||||
pub error: RpcError,
|
||||
pub id: u64,
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum SequencerClientError {
|
||||
#[error("HTTP error")]
|
||||
HTTPError(reqwest::Error),
|
||||
#[error("Serde error")]
|
||||
SerdeError(serde_json::Error),
|
||||
#[error("Internal error")]
|
||||
InternalError(SequencerRpcError),
|
||||
}
|
||||
|
||||
impl From<reqwest::Error> for SequencerClientError {
|
||||
fn from(value: reqwest::Error) -> Self {
|
||||
SequencerClientError::HTTPError(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for SequencerClientError {
|
||||
fn from(value: serde_json::Error) -> Self {
|
||||
SequencerClientError::SerdeError(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SequencerRpcError> for SequencerClientError {
|
||||
fn from(value: SequencerRpcError) -> Self {
|
||||
SequencerClientError::InternalError(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ExecutionFailureKind {
|
||||
#[error("Failed to write into builder err: {0:?}")]
|
||||
WriteError(anyhow::Error),
|
||||
#[error("Failed to interact with a db err: {0:?}")]
|
||||
DBError(anyhow::Error),
|
||||
#[error("Failed to build builder err: {0:?}")]
|
||||
BuilderError(anyhow::Error),
|
||||
#[error("Failed prove execution err: {0:?}")]
|
||||
ProveError(anyhow::Error),
|
||||
#[error("Failed to decode data from VM: {0:?}")]
|
||||
DecodeError(String),
|
||||
#[error("Failed to get account data from sequencer")]
|
||||
SequencerError,
|
||||
#[error("Inputs amounts does not match outputs")]
|
||||
AmountMismatchError,
|
||||
#[error("Accounts key not found")]
|
||||
KeyNotFoundError,
|
||||
#[error("Sequencer client error: {0:?}")]
|
||||
SequencerClientError(#[from] SequencerClientError),
|
||||
#[error("Insufficient gas for operation")]
|
||||
InsufficientGasError,
|
||||
#[error("Can not pay for operation")]
|
||||
InsufficientFundsError,
|
||||
}
|
||||
|
||||
impl ExecutionFailureKind {
|
||||
pub fn write_error(err: anyhow::Error) -> Self {
|
||||
Self::WriteError(err)
|
||||
}
|
||||
|
||||
pub fn builder_error(err: anyhow::Error) -> Self {
|
||||
Self::BuilderError(err)
|
||||
}
|
||||
|
||||
pub fn prove_error(err: anyhow::Error) -> Self {
|
||||
Self::ProveError(err)
|
||||
}
|
||||
|
||||
pub fn db_error(err: anyhow::Error) -> Self {
|
||||
Self::DBError(err)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum TransactionSignatureError {
|
||||
#[error("invalid signature for transaction body")]
|
||||
InvalidSignature,
|
||||
}
|
||||
pub type HashType = [u8; 32];
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::TreeHashType;
|
||||
|
||||
//ToDo: Update Nullifier model, when it is clear
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash)]
|
||||
///General nullifier object
|
||||
pub struct UTXONullifier {
|
||||
pub utxo_hash: TreeHashType,
|
||||
}
|
||||
@ -10,6 +10,7 @@ use nssa_core::program::ProgramId;
|
||||
use reqwest::Client;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::error::{SequencerClientError, SequencerRpcError};
|
||||
use crate::rpc_primitives::requests::{
|
||||
GetAccountRequest, GetAccountResponse, GetAccountsNoncesRequest, GetAccountsNoncesResponse,
|
||||
GetLastBlockRequest, GetLastBlockResponse, GetProgramIdsRequest, GetProgramIdsResponse,
|
||||
@ -18,7 +19,6 @@ use crate::rpc_primitives::requests::{
|
||||
};
|
||||
use crate::sequencer_client::json::AccountInitialData;
|
||||
use crate::transaction::{EncodedTransaction, NSSATransaction};
|
||||
use crate::{SequencerClientError, SequencerRpcError};
|
||||
|
||||
pub mod json;
|
||||
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
use borsh::{BorshDeserialize, BorshSerialize};
|
||||
use k256::ecdsa::{Signature, SigningKey, VerifyingKey};
|
||||
use log::info;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use sha2::{Digest, digest::FixedOutput};
|
||||
|
||||
pub type HashType = [u8; 32];
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum NSSATransaction {
|
||||
Public(nssa::PublicTransaction),
|
||||
@ -30,11 +31,6 @@ impl From<nssa::ProgramDeploymentTransaction> for NSSATransaction {
|
||||
}
|
||||
}
|
||||
|
||||
use crate::TreeHashType;
|
||||
|
||||
pub type CipherText = Vec<u8>;
|
||||
pub type Tag = u8;
|
||||
|
||||
#[derive(
|
||||
Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, BorshSerialize, BorshDeserialize,
|
||||
)]
|
||||
@ -90,106 +86,13 @@ impl TryFrom<&EncodedTransaction> for NSSATransaction {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct MintMoneyPublicTx {
|
||||
pub acc: [u8; 32],
|
||||
pub amount: u128,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct SendMoneyShieldedTx {
|
||||
pub acc_sender: [u8; 32],
|
||||
pub amount: u128,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct SendMoneyDeshieldedTx {
|
||||
pub receiver_data: Vec<(u128, [u8; 32])>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct OwnedUTXO {
|
||||
pub hash: [u8; 32],
|
||||
pub owner: [u8; 32],
|
||||
pub amount: u128,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct OwnedUTXOForPublication {
|
||||
pub hash: String,
|
||||
pub owner: String,
|
||||
pub amount: u128,
|
||||
}
|
||||
|
||||
impl From<OwnedUTXO> for OwnedUTXOForPublication {
|
||||
fn from(value: OwnedUTXO) -> Self {
|
||||
Self {
|
||||
hash: hex::encode(value.hash),
|
||||
owner: hex::encode(value.owner),
|
||||
amount: value.amount,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct UTXOPublication {
|
||||
pub utxos: Vec<OwnedUTXO>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum ActionData {
|
||||
MintMoneyPublicTx(MintMoneyPublicTx),
|
||||
SendMoneyShieldedTx(SendMoneyShieldedTx),
|
||||
SendMoneyDeshieldedTx(SendMoneyDeshieldedTx),
|
||||
UTXOPublication(UTXOPublication),
|
||||
}
|
||||
|
||||
impl ActionData {
|
||||
pub fn into_hexed_print(self) -> String {
|
||||
match self {
|
||||
ActionData::MintMoneyPublicTx(action) => {
|
||||
format!(
|
||||
"Account {:?} minted {:?} balance",
|
||||
hex::encode(action.acc),
|
||||
action.amount
|
||||
)
|
||||
}
|
||||
ActionData::SendMoneyDeshieldedTx(action) => {
|
||||
format!(
|
||||
"Receivers receipt {:?}",
|
||||
action
|
||||
.receiver_data
|
||||
.into_iter()
|
||||
.map(|(amount, rec)| (amount, hex::encode(rec)))
|
||||
.collect::<Vec<_>>()
|
||||
)
|
||||
}
|
||||
ActionData::SendMoneyShieldedTx(action) => {
|
||||
format!(
|
||||
"Shielded send from {:?} for {:?} balance",
|
||||
hex::encode(action.acc_sender),
|
||||
action.amount
|
||||
)
|
||||
}
|
||||
ActionData::UTXOPublication(action) => {
|
||||
let pub_own_utxo: Vec<OwnedUTXOForPublication> = action
|
||||
.utxos
|
||||
.into_iter()
|
||||
.map(|owned_utxo| owned_utxo.into())
|
||||
.collect();
|
||||
format!("Published utxos {pub_own_utxo:?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EncodedTransaction {
|
||||
/// Computes and returns the SHA-256 hash of the JSON-serialized representation of `self`.
|
||||
pub fn hash(&self) -> TreeHashType {
|
||||
pub fn hash(&self) -> HashType {
|
||||
let bytes_to_hash = borsh::to_vec(&self).unwrap();
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(&bytes_to_hash);
|
||||
TreeHashType::from(hasher.finalize_fixed())
|
||||
HashType::from(hasher.finalize_fixed())
|
||||
}
|
||||
|
||||
pub fn log(&self) {
|
||||
@ -198,16 +101,12 @@ impl EncodedTransaction {
|
||||
}
|
||||
}
|
||||
|
||||
pub type TransactionSignature = Signature;
|
||||
pub type SignaturePublicKey = VerifyingKey;
|
||||
pub type SignaturePrivateKey = SigningKey;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use sha2::{Digest, digest::FixedOutput};
|
||||
|
||||
use crate::{
|
||||
TreeHashType,
|
||||
HashType,
|
||||
transaction::{EncodedTransaction, TxKind},
|
||||
};
|
||||
|
||||
@ -225,7 +124,7 @@ mod tests {
|
||||
let data = borsh::to_vec(&body).unwrap();
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(&data);
|
||||
TreeHashType::from(hasher.finalize_fixed())
|
||||
HashType::from(hasher.finalize_fixed())
|
||||
};
|
||||
|
||||
let hash = body.hash();
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::TreeHashType;
|
||||
|
||||
//ToDo: Update UTXO Commitment model, when it is clear
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
///General commitment object
|
||||
pub struct UTXOCommitment {
|
||||
pub hash: TreeHashType,
|
||||
}
|
||||
2
env.sh
2
env.sh
@ -1,2 +0,0 @@
|
||||
export NULLIFIER_SECRET_CONST="261d61d294ac4bdc24f91b6f490efa263757a4a95f65871cd4f16b2ea23c3b5d"
|
||||
export VIEWING_SECRET_CONST="6117af750b30d7a296672ec3b3b25d3489beca3cfe5770fa39f275cec395d5ce"
|
||||
@ -1,5 +1,5 @@
|
||||
use bip39::Mnemonic;
|
||||
use common::TreeHashType;
|
||||
use common::HashType;
|
||||
use nssa_core::{
|
||||
NullifierPublicKey, NullifierSecretKey,
|
||||
encryption::{IncomingViewingPublicKey, Scalar},
|
||||
@ -44,7 +44,7 @@ impl SeedHolder {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_secret_spending_key_hash(&self) -> TreeHashType {
|
||||
pub fn generate_secret_spending_key_hash(&self) -> HashType {
|
||||
let mut hash = hmac_sha512::HMAC::mac(&self.seed, "NSSA_seed");
|
||||
|
||||
for _ in 1..2048 {
|
||||
@ -80,7 +80,7 @@ impl SecretSpendingKey {
|
||||
hasher.update([2u8]);
|
||||
hasher.update([0u8; 22]);
|
||||
|
||||
<TreeHashType>::from(hasher.finalize_fixed())
|
||||
<HashType>::from(hasher.finalize_fixed())
|
||||
}
|
||||
|
||||
pub fn generate_outgoing_viewing_secret_key(&self) -> OutgoingViewingSecretKey {
|
||||
@ -91,7 +91,7 @@ impl SecretSpendingKey {
|
||||
hasher.update([3u8]);
|
||||
hasher.update([0u8; 22]);
|
||||
|
||||
<TreeHashType>::from(hasher.finalize_fixed())
|
||||
<HashType>::from(hasher.finalize_fixed())
|
||||
}
|
||||
|
||||
pub fn produce_private_key_holder(&self) -> PrivateKeyHolder {
|
||||
|
||||
@ -2,7 +2,7 @@ use std::fmt::Display;
|
||||
|
||||
use anyhow::Result;
|
||||
use common::{
|
||||
TreeHashType,
|
||||
HashType,
|
||||
block::HashableBlockData,
|
||||
transaction::{EncodedTransaction, NSSATransaction},
|
||||
};
|
||||
@ -23,29 +23,19 @@ pub struct SequencerCore {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub enum TransactionMalformationErrorKind {
|
||||
PublicTransactionChangedPrivateData { tx: TreeHashType },
|
||||
PrivateTransactionChangedPublicData { tx: TreeHashType },
|
||||
TxHashAlreadyPresentInTree { tx: TreeHashType },
|
||||
NullifierAlreadyPresentInTree { tx: TreeHashType },
|
||||
UTXOCommitmentAlreadyPresentInTree { tx: TreeHashType },
|
||||
pub enum TransactionMalformationError {
|
||||
MempoolFullForRound,
|
||||
ChainStateFurtherThanTransactionState { tx: TreeHashType },
|
||||
FailedToInsert { tx: TreeHashType, details: String },
|
||||
InvalidSignature,
|
||||
IncorrectSender,
|
||||
BalanceMismatch { tx: TreeHashType },
|
||||
NonceMismatch { tx: TreeHashType },
|
||||
FailedToDecode { tx: TreeHashType },
|
||||
FailedToDecode { tx: HashType },
|
||||
}
|
||||
|
||||
impl Display for TransactionMalformationErrorKind {
|
||||
impl Display for TransactionMalformationError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{self:#?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for TransactionMalformationErrorKind {}
|
||||
impl std::error::Error for TransactionMalformationError {}
|
||||
|
||||
impl SequencerCore {
|
||||
pub fn start_from_config(config: SequencerConfig) -> Self {
|
||||
@ -81,21 +71,21 @@ impl SequencerCore {
|
||||
pub fn transaction_pre_check(
|
||||
&mut self,
|
||||
tx: NSSATransaction,
|
||||
) -> Result<NSSATransaction, TransactionMalformationErrorKind> {
|
||||
) -> Result<NSSATransaction, TransactionMalformationError> {
|
||||
// Stateless checks here
|
||||
match tx {
|
||||
NSSATransaction::Public(tx) => {
|
||||
if tx.witness_set().is_valid_for(tx.message()) {
|
||||
Ok(NSSATransaction::Public(tx))
|
||||
} else {
|
||||
Err(TransactionMalformationErrorKind::InvalidSignature)
|
||||
Err(TransactionMalformationError::InvalidSignature)
|
||||
}
|
||||
}
|
||||
NSSATransaction::PrivacyPreserving(tx) => {
|
||||
if tx.witness_set().signatures_are_valid_for(tx.message()) {
|
||||
Ok(NSSATransaction::PrivacyPreserving(tx))
|
||||
} else {
|
||||
Err(TransactionMalformationErrorKind::InvalidSignature)
|
||||
Err(TransactionMalformationError::InvalidSignature)
|
||||
}
|
||||
}
|
||||
NSSATransaction::ProgramDeployment(tx) => Ok(NSSATransaction::ProgramDeployment(tx)),
|
||||
@ -105,16 +95,16 @@ impl SequencerCore {
|
||||
pub fn push_tx_into_mempool_pre_check(
|
||||
&mut self,
|
||||
transaction: EncodedTransaction,
|
||||
) -> Result<(), TransactionMalformationErrorKind> {
|
||||
) -> Result<(), TransactionMalformationError> {
|
||||
let transaction = NSSATransaction::try_from(&transaction).map_err(|_| {
|
||||
TransactionMalformationErrorKind::FailedToDecode {
|
||||
TransactionMalformationError::FailedToDecode {
|
||||
tx: transaction.hash(),
|
||||
}
|
||||
})?;
|
||||
|
||||
let mempool_size = self.mempool.len();
|
||||
if mempool_size >= self.sequencer_config.max_num_tx_in_block {
|
||||
return Err(TransactionMalformationErrorKind::MempoolFullForRound);
|
||||
return Err(TransactionMalformationError::MempoolFullForRound);
|
||||
}
|
||||
|
||||
let authenticated_tx = self
|
||||
@ -163,7 +153,7 @@ impl SequencerCore {
|
||||
|
||||
while let Some(tx) = self.mempool.pop_last() {
|
||||
let nssa_transaction = NSSATransaction::try_from(&tx)
|
||||
.map_err(|_| TransactionMalformationErrorKind::FailedToDecode { tx: tx.hash() })?;
|
||||
.map_err(|_| TransactionMalformationError::FailedToDecode { tx: tx.hash() })?;
|
||||
|
||||
if let Ok(valid_tx) = self.execute_check_transaction_on_state(nssa_transaction) {
|
||||
valid_transactions.push(valid_tx.into());
|
||||
@ -212,7 +202,7 @@ mod tests {
|
||||
|
||||
fn parse_unwrap_tx_body_into_nssa_tx(tx_body: EncodedTransaction) -> NSSATransaction {
|
||||
NSSATransaction::try_from(&tx_body)
|
||||
.map_err(|_| TransactionMalformationErrorKind::FailedToDecode { tx: tx_body.hash() })
|
||||
.map_err(|_| TransactionMalformationError::FailedToDecode { tx: tx_body.hash() })
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
@ -537,7 +527,7 @@ mod tests {
|
||||
|
||||
assert!(matches!(
|
||||
result,
|
||||
Err(TransactionMalformationErrorKind::MempoolFullForRound)
|
||||
Err(TransactionMalformationError::MempoolFullForRound)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
use std::{collections::HashMap, path::Path};
|
||||
|
||||
use anyhow::Result;
|
||||
use common::{TreeHashType, block::Block, transaction::EncodedTransaction};
|
||||
use common::{HashType, block::Block, transaction::EncodedTransaction};
|
||||
use storage::RocksDBIO;
|
||||
|
||||
pub struct SequecerBlockStore {
|
||||
dbio: RocksDBIO,
|
||||
// TODO: Consider adding the hashmap to the database for faster recovery.
|
||||
tx_hash_to_block_map: HashMap<TreeHashType, u64>,
|
||||
tx_hash_to_block_map: HashMap<HashType, u64>,
|
||||
pub genesis_id: u64,
|
||||
pub signing_key: nssa::PrivateKey,
|
||||
}
|
||||
@ -57,7 +57,7 @@ impl SequecerBlockStore {
|
||||
}
|
||||
|
||||
/// Returns the transaction corresponding to the given hash, if it exists in the blockchain.
|
||||
pub fn get_transaction_by_hash(&self, hash: TreeHashType) -> Option<EncodedTransaction> {
|
||||
pub fn get_transaction_by_hash(&self, hash: HashType) -> Option<EncodedTransaction> {
|
||||
let block_id = self.tx_hash_to_block_map.get(&hash);
|
||||
let block = block_id.map(|&id| self.get_block_at_id(id));
|
||||
if let Some(Ok(block)) = block {
|
||||
@ -71,7 +71,7 @@ impl SequecerBlockStore {
|
||||
}
|
||||
}
|
||||
|
||||
fn block_to_transactions_map(block: &Block) -> HashMap<TreeHashType, u64> {
|
||||
fn block_to_transactions_map(block: &Block) -> HashMap<HashType, u64> {
|
||||
block
|
||||
.body
|
||||
.transactions
|
||||
|
||||
@ -7,7 +7,7 @@ use sequencer_core::config::AccountInitialData;
|
||||
use serde_json::Value;
|
||||
|
||||
use common::{
|
||||
TreeHashType,
|
||||
HashType,
|
||||
block::HashableBlockData,
|
||||
rpc_primitives::{
|
||||
errors::RpcError,
|
||||
@ -236,7 +236,7 @@ impl JsonHandler {
|
||||
let get_transaction_req = GetTransactionByHashRequest::parse(Some(request.params))?;
|
||||
let bytes: Vec<u8> = hex::decode(get_transaction_req.hash)
|
||||
.map_err(|_| RpcError::invalid_params("invalid hex".to_string()))?;
|
||||
let hash: TreeHashType = bytes
|
||||
let hash: HashType = bytes
|
||||
.try_into()
|
||||
.map_err(|_| RpcError::invalid_params("invalid length".to_string()))?;
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use log::debug;
|
||||
|
||||
use common::rpc_primitives::errors::{RpcError, RpcParseError};
|
||||
use sequencer_core::TransactionMalformationErrorKind;
|
||||
use sequencer_core::TransactionMalformationError;
|
||||
|
||||
pub struct RpcErr(pub RpcError);
|
||||
|
||||
@ -41,7 +41,7 @@ impl RpcErrKind for RpcErrInternal {
|
||||
}
|
||||
}
|
||||
|
||||
impl RpcErrKind for TransactionMalformationErrorKind {
|
||||
impl RpcErrKind for TransactionMalformationError {
|
||||
fn into_rpc_err(self) -> RpcError {
|
||||
RpcError::new_internal_error(
|
||||
Some(serde_json::to_value(self).unwrap()),
|
||||
|
||||
@ -26,8 +26,6 @@ pub const DB_META_FIRST_BLOCK_IN_DB_KEY: &str = "first_block_in_db";
|
||||
pub const DB_META_LAST_BLOCK_IN_DB_KEY: &str = "last_block_in_db";
|
||||
///Key base for storing metainformation which describe if first block has been set
|
||||
pub const DB_META_FIRST_BLOCK_SET_KEY: &str = "first_block_set";
|
||||
///Key to list of all known smart contract addresses
|
||||
pub const DB_META_SC_LIST: &str = "sc_list";
|
||||
|
||||
///Key base for storing snapshot which describe block id
|
||||
pub const DB_SNAPSHOT_BLOCK_ID_KEY: &str = "block_id";
|
||||
@ -36,8 +34,6 @@ pub const DB_SNAPSHOT_BLOCK_ID_KEY: &str = "block_id";
|
||||
pub const CF_BLOCK_NAME: &str = "cf_block";
|
||||
///Name of meta column family
|
||||
pub const CF_META_NAME: &str = "cf_meta";
|
||||
///Name of smart contract column family
|
||||
pub const CF_SC_NAME: &str = "cf_sc";
|
||||
///Name of snapshot column family
|
||||
pub const CF_SNAPSHOT_NAME: &str = "cf_snapshot";
|
||||
|
||||
@ -54,7 +50,6 @@ impl RocksDBIO {
|
||||
//ToDo: Add more column families for different data
|
||||
let cfb = ColumnFamilyDescriptor::new(CF_BLOCK_NAME, cf_opts.clone());
|
||||
let cfmeta = ColumnFamilyDescriptor::new(CF_META_NAME, cf_opts.clone());
|
||||
let cfsc = ColumnFamilyDescriptor::new(CF_SC_NAME, cf_opts.clone());
|
||||
let cfsnapshot = ColumnFamilyDescriptor::new(CF_SNAPSHOT_NAME, cf_opts.clone());
|
||||
|
||||
let mut db_opts = Options::default();
|
||||
@ -63,7 +58,7 @@ impl RocksDBIO {
|
||||
let db = DBWithThreadMode::<MultiThreaded>::open_cf_descriptors(
|
||||
&db_opts,
|
||||
path,
|
||||
vec![cfb, cfmeta, cfsc, cfsnapshot],
|
||||
vec![cfb, cfmeta, cfsnapshot],
|
||||
);
|
||||
|
||||
let dbio = Self {
|
||||
@ -82,8 +77,6 @@ impl RocksDBIO {
|
||||
|
||||
dbio.put_meta_last_block_in_db(block_id)?;
|
||||
|
||||
dbio.put_meta_sc_list(vec![])?;
|
||||
|
||||
Ok(dbio)
|
||||
} else {
|
||||
// Here we are trying to start a DB without a block, one should not do it.
|
||||
@ -114,10 +107,6 @@ impl RocksDBIO {
|
||||
self.db.cf_handle(CF_BLOCK_NAME).unwrap()
|
||||
}
|
||||
|
||||
pub fn sc_column(&self) -> Arc<BoundColumnFamily<'_>> {
|
||||
self.db.cf_handle(CF_SC_NAME).unwrap()
|
||||
}
|
||||
|
||||
pub fn snapshot_column(&self) -> Arc<BoundColumnFamily<'_>> {
|
||||
self.db.cf_handle(CF_SNAPSHOT_NAME).unwrap()
|
||||
}
|
||||
@ -244,29 +233,6 @@ impl RocksDBIO {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
///Setting list of known smart contracts in a DB as a `sc_list`
|
||||
pub fn put_meta_sc_list(&self, sc_list: Vec<String>) -> DbResult<()> {
|
||||
let cf_meta = self.meta_column();
|
||||
self.db
|
||||
.put_cf(
|
||||
&cf_meta,
|
||||
borsh::to_vec(&DB_META_SC_LIST).map_err(|err| {
|
||||
DbError::borsh_cast_message(
|
||||
err,
|
||||
Some("Failed to serialize DB_META_SC_LIST".to_string()),
|
||||
)
|
||||
})?,
|
||||
borsh::to_vec(&sc_list).map_err(|err| {
|
||||
DbError::borsh_cast_message(
|
||||
err,
|
||||
Some("Failed to serialize list of sc".to_string()),
|
||||
)
|
||||
})?,
|
||||
)
|
||||
.map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn put_meta_is_first_block_set(&self) -> DbResult<()> {
|
||||
let cf_meta = self.meta_column();
|
||||
self.db
|
||||
@ -346,45 +312,6 @@ impl RocksDBIO {
|
||||
}
|
||||
}
|
||||
|
||||
///Getting list of known smart contracts in a DB
|
||||
pub fn get_meta_sc_list(&self) -> DbResult<Vec<String>> {
|
||||
let cf_meta = self.meta_column();
|
||||
let sc_list = self
|
||||
.db
|
||||
.get_cf(
|
||||
&cf_meta,
|
||||
borsh::to_vec(&DB_META_SC_LIST).map_err(|err| {
|
||||
DbError::borsh_cast_message(
|
||||
err,
|
||||
Some("Failed to serialize DB_META_SC_LIST".to_string()),
|
||||
)
|
||||
})?,
|
||||
)
|
||||
.map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?;
|
||||
if let Some(data) = sc_list {
|
||||
Ok(borsh::from_slice::<Vec<String>>(&data).map_err(|serr| {
|
||||
DbError::borsh_cast_message(
|
||||
serr,
|
||||
Some("List of Sc Deserialization failed".to_string()),
|
||||
)
|
||||
})?)
|
||||
} else {
|
||||
Err(DbError::db_interaction_error(
|
||||
"Sc list not found".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
///Push additional contract into list of known contracts in a DB
|
||||
pub fn put_meta_sc(&self, sc_addr: String) -> DbResult<()> {
|
||||
let mut sc_list = self.get_meta_sc_list()?;
|
||||
if !sc_list.contains(&sc_addr) {
|
||||
sc_list.push(sc_addr);
|
||||
}
|
||||
self.put_meta_sc_list(sc_list)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_snapshot_block_id(&self) -> DbResult<u64> {
|
||||
let cf_snapshot = self.snapshot_column();
|
||||
let res = self
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
|
||||
use nssa::{Address, privacy_preserving_transaction::circuit};
|
||||
use nssa_core::{MembershipProof, SharedSecretKey, account::AccountWithMetadata};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use nssa::{Account, Address, program::Program};
|
||||
use nssa_core::{
|
||||
MembershipProof, NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use nssa::Address;
|
||||
|
||||
use crate::WalletCore;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use common::ExecutionFailureKind;
|
||||
use common::error::ExecutionFailureKind;
|
||||
use nssa::{Account, program::Program};
|
||||
use nssa_core::program::InstructionData;
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use nssa::Address;
|
||||
use nssa_core::{
|
||||
MembershipProof, NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use nssa::{
|
||||
Address, PublicTransaction,
|
||||
program::Program,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use nssa::Address;
|
||||
use nssa_core::{
|
||||
MembershipProof, NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
|
||||
use nssa::{
|
||||
Account, Address, PrivacyPreservingTransaction,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user