mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-05 23:03:06 +00:00
Merge branch 'main' into schouhy/add-get-account-balance-rpc-method
This commit is contained in:
commit
af6608585c
45
.github/workflows/ci.yml
vendored
45
.github/workflows/ci.yml
vendored
@ -14,35 +14,13 @@ on:
|
|||||||
name: General
|
name: General
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-ubuntu-latest:
|
ubuntu-latest-pipeline:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
|
|
||||||
name: build - ubuntu-latest
|
name: ubuntu-latest-pipeline
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Install stable toolchain
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
profile: minimal
|
|
||||||
toolchain: nightly
|
|
||||||
override: true
|
|
||||||
- name: build - ubuntu-latest
|
|
||||||
if: success() || failure()
|
|
||||||
run: chmod 777 ./ci_scripts/build-ubuntu.sh && ./ci_scripts/build-ubuntu.sh
|
|
||||||
|
|
||||||
|
|
||||||
lint:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
platform: [ ubuntu-latest ]
|
|
||||||
runs-on: ${{ matrix.platform }}
|
|
||||||
timeout-minutes: 60
|
|
||||||
|
|
||||||
name: lint - ${{ matrix.crate }} - ${{ matrix.platform }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout sources
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Install stable toolchain
|
- name: Install stable toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
@ -53,25 +31,6 @@ jobs:
|
|||||||
- name: lint - ubuntu-latest
|
- name: lint - ubuntu-latest
|
||||||
if: success() || failure()
|
if: success() || failure()
|
||||||
run: chmod 777 ./ci_scripts/lint-ubuntu.sh && ./ci_scripts/lint-ubuntu.sh
|
run: chmod 777 ./ci_scripts/lint-ubuntu.sh && ./ci_scripts/lint-ubuntu.sh
|
||||||
|
|
||||||
|
|
||||||
test:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
platform: [ ubuntu-latest ]
|
|
||||||
runs-on: ${{ matrix.platform }}
|
|
||||||
timeout-minutes: 60
|
|
||||||
|
|
||||||
name: test - ${{ matrix.crate }} - ${{ matrix.platform }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout sources
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Install stable toolchain
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
profile: minimal
|
|
||||||
toolchain: nightly
|
|
||||||
override: true
|
|
||||||
- name: test ubuntu-latest
|
- name: test ubuntu-latest
|
||||||
if: success() || failure()
|
if: success() || failure()
|
||||||
run: chmod 777 ./ci_scripts/test-ubuntu.sh && ./ci_scripts/test-ubuntu.sh
|
run: chmod 777 ./ci_scripts/test-ubuntu.sh && ./ci_scripts/test-ubuntu.sh
|
||||||
|
|||||||
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -1010,6 +1010,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
"hex",
|
"hex",
|
||||||
|
"k256",
|
||||||
"log",
|
"log",
|
||||||
"reqwest 0.11.27",
|
"reqwest 0.11.27",
|
||||||
"risc0-zkvm",
|
"risc0-zkvm",
|
||||||
@ -1260,6 +1261,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
|
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"const-oid",
|
"const-oid",
|
||||||
|
"pem-rfc7468",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1499,6 +1501,7 @@ dependencies = [
|
|||||||
"ff",
|
"ff",
|
||||||
"generic-array",
|
"generic-array",
|
||||||
"group",
|
"group",
|
||||||
|
"pem-rfc7468",
|
||||||
"pkcs8",
|
"pkcs8",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"sec1",
|
"sec1",
|
||||||
@ -3209,6 +3212,15 @@ version = "0.1.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pem-rfc7468"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
|
||||||
|
dependencies = [
|
||||||
|
"base64ct",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
|||||||
@ -55,7 +55,7 @@ features = ["std", "std_rng", "getrandom"]
|
|||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
|
|
||||||
[workspace.dependencies.k256]
|
[workspace.dependencies.k256]
|
||||||
features = ["ecdsa-core", "arithmetic", "expose-field", "serde"]
|
features = ["ecdsa-core", "arithmetic", "expose-field", "serde", "pem"]
|
||||||
version = "0.13.4"
|
version = "0.13.4"
|
||||||
|
|
||||||
[workspace.dependencies.elliptic-curve]
|
[workspace.dependencies.elliptic-curve]
|
||||||
|
|||||||
@ -2,12 +2,14 @@ use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit};
|
|||||||
use common::merkle_tree_public::TreeHashType;
|
use common::merkle_tree_public::TreeHashType;
|
||||||
use constants_types::{CipherText, Nonce};
|
use constants_types::{CipherText, Nonce};
|
||||||
use elliptic_curve::point::AffineCoordinates;
|
use elliptic_curve::point::AffineCoordinates;
|
||||||
use k256::AffinePoint;
|
use k256::{ecdsa::SigningKey, AffinePoint, FieldBytes};
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use rand::{rngs::OsRng, RngCore};
|
||||||
use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder};
|
use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::account_core::PublicKey;
|
use crate::account_core::PublicKey;
|
||||||
|
pub type PublicAccountSigningKey = [u8; 32];
|
||||||
|
|
||||||
pub mod constants_types;
|
pub mod constants_types;
|
||||||
pub mod ephemeral_key_holder;
|
pub mod ephemeral_key_holder;
|
||||||
@ -20,6 +22,7 @@ pub struct AddressKeyHolder {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
top_secret_key_holder: TopSecretKeyHolder,
|
top_secret_key_holder: TopSecretKeyHolder,
|
||||||
pub utxo_secret_key_holder: UTXOSecretKeyHolder,
|
pub utxo_secret_key_holder: UTXOSecretKeyHolder,
|
||||||
|
pub_account_signing_key: PublicAccountSigningKey,
|
||||||
pub address: TreeHashType,
|
pub address: TreeHashType,
|
||||||
pub nullifer_public_key: PublicKey,
|
pub nullifer_public_key: PublicKey,
|
||||||
pub viewing_public_key: PublicKey,
|
pub viewing_public_key: PublicKey,
|
||||||
@ -38,15 +41,29 @@ impl AddressKeyHolder {
|
|||||||
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
|
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
|
||||||
let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key();
|
let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key();
|
||||||
|
|
||||||
|
let pub_account_signing_key = {
|
||||||
|
let mut bytes = [0; 32];
|
||||||
|
OsRng.fill_bytes(&mut bytes);
|
||||||
|
bytes
|
||||||
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
top_secret_key_holder,
|
top_secret_key_holder,
|
||||||
utxo_secret_key_holder,
|
utxo_secret_key_holder,
|
||||||
address,
|
address,
|
||||||
nullifer_public_key,
|
nullifer_public_key,
|
||||||
viewing_public_key,
|
viewing_public_key,
|
||||||
|
pub_account_signing_key,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the signing key for public transaction signatures
|
||||||
|
pub fn get_pub_account_signing_key(&self) -> SigningKey {
|
||||||
|
let field_bytes = FieldBytes::from_slice(&self.pub_account_signing_key);
|
||||||
|
// TODO: remove unwrap
|
||||||
|
SigningKey::from_bytes(field_bytes).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn calculate_shared_secret_receiver(
|
pub fn calculate_shared_secret_receiver(
|
||||||
&self,
|
&self,
|
||||||
ephemeral_public_key_sender: AffinePoint,
|
ephemeral_public_key_sender: AffinePoint,
|
||||||
@ -166,7 +183,7 @@ mod tests {
|
|||||||
.decrypt_data(
|
.decrypt_data(
|
||||||
ephemeral_public_key_sender,
|
ephemeral_public_key_sender,
|
||||||
CipherText::from(ciphertext),
|
CipherText::from(ciphertext),
|
||||||
nonce.clone(),
|
*nonce,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -186,7 +203,7 @@ mod tests {
|
|||||||
assert!(!Into::<bool>::into(
|
assert!(!Into::<bool>::into(
|
||||||
address_key_holder.viewing_public_key.is_identity()
|
address_key_holder.viewing_public_key.is_identity()
|
||||||
));
|
));
|
||||||
assert!(address_key_holder.address.as_slice().len() > 0); // Assume TreeHashType has non-zero length for a valid address
|
assert!(!address_key_holder.address.as_slice().is_empty()); // Assume TreeHashType has non-zero length for a valid address
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -228,7 +245,7 @@ mod tests {
|
|||||||
.decrypt_data(
|
.decrypt_data(
|
||||||
ephemeral_public_key_sender,
|
ephemeral_public_key_sender,
|
||||||
CipherText::from(ciphertext.clone()),
|
CipherText::from(ciphertext.clone()),
|
||||||
incorrect_nonce.clone(),
|
*incorrect_nonce,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -264,7 +281,7 @@ mod tests {
|
|||||||
.decrypt_data(
|
.decrypt_data(
|
||||||
ephemeral_public_key_sender,
|
ephemeral_public_key_sender,
|
||||||
CipherText::from(corrupted_ciphertext),
|
CipherText::from(corrupted_ciphertext),
|
||||||
nonce.clone(),
|
*nonce,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -297,7 +314,7 @@ mod tests {
|
|||||||
.decrypt_data(
|
.decrypt_data(
|
||||||
ephemeral_public_key_sender,
|
ephemeral_public_key_sender,
|
||||||
CipherText::from(ciphertext),
|
CipherText::from(ciphertext),
|
||||||
nonce.clone(),
|
*nonce,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -305,6 +322,16 @@ mod tests {
|
|||||||
assert_eq!(decrypted_data, plaintext);
|
assert_eq!(decrypted_data, plaintext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_public_account_signing_key() {
|
||||||
|
let address_key_holder = AddressKeyHolder::new_os_random();
|
||||||
|
let signing_key = address_key_holder.get_pub_account_signing_key();
|
||||||
|
assert_eq!(
|
||||||
|
signing_key.to_bytes().as_slice(),
|
||||||
|
address_key_holder.pub_account_signing_key
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn key_generation_test() {
|
fn key_generation_test() {
|
||||||
let seed_holder = SeedHolder::new_os_random();
|
let seed_holder = SeedHolder::new_os_random();
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
curl -L https://risczero.com/install | bash
|
|
||||||
/home/runner/.risc0/bin/rzup install
|
|
||||||
source env.sh
|
source env.sh
|
||||||
cargo install taplo-cli --locked
|
cargo install taplo-cli --locked
|
||||||
|
|
||||||
cargo fmt -- --check
|
cargo fmt -- --check
|
||||||
taplo fmt --check
|
taplo fmt --check
|
||||||
|
|
||||||
|
export RISC0_SKIP_BUILD=1
|
||||||
|
cargo clippy --workspace --all-targets -- -D warnings
|
||||||
|
|||||||
@ -10,6 +10,7 @@ serde_json.workspace = true
|
|||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
reqwest.workspace = true
|
reqwest.workspace = true
|
||||||
risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" }
|
risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" }
|
||||||
|
k256.workspace = true
|
||||||
|
|
||||||
rs_merkle.workspace = true
|
rs_merkle.workspace = true
|
||||||
sha2.workspace = true
|
sha2.workspace = true
|
||||||
|
|||||||
@ -88,3 +88,9 @@ impl ExecutionFailureKind {
|
|||||||
Self::DBError(err)
|
Self::DBError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum TransactionSignatureError {
|
||||||
|
#[error("invalid signature for transaction body")]
|
||||||
|
InvalidSignature,
|
||||||
|
}
|
||||||
|
|||||||
@ -140,7 +140,7 @@ impl<Leav: TreeLeavItem + Clone> HashStorageMerkleTree<Leav> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_tx(&mut self, tx: Leav) {
|
pub fn add_tx(&mut self, tx: &Leav) {
|
||||||
let last = self.leaves.len();
|
let last = self.leaves.len();
|
||||||
|
|
||||||
self.leaves.insert(last, tx.clone());
|
self.leaves.insert(last, tx.clone());
|
||||||
@ -267,7 +267,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut tree = HashStorageMerkleTree::new(vec![tx1.clone()]);
|
let mut tree = HashStorageMerkleTree::new(vec![tx1.clone()]);
|
||||||
|
|
||||||
tree.add_tx(tx2.clone());
|
tree.add_tx(&tx2);
|
||||||
assert_eq!(tree.leaves.len(), 2);
|
assert_eq!(tree.leaves.len(), 2);
|
||||||
assert_eq!(tree.get_tx(tx2.hash()), Some(&tx2));
|
assert_eq!(tree.get_tx(tx2.hash()), Some(&tx2));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ pub trait TreeLeavItem {
|
|||||||
|
|
||||||
impl TreeLeavItem for Transaction {
|
impl TreeLeavItem for Transaction {
|
||||||
fn hash(&self) -> TreeHashType {
|
fn hash(&self) -> TreeHashType {
|
||||||
self.hash()
|
self.body().hash()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -447,7 +447,7 @@ mod tests {
|
|||||||
/// A helper for the `broken` test.
|
/// A helper for the `broken` test.
|
||||||
///
|
///
|
||||||
/// Check that the given JSON string parses, but is not recognized as a valid RPC message.
|
/// Check that the given JSON string parses, but is not recognized as a valid RPC message.
|
||||||
|
///
|
||||||
/// Test things that are almost but not entirely JSONRPC are rejected
|
/// Test things that are almost but not entirely JSONRPC are rejected
|
||||||
///
|
///
|
||||||
/// The reject is done by returning it as Unmatched.
|
/// The reject is done by returning it as Unmatched.
|
||||||
|
|||||||
@ -1,6 +1,11 @@
|
|||||||
|
use k256::ecdsa::{
|
||||||
|
signature::{Signer, Verifier},
|
||||||
|
Signature, SigningKey, VerifyingKey,
|
||||||
|
};
|
||||||
use log::info;
|
use log::info;
|
||||||
use secp256k1_zkp::{PedersenCommitment, Tweak};
|
use secp256k1_zkp::{PedersenCommitment, Tweak};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use sha2::{digest::FixedOutput, Digest};
|
use sha2::{digest::FixedOutput, Digest};
|
||||||
|
|
||||||
use crate::merkle_tree_public::TreeHashType;
|
use crate::merkle_tree_public::TreeHashType;
|
||||||
@ -11,11 +16,13 @@ use elliptic_curve::{
|
|||||||
};
|
};
|
||||||
use sha2::digest::typenum::{UInt, UTerm};
|
use sha2::digest::typenum::{UInt, UTerm};
|
||||||
|
|
||||||
|
use crate::TransactionSignatureError;
|
||||||
|
|
||||||
pub type CipherText = Vec<u8>;
|
pub type CipherText = Vec<u8>;
|
||||||
pub type Nonce = GenericArray<u8, UInt<UInt<UInt<UInt<UTerm, B1>, B1>, B0>, B0>>;
|
pub type Nonce = GenericArray<u8, UInt<UInt<UInt<UInt<UTerm, B1>, B1>, B0>, B0>>;
|
||||||
pub type Tag = u8;
|
pub type Tag = u8;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum TxKind {
|
pub enum TxKind {
|
||||||
Public,
|
Public,
|
||||||
Private,
|
Private,
|
||||||
@ -23,9 +30,9 @@ pub enum TxKind {
|
|||||||
Deshielded,
|
Deshielded,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
///General transaction object
|
///General transaction object
|
||||||
pub struct Transaction {
|
pub struct TransactionBody {
|
||||||
pub tx_kind: TxKind,
|
pub tx_kind: TxKind,
|
||||||
///Tx input data (public part)
|
///Tx input data (public part)
|
||||||
pub execution_input: Vec<u8>,
|
pub execution_input: Vec<u8>,
|
||||||
@ -144,22 +151,26 @@ impl ActionData {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|owned_utxo| owned_utxo.into())
|
.map(|owned_utxo| owned_utxo.into())
|
||||||
.collect();
|
.collect();
|
||||||
format!("Published utxos {:?}", pub_own_utxo)
|
format!("Published utxos {pub_own_utxo:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transaction {
|
impl TransactionBody {
|
||||||
/// Computes and returns the SHA-256 hash of the JSON-serialized representation of `self`.
|
/// Computes and returns the SHA-256 hash of the JSON-serialized representation of `self`.
|
||||||
pub fn hash(&self) -> TreeHashType {
|
pub fn hash(&self) -> TreeHashType {
|
||||||
|
let bytes_to_hash = self.to_bytes();
|
||||||
|
let mut hasher = sha2::Sha256::new();
|
||||||
|
hasher.update(&bytes_to_hash);
|
||||||
|
TreeHashType::from(hasher.finalize_fixed())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
// TODO: Remove `unwrap` by implementing a `to_bytes` method
|
// TODO: Remove `unwrap` by implementing a `to_bytes` method
|
||||||
// that deterministically encodes all transaction fields to bytes
|
// that deterministically encodes all transaction fields to bytes
|
||||||
// and guarantees serialization will succeed.
|
// and guarantees serialization will succeed.
|
||||||
let raw_data = serde_json::to_vec(&self).unwrap();
|
serde_json::to_vec(&self).unwrap()
|
||||||
let mut hasher = sha2::Sha256::new();
|
|
||||||
hasher.update(&raw_data);
|
|
||||||
TreeHashType::from(hasher.finalize_fixed())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log(&self) {
|
pub fn log(&self) {
|
||||||
@ -183,21 +194,21 @@ impl Transaction {
|
|||||||
"Transaction utxo_commitments_spent_hashes is {:?}",
|
"Transaction utxo_commitments_spent_hashes is {:?}",
|
||||||
self.utxo_commitments_spent_hashes
|
self.utxo_commitments_spent_hashes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|val| hex::encode(val.clone()))
|
.map(|val| hex::encode(*val))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
);
|
);
|
||||||
info!(
|
info!(
|
||||||
"Transaction utxo_commitments_created_hashes is {:?}",
|
"Transaction utxo_commitments_created_hashes is {:?}",
|
||||||
self.utxo_commitments_created_hashes
|
self.utxo_commitments_created_hashes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|val| hex::encode(val.clone()))
|
.map(|val| hex::encode(*val))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
);
|
);
|
||||||
info!(
|
info!(
|
||||||
"Transaction nullifier_created_hashes is {:?}",
|
"Transaction nullifier_created_hashes is {:?}",
|
||||||
self.nullifier_created_hashes
|
self.nullifier_created_hashes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|val| hex::encode(val.clone()))
|
.map(|val| hex::encode(*val))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
);
|
);
|
||||||
info!(
|
info!(
|
||||||
@ -214,19 +225,89 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TransactionHash = [u8; 32];
|
||||||
|
pub type TransactionSignature = Signature;
|
||||||
|
pub type SignaturePublicKey = VerifyingKey;
|
||||||
|
pub type SignaturePrivateKey = SigningKey;
|
||||||
|
|
||||||
|
/// A container for a transaction body with a signature.
|
||||||
|
/// Meant to be sent through the network to the sequencer
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
|
pub struct Transaction {
|
||||||
|
body: TransactionBody,
|
||||||
|
signature: TransactionSignature,
|
||||||
|
public_key: VerifyingKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Transaction {
|
||||||
|
/// Returns a new transaction signed with the provided `private_key`.
|
||||||
|
/// The signature is generated over the hash of the body as computed by `body.hash()`
|
||||||
|
pub fn new(body: TransactionBody, private_key: SigningKey) -> Transaction {
|
||||||
|
let signature: TransactionSignature = private_key.sign(&body.to_bytes());
|
||||||
|
let public_key = VerifyingKey::from(&private_key);
|
||||||
|
Self {
|
||||||
|
body,
|
||||||
|
signature,
|
||||||
|
public_key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts the transaction into an `AuthenticatedTransaction` by verifying its signature.
|
||||||
|
/// Returns an error if the signature verification fails.
|
||||||
|
pub fn into_authenticated(self) -> Result<AuthenticatedTransaction, TransactionSignatureError> {
|
||||||
|
let hash = self.body.hash();
|
||||||
|
|
||||||
|
self.public_key
|
||||||
|
.verify(&self.body.to_bytes(), &self.signature)
|
||||||
|
.map_err(|_| TransactionSignatureError::InvalidSignature)?;
|
||||||
|
|
||||||
|
Ok(AuthenticatedTransaction {
|
||||||
|
hash,
|
||||||
|
transaction: self,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the body of the transaction
|
||||||
|
pub fn body(&self) -> &TransactionBody {
|
||||||
|
&self.body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A transaction with a valid signature over the hash of its body.
|
||||||
|
/// Can only be constructed from an `Transaction`
|
||||||
|
/// if the signature is valid
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct AuthenticatedTransaction {
|
||||||
|
hash: TransactionHash,
|
||||||
|
transaction: Transaction,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthenticatedTransaction {
|
||||||
|
/// Returns the underlying transaction
|
||||||
|
pub fn transaction(&self) -> &Transaction {
|
||||||
|
&self.transaction
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the precomputed hash over the body of the transaction
|
||||||
|
pub fn hash(&self) -> &TransactionHash {
|
||||||
|
&self.hash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use k256::{ecdsa::signature::Signer, FieldBytes};
|
||||||
use secp256k1_zkp::{constants::SECRET_KEY_SIZE, Tweak};
|
use secp256k1_zkp::{constants::SECRET_KEY_SIZE, Tweak};
|
||||||
use sha2::{digest::FixedOutput, Digest};
|
use sha2::{digest::FixedOutput, Digest};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
merkle_tree_public::TreeHashType,
|
merkle_tree_public::TreeHashType,
|
||||||
transaction::{Transaction, TxKind},
|
transaction::{Transaction, TransactionBody, TxKind},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
fn test_transaction_body() -> TransactionBody {
|
||||||
fn test_transaction_hash_is_sha256_of_json_bytes() {
|
TransactionBody {
|
||||||
let tx = Transaction {
|
|
||||||
tx_kind: TxKind::Public,
|
tx_kind: TxKind::Public,
|
||||||
execution_input: vec![1, 2, 3, 4],
|
execution_input: vec![1, 2, 3, 4],
|
||||||
execution_output: vec![5, 6, 7, 8],
|
execution_output: vec![5, 6, 7, 8],
|
||||||
@ -241,16 +322,100 @@ mod tests {
|
|||||||
secret_r: [8; 32],
|
secret_r: [8; 32],
|
||||||
sc_addr: "someAddress".to_string(),
|
sc_addr: "someAddress".to_string(),
|
||||||
state_changes: (serde_json::Value::Null, 10),
|
state_changes: (serde_json::Value::Null, 10),
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_transaction() -> Transaction {
|
||||||
|
let body = test_transaction_body();
|
||||||
|
let key_bytes = FieldBytes::from_slice(&[37; 32]);
|
||||||
|
let private_key: SigningKey = SigningKey::from_bytes(key_bytes).unwrap();
|
||||||
|
Transaction::new(body, private_key)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_transaction_hash_is_sha256_of_json_bytes() {
|
||||||
|
let body = test_transaction_body();
|
||||||
let expected_hash = {
|
let expected_hash = {
|
||||||
let data = serde_json::to_vec(&tx).unwrap();
|
let data = serde_json::to_vec(&body).unwrap();
|
||||||
let mut hasher = sha2::Sha256::new();
|
let mut hasher = sha2::Sha256::new();
|
||||||
hasher.update(&data);
|
hasher.update(&data);
|
||||||
TreeHashType::from(hasher.finalize_fixed())
|
TreeHashType::from(hasher.finalize_fixed())
|
||||||
};
|
};
|
||||||
|
|
||||||
let hash = tx.hash();
|
let hash = body.hash();
|
||||||
|
|
||||||
assert_eq!(expected_hash, hash);
|
assert_eq!(expected_hash, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_transaction_constructor() {
|
||||||
|
let body = test_transaction_body();
|
||||||
|
let key_bytes = FieldBytes::from_slice(&[37; 32]);
|
||||||
|
let private_key: SigningKey = SigningKey::from_bytes(key_bytes).unwrap();
|
||||||
|
let transaction = Transaction::new(body.clone(), private_key.clone());
|
||||||
|
assert_eq!(
|
||||||
|
transaction.public_key,
|
||||||
|
SignaturePublicKey::from(&private_key)
|
||||||
|
);
|
||||||
|
assert_eq!(transaction.body, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_transaction_body_getter() {
|
||||||
|
let body = test_transaction_body();
|
||||||
|
let key_bytes = FieldBytes::from_slice(&[37; 32]);
|
||||||
|
let private_key: SigningKey = SigningKey::from_bytes(key_bytes).unwrap();
|
||||||
|
let transaction = Transaction::new(body.clone(), private_key.clone());
|
||||||
|
assert_eq!(transaction.body(), &body);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_into_authenticated_succeeds_for_valid_signature() {
|
||||||
|
let transaction = test_transaction();
|
||||||
|
let authenticated_tx = transaction.clone().into_authenticated().unwrap();
|
||||||
|
|
||||||
|
let signature = authenticated_tx.transaction().signature;
|
||||||
|
let hash = authenticated_tx.hash();
|
||||||
|
|
||||||
|
assert_eq!(authenticated_tx.transaction(), &transaction);
|
||||||
|
assert_eq!(hash, &transaction.body.hash());
|
||||||
|
assert!(authenticated_tx
|
||||||
|
.transaction()
|
||||||
|
.public_key
|
||||||
|
.verify(&transaction.body.to_bytes(), &signature)
|
||||||
|
.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_into_authenticated_fails_for_invalid_signature() {
|
||||||
|
let body = test_transaction_body();
|
||||||
|
let key_bytes = FieldBytes::from_slice(&[37; 32]);
|
||||||
|
let private_key: SigningKey = SigningKey::from_bytes(key_bytes).unwrap();
|
||||||
|
let transaction = {
|
||||||
|
let mut this = Transaction::new(body, private_key.clone());
|
||||||
|
// Modify the signature to make it invalid
|
||||||
|
// We do this by changing it to the signature of something else
|
||||||
|
this.signature = private_key.sign(b"deadbeef");
|
||||||
|
this
|
||||||
|
};
|
||||||
|
|
||||||
|
matches!(
|
||||||
|
transaction.into_authenticated(),
|
||||||
|
Err(TransactionSignatureError::InvalidSignature)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_authenticated_transaction_getter() {
|
||||||
|
let transaction = test_transaction();
|
||||||
|
let authenticated_tx = transaction.clone().into_authenticated().unwrap();
|
||||||
|
assert_eq!(authenticated_tx.transaction(), &transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_authenticated_transaction_hash_getter() {
|
||||||
|
let transaction = test_transaction();
|
||||||
|
let authenticated_tx = transaction.clone().into_authenticated().unwrap();
|
||||||
|
assert_eq!(authenticated_tx.hash(), &transaction.body.hash());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,7 +54,7 @@ mod tests {
|
|||||||
let mut store = NodeAccountsStore::new();
|
let mut store = NodeAccountsStore::new();
|
||||||
|
|
||||||
let account = create_sample_account(100);
|
let account = create_sample_account(100);
|
||||||
let account_addr = account.address.clone();
|
let account_addr = account.address;
|
||||||
|
|
||||||
store.register_account(account);
|
store.register_account(account);
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ mod tests {
|
|||||||
let mut store = NodeAccountsStore::new();
|
let mut store = NodeAccountsStore::new();
|
||||||
|
|
||||||
let account = create_sample_account(100);
|
let account = create_sample_account(100);
|
||||||
let account_addr = account.address.clone();
|
let account_addr = account.address;
|
||||||
store.register_account(account);
|
store.register_account(account);
|
||||||
|
|
||||||
assert_eq!(store.accounts.len(), 1);
|
assert_eq!(store.accounts.len(), 1);
|
||||||
@ -94,8 +94,8 @@ mod tests {
|
|||||||
let account1 = create_sample_account(100);
|
let account1 = create_sample_account(100);
|
||||||
let account2 = create_sample_account(200);
|
let account2 = create_sample_account(200);
|
||||||
|
|
||||||
let address_1 = account1.address.clone();
|
let address_1 = account1.address;
|
||||||
let address_2 = account2.address.clone();
|
let address_2 = account2.address;
|
||||||
|
|
||||||
store.register_account(account1);
|
store.register_account(account1);
|
||||||
store.register_account(account2);
|
store.register_account(account2);
|
||||||
|
|||||||
@ -145,8 +145,8 @@ mod tests {
|
|||||||
|
|
||||||
fn create_sample_block(block_id: u64, prev_block_id: u64) -> Block {
|
fn create_sample_block(block_id: u64, prev_block_id: u64) -> Block {
|
||||||
Block {
|
Block {
|
||||||
block_id: block_id,
|
block_id,
|
||||||
prev_block_id: prev_block_id,
|
prev_block_id,
|
||||||
prev_block_hash: [0; 32],
|
prev_block_hash: [0; 32],
|
||||||
hash: [1; 32],
|
hash: [1; 32],
|
||||||
transactions: vec![],
|
transactions: vec![],
|
||||||
@ -211,7 +211,7 @@ mod tests {
|
|||||||
|
|
||||||
// The genesis block should be available on reload
|
// The genesis block should be available on reload
|
||||||
let result = node_store.get_block_at_id(0);
|
let result = node_store.get_block_at_id(0);
|
||||||
assert!(!result.is_err());
|
assert!(result.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -79,7 +79,7 @@ impl NodeChainStore {
|
|||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
Self {
|
Self {
|
||||||
acc_map: From::from(acc_map),
|
acc_map,
|
||||||
block_store,
|
block_store,
|
||||||
nullifier_store,
|
nullifier_store,
|
||||||
utxo_commitments_store,
|
utxo_commitments_store,
|
||||||
@ -126,8 +126,9 @@ impl NodeChainStore {
|
|||||||
let block_id = block.block_id;
|
let block_id = block.block_id;
|
||||||
|
|
||||||
for tx in &block.transactions {
|
for tx in &block.transactions {
|
||||||
if !tx.execution_input.is_empty() {
|
if !tx.body().execution_input.is_empty() {
|
||||||
let public_action = serde_json::from_slice::<ActionData>(&tx.execution_input);
|
let public_action =
|
||||||
|
serde_json::from_slice::<ActionData>(&tx.body().execution_input);
|
||||||
|
|
||||||
if let Ok(public_action) = public_action {
|
if let Ok(public_action) = public_action {
|
||||||
match public_action {
|
match public_action {
|
||||||
@ -161,24 +162,25 @@ impl NodeChainStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.utxo_commitments_store.add_tx_multiple(
|
self.utxo_commitments_store.add_tx_multiple(
|
||||||
tx.utxo_commitments_created_hashes
|
tx.body()
|
||||||
|
.utxo_commitments_created_hashes
|
||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|hash| UTXOCommitment { hash })
|
.map(|hash| UTXOCommitment { hash })
|
||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
|
|
||||||
for nullifier in tx.nullifier_created_hashes.iter() {
|
for nullifier in tx.body().nullifier_created_hashes.iter() {
|
||||||
self.nullifier_store.insert(UTXONullifier {
|
self.nullifier_store.insert(UTXONullifier {
|
||||||
utxo_hash: *nullifier,
|
utxo_hash: *nullifier,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if !tx.encoded_data.is_empty() {
|
if !tx.body().encoded_data.is_empty() {
|
||||||
let ephemeral_public_key_sender =
|
let ephemeral_public_key_sender =
|
||||||
serde_json::from_slice::<AffinePoint>(&tx.ephemeral_pub_key)?;
|
serde_json::from_slice::<AffinePoint>(&tx.body().ephemeral_pub_key)?;
|
||||||
|
|
||||||
for (ciphertext, nonce, tag) in tx.encoded_data.clone() {
|
for (ciphertext, nonce, tag) in tx.body().encoded_data.clone() {
|
||||||
let slice = nonce.as_slice();
|
let slice = nonce.as_slice();
|
||||||
let nonce =
|
let nonce =
|
||||||
accounts::key_management::constants_types::Nonce::clone_from_slice(slice);
|
accounts::key_management::constants_types::Nonce::clone_from_slice(slice);
|
||||||
@ -203,13 +205,13 @@ impl NodeChainStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pub_tx_store.add_tx(tx.clone());
|
self.pub_tx_store.add_tx(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.block_store.put_block_at_id(block)?;
|
self.block_store.put_block_at_id(block)?;
|
||||||
|
|
||||||
//Snapshot
|
//Snapshot
|
||||||
if block_id % self.node_config.shapshot_frequency_in_blocks == 0 {
|
if block_id.is_multiple_of(self.node_config.shapshot_frequency_in_blocks) {
|
||||||
//Serializing all important data structures
|
//Serializing all important data structures
|
||||||
|
|
||||||
//If we fail serialization, it is not the reason to stop running
|
//If we fail serialization, it is not the reason to stop running
|
||||||
@ -241,8 +243,7 @@ impl NodeChainStore {
|
|||||||
);
|
);
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Snapshot executed at {:?} with results {snapshot_trace:#?}",
|
"Snapshot executed at {block_id:?} with results {snapshot_trace:#?}"
|
||||||
block_id
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,7 +284,7 @@ mod tests {
|
|||||||
use accounts::account_core::Account;
|
use accounts::account_core::Account;
|
||||||
use common::block::{Block, Data};
|
use common::block::{Block, Data};
|
||||||
use common::merkle_tree_public::TreeHashType;
|
use common::merkle_tree_public::TreeHashType;
|
||||||
use common::transaction::{Transaction, TxKind};
|
use common::transaction::{SignaturePrivateKey, Transaction, TransactionBody, TxKind};
|
||||||
use secp256k1_zkp::Tweak;
|
use secp256k1_zkp::Tweak;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
@ -306,7 +307,7 @@ mod tests {
|
|||||||
) -> Transaction {
|
) -> Transaction {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
Transaction {
|
let body = TransactionBody {
|
||||||
tx_kind: TxKind::Private,
|
tx_kind: TxKind::Private,
|
||||||
execution_input: vec![],
|
execution_input: vec![],
|
||||||
execution_output: vec![],
|
execution_output: vec![],
|
||||||
@ -321,13 +322,14 @@ mod tests {
|
|||||||
secret_r: [0; 32],
|
secret_r: [0; 32],
|
||||||
sc_addr: "sc_addr".to_string(),
|
sc_addr: "sc_addr".to_string(),
|
||||||
state_changes: (serde_json::Value::Null, 0),
|
state_changes: (serde_json::Value::Null, 0),
|
||||||
}
|
};
|
||||||
|
Transaction::new(body, SignaturePrivateKey::random(&mut rng))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_sample_block(block_id: u64, prev_block_id: u64) -> Block {
|
fn create_sample_block(block_id: u64, prev_block_id: u64) -> Block {
|
||||||
Block {
|
Block {
|
||||||
block_id: block_id,
|
block_id,
|
||||||
prev_block_id: prev_block_id,
|
prev_block_id,
|
||||||
prev_block_hash: [0; 32],
|
prev_block_hash: [0; 32],
|
||||||
hash: [1; 32],
|
hash: [1; 32],
|
||||||
transactions: vec![],
|
transactions: vec![],
|
||||||
@ -417,7 +419,7 @@ mod tests {
|
|||||||
store
|
store
|
||||||
.utxo_commitments_store
|
.utxo_commitments_store
|
||||||
.add_tx_multiple(vec![UTXOCommitment { hash: [3u8; 32] }]);
|
.add_tx_multiple(vec![UTXOCommitment { hash: [3u8; 32] }]);
|
||||||
store.pub_tx_store.add_tx(create_dummy_transaction(
|
store.pub_tx_store.add_tx(&create_dummy_transaction(
|
||||||
vec![[9; 32]],
|
vec![[9; 32]],
|
||||||
vec![[7; 32]],
|
vec![[7; 32]],
|
||||||
vec![[8; 32]],
|
vec![[8; 32]],
|
||||||
@ -435,9 +437,6 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(block_id, 1);
|
assert_eq!(block_id, 1);
|
||||||
assert_eq!(recovered_store.acc_map.len(), 1);
|
assert_eq!(recovered_store.acc_map.len(), 1);
|
||||||
assert_eq!(
|
assert!(recovered_store.utxo_commitments_store.get_root().is_some());
|
||||||
recovered_store.utxo_commitments_store.get_root().is_some(),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use std::sync::{
|
|||||||
Arc,
|
Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use common::ExecutionFailureKind;
|
use common::{transaction::Transaction, ExecutionFailureKind};
|
||||||
|
|
||||||
use accounts::{
|
use accounts::{
|
||||||
account_core::{Account, AccountAddress},
|
account_core::{Account, AccountAddress},
|
||||||
@ -11,7 +11,7 @@ use accounts::{
|
|||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use chain_storage::NodeChainStore;
|
use chain_storage::NodeChainStore;
|
||||||
use common::transaction::{Transaction, TxKind};
|
use common::transaction::{TransactionBody, TxKind};
|
||||||
use config::NodeConfig;
|
use config::NodeConfig;
|
||||||
use log::info;
|
use log::info;
|
||||||
use sc_core::proofs_circuits::{
|
use sc_core::proofs_circuits::{
|
||||||
@ -39,7 +39,7 @@ pub mod sequencer_client;
|
|||||||
fn vec_u8_to_vec_u64(bytes: Vec<u8>) -> Vec<u64> {
|
fn vec_u8_to_vec_u64(bytes: Vec<u8>) -> Vec<u64> {
|
||||||
// Pad with zeros to make sure it's a multiple of 8
|
// Pad with zeros to make sure it's a multiple of 8
|
||||||
let mut padded = bytes.clone();
|
let mut padded = bytes.clone();
|
||||||
while padded.len() % 8 != 0 {
|
while !padded.len().is_multiple_of(8) {
|
||||||
padded.push(0);
|
padded.push(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,12 +214,11 @@ impl NodeCore {
|
|||||||
|
|
||||||
let tag = account.make_tag();
|
let tag = account.make_tag();
|
||||||
|
|
||||||
let comm = generate_commitments(&vec![utxo]);
|
let comm = generate_commitments(&[utxo]);
|
||||||
|
|
||||||
let mint_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::MINT_UTXO_ID
|
let mint_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::MINT_UTXO_ID
|
||||||
.iter()
|
.iter()
|
||||||
.map(|num| num.to_le_bytes())
|
.flat_map(|num| num.to_le_bytes())
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
let sc_addr = hex::encode(mint_utxo_addr_bytes);
|
let sc_addr = hex::encode(mint_utxo_addr_bytes);
|
||||||
|
|
||||||
@ -247,31 +246,30 @@ impl NodeCore {
|
|||||||
let vec_public_info: Vec<u64> = vec_values_u64.into_iter().flatten().collect();
|
let vec_public_info: Vec<u64> = vec_values_u64.into_iter().flatten().collect();
|
||||||
|
|
||||||
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
||||||
|
let transaction_body = TransactionBody {
|
||||||
|
tx_kind: TxKind::Private,
|
||||||
|
execution_input: vec![],
|
||||||
|
execution_output: vec![],
|
||||||
|
utxo_commitments_spent_hashes: vec![],
|
||||||
|
utxo_commitments_created_hashes: comm
|
||||||
|
.into_iter()
|
||||||
|
.map(|hash_data| hash_data.try_into().unwrap())
|
||||||
|
.collect(),
|
||||||
|
nullifier_created_hashes: vec![],
|
||||||
|
execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt)
|
||||||
|
.unwrap(),
|
||||||
|
encoded_data: vec![(encoded_data.0, encoded_data.1.to_vec(), tag)],
|
||||||
|
ephemeral_pub_key: eph_pub_key.to_vec(),
|
||||||
|
commitment,
|
||||||
|
tweak,
|
||||||
|
secret_r,
|
||||||
|
sc_addr,
|
||||||
|
state_changes,
|
||||||
|
};
|
||||||
|
let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key();
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
Transaction {
|
Transaction::new(transaction_body, key_to_sign_transaction),
|
||||||
tx_kind: TxKind::Private,
|
|
||||||
execution_input: vec![],
|
|
||||||
execution_output: vec![],
|
|
||||||
utxo_commitments_spent_hashes: vec![],
|
|
||||||
utxo_commitments_created_hashes: comm
|
|
||||||
.into_iter()
|
|
||||||
.map(|hash_data| hash_data.try_into().unwrap())
|
|
||||||
.collect(),
|
|
||||||
nullifier_created_hashes: vec![],
|
|
||||||
execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(
|
|
||||||
receipt,
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
encoded_data: vec![(encoded_data.0, encoded_data.1.to_vec(), tag)],
|
|
||||||
ephemeral_pub_key: eph_pub_key.to_vec(),
|
|
||||||
commitment,
|
|
||||||
tweak,
|
|
||||||
secret_r,
|
|
||||||
sc_addr,
|
|
||||||
state_changes,
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
result_hash,
|
result_hash,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -315,8 +313,7 @@ impl NodeCore {
|
|||||||
let mint_multiple_utxo_addr_bytes: Vec<u8> =
|
let mint_multiple_utxo_addr_bytes: Vec<u8> =
|
||||||
zkvm::test_methods::MINT_UTXO_MULTIPLE_ASSETS_ID
|
zkvm::test_methods::MINT_UTXO_MULTIPLE_ASSETS_ID
|
||||||
.iter()
|
.iter()
|
||||||
.map(|num| num.to_le_bytes())
|
.flat_map(|num| num.to_le_bytes())
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
let sc_addr = hex::encode(mint_multiple_utxo_addr_bytes);
|
let sc_addr = hex::encode(mint_multiple_utxo_addr_bytes);
|
||||||
|
|
||||||
@ -345,30 +342,30 @@ impl NodeCore {
|
|||||||
|
|
||||||
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
||||||
|
|
||||||
Ok((
|
let transaction_body = TransactionBody {
|
||||||
Transaction {
|
tx_kind: TxKind::Private,
|
||||||
tx_kind: TxKind::Private,
|
execution_input: vec![],
|
||||||
execution_input: vec![],
|
execution_output: vec![],
|
||||||
execution_output: vec![],
|
utxo_commitments_spent_hashes: vec![],
|
||||||
utxo_commitments_spent_hashes: vec![],
|
utxo_commitments_created_hashes: comm
|
||||||
utxo_commitments_created_hashes: comm
|
.into_iter()
|
||||||
.into_iter()
|
.map(|hash_data| hash_data.try_into().unwrap())
|
||||||
.map(|hash_data| hash_data.try_into().unwrap())
|
.collect(),
|
||||||
.collect(),
|
nullifier_created_hashes: vec![],
|
||||||
nullifier_created_hashes: vec![],
|
execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt)
|
||||||
execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(
|
|
||||||
receipt,
|
|
||||||
)
|
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
encoded_data,
|
encoded_data,
|
||||||
ephemeral_pub_key: eph_pub_key.to_vec(),
|
ephemeral_pub_key: eph_pub_key.to_vec(),
|
||||||
commitment,
|
commitment,
|
||||||
tweak,
|
tweak,
|
||||||
secret_r,
|
secret_r,
|
||||||
sc_addr,
|
sc_addr,
|
||||||
state_changes,
|
state_changes,
|
||||||
}
|
};
|
||||||
.into(),
|
let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key();
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Transaction::new(transaction_body, key_to_sign_transaction),
|
||||||
result_hashes,
|
result_hashes,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -389,14 +386,13 @@ impl NodeCore {
|
|||||||
.key_holder
|
.key_holder
|
||||||
.utxo_secret_key_holder
|
.utxo_secret_key_holder
|
||||||
.nullifier_secret_key
|
.nullifier_secret_key
|
||||||
.to_bytes()
|
.to_bytes(),
|
||||||
.to_vec(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let (resulting_utxos, receipt) = prove_send_utxo(utxo, receivers)?;
|
let (resulting_utxos, receipt) = prove_send_utxo(utxo, receivers)?;
|
||||||
let utxo_hashes = resulting_utxos
|
let utxo_hashes = resulting_utxos
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(utxo, addr)| (addr.clone(), utxo.hash))
|
.map(|(utxo, addr)| (*addr, utxo.hash))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let utxos: Vec<UTXO> = resulting_utxos
|
let utxos: Vec<UTXO> = resulting_utxos
|
||||||
@ -431,8 +427,7 @@ impl NodeCore {
|
|||||||
|
|
||||||
let send_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::SEND_UTXO_ID
|
let send_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::SEND_UTXO_ID
|
||||||
.iter()
|
.iter()
|
||||||
.map(|num| num.to_le_bytes())
|
.flat_map(|num| num.to_le_bytes())
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
let sc_addr = hex::encode(send_utxo_addr_bytes);
|
let sc_addr = hex::encode(send_utxo_addr_bytes);
|
||||||
|
|
||||||
@ -461,30 +456,31 @@ impl NodeCore {
|
|||||||
|
|
||||||
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
||||||
|
|
||||||
Ok((
|
let transaction_body = TransactionBody {
|
||||||
Transaction {
|
tx_kind: TxKind::Private,
|
||||||
tx_kind: TxKind::Private,
|
execution_input: vec![],
|
||||||
execution_input: vec![],
|
execution_output: vec![],
|
||||||
execution_output: vec![],
|
utxo_commitments_spent_hashes: vec![commitment_in],
|
||||||
utxo_commitments_spent_hashes: vec![commitment_in],
|
utxo_commitments_created_hashes: commitments
|
||||||
utxo_commitments_created_hashes: commitments
|
.into_iter()
|
||||||
.into_iter()
|
.map(|hash_data| hash_data.try_into().unwrap())
|
||||||
.map(|hash_data| hash_data.try_into().unwrap())
|
.collect(),
|
||||||
.collect(),
|
nullifier_created_hashes: vec![nullifier.try_into().unwrap()],
|
||||||
nullifier_created_hashes: vec![nullifier.try_into().unwrap()],
|
execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt)
|
||||||
execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(
|
|
||||||
receipt,
|
|
||||||
)
|
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
encoded_data,
|
encoded_data,
|
||||||
ephemeral_pub_key: eph_pub_key.to_vec(),
|
ephemeral_pub_key: eph_pub_key.to_vec(),
|
||||||
commitment,
|
commitment,
|
||||||
tweak,
|
tweak,
|
||||||
secret_r,
|
secret_r,
|
||||||
sc_addr,
|
sc_addr,
|
||||||
state_changes,
|
state_changes,
|
||||||
}
|
};
|
||||||
.into(),
|
|
||||||
|
let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key();
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Transaction::new(transaction_body, key_to_sign_transaction),
|
||||||
utxo_hashes,
|
utxo_hashes,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -576,8 +572,7 @@ impl NodeCore {
|
|||||||
let send_multiple_utxo_addr_bytes: Vec<u8> =
|
let send_multiple_utxo_addr_bytes: Vec<u8> =
|
||||||
zkvm::test_methods::SEND_UTXO_MULTIPLE_ASSETS_ID
|
zkvm::test_methods::SEND_UTXO_MULTIPLE_ASSETS_ID
|
||||||
.iter()
|
.iter()
|
||||||
.map(|num| num.to_le_bytes())
|
.flat_map(|num| num.to_le_bytes())
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
let sc_addr = hex::encode(send_multiple_utxo_addr_bytes);
|
let sc_addr = hex::encode(send_multiple_utxo_addr_bytes);
|
||||||
|
|
||||||
@ -606,30 +601,31 @@ impl NodeCore {
|
|||||||
|
|
||||||
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
||||||
|
|
||||||
Ok((
|
let transaction_body = TransactionBody {
|
||||||
Transaction {
|
tx_kind: TxKind::Private,
|
||||||
tx_kind: TxKind::Private,
|
execution_input: vec![],
|
||||||
execution_input: vec![],
|
execution_output: vec![],
|
||||||
execution_output: vec![],
|
utxo_commitments_spent_hashes: commitments_in,
|
||||||
utxo_commitments_spent_hashes: commitments_in,
|
utxo_commitments_created_hashes: commitments
|
||||||
utxo_commitments_created_hashes: commitments
|
.into_iter()
|
||||||
.into_iter()
|
.map(|hash_data| hash_data.try_into().unwrap())
|
||||||
.map(|hash_data| hash_data.try_into().unwrap())
|
.collect(),
|
||||||
.collect(),
|
nullifier_created_hashes: nullifiers,
|
||||||
nullifier_created_hashes: nullifiers,
|
execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt)
|
||||||
execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(
|
|
||||||
receipt,
|
|
||||||
)
|
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
encoded_data,
|
encoded_data,
|
||||||
ephemeral_pub_key: eph_pub_key.to_vec(),
|
ephemeral_pub_key: eph_pub_key.to_vec(),
|
||||||
commitment,
|
commitment,
|
||||||
tweak,
|
tweak,
|
||||||
secret_r,
|
secret_r,
|
||||||
sc_addr,
|
sc_addr,
|
||||||
state_changes,
|
state_changes,
|
||||||
}
|
};
|
||||||
.into(),
|
|
||||||
|
let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key();
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Transaction::new(transaction_body, key_to_sign_transaction),
|
||||||
utxo_hashes_receiver,
|
utxo_hashes_receiver,
|
||||||
utxo_hashes_not_spent,
|
utxo_hashes_not_spent,
|
||||||
))
|
))
|
||||||
@ -657,14 +653,13 @@ impl NodeCore {
|
|||||||
.key_holder
|
.key_holder
|
||||||
.utxo_secret_key_holder
|
.utxo_secret_key_holder
|
||||||
.nullifier_secret_key
|
.nullifier_secret_key
|
||||||
.to_bytes()
|
.to_bytes(),
|
||||||
.to_vec(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let (resulting_utxos, receipt) = prove_send_utxo_shielded(acc, balance as u128, receivers)?;
|
let (resulting_utxos, receipt) = prove_send_utxo_shielded(acc, balance as u128, receivers)?;
|
||||||
let utxo_hashes = resulting_utxos
|
let utxo_hashes = resulting_utxos
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(utxo, addr)| (addr.clone(), utxo.hash))
|
.map(|(utxo, addr)| (*addr, utxo.hash))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let utxos: Vec<UTXO> = resulting_utxos
|
let utxos: Vec<UTXO> = resulting_utxos
|
||||||
@ -699,8 +694,7 @@ impl NodeCore {
|
|||||||
|
|
||||||
let mint_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::SEND_UTXO_ID
|
let mint_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::SEND_UTXO_ID
|
||||||
.iter()
|
.iter()
|
||||||
.map(|num| num.to_le_bytes())
|
.flat_map(|num| num.to_le_bytes())
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
let sc_addr = hex::encode(mint_utxo_addr_bytes);
|
let sc_addr = hex::encode(mint_utxo_addr_bytes);
|
||||||
|
|
||||||
@ -729,36 +723,37 @@ impl NodeCore {
|
|||||||
|
|
||||||
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
||||||
|
|
||||||
|
let transaction_body = TransactionBody {
|
||||||
|
tx_kind: TxKind::Shielded,
|
||||||
|
execution_input: serde_json::to_vec(&ActionData::SendMoneyShieldedTx(
|
||||||
|
SendMoneyShieldedTx {
|
||||||
|
acc_sender: acc,
|
||||||
|
amount: balance as u128,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.unwrap(),
|
||||||
|
execution_output: vec![],
|
||||||
|
utxo_commitments_spent_hashes: vec![],
|
||||||
|
utxo_commitments_created_hashes: commitments
|
||||||
|
.into_iter()
|
||||||
|
.map(|hash_data| hash_data.try_into().unwrap())
|
||||||
|
.collect(),
|
||||||
|
nullifier_created_hashes: vec![nullifier.try_into().unwrap()],
|
||||||
|
execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt)
|
||||||
|
.unwrap(),
|
||||||
|
encoded_data,
|
||||||
|
ephemeral_pub_key: eph_pub_key.to_vec(),
|
||||||
|
commitment,
|
||||||
|
tweak,
|
||||||
|
secret_r,
|
||||||
|
sc_addr,
|
||||||
|
state_changes,
|
||||||
|
};
|
||||||
|
|
||||||
|
let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key();
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
Transaction {
|
Transaction::new(transaction_body, key_to_sign_transaction),
|
||||||
tx_kind: TxKind::Shielded,
|
|
||||||
execution_input: serde_json::to_vec(&ActionData::SendMoneyShieldedTx(
|
|
||||||
SendMoneyShieldedTx {
|
|
||||||
acc_sender: acc,
|
|
||||||
amount: balance as u128,
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.unwrap(),
|
|
||||||
execution_output: vec![],
|
|
||||||
utxo_commitments_spent_hashes: vec![],
|
|
||||||
utxo_commitments_created_hashes: commitments
|
|
||||||
.into_iter()
|
|
||||||
.map(|hash_data| hash_data.try_into().unwrap())
|
|
||||||
.collect(),
|
|
||||||
nullifier_created_hashes: vec![nullifier.try_into().unwrap()],
|
|
||||||
execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(
|
|
||||||
receipt,
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
encoded_data,
|
|
||||||
ephemeral_pub_key: eph_pub_key.to_vec(),
|
|
||||||
commitment,
|
|
||||||
tweak,
|
|
||||||
secret_r,
|
|
||||||
sc_addr,
|
|
||||||
state_changes,
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
utxo_hashes,
|
utxo_hashes,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -785,16 +780,14 @@ impl NodeCore {
|
|||||||
.key_holder
|
.key_holder
|
||||||
.utxo_secret_key_holder
|
.utxo_secret_key_holder
|
||||||
.nullifier_secret_key
|
.nullifier_secret_key
|
||||||
.to_bytes()
|
.to_bytes(),
|
||||||
.to_vec(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let (resulting_balances, receipt) = prove_send_utxo_deshielded(utxo, receivers)?;
|
let (resulting_balances, receipt) = prove_send_utxo_deshielded(utxo, receivers)?;
|
||||||
|
|
||||||
let send_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::SEND_UTXO_ID
|
let send_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::SEND_UTXO_ID
|
||||||
.iter()
|
.iter()
|
||||||
.map(|num| num.to_le_bytes())
|
.flat_map(|num| num.to_le_bytes())
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
let sc_addr = hex::encode(send_utxo_addr_bytes);
|
let sc_addr = hex::encode(send_utxo_addr_bytes);
|
||||||
|
|
||||||
@ -823,7 +816,7 @@ impl NodeCore {
|
|||||||
|
|
||||||
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
||||||
|
|
||||||
Ok(Transaction {
|
let transaction_body = TransactionBody {
|
||||||
tx_kind: TxKind::Deshielded,
|
tx_kind: TxKind::Deshielded,
|
||||||
execution_input: serde_json::to_vec(&ActionData::SendMoneyDeshieldedTx(
|
execution_input: serde_json::to_vec(&ActionData::SendMoneyDeshieldedTx(
|
||||||
SendMoneyDeshieldedTx {
|
SendMoneyDeshieldedTx {
|
||||||
@ -844,8 +837,11 @@ impl NodeCore {
|
|||||||
secret_r,
|
secret_r,
|
||||||
sc_addr,
|
sc_addr,
|
||||||
state_changes,
|
state_changes,
|
||||||
}
|
};
|
||||||
.into())
|
|
||||||
|
let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key();
|
||||||
|
|
||||||
|
Ok(Transaction::new(transaction_body, key_to_sign_transaction))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_private_mint_tx(
|
pub async fn send_private_mint_tx(
|
||||||
@ -858,10 +854,10 @@ impl NodeCore {
|
|||||||
|
|
||||||
let point_before_prove = std::time::Instant::now();
|
let point_before_prove = std::time::Instant::now();
|
||||||
let (tx, utxo_hash) = self.mint_utxo_private(acc, amount).await?;
|
let (tx, utxo_hash) = self.mint_utxo_private(acc, amount).await?;
|
||||||
tx.log();
|
tx.body().log();
|
||||||
let point_after_prove = std::time::Instant::now();
|
let point_after_prove = std::time::Instant::now();
|
||||||
|
|
||||||
let commitment_generated_hash = tx.utxo_commitments_created_hashes[0];
|
let commitment_generated_hash = tx.body().utxo_commitments_created_hashes[0];
|
||||||
|
|
||||||
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
||||||
info!("Mint utxo proof spent {timedelta:?} milliseconds");
|
info!("Mint utxo proof spent {timedelta:?} milliseconds");
|
||||||
@ -886,10 +882,10 @@ impl NodeCore {
|
|||||||
let (tx, utxo_hashes) = self
|
let (tx, utxo_hashes) = self
|
||||||
.mint_utxo_multiple_assets_private(acc, amount, number_of_assets)
|
.mint_utxo_multiple_assets_private(acc, amount, number_of_assets)
|
||||||
.await?;
|
.await?;
|
||||||
tx.log();
|
tx.body().log();
|
||||||
let point_after_prove = std::time::Instant::now();
|
let point_after_prove = std::time::Instant::now();
|
||||||
|
|
||||||
let commitment_generated_hashes = tx.utxo_commitments_created_hashes.clone();
|
let commitment_generated_hashes = tx.body().utxo_commitments_created_hashes.clone();
|
||||||
|
|
||||||
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
||||||
info!("Mint utxo proof spent {timedelta:?} milliseconds");
|
info!("Mint utxo proof spent {timedelta:?} milliseconds");
|
||||||
@ -901,50 +897,50 @@ impl NodeCore {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_public_deposit(
|
// pub async fn send_public_deposit(
|
||||||
&self,
|
// &self,
|
||||||
acc: AccountAddress,
|
// acc: AccountAddress,
|
||||||
amount: u128,
|
// amount: u128,
|
||||||
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
// ) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||||
//Considering proof time, needs to be done before proof
|
// //Considering proof time, needs to be done before proof
|
||||||
let tx_roots = self.get_roots().await;
|
// let tx_roots = self.get_roots().await;
|
||||||
|
//
|
||||||
let public_context = {
|
// let public_context = {
|
||||||
let read_guard = self.storage.read().await;
|
// let read_guard = self.storage.read().await;
|
||||||
|
//
|
||||||
read_guard.produce_context(acc)
|
// read_guard.produce_context(acc)
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
let (tweak, secret_r, commitment) = pedersen_commitment_vec(
|
// let (tweak, secret_r, commitment) = pedersen_commitment_vec(
|
||||||
//Will not panic, as public context is serializable
|
// //Will not panic, as public context is serializable
|
||||||
public_context.produce_u64_list_from_context().unwrap(),
|
// public_context.produce_u64_list_from_context().unwrap(),
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
let sc_addr = hex::encode([0; 32]);
|
// let sc_addr = hex::encode([0; 32]);
|
||||||
|
//
|
||||||
//Sc does not change its state
|
// //Sc does not change its state
|
||||||
let state_changes: Vec<DataBlobChangeVariant> = vec![];
|
// let state_changes: Vec<DataBlobChangeVariant> = vec![];
|
||||||
let new_len = 0;
|
// let new_len = 0;
|
||||||
let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len);
|
// let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len);
|
||||||
|
//
|
||||||
let tx: Transaction =
|
// let tx: TransactionBody =
|
||||||
sc_core::transaction_payloads_tools::create_public_transaction_payload(
|
// sc_core::transaction_payloads_tools::create_public_transaction_payload(
|
||||||
serde_json::to_vec(&ActionData::MintMoneyPublicTx(MintMoneyPublicTx {
|
// serde_json::to_vec(&ActionData::MintMoneyPublicTx(MintMoneyPublicTx {
|
||||||
acc,
|
// acc,
|
||||||
amount,
|
// amount,
|
||||||
}))
|
// }))
|
||||||
.unwrap(),
|
// .unwrap(),
|
||||||
commitment,
|
// commitment,
|
||||||
tweak,
|
// tweak,
|
||||||
secret_r,
|
// secret_r,
|
||||||
sc_addr,
|
// sc_addr,
|
||||||
state_changes,
|
// state_changes,
|
||||||
)
|
// )
|
||||||
.into();
|
// .into();
|
||||||
tx.log();
|
// tx.log();
|
||||||
|
//
|
||||||
Ok(self.sequencer_client.send_tx(tx, tx_roots).await?)
|
// Ok(self.sequencer_client.send_tx(tx, tx_roots).await?)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub async fn send_private_send_tx(
|
pub async fn send_private_send_tx(
|
||||||
&self,
|
&self,
|
||||||
@ -959,7 +955,7 @@ impl NodeCore {
|
|||||||
let (tx, utxo_hashes) = self
|
let (tx, utxo_hashes) = self
|
||||||
.transfer_utxo_private(utxo, comm_hash, receivers)
|
.transfer_utxo_private(utxo, comm_hash, receivers)
|
||||||
.await?;
|
.await?;
|
||||||
tx.log();
|
tx.body().log();
|
||||||
let point_after_prove = std::time::Instant::now();
|
let point_after_prove = std::time::Instant::now();
|
||||||
|
|
||||||
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
||||||
@ -985,7 +981,7 @@ impl NodeCore {
|
|||||||
let (tx, utxo_hashes_received, utxo_hashes_not_spent) = self
|
let (tx, utxo_hashes_received, utxo_hashes_not_spent) = self
|
||||||
.transfer_utxo_multiple_assets_private(utxos, comm_hashes, number_to_send, receiver)
|
.transfer_utxo_multiple_assets_private(utxos, comm_hashes, number_to_send, receiver)
|
||||||
.await?;
|
.await?;
|
||||||
tx.log();
|
tx.body().log();
|
||||||
let point_after_prove = std::time::Instant::now();
|
let point_after_prove = std::time::Instant::now();
|
||||||
|
|
||||||
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
||||||
@ -1011,7 +1007,7 @@ impl NodeCore {
|
|||||||
let (tx, utxo_hashes) = self
|
let (tx, utxo_hashes) = self
|
||||||
.transfer_balance_shielded(acc, amount, receivers)
|
.transfer_balance_shielded(acc, amount, receivers)
|
||||||
.await?;
|
.await?;
|
||||||
tx.log();
|
tx.body().log();
|
||||||
let point_after_prove = std::time::Instant::now();
|
let point_after_prove = std::time::Instant::now();
|
||||||
|
|
||||||
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
||||||
@ -1036,7 +1032,7 @@ impl NodeCore {
|
|||||||
let tx = self
|
let tx = self
|
||||||
.transfer_utxo_deshielded(utxo, comm_gen_hash, receivers)
|
.transfer_utxo_deshielded(utxo, comm_gen_hash, receivers)
|
||||||
.await?;
|
.await?;
|
||||||
tx.log();
|
tx.body().log();
|
||||||
let point_after_prove = std::time::Instant::now();
|
let point_after_prove = std::time::Instant::now();
|
||||||
|
|
||||||
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
||||||
@ -1170,46 +1166,46 @@ impl NodeCore {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn operate_account_deposit_public(
|
// pub async fn operate_account_deposit_public(
|
||||||
&mut self,
|
// &mut self,
|
||||||
acc_addr: AccountAddress,
|
// acc_addr: AccountAddress,
|
||||||
amount: u128,
|
// amount: u128,
|
||||||
) -> Result<(), ExecutionFailureKind> {
|
// ) -> Result<(), ExecutionFailureKind> {
|
||||||
let old_balance = {
|
// let old_balance = {
|
||||||
let acc_map_read_guard = self.storage.read().await;
|
// let acc_map_read_guard = self.storage.read().await;
|
||||||
|
//
|
||||||
let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap();
|
// let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap();
|
||||||
|
//
|
||||||
acc.balance
|
// acc.balance
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
info!(
|
// info!(
|
||||||
"Balance of {:?} now is {old_balance:?}",
|
// "Balance of {:?} now is {old_balance:?}",
|
||||||
hex::encode(acc_addr)
|
// hex::encode(acc_addr)
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
let resp = self.send_public_deposit(acc_addr, amount).await?;
|
// let resp = self.send_public_deposit(acc_addr, amount).await?;
|
||||||
info!("Response for public deposit is {resp:?}");
|
// info!("Response for public deposit is {resp:?}");
|
||||||
|
//
|
||||||
info!("Awaiting new blocks");
|
// info!("Awaiting new blocks");
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
|
// tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
|
||||||
|
//
|
||||||
let new_balance = {
|
// let new_balance = {
|
||||||
let acc_map_read_guard = self.storage.read().await;
|
// let acc_map_read_guard = self.storage.read().await;
|
||||||
|
//
|
||||||
let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap();
|
// let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap();
|
||||||
|
//
|
||||||
acc.balance
|
// acc.balance
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
info!(
|
// info!(
|
||||||
"Balance of {:?} now is {new_balance:?}, delta is {:?}",
|
// "Balance of {:?} now is {new_balance:?}, delta is {:?}",
|
||||||
hex::encode(acc_addr),
|
// hex::encode(acc_addr),
|
||||||
new_balance - old_balance
|
// new_balance - old_balance
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub async fn operate_account_send_shielded_one_receiver(
|
pub async fn operate_account_send_shielded_one_receiver(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -1375,14 +1371,13 @@ impl NodeCore {
|
|||||||
.key_holder
|
.key_holder
|
||||||
.utxo_secret_key_holder
|
.utxo_secret_key_holder
|
||||||
.nullifier_secret_key
|
.nullifier_secret_key
|
||||||
.to_bytes()
|
.to_bytes(),
|
||||||
.to_vec(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let (resulting_utxos, receipt) = prove_send_utxo(utxo, receivers)?;
|
let (resulting_utxos, receipt) = prove_send_utxo(utxo, receivers)?;
|
||||||
let utxo_hashes = resulting_utxos
|
let utxo_hashes = resulting_utxos
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(utxo, addr)| (addr.clone(), utxo.hash))
|
.map(|(utxo, addr)| (*addr, utxo.hash))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let utxos: Vec<UTXO> = resulting_utxos
|
let utxos: Vec<UTXO> = resulting_utxos
|
||||||
@ -1431,8 +1426,7 @@ impl NodeCore {
|
|||||||
|
|
||||||
let send_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::SEND_UTXO_ID
|
let send_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::SEND_UTXO_ID
|
||||||
.iter()
|
.iter()
|
||||||
.map(|num| num.to_le_bytes())
|
.flat_map(|num| num.to_le_bytes())
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
let sc_addr = hex::encode(send_utxo_addr_bytes);
|
let sc_addr = hex::encode(send_utxo_addr_bytes);
|
||||||
|
|
||||||
@ -1461,31 +1455,31 @@ impl NodeCore {
|
|||||||
|
|
||||||
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info);
|
||||||
|
|
||||||
Ok((
|
let transaction_body = TransactionBody {
|
||||||
Transaction {
|
tx_kind: TxKind::Shielded,
|
||||||
tx_kind: TxKind::Shielded,
|
execution_input: vec![],
|
||||||
execution_input: vec![],
|
execution_output: serde_json::to_vec(&publication).unwrap(),
|
||||||
execution_output: serde_json::to_vec(&publication).unwrap(),
|
utxo_commitments_spent_hashes: vec![commitment_in],
|
||||||
utxo_commitments_spent_hashes: vec![commitment_in],
|
utxo_commitments_created_hashes: commitments
|
||||||
utxo_commitments_created_hashes: commitments
|
.clone()
|
||||||
.clone()
|
.into_iter()
|
||||||
.into_iter()
|
.map(|hash_data| hash_data.try_into().unwrap())
|
||||||
.map(|hash_data| hash_data.try_into().unwrap())
|
.collect(),
|
||||||
.collect(),
|
nullifier_created_hashes: vec![nullifier.try_into().unwrap()],
|
||||||
nullifier_created_hashes: vec![nullifier.try_into().unwrap()],
|
execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(receipt)
|
||||||
execution_proof_private: sc_core::transaction_payloads_tools::encode_receipt(
|
|
||||||
receipt,
|
|
||||||
)
|
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
encoded_data,
|
encoded_data,
|
||||||
ephemeral_pub_key: eph_pub_key.to_vec(),
|
ephemeral_pub_key: eph_pub_key.to_vec(),
|
||||||
commitment,
|
commitment,
|
||||||
tweak,
|
tweak,
|
||||||
secret_r,
|
secret_r,
|
||||||
sc_addr,
|
sc_addr,
|
||||||
state_changes,
|
state_changes,
|
||||||
}
|
};
|
||||||
.into(),
|
let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key();
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Transaction::new(transaction_body, key_to_sign_transaction),
|
||||||
utxo_hashes,
|
utxo_hashes,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -1505,13 +1499,13 @@ impl NodeCore {
|
|||||||
let (tx, utxo_hashes) = self
|
let (tx, utxo_hashes) = self
|
||||||
.split_utxo(utxo, comm_hash, receivers, visibility_list)
|
.split_utxo(utxo, comm_hash, receivers, visibility_list)
|
||||||
.await?;
|
.await?;
|
||||||
tx.log();
|
tx.body().log();
|
||||||
let point_after_prove = std::time::Instant::now();
|
let point_after_prove = std::time::Instant::now();
|
||||||
|
|
||||||
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
let timedelta = (point_after_prove - point_before_prove).as_millis();
|
||||||
info!("Send private utxo proof spent {timedelta:?} milliseconds");
|
info!("Send private utxo proof spent {timedelta:?} milliseconds");
|
||||||
|
|
||||||
let commitments = tx.utxo_commitments_created_hashes.clone();
|
let commitments = tx.body().utxo_commitments_created_hashes.clone();
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
self.sequencer_client.send_tx(tx, tx_roots).await?,
|
self.sequencer_client.send_tx(tx, tx_roots).await?,
|
||||||
@ -1531,10 +1525,7 @@ impl NodeCore {
|
|||||||
.send_split_tx(
|
.send_split_tx(
|
||||||
utxo.clone(),
|
utxo.clone(),
|
||||||
comm_gen_hash,
|
comm_gen_hash,
|
||||||
addrs_receivers
|
addrs_receivers.map(|addr| (utxo.amount / 3, addr)).to_vec(),
|
||||||
.clone()
|
|
||||||
.map(|addr| (utxo.amount / 3, addr))
|
|
||||||
.to_vec(),
|
|
||||||
visibility_list,
|
visibility_list,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -1585,20 +1576,8 @@ impl NodeCore {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
///Deposit balance, make it private
|
|
||||||
pub async fn subscenario_2(&mut self) -> Result<(), ExecutionFailureKind> {
|
|
||||||
let acc_addr = self.create_new_account().await;
|
|
||||||
|
|
||||||
self.operate_account_deposit_public(acc_addr, 100).await?;
|
|
||||||
|
|
||||||
self.operate_account_send_shielded_one_receiver(acc_addr, acc_addr, 100)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
///Mint utxo, privately send it to another user
|
///Mint utxo, privately send it to another user
|
||||||
pub async fn subscenario_3(&mut self) -> Result<(), ExecutionFailureKind> {
|
pub async fn subscenario_2(&mut self) -> Result<(), ExecutionFailureKind> {
|
||||||
let acc_addr = self.create_new_account().await;
|
let acc_addr = self.create_new_account().await;
|
||||||
let acc_addr_rec = self.create_new_account().await;
|
let acc_addr_rec = self.create_new_account().await;
|
||||||
|
|
||||||
@ -1610,21 +1589,8 @@ impl NodeCore {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
///Deposit balance, shielded send it to another user
|
|
||||||
pub async fn subscenario_4(&mut self) -> Result<(), ExecutionFailureKind> {
|
|
||||||
let acc_addr = self.create_new_account().await;
|
|
||||||
let acc_addr_rec = self.create_new_account().await;
|
|
||||||
|
|
||||||
self.operate_account_deposit_public(acc_addr, 100).await?;
|
|
||||||
|
|
||||||
self.operate_account_send_shielded_one_receiver(acc_addr, acc_addr_rec, 100)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
///Mint utxo, deshielded send it to another user
|
///Mint utxo, deshielded send it to another user
|
||||||
pub async fn subscenario_5(&mut self) -> Result<(), ExecutionFailureKind> {
|
pub async fn subscenario_3(&mut self) -> Result<(), ExecutionFailureKind> {
|
||||||
let acc_addr = self.create_new_account().await;
|
let acc_addr = self.create_new_account().await;
|
||||||
let acc_addr_rec = self.create_new_account().await;
|
let acc_addr_rec = self.create_new_account().await;
|
||||||
|
|
||||||
|
|||||||
@ -22,8 +22,7 @@ pub async fn setup_empty_sc_states(node: &NodeChainStore) -> Result<()> {
|
|||||||
|
|
||||||
let mint_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::MINT_UTXO_ID
|
let mint_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::MINT_UTXO_ID
|
||||||
.iter()
|
.iter()
|
||||||
.map(|num| num.to_le_bytes())
|
.flat_map(|num| num.to_le_bytes())
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
let mint_utxo_addr = hex::encode(mint_utxo_addr_bytes);
|
let mint_utxo_addr = hex::encode(mint_utxo_addr_bytes);
|
||||||
node.block_store
|
node.block_store
|
||||||
@ -32,8 +31,7 @@ pub async fn setup_empty_sc_states(node: &NodeChainStore) -> Result<()> {
|
|||||||
|
|
||||||
let single_utxo_transfer_addr_bytes: Vec<u8> = zkvm::test_methods::SEND_UTXO_ID
|
let single_utxo_transfer_addr_bytes: Vec<u8> = zkvm::test_methods::SEND_UTXO_ID
|
||||||
.iter()
|
.iter()
|
||||||
.map(|num| num.to_le_bytes())
|
.flat_map(|num| num.to_le_bytes())
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
let single_utxo_transfer_addr = hex::encode(single_utxo_transfer_addr_bytes);
|
let single_utxo_transfer_addr = hex::encode(single_utxo_transfer_addr_bytes);
|
||||||
node.block_store.put_sc_sc_state(
|
node.block_store.put_sc_sc_state(
|
||||||
@ -46,8 +44,7 @@ pub async fn setup_empty_sc_states(node: &NodeChainStore) -> Result<()> {
|
|||||||
let mint_utxo_multiple_assets_addr_bytes: Vec<u8> =
|
let mint_utxo_multiple_assets_addr_bytes: Vec<u8> =
|
||||||
zkvm::test_methods::MINT_UTXO_MULTIPLE_ASSETS_ID
|
zkvm::test_methods::MINT_UTXO_MULTIPLE_ASSETS_ID
|
||||||
.iter()
|
.iter()
|
||||||
.map(|num| num.to_le_bytes())
|
.flat_map(|num| num.to_le_bytes())
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
let mint_utxo_multiple_assets_addr = hex::encode(mint_utxo_multiple_assets_addr_bytes);
|
let mint_utxo_multiple_assets_addr = hex::encode(mint_utxo_multiple_assets_addr_bytes);
|
||||||
node.block_store.put_sc_sc_state(
|
node.block_store.put_sc_sc_state(
|
||||||
@ -60,8 +57,7 @@ pub async fn setup_empty_sc_states(node: &NodeChainStore) -> Result<()> {
|
|||||||
let multiple_assets_utxo_transfer_addr_bytes: Vec<u8> =
|
let multiple_assets_utxo_transfer_addr_bytes: Vec<u8> =
|
||||||
zkvm::test_methods::SEND_UTXO_MULTIPLE_ASSETS_ID
|
zkvm::test_methods::SEND_UTXO_MULTIPLE_ASSETS_ID
|
||||||
.iter()
|
.iter()
|
||||||
.map(|num| num.to_le_bytes())
|
.flat_map(|num| num.to_le_bytes())
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
let multiple_assets_utxo_transfer_addr = hex::encode(multiple_assets_utxo_transfer_addr_bytes);
|
let multiple_assets_utxo_transfer_addr = hex::encode(multiple_assets_utxo_transfer_addr_bytes);
|
||||||
node.block_store.put_sc_sc_state(
|
node.block_store.put_sc_sc_state(
|
||||||
|
|||||||
@ -53,7 +53,7 @@ pub fn new_http_server(
|
|||||||
polling_config,
|
polling_config,
|
||||||
limits_config,
|
limits_config,
|
||||||
} = config;
|
} = config;
|
||||||
info!(target:"network", "Starting http server at {}", addr);
|
info!(target:"network", "Starting http server at {addr}");
|
||||||
let handler = web::Data::new(JsonHandler {
|
let handler = web::Data::new(JsonHandler {
|
||||||
polling_config,
|
polling_config,
|
||||||
node_core_config: node_config,
|
node_core_config: node_config,
|
||||||
|
|||||||
@ -23,8 +23,7 @@ use crate::types::{
|
|||||||
ExecuteScenarioSplitResponse, ExecuteSubscenarioRequest, ExecuteSubscenarioResponse,
|
ExecuteScenarioSplitResponse, ExecuteSubscenarioRequest, ExecuteSubscenarioResponse,
|
||||||
ShowAccountPublicBalanceRequest, ShowAccountPublicBalanceResponse, ShowAccountUTXORequest,
|
ShowAccountPublicBalanceRequest, ShowAccountPublicBalanceResponse, ShowAccountUTXORequest,
|
||||||
ShowAccountUTXOResponse, ShowTransactionRequest, ShowTransactionResponse,
|
ShowAccountUTXOResponse, ShowTransactionRequest, ShowTransactionResponse,
|
||||||
UTXOShortEssentialStruct, WriteDepositPublicBalanceRequest,
|
UTXOShortEssentialStruct, WriteMintPrivateUTXOMultipleAssetsRequest,
|
||||||
WriteDepositPublicBalanceResponse, WriteMintPrivateUTXOMultipleAssetsRequest,
|
|
||||||
WriteMintPrivateUTXOMultipleAssetsResponse, WriteMintPrivateUTXORequest,
|
WriteMintPrivateUTXOMultipleAssetsResponse, WriteMintPrivateUTXORequest,
|
||||||
WriteMintPrivateUTXOResponse, WriteSendDeshieldedBalanceRequest,
|
WriteMintPrivateUTXOResponse, WriteSendDeshieldedBalanceRequest,
|
||||||
WriteSendDeshieldedUTXOResponse, WriteSendPrivateUTXORequest, WriteSendPrivateUTXOResponse,
|
WriteSendDeshieldedUTXOResponse, WriteSendPrivateUTXORequest, WriteSendPrivateUTXOResponse,
|
||||||
@ -42,7 +41,6 @@ pub const EXECUTE_SCENARIO_MULTIPLE_SEND: &str = "execute_scenario_multiple_send
|
|||||||
pub const SHOW_ACCOUNT_PUBLIC_BALANCE: &str = "show_account_public_balance";
|
pub const SHOW_ACCOUNT_PUBLIC_BALANCE: &str = "show_account_public_balance";
|
||||||
pub const SHOW_ACCOUNT_UTXO: &str = "show_account_utxo";
|
pub const SHOW_ACCOUNT_UTXO: &str = "show_account_utxo";
|
||||||
pub const SHOW_TRANSACTION: &str = "show_transaction";
|
pub const SHOW_TRANSACTION: &str = "show_transaction";
|
||||||
pub const WRITE_DEPOSIT_PUBLIC_BALANCE: &str = "write_deposit_public_balance";
|
|
||||||
pub const WRITE_MINT_UTXO: &str = "write_mint_utxo";
|
pub const WRITE_MINT_UTXO: &str = "write_mint_utxo";
|
||||||
pub const WRITE_MINT_UTXO_MULTIPLE_ASSETS: &str = "write_mint_utxo_multiple_assets";
|
pub const WRITE_MINT_UTXO_MULTIPLE_ASSETS: &str = "write_mint_utxo_multiple_assets";
|
||||||
pub const WRITE_SEND_UTXO_PRIVATE: &str = "write_send_utxo_private";
|
pub const WRITE_SEND_UTXO_PRIVATE: &str = "write_send_utxo_private";
|
||||||
@ -92,14 +90,6 @@ impl JsonHandler {
|
|||||||
.subscenario_3()
|
.subscenario_3()
|
||||||
.await
|
.await
|
||||||
.map_err(cast_common_execution_error_into_rpc_error)?,
|
.map_err(cast_common_execution_error_into_rpc_error)?,
|
||||||
4 => store
|
|
||||||
.subscenario_4()
|
|
||||||
.await
|
|
||||||
.map_err(cast_common_execution_error_into_rpc_error)?,
|
|
||||||
5 => store
|
|
||||||
.subscenario_5()
|
|
||||||
.await
|
|
||||||
.map_err(cast_common_execution_error_into_rpc_error)?,
|
|
||||||
_ => return Err(RpcErr(RpcError::invalid_params("Scenario id not found"))),
|
_ => return Err(RpcErr(RpcError::invalid_params("Scenario id not found"))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,42 +302,46 @@ impl JsonHandler {
|
|||||||
|
|
||||||
ShowTransactionResponse {
|
ShowTransactionResponse {
|
||||||
hash: req.tx_hash,
|
hash: req.tx_hash,
|
||||||
tx_kind: tx.tx_kind,
|
tx_kind: tx.body().tx_kind,
|
||||||
public_input: if let Ok(action) =
|
public_input: if let Ok(action) =
|
||||||
serde_json::from_slice::<ActionData>(&tx.execution_input)
|
serde_json::from_slice::<ActionData>(&tx.body().execution_input)
|
||||||
{
|
{
|
||||||
action.into_hexed_print()
|
action.into_hexed_print()
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
},
|
},
|
||||||
public_output: if let Ok(action) =
|
public_output: if let Ok(action) =
|
||||||
serde_json::from_slice::<ActionData>(&tx.execution_output)
|
serde_json::from_slice::<ActionData>(&tx.body().execution_output)
|
||||||
{
|
{
|
||||||
action.into_hexed_print()
|
action.into_hexed_print()
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
},
|
},
|
||||||
utxo_commitments_created_hashes: tx
|
utxo_commitments_created_hashes: tx
|
||||||
|
.body()
|
||||||
.utxo_commitments_created_hashes
|
.utxo_commitments_created_hashes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|val| hex::encode(val.clone()))
|
.map(hex::encode)
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
utxo_commitments_spent_hashes: tx
|
utxo_commitments_spent_hashes: tx
|
||||||
|
.body()
|
||||||
.utxo_commitments_spent_hashes
|
.utxo_commitments_spent_hashes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|val| hex::encode(val.clone()))
|
.map(hex::encode)
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
utxo_nullifiers_created_hashes: tx
|
utxo_nullifiers_created_hashes: tx
|
||||||
|
.body()
|
||||||
.nullifier_created_hashes
|
.nullifier_created_hashes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|val| hex::encode(val.clone()))
|
.map(hex::encode)
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
encoded_data: tx
|
encoded_data: tx
|
||||||
|
.body()
|
||||||
.encoded_data
|
.encoded_data
|
||||||
.iter()
|
.iter()
|
||||||
.map(|val| (hex::encode(val.0.clone()), hex::encode(val.1.clone())))
|
.map(|val| (hex::encode(val.0.clone()), hex::encode(val.1.clone())))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
ephemeral_pub_key: hex::encode(tx.ephemeral_pub_key.clone()),
|
ephemeral_pub_key: hex::encode(tx.body().ephemeral_pub_key.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -355,36 +349,6 @@ impl JsonHandler {
|
|||||||
respond(helperstruct)
|
respond(helperstruct)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn process_write_deposit_public_balance(
|
|
||||||
&self,
|
|
||||||
request: Request,
|
|
||||||
) -> Result<Value, RpcErr> {
|
|
||||||
let req = WriteDepositPublicBalanceRequest::parse(Some(request.params))?;
|
|
||||||
|
|
||||||
let acc_addr_hex_dec = hex::decode(req.account_addr.clone()).map_err(|_| {
|
|
||||||
RpcError::parse_error("Failed to decode account address from hex string".to_string())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| {
|
|
||||||
RpcError::parse_error("Failed to parse account address from bytes".to_string())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut cover_guard = self.node_chain_store.lock().await;
|
|
||||||
|
|
||||||
cover_guard
|
|
||||||
.operate_account_deposit_public(acc_addr, req.amount as u128)
|
|
||||||
.await
|
|
||||||
.map_err(cast_common_execution_error_into_rpc_error)?;
|
|
||||||
};
|
|
||||||
|
|
||||||
let helperstruct = WriteDepositPublicBalanceResponse {
|
|
||||||
status: SUCCESS.to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
respond(helperstruct)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn process_write_mint_utxo(&self, request: Request) -> Result<Value, RpcErr> {
|
pub async fn process_write_mint_utxo(&self, request: Request) -> Result<Value, RpcErr> {
|
||||||
let req = WriteMintPrivateUTXORequest::parse(Some(request.params))?;
|
let req = WriteMintPrivateUTXORequest::parse(Some(request.params))?;
|
||||||
|
|
||||||
@ -529,7 +493,7 @@ impl JsonHandler {
|
|||||||
utxo_result: UTXOShortEssentialStruct {
|
utxo_result: UTXOShortEssentialStruct {
|
||||||
hash: hex::encode(new_utxo_rec.hash),
|
hash: hex::encode(new_utxo_rec.hash),
|
||||||
asset: new_utxo_rec.asset.clone(),
|
asset: new_utxo_rec.asset.clone(),
|
||||||
commitment_hash: hex::encode(generate_commitments_helper(&vec![new_utxo_rec])[0]),
|
commitment_hash: hex::encode(generate_commitments_helper(&[new_utxo_rec])[0]),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -582,7 +546,7 @@ impl JsonHandler {
|
|||||||
utxo_result: UTXOShortEssentialStruct {
|
utxo_result: UTXOShortEssentialStruct {
|
||||||
hash: hex::encode(new_utxo_rec.hash),
|
hash: hex::encode(new_utxo_rec.hash),
|
||||||
asset: new_utxo_rec.asset.clone(),
|
asset: new_utxo_rec.asset.clone(),
|
||||||
commitment_hash: hex::encode(generate_commitments_helper(&vec![new_utxo_rec])[0]),
|
commitment_hash: hex::encode(generate_commitments_helper(&[new_utxo_rec])[0]),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -777,9 +741,6 @@ impl JsonHandler {
|
|||||||
SHOW_ACCOUNT_PUBLIC_BALANCE => self.process_show_account_public_balance(request).await,
|
SHOW_ACCOUNT_PUBLIC_BALANCE => self.process_show_account_public_balance(request).await,
|
||||||
SHOW_ACCOUNT_UTXO => self.process_show_account_utxo_request(request).await,
|
SHOW_ACCOUNT_UTXO => self.process_show_account_utxo_request(request).await,
|
||||||
SHOW_TRANSACTION => self.process_show_transaction(request).await,
|
SHOW_TRANSACTION => self.process_show_transaction(request).await,
|
||||||
WRITE_DEPOSIT_PUBLIC_BALANCE => {
|
|
||||||
self.process_write_deposit_public_balance(request).await
|
|
||||||
}
|
|
||||||
WRITE_MINT_UTXO => self.process_write_mint_utxo(request).await,
|
WRITE_MINT_UTXO => self.process_write_mint_utxo(request).await,
|
||||||
WRITE_MINT_UTXO_MULTIPLE_ASSETS => {
|
WRITE_MINT_UTXO_MULTIPLE_ASSETS => {
|
||||||
self.process_write_mint_utxo_multiple_assets(request).await
|
self.process_write_mint_utxo_multiple_assets(request).await
|
||||||
|
|||||||
@ -16,19 +16,11 @@ pub fn produce_blob_list_from_sc_public_state<S: Serialize>(
|
|||||||
|
|
||||||
//`ToDo` Replace with `next_chunk` usage, when feature stabilizes in Rust
|
//`ToDo` Replace with `next_chunk` usage, when feature stabilizes in Rust
|
||||||
for i in 0..=(ser_data.len() / SC_DATA_BLOB_SIZE) {
|
for i in 0..=(ser_data.len() / SC_DATA_BLOB_SIZE) {
|
||||||
let next_chunk: Vec<u8>;
|
let next_chunk: Vec<u8> = if (i + 1) * SC_DATA_BLOB_SIZE < ser_data.len() {
|
||||||
|
ser_data[(i * SC_DATA_BLOB_SIZE)..((i + 1) * SC_DATA_BLOB_SIZE)].to_vec()
|
||||||
if (i + 1) * SC_DATA_BLOB_SIZE < ser_data.len() {
|
|
||||||
next_chunk = ser_data[(i * SC_DATA_BLOB_SIZE)..((i + 1) * SC_DATA_BLOB_SIZE)]
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
} else {
|
} else {
|
||||||
next_chunk = ser_data[(i * SC_DATA_BLOB_SIZE)..(ser_data.len())]
|
ser_data[(i * SC_DATA_BLOB_SIZE)..(ser_data.len())].to_vec()
|
||||||
.iter()
|
};
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
blob_list.push(produce_blob_from_fit_vec(next_chunk));
|
blob_list.push(produce_blob_from_fit_vec(next_chunk));
|
||||||
}
|
}
|
||||||
@ -52,11 +44,8 @@ pub fn compare_blob_lists(
|
|||||||
changed_ids.push(DataBlobChangeVariant::Deleted { id });
|
changed_ids.push(DataBlobChangeVariant::Deleted { id });
|
||||||
}
|
}
|
||||||
} else if new_len > old_len {
|
} else if new_len > old_len {
|
||||||
for id in old_len..new_len {
|
for (id, blob) in blob_list_new.iter().enumerate().take(new_len).skip(old_len) {
|
||||||
changed_ids.push(DataBlobChangeVariant::Created {
|
changed_ids.push(DataBlobChangeVariant::Created { id, blob: *blob });
|
||||||
id,
|
|
||||||
blob: blob_list_new[id],
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -52,10 +52,10 @@ pub fn generate_commitments(input_utxos: &[UTXO]) -> Vec<Vec<u8>> {
|
|||||||
///
|
///
|
||||||
/// ToDo: Solve it in more scalable way
|
/// ToDo: Solve it in more scalable way
|
||||||
pub fn validate_in_commitments_tree(
|
pub fn validate_in_commitments_tree(
|
||||||
in_commitment: &Vec<u8>,
|
in_commitment: &[u8],
|
||||||
commitment_tree: &UTXOCommitmentsMerkleTree,
|
commitment_tree: &UTXOCommitmentsMerkleTree,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let alighned_hash: [u8; 32] = in_commitment.clone().try_into().unwrap();
|
let alighned_hash: [u8; 32] = in_commitment.try_into().unwrap();
|
||||||
|
|
||||||
commitment_tree.get_proof(alighned_hash).is_some()
|
commitment_tree.get_proof(alighned_hash).is_some()
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ pub fn private_circuit(
|
|||||||
) -> (Vec<Vec<u8>>, Vec<Vec<u8>>) {
|
) -> (Vec<Vec<u8>>, Vec<Vec<u8>>) {
|
||||||
assert!(check_balances_private(input_utxos, output_utxos));
|
assert!(check_balances_private(input_utxos, output_utxos));
|
||||||
|
|
||||||
let in_commitments = generate_commitments(&input_utxos);
|
let in_commitments = generate_commitments(input_utxos);
|
||||||
|
|
||||||
let mut in_nullifiers = vec![];
|
let mut in_nullifiers = vec![];
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ pub fn private_circuit(
|
|||||||
assert!(!public_context.nullifiers_set.contains(&nullifier));
|
assert!(!public_context.nullifiers_set.contains(&nullifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
(in_nullifiers, generate_commitments(&output_utxos))
|
(in_nullifiers, generate_commitments(output_utxos))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check balances DE
|
/// Check balances DE
|
||||||
@ -124,7 +124,7 @@ pub fn deshielded_circuit(
|
|||||||
) -> Vec<Vec<u8>> {
|
) -> Vec<Vec<u8>> {
|
||||||
assert!(check_balances_de(input_utxos, output_balance));
|
assert!(check_balances_de(input_utxos, output_balance));
|
||||||
|
|
||||||
let in_commitments = generate_commitments(&input_utxos);
|
let in_commitments = generate_commitments(input_utxos);
|
||||||
|
|
||||||
let mut in_nullifiers = vec![];
|
let mut in_nullifiers = vec![];
|
||||||
|
|
||||||
|
|||||||
@ -77,16 +77,11 @@ impl PublicSCContext {
|
|||||||
|
|
||||||
//`ToDo` Replace with `next_chunk` usage, when feature stabilizes in Rust
|
//`ToDo` Replace with `next_chunk` usage, when feature stabilizes in Rust
|
||||||
for i in 0..=(ser_data.len() / 8) {
|
for i in 0..=(ser_data.len() / 8) {
|
||||||
let next_chunk: Vec<u8>;
|
let next_chunk: Vec<u8> = if (i + 1) * 8 < ser_data.len() {
|
||||||
|
ser_data[(i * 8)..((i + 1) * 8)].to_vec()
|
||||||
if (i + 1) * 8 < ser_data.len() {
|
|
||||||
next_chunk = ser_data[(i * 8)..((i + 1) * 8)].iter().cloned().collect();
|
|
||||||
} else {
|
} else {
|
||||||
next_chunk = ser_data[(i * 8)..(ser_data.len())]
|
ser_data[(i * 8)..(ser_data.len())].to_vec()
|
||||||
.iter()
|
};
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
u64_list.push(PublicSCContext::produce_u64_from_fit_vec(next_chunk));
|
u64_list.push(PublicSCContext::produce_u64_from_fit_vec(next_chunk));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use accounts::{account_core::Account, key_management::ephemeral_key_holder::EphemeralKeyHolder};
|
use accounts::{account_core::Account, key_management::ephemeral_key_holder::EphemeralKeyHolder};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use common::transaction::{Transaction, TxKind};
|
use common::transaction::{TransactionBody, TxKind};
|
||||||
use rand::thread_rng;
|
use rand::thread_rng;
|
||||||
use risc0_zkvm::Receipt;
|
use risc0_zkvm::Receipt;
|
||||||
use secp256k1_zkp::{CommitmentSecrets, PedersenCommitment, Tweak};
|
use secp256k1_zkp::{CommitmentSecrets, PedersenCommitment, Tweak};
|
||||||
@ -15,8 +15,8 @@ pub fn create_public_transaction_payload(
|
|||||||
secret_r: [u8; 32],
|
secret_r: [u8; 32],
|
||||||
sc_addr: String,
|
sc_addr: String,
|
||||||
state_changes: (serde_json::Value, usize),
|
state_changes: (serde_json::Value, usize),
|
||||||
) -> Transaction {
|
) -> TransactionBody {
|
||||||
Transaction {
|
TransactionBody {
|
||||||
tx_kind: TxKind::Public,
|
tx_kind: TxKind::Public,
|
||||||
execution_input,
|
execution_input,
|
||||||
execution_output: vec![],
|
execution_output: vec![],
|
||||||
@ -66,8 +66,7 @@ pub fn generate_nullifiers_spent_utxos(utxos_spent: Vec<(UTXO, &Account)>) -> Ve
|
|||||||
.key_holder
|
.key_holder
|
||||||
.utxo_secret_key_holder
|
.utxo_secret_key_holder
|
||||||
.nullifier_secret_key
|
.nullifier_secret_key
|
||||||
.to_bytes()
|
.to_bytes(),
|
||||||
.to_vec(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
all_nullifiers.push(nullifier);
|
all_nullifiers.push(nullifier);
|
||||||
@ -91,8 +90,7 @@ pub fn generate_secret_random_commitment(
|
|||||||
.key_holder
|
.key_holder
|
||||||
.utxo_secret_key_holder
|
.utxo_secret_key_holder
|
||||||
.viewing_secret_key
|
.viewing_secret_key
|
||||||
.to_bytes()
|
.to_bytes(),
|
||||||
.to_vec(),
|
|
||||||
)?,
|
)?,
|
||||||
generator_blinding_factor: Tweak::new(&mut thread_rng()),
|
generator_blinding_factor: Tweak::new(&mut thread_rng()),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,22 +6,22 @@ use common::{
|
|||||||
block::{Block, HashableBlockData},
|
block::{Block, HashableBlockData},
|
||||||
merkle_tree_public::TreeHashType,
|
merkle_tree_public::TreeHashType,
|
||||||
nullifier::UTXONullifier,
|
nullifier::UTXONullifier,
|
||||||
transaction::{Transaction, TxKind},
|
transaction::{AuthenticatedTransaction, Transaction, TransactionBody, TxKind},
|
||||||
utxo_commitment::UTXOCommitment,
|
utxo_commitment::UTXOCommitment,
|
||||||
};
|
};
|
||||||
use config::SequencerConfig;
|
use config::SequencerConfig;
|
||||||
use mempool::MemPool;
|
use mempool::MemPool;
|
||||||
|
use mempool_transaction::MempoolTransaction;
|
||||||
use sequencer_store::SequecerChainStore;
|
use sequencer_store::SequecerChainStore;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use transaction_mempool::TransactionMempool;
|
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod mempool_transaction;
|
||||||
pub mod sequencer_store;
|
pub mod sequencer_store;
|
||||||
pub mod transaction_mempool;
|
|
||||||
|
|
||||||
pub struct SequencerCore {
|
pub struct SequencerCore {
|
||||||
pub store: SequecerChainStore,
|
pub store: SequecerChainStore,
|
||||||
pub mempool: MemPool<TransactionMempool>,
|
pub mempool: MemPool<MempoolTransaction>,
|
||||||
pub sequencer_config: SequencerConfig,
|
pub sequencer_config: SequencerConfig,
|
||||||
pub chain_height: u64,
|
pub chain_height: u64,
|
||||||
}
|
}
|
||||||
@ -36,6 +36,7 @@ pub enum TransactionMalformationErrorKind {
|
|||||||
MempoolFullForRound { tx: TreeHashType },
|
MempoolFullForRound { tx: TreeHashType },
|
||||||
ChainStateFurtherThanTransactionState { tx: TreeHashType },
|
ChainStateFurtherThanTransactionState { tx: TreeHashType },
|
||||||
FailedToInsert { tx: TreeHashType, details: String },
|
FailedToInsert { tx: TreeHashType, details: String },
|
||||||
|
InvalidSignature,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for TransactionMalformationErrorKind {
|
impl Display for TransactionMalformationErrorKind {
|
||||||
@ -55,7 +56,7 @@ impl SequencerCore {
|
|||||||
config.is_genesis_random,
|
config.is_genesis_random,
|
||||||
&config.initial_accounts,
|
&config.initial_accounts,
|
||||||
),
|
),
|
||||||
mempool: MemPool::<TransactionMempool>::default(),
|
mempool: MemPool::<MempoolTransaction>::default(),
|
||||||
chain_height: config.genesis_id,
|
chain_height: config.genesis_id,
|
||||||
sequencer_config: config,
|
sequencer_config: config,
|
||||||
}
|
}
|
||||||
@ -73,18 +74,23 @@ impl SequencerCore {
|
|||||||
|
|
||||||
pub fn transaction_pre_check(
|
pub fn transaction_pre_check(
|
||||||
&mut self,
|
&mut self,
|
||||||
tx: &Transaction,
|
tx: Transaction,
|
||||||
tx_roots: [[u8; 32]; 2],
|
tx_roots: [[u8; 32]; 2],
|
||||||
) -> Result<(), TransactionMalformationErrorKind> {
|
) -> Result<AuthenticatedTransaction, TransactionMalformationErrorKind> {
|
||||||
let Transaction {
|
let tx = tx
|
||||||
|
.into_authenticated()
|
||||||
|
.map_err(|_| TransactionMalformationErrorKind::InvalidSignature)?;
|
||||||
|
|
||||||
|
let TransactionBody {
|
||||||
tx_kind,
|
tx_kind,
|
||||||
ref execution_input,
|
ref execution_input,
|
||||||
ref execution_output,
|
ref execution_output,
|
||||||
ref utxo_commitments_created_hashes,
|
ref utxo_commitments_created_hashes,
|
||||||
ref nullifier_created_hashes,
|
ref nullifier_created_hashes,
|
||||||
..
|
..
|
||||||
} = tx;
|
} = tx.transaction().body();
|
||||||
let tx_hash = tx.hash();
|
|
||||||
|
let tx_hash = *tx.hash();
|
||||||
|
|
||||||
let mempool_size = self.mempool.len();
|
let mempool_size = self.mempool.len();
|
||||||
|
|
||||||
@ -133,73 +139,77 @@ impl SequencerCore {
|
|||||||
|
|
||||||
//Tree checks
|
//Tree checks
|
||||||
let tx_tree_check = self.store.pub_tx_store.get_tx(tx_hash).is_some();
|
let tx_tree_check = self.store.pub_tx_store.get_tx(tx_hash).is_some();
|
||||||
let nullifier_tree_check = nullifier_created_hashes
|
let nullifier_tree_check = nullifier_created_hashes.iter().any(|nullifier_hash| {
|
||||||
.iter()
|
self.store.nullifier_store.contains(&UTXONullifier {
|
||||||
.map(|nullifier_hash| {
|
utxo_hash: *nullifier_hash,
|
||||||
self.store.nullifier_store.contains(&UTXONullifier {
|
|
||||||
utxo_hash: *nullifier_hash,
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.any(|check| check);
|
});
|
||||||
let utxo_commitments_check = utxo_commitments_created_hashes
|
let utxo_commitments_check =
|
||||||
.iter()
|
utxo_commitments_created_hashes
|
||||||
.map(|utxo_commitment_hash| {
|
.iter()
|
||||||
self.store
|
.any(|utxo_commitment_hash| {
|
||||||
.utxo_commitments_store
|
self.store
|
||||||
.get_tx(*utxo_commitment_hash)
|
.utxo_commitments_store
|
||||||
.is_some()
|
.get_tx(*utxo_commitment_hash)
|
||||||
})
|
.is_some()
|
||||||
.any(|check| check);
|
});
|
||||||
|
|
||||||
if tx_tree_check {
|
if tx_tree_check {
|
||||||
return Err(
|
return Err(
|
||||||
TransactionMalformationErrorKind::TxHashAlreadyPresentInTree { tx: tx.hash() },
|
TransactionMalformationErrorKind::TxHashAlreadyPresentInTree { tx: *tx.hash() },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if nullifier_tree_check {
|
if nullifier_tree_check {
|
||||||
return Err(
|
return Err(
|
||||||
TransactionMalformationErrorKind::NullifierAlreadyPresentInTree { tx: tx.hash() },
|
TransactionMalformationErrorKind::NullifierAlreadyPresentInTree { tx: *tx.hash() },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if utxo_commitments_check {
|
if utxo_commitments_check {
|
||||||
return Err(
|
return Err(
|
||||||
TransactionMalformationErrorKind::UTXOCommitmentAlreadyPresentInTree {
|
TransactionMalformationErrorKind::UTXOCommitmentAlreadyPresentInTree {
|
||||||
tx: tx.hash(),
|
tx: *tx.hash(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_tx_into_mempool_pre_check(
|
pub fn push_tx_into_mempool_pre_check(
|
||||||
&mut self,
|
&mut self,
|
||||||
item: TransactionMempool,
|
transaction: Transaction,
|
||||||
tx_roots: [[u8; 32]; 2],
|
tx_roots: [[u8; 32]; 2],
|
||||||
) -> Result<(), TransactionMalformationErrorKind> {
|
) -> Result<(), TransactionMalformationErrorKind> {
|
||||||
self.transaction_pre_check(&item.tx, tx_roots)?;
|
let mempool_size = self.mempool.len();
|
||||||
|
if mempool_size >= self.sequencer_config.max_num_tx_in_block {
|
||||||
|
return Err(TransactionMalformationErrorKind::MempoolFullForRound {
|
||||||
|
tx: transaction.body().hash(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
self.mempool.push_item(item);
|
let authenticated_tx = self.transaction_pre_check(transaction, tx_roots)?;
|
||||||
|
|
||||||
|
self.mempool.push_item(authenticated_tx.into());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_check_transaction_on_state(
|
fn execute_check_transaction_on_state(
|
||||||
&mut self,
|
&mut self,
|
||||||
tx: TransactionMempool,
|
mempool_tx: &MempoolTransaction,
|
||||||
) -> Result<(), TransactionMalformationErrorKind> {
|
) -> Result<(), TransactionMalformationErrorKind> {
|
||||||
let Transaction {
|
let TransactionBody {
|
||||||
ref utxo_commitments_created_hashes,
|
ref utxo_commitments_created_hashes,
|
||||||
ref nullifier_created_hashes,
|
ref nullifier_created_hashes,
|
||||||
..
|
..
|
||||||
} = tx.tx;
|
} = mempool_tx.auth_tx.transaction().body();
|
||||||
|
|
||||||
for utxo_comm in utxo_commitments_created_hashes {
|
for utxo_comm in utxo_commitments_created_hashes {
|
||||||
self.store
|
self.store
|
||||||
.utxo_commitments_store
|
.utxo_commitments_store
|
||||||
.add_tx(UTXOCommitment { hash: *utxo_comm });
|
.add_tx(&UTXOCommitment { hash: *utxo_comm });
|
||||||
}
|
}
|
||||||
|
|
||||||
for nullifier in nullifier_created_hashes.iter() {
|
for nullifier in nullifier_created_hashes.iter() {
|
||||||
@ -208,7 +218,9 @@ impl SequencerCore {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
self.store.pub_tx_store.add_tx(tx.tx);
|
self.store
|
||||||
|
.pub_tx_store
|
||||||
|
.add_tx(mempool_tx.auth_tx.transaction());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -226,7 +238,7 @@ impl SequencerCore {
|
|||||||
.pop_size(self.sequencer_config.max_num_tx_in_block);
|
.pop_size(self.sequencer_config.max_num_tx_in_block);
|
||||||
|
|
||||||
for tx in &transactions {
|
for tx in &transactions {
|
||||||
self.execute_check_transaction_on_state(tx.clone())?;
|
self.execute_check_transaction_on_state(tx)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let prev_block_hash = self
|
let prev_block_hash = self
|
||||||
@ -238,7 +250,10 @@ impl SequencerCore {
|
|||||||
let hashable_data = HashableBlockData {
|
let hashable_data = HashableBlockData {
|
||||||
block_id: new_block_height,
|
block_id: new_block_height,
|
||||||
prev_block_id: self.chain_height,
|
prev_block_id: self.chain_height,
|
||||||
transactions: transactions.into_iter().map(|tx_mem| tx_mem.tx).collect(),
|
transactions: transactions
|
||||||
|
.into_iter()
|
||||||
|
.map(|tx_mem| tx_mem.auth_tx.transaction().clone())
|
||||||
|
.collect(),
|
||||||
data: vec![],
|
data: vec![],
|
||||||
prev_block_hash,
|
prev_block_hash,
|
||||||
};
|
};
|
||||||
@ -260,10 +275,10 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use common::transaction::{Transaction, TxKind};
|
use common::transaction::{SignaturePrivateKey, Transaction, TransactionBody, TxKind};
|
||||||
|
use mempool_transaction::MempoolTransaction;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use secp256k1_zkp::Tweak;
|
use secp256k1_zkp::Tweak;
|
||||||
use transaction_mempool::TransactionMempool;
|
|
||||||
|
|
||||||
fn setup_sequencer_config_variable_initial_accounts(
|
fn setup_sequencer_config_variable_initial_accounts(
|
||||||
initial_accounts: Vec<AccountInitialData>,
|
initial_accounts: Vec<AccountInitialData>,
|
||||||
@ -271,7 +286,7 @@ mod tests {
|
|||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let random_u8: u8 = rng.gen();
|
let random_u8: u8 = rng.gen();
|
||||||
|
|
||||||
let path_str = format!("/tmp/sequencer_{:?}", random_u8);
|
let path_str = format!("/tmp/sequencer_{random_u8:?}");
|
||||||
|
|
||||||
SequencerConfig {
|
SequencerConfig {
|
||||||
home: PathBuf::from(path_str),
|
home: PathBuf::from(path_str),
|
||||||
@ -309,7 +324,7 @@ mod tests {
|
|||||||
) -> Transaction {
|
) -> Transaction {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
Transaction {
|
let body = TransactionBody {
|
||||||
tx_kind: TxKind::Private,
|
tx_kind: TxKind::Private,
|
||||||
execution_input: vec![],
|
execution_input: vec![],
|
||||||
execution_output: vec![],
|
execution_output: vec![],
|
||||||
@ -324,13 +339,16 @@ mod tests {
|
|||||||
secret_r: [0; 32],
|
secret_r: [0; 32],
|
||||||
sc_addr: "sc_addr".to_string(),
|
sc_addr: "sc_addr".to_string(),
|
||||||
state_changes: (serde_json::Value::Null, 0),
|
state_changes: (serde_json::Value::Null, 0),
|
||||||
}
|
};
|
||||||
|
Transaction::new(body, SignaturePrivateKey::random(&mut rng))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn common_setup(sequencer: &mut SequencerCore) {
|
fn common_setup(sequencer: &mut SequencerCore) {
|
||||||
let tx = create_dummy_transaction(vec![[9; 32]], vec![[7; 32]], vec![[8; 32]]);
|
let tx = create_dummy_transaction(vec![[9; 32]], vec![[7; 32]], vec![[8; 32]]);
|
||||||
let tx_mempool = TransactionMempool { tx };
|
let mempool_tx = MempoolTransaction {
|
||||||
sequencer.mempool.push_item(tx_mempool);
|
auth_tx: tx.into_authenticated().unwrap(),
|
||||||
|
};
|
||||||
|
sequencer.mempool.push_item(mempool_tx);
|
||||||
|
|
||||||
sequencer
|
sequencer
|
||||||
.produce_new_block_with_mempool_transactions()
|
.produce_new_block_with_mempool_transactions()
|
||||||
@ -346,18 +364,16 @@ mod tests {
|
|||||||
assert_eq!(sequencer.sequencer_config.max_num_tx_in_block, 10);
|
assert_eq!(sequencer.sequencer_config.max_num_tx_in_block, 10);
|
||||||
assert_eq!(sequencer.sequencer_config.port, 8080);
|
assert_eq!(sequencer.sequencer_config.port, 8080);
|
||||||
|
|
||||||
let acc1_addr: [u8; 32] = hex::decode(
|
let acc1_addr: [u8; 32] =
|
||||||
"bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c".to_string(),
|
hex::decode("bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c")
|
||||||
)
|
.unwrap()
|
||||||
.unwrap()
|
.try_into()
|
||||||
.try_into()
|
.unwrap();
|
||||||
.unwrap();
|
let acc2_addr: [u8; 32] =
|
||||||
let acc2_addr: [u8; 32] = hex::decode(
|
hex::decode("20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31")
|
||||||
"20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31".to_string(),
|
.unwrap()
|
||||||
)
|
.try_into()
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.try_into()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert!(sequencer.store.acc_store.contains_account(&acc1_addr));
|
assert!(sequencer.store.acc_store.contains_account(&acc1_addr));
|
||||||
assert!(sequencer.store.acc_store.contains_account(&acc2_addr));
|
assert!(sequencer.store.acc_store.contains_account(&acc2_addr));
|
||||||
@ -400,18 +416,16 @@ mod tests {
|
|||||||
let config = setup_sequencer_config_variable_initial_accounts(initial_accounts);
|
let config = setup_sequencer_config_variable_initial_accounts(initial_accounts);
|
||||||
let sequencer = SequencerCore::start_from_config(config.clone());
|
let sequencer = SequencerCore::start_from_config(config.clone());
|
||||||
|
|
||||||
let acc1_addr: [u8; 32] = hex::decode(
|
let acc1_addr: [u8; 32] =
|
||||||
"bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117ffffff".to_string(),
|
hex::decode("bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117ffffff")
|
||||||
)
|
.unwrap()
|
||||||
.unwrap()
|
.try_into()
|
||||||
.try_into()
|
.unwrap();
|
||||||
.unwrap();
|
let acc2_addr: [u8; 32] =
|
||||||
let acc2_addr: [u8; 32] = hex::decode(
|
hex::decode("20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1effffff")
|
||||||
"20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1effffff".to_string(),
|
.unwrap()
|
||||||
)
|
.try_into()
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.try_into()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert!(sequencer.store.acc_store.contains_account(&acc1_addr));
|
assert!(sequencer.store.acc_store.contains_account(&acc1_addr));
|
||||||
assert!(sequencer.store.acc_store.contains_account(&acc2_addr));
|
assert!(sequencer.store.acc_store.contains_account(&acc2_addr));
|
||||||
@ -456,13 +470,13 @@ mod tests {
|
|||||||
|
|
||||||
let tx = create_dummy_transaction(vec![[91; 32]], vec![[71; 32]], vec![[81; 32]]);
|
let tx = create_dummy_transaction(vec![[91; 32]], vec![[71; 32]], vec![[81; 32]]);
|
||||||
let tx_roots = sequencer.get_tree_roots();
|
let tx_roots = sequencer.get_tree_roots();
|
||||||
let result = sequencer.transaction_pre_check(&tx, tx_roots);
|
let result = sequencer.transaction_pre_check(tx, tx_roots);
|
||||||
|
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transaction_pre_check_fail_mempool_full() {
|
fn test_push_tx_into_mempool_fails_mempool_full() {
|
||||||
let config = SequencerConfig {
|
let config = SequencerConfig {
|
||||||
max_num_tx_in_block: 1,
|
max_num_tx_in_block: 1,
|
||||||
..setup_sequencer_config()
|
..setup_sequencer_config()
|
||||||
@ -475,10 +489,12 @@ mod tests {
|
|||||||
let tx_roots = sequencer.get_tree_roots();
|
let tx_roots = sequencer.get_tree_roots();
|
||||||
|
|
||||||
// Fill the mempool
|
// Fill the mempool
|
||||||
let dummy_tx = TransactionMempool { tx: tx.clone() };
|
let dummy_tx = MempoolTransaction {
|
||||||
|
auth_tx: tx.clone().into_authenticated().unwrap(),
|
||||||
|
};
|
||||||
sequencer.mempool.push_item(dummy_tx);
|
sequencer.mempool.push_item(dummy_tx);
|
||||||
|
|
||||||
let result = sequencer.transaction_pre_check(&tx, tx_roots);
|
let result = sequencer.push_tx_into_mempool_pre_check(tx, tx_roots);
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
result,
|
result,
|
||||||
@ -495,9 +511,8 @@ mod tests {
|
|||||||
|
|
||||||
let tx = create_dummy_transaction(vec![[93; 32]], vec![[73; 32]], vec![[83; 32]]);
|
let tx = create_dummy_transaction(vec![[93; 32]], vec![[73; 32]], vec![[83; 32]]);
|
||||||
let tx_roots = sequencer.get_tree_roots();
|
let tx_roots = sequencer.get_tree_roots();
|
||||||
let tx_mempool = TransactionMempool { tx };
|
|
||||||
|
|
||||||
let result = sequencer.push_tx_into_mempool_pre_check(tx_mempool.clone(), tx_roots);
|
let result = sequencer.push_tx_into_mempool_pre_check(tx, tx_roots);
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
assert_eq!(sequencer.mempool.len(), 1);
|
assert_eq!(sequencer.mempool.len(), 1);
|
||||||
}
|
}
|
||||||
@ -508,7 +523,9 @@ mod tests {
|
|||||||
let mut sequencer = SequencerCore::start_from_config(config);
|
let mut sequencer = SequencerCore::start_from_config(config);
|
||||||
|
|
||||||
let tx = create_dummy_transaction(vec![[94; 32]], vec![[7; 32]], vec![[8; 32]]);
|
let tx = create_dummy_transaction(vec![[94; 32]], vec![[7; 32]], vec![[8; 32]]);
|
||||||
let tx_mempool = TransactionMempool { tx };
|
let tx_mempool = MempoolTransaction {
|
||||||
|
auth_tx: tx.into_authenticated().unwrap(),
|
||||||
|
};
|
||||||
sequencer.mempool.push_item(tx_mempool);
|
sequencer.mempool.push_item(tx_mempool);
|
||||||
|
|
||||||
let block_id = sequencer.produce_new_block_with_mempool_transactions();
|
let block_id = sequencer.produce_new_block_with_mempool_transactions();
|
||||||
|
|||||||
20
sequencer_core/src/mempool_transaction.rs
Normal file
20
sequencer_core/src/mempool_transaction.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use common::{merkle_tree_public::TreeHashType, transaction::AuthenticatedTransaction};
|
||||||
|
use mempool::mempoolitem::MemPoolItem;
|
||||||
|
|
||||||
|
pub struct MempoolTransaction {
|
||||||
|
pub auth_tx: AuthenticatedTransaction,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AuthenticatedTransaction> for MempoolTransaction {
|
||||||
|
fn from(auth_tx: AuthenticatedTransaction) -> Self {
|
||||||
|
Self { auth_tx }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemPoolItem for MempoolTransaction {
|
||||||
|
type Identifier = TreeHashType;
|
||||||
|
|
||||||
|
fn identifier(&self) -> Self::Identifier {
|
||||||
|
*self.auth_tx.hash()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -85,6 +85,11 @@ impl SequencerAccountsStore {
|
|||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.accounts.len()
|
self.accounts.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Is accounts store empty
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.accounts.is_empty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SequencerAccountsStore {
|
impl Default for SequencerAccountsStore {
|
||||||
@ -213,4 +218,11 @@ mod tests {
|
|||||||
|
|
||||||
assert!(acc_balance.is_none());
|
assert!(acc_balance.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn account_sequencer_store_is_empty_test() {
|
||||||
|
let seq_acc_store = SequencerAccountsStore::default();
|
||||||
|
|
||||||
|
assert!(seq_acc_store.is_empty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,43 +0,0 @@
|
|||||||
use common::{merkle_tree_public::TreeHashType, transaction::Transaction};
|
|
||||||
use mempool::mempoolitem::MemPoolItem;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct TransactionMempool {
|
|
||||||
pub tx: Transaction,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Transaction> for TransactionMempool {
|
|
||||||
fn from(value: Transaction) -> Self {
|
|
||||||
Self { tx: value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for TransactionMempool {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
self.tx.serialize(serializer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for TransactionMempool {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
match Transaction::deserialize(deserializer) {
|
|
||||||
Ok(tx) => Ok(TransactionMempool { tx }),
|
|
||||||
Err(err) => Err(err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MemPoolItem for TransactionMempool {
|
|
||||||
type Identifier = TreeHashType;
|
|
||||||
|
|
||||||
fn identifier(&self) -> Self::Identifier {
|
|
||||||
self.tx.hash()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -53,7 +53,7 @@ pub fn new_http_server(
|
|||||||
polling_config,
|
polling_config,
|
||||||
limits_config,
|
limits_config,
|
||||||
} = config;
|
} = config;
|
||||||
info!(target:NETWORK, "Starting http server at {}", addr);
|
info!(target:NETWORK, "Starting http server at {addr}");
|
||||||
let handler = web::Data::new(JsonHandler {
|
let handler = web::Data::new(JsonHandler {
|
||||||
polling_config,
|
polling_config,
|
||||||
sequencer_state: seuquencer_core.clone(),
|
sequencer_state: seuquencer_core.clone(),
|
||||||
|
|||||||
@ -78,10 +78,7 @@ impl JsonHandler {
|
|||||||
{
|
{
|
||||||
let mut state = self.sequencer_state.lock().await;
|
let mut state = self.sequencer_state.lock().await;
|
||||||
|
|
||||||
state.push_tx_into_mempool_pre_check(
|
state.push_tx_into_mempool_pre_check(send_tx_req.transaction, send_tx_req.tx_roots)?;
|
||||||
send_tx_req.transaction.into(),
|
|
||||||
send_tx_req.tx_roots,
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let helperstruct = SendTxResponse {
|
let helperstruct = SendTxResponse {
|
||||||
|
|||||||
@ -316,7 +316,7 @@ impl RocksDBIO {
|
|||||||
let cf_sc = self.sc_column();
|
let cf_sc = self.sc_column();
|
||||||
|
|
||||||
let sc_addr_loc = format!("{sc_addr:?}{SC_LEN_SUFFIX}");
|
let sc_addr_loc = format!("{sc_addr:?}{SC_LEN_SUFFIX}");
|
||||||
let sc_len_addr = sc_addr_loc.as_str().as_bytes();
|
let sc_len_addr = sc_addr_loc.as_bytes();
|
||||||
|
|
||||||
self.db
|
self.db
|
||||||
.put_cf(&cf_sc, sc_len_addr, length.to_be_bytes())
|
.put_cf(&cf_sc, sc_len_addr, length.to_be_bytes())
|
||||||
@ -360,7 +360,7 @@ impl RocksDBIO {
|
|||||||
let cf_sc = self.sc_column();
|
let cf_sc = self.sc_column();
|
||||||
let sc_addr_loc = format!("{sc_addr:?}{SC_LEN_SUFFIX}");
|
let sc_addr_loc = format!("{sc_addr:?}{SC_LEN_SUFFIX}");
|
||||||
|
|
||||||
let sc_len_addr = sc_addr_loc.as_str().as_bytes();
|
let sc_len_addr = sc_addr_loc.as_bytes();
|
||||||
|
|
||||||
let sc_len = self
|
let sc_len = self
|
||||||
.db
|
.db
|
||||||
@ -379,11 +379,11 @@ impl RocksDBIO {
|
|||||||
///Get full sc state from DB
|
///Get full sc state from DB
|
||||||
pub fn get_sc_sc_state(&self, sc_addr: &str) -> DbResult<Vec<DataBlob>> {
|
pub fn get_sc_sc_state(&self, sc_addr: &str) -> DbResult<Vec<DataBlob>> {
|
||||||
let cf_sc = self.sc_column();
|
let cf_sc = self.sc_column();
|
||||||
let sc_len = self.get_sc_sc_state_len(&sc_addr)?;
|
let sc_len = self.get_sc_sc_state_len(sc_addr)?;
|
||||||
let mut data_blob_list = vec![];
|
let mut data_blob_list = vec![];
|
||||||
|
|
||||||
for id in 0..sc_len {
|
for id in 0..sc_len {
|
||||||
let blob_addr = produce_address_for_data_blob_at_id(&sc_addr, id);
|
let blob_addr = produce_address_for_data_blob_at_id(sc_addr, id);
|
||||||
|
|
||||||
let blob = self
|
let blob = self
|
||||||
.db
|
.db
|
||||||
@ -541,7 +541,7 @@ impl RocksDBIO {
|
|||||||
|
|
||||||
///Creates address for sc data blob at corresponding id
|
///Creates address for sc data blob at corresponding id
|
||||||
fn produce_address_for_data_blob_at_id(sc_addr: &str, id: usize) -> Vec<u8> {
|
fn produce_address_for_data_blob_at_id(sc_addr: &str, id: usize) -> Vec<u8> {
|
||||||
let mut prefix_bytes: Vec<u8> = sc_addr.as_bytes().iter().cloned().collect();
|
let mut prefix_bytes: Vec<u8> = sc_addr.as_bytes().to_vec();
|
||||||
|
|
||||||
let id_bytes = id.to_be_bytes();
|
let id_bytes = id.to_be_bytes();
|
||||||
|
|
||||||
|
|||||||
@ -49,6 +49,7 @@ impl DataBlob {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub enum DataBlobChangeVariant {
|
pub enum DataBlobChangeVariant {
|
||||||
Created {
|
Created {
|
||||||
@ -145,7 +146,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_produce_blob_from_fit_vec() {
|
fn test_produce_blob_from_fit_vec() {
|
||||||
let data = (0..0 + 255).collect();
|
let data = (0..255).collect();
|
||||||
let blob = produce_blob_from_fit_vec(data);
|
let blob = produce_blob_from_fit_vec(data);
|
||||||
assert_eq!(blob.0[..4], [0, 1, 2, 3]);
|
assert_eq!(blob.0[..4], [0, 1, 2, 3]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,7 +58,7 @@ impl UTXO {
|
|||||||
}
|
}
|
||||||
pub fn create_utxo_from_payload(payload_with_asset: UTXOPayload) -> Self {
|
pub fn create_utxo_from_payload(payload_with_asset: UTXOPayload) -> Self {
|
||||||
let mut hasher = sha2::Sha256::new();
|
let mut hasher = sha2::Sha256::new();
|
||||||
hasher.update(&payload_with_asset.to_bytes());
|
hasher.update(payload_with_asset.to_bytes());
|
||||||
let hash = <TreeHashType>::from(hasher.finalize_fixed());
|
let hash = <TreeHashType>::from(hasher.finalize_fixed());
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@ -9,6 +9,7 @@ pub mod gas_calculator;
|
|||||||
|
|
||||||
pub use test_methods;
|
pub use test_methods;
|
||||||
|
|
||||||
|
#[allow(clippy::result_large_err)]
|
||||||
pub fn gas_limits_check<INP: Serialize>(
|
pub fn gas_limits_check<INP: Serialize>(
|
||||||
input_buffer: INP,
|
input_buffer: INP,
|
||||||
elf: &[u8],
|
elf: &[u8],
|
||||||
@ -31,6 +32,7 @@ pub fn gas_limits_check<INP: Serialize>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::result_large_err)]
|
||||||
pub fn prove_mint_utxo(
|
pub fn prove_mint_utxo(
|
||||||
amount_to_mint: u128,
|
amount_to_mint: u128,
|
||||||
owner: AccountAddress,
|
owner: AccountAddress,
|
||||||
@ -66,6 +68,7 @@ pub fn prove_mint_utxo(
|
|||||||
Ok((UTXO::create_utxo_from_payload(digest), receipt))
|
Ok((UTXO::create_utxo_from_payload(digest), receipt))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::result_large_err)]
|
||||||
pub fn prove_send_utxo(
|
pub fn prove_send_utxo(
|
||||||
spent_utxo: UTXO,
|
spent_utxo: UTXO,
|
||||||
owners_parts: Vec<(u128, AccountAddress)>,
|
owners_parts: Vec<(u128, AccountAddress)>,
|
||||||
@ -118,6 +121,7 @@ pub fn prove_send_utxo(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::result_large_err)]
|
||||||
pub fn prove_send_utxo_multiple_assets_one_receiver(
|
pub fn prove_send_utxo_multiple_assets_one_receiver(
|
||||||
spent_utxos: Vec<UTXO>,
|
spent_utxos: Vec<UTXO>,
|
||||||
number_to_send: usize,
|
number_to_send: usize,
|
||||||
@ -160,17 +164,18 @@ pub fn prove_send_utxo_multiple_assets_one_receiver(
|
|||||||
digest
|
digest
|
||||||
.0
|
.0
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|payload| UTXO::create_utxo_from_payload(payload))
|
.map(UTXO::create_utxo_from_payload)
|
||||||
.collect(),
|
.collect(),
|
||||||
digest
|
digest
|
||||||
.1
|
.1
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|payload| UTXO::create_utxo_from_payload(payload))
|
.map(UTXO::create_utxo_from_payload)
|
||||||
.collect(),
|
.collect(),
|
||||||
receipt,
|
receipt,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::result_large_err)]
|
||||||
pub fn prove_send_utxo_shielded(
|
pub fn prove_send_utxo_shielded(
|
||||||
owner: AccountAddress,
|
owner: AccountAddress,
|
||||||
amount: u128,
|
amount: u128,
|
||||||
@ -226,6 +231,7 @@ pub fn prove_send_utxo_shielded(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::result_large_err)]
|
||||||
pub fn prove_send_utxo_deshielded(
|
pub fn prove_send_utxo_deshielded(
|
||||||
spent_utxo: UTXO,
|
spent_utxo: UTXO,
|
||||||
owners_parts: Vec<(u128, AccountAddress)>,
|
owners_parts: Vec<(u128, AccountAddress)>,
|
||||||
@ -278,6 +284,7 @@ pub fn prove_send_utxo_deshielded(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::result_large_err)]
|
||||||
pub fn prove_mint_utxo_multiple_assets(
|
pub fn prove_mint_utxo_multiple_assets(
|
||||||
amount_to_mint: u128,
|
amount_to_mint: u128,
|
||||||
number_of_assets: usize,
|
number_of_assets: usize,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user