Skip to content

Commit

Permalink
feat: add encrypted_field to the TransactionOutput
Browse files Browse the repository at this point in the history
  • Loading branch information
therustmonk committed Jun 16, 2022
1 parent 50ce20a commit 8490aea
Show file tree
Hide file tree
Showing 28 changed files with 4,176 additions and 4,072 deletions.
4 changes: 4 additions & 0 deletions applications/tari_app_grpc/proto/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ message TransactionInput {
bytes covenant = 10;
// Version
uint32 version = 11;
// The encrypted value
bytes encrypted_value = 12;
}

// Output for a transaction, defining the new ownership of coins that are being transferred. The commitment is a
Expand All @@ -202,6 +204,8 @@ message TransactionOutput {
bytes covenant = 8;
// Version
uint32 version = 9;
// The encrypted value
bytes encrypted_value = 10;
}

// Options for UTXOs
Expand Down
11 changes: 7 additions & 4 deletions applications/tari_app_grpc/src/conversions/transaction_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use std::convert::{TryFrom, TryInto};
use tari_common_types::types::{Commitment, PublicKey};
use tari_core::{
covenants::Covenant,
transactions::transaction_components::{TransactionInput, TransactionInputVersion},
transactions::transaction_components::{EncryptedValue, TransactionInput, TransactionInputVersion},
};
use tari_script::{ExecutionStack, TariScript};
use tari_utilities::ByteArray;
Expand Down Expand Up @@ -62,7 +62,7 @@ impl TryFrom<grpc::TransactionInput> for TransactionInput {
let sender_offset_public_key =
PublicKey::from_bytes(input.sender_offset_public_key.as_bytes()).map_err(|err| format!("{:?}", err))?;
let covenant = Covenant::from_bytes(&input.covenant).map_err(|err| err.to_string())?;

let encrypted_value = EncryptedValue::from_bytes(&input.encrypted_value).map_err(|err| err.to_string())?;
Ok(TransactionInput::new_with_output_data(
TransactionInputVersion::try_from(
u8::try_from(input.version).map_err(|_| "Invalid version: overflowed u8")?,
Expand All @@ -74,6 +74,7 @@ impl TryFrom<grpc::TransactionInput> for TransactionInput {
script_signature,
sender_offset_public_key,
covenant,
encrypted_value,
))
}
}
Expand Down Expand Up @@ -105,7 +106,6 @@ impl TryFrom<TransactionInput> for grpc::TransactionInput {
commitment: input
.commitment()
.map_err(|_| "Non-compact Transaction input should contain commitment".to_string())?
.as_bytes()
.to_vec(),
hash: input
.canonical_hash()
Expand All @@ -120,14 +120,17 @@ impl TryFrom<TransactionInput> for grpc::TransactionInput {
sender_offset_public_key: input
.sender_offset_public_key()
.map_err(|_| "Non-compact Transaction input should contain sender_offset_public_key".to_string())?
.as_bytes()
.to_vec(),
output_hash: Vec::new(),
covenant: input
.covenant()
.map_err(|_| "Non-compact Transaction input should contain covenant".to_string())?
.to_bytes(),
version: input.version as u32,
encrypted_value: input
.encrypted_value()
.map_err(|_| "Non-compact Transaction input should contain encrypted value".to_string())?
.to_vec(),
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use std::convert::{TryFrom, TryInto};
use tari_common_types::types::{BulletRangeProof, Commitment, PublicKey};
use tari_core::{
covenants::Covenant,
transactions::transaction_components::{TransactionOutput, TransactionOutputVersion},
transactions::transaction_components::{EncryptedValue, TransactionOutput, TransactionOutputVersion},
};
use tari_script::TariScript;
use tari_utilities::{ByteArray, Hashable};
Expand Down Expand Up @@ -55,6 +55,7 @@ impl TryFrom<grpc::TransactionOutput> for TransactionOutput {
.try_into()
.map_err(|_| "Metadata signature could not be converted".to_string())?;
let covenant = Covenant::from_bytes(&output.covenant).map_err(|err| err.to_string())?;
let encrypted_value = EncryptedValue::from_bytes(&output.encrypted_value).map_err(|err| err.to_string())?;
Ok(Self::new(
TransactionOutputVersion::try_from(
u8::try_from(output.version).map_err(|_| "Invalid version: overflowed u8")?,
Expand All @@ -66,6 +67,7 @@ impl TryFrom<grpc::TransactionOutput> for TransactionOutput {
sender_offset_public_key,
metadata_signature,
covenant,
encrypted_value,
))
}
}
Expand All @@ -87,6 +89,7 @@ impl From<TransactionOutput> for grpc::TransactionOutput {
}),
covenant: output.covenant.to_bytes(),
version: output.version as u32,
encrypted_value: output.encrypted_value.to_vec(),
}
}
}
1 change: 1 addition & 0 deletions applications/test_faucet/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ fn create_utxo(
offset_keys.pk,
metadata_sig,
covenant,
encrypted_value,
);
(utxo, keys.k, offset_keys.k)
}
8,000 changes: 4,000 additions & 4,000 deletions base_layer/core/src/blocks/faucets/dibbler_faucet.json

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions base_layer/core/src/blocks/genesis_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use crate::{
aggregated_body::AggregateBody,
tari_amount::MicroTari,
transaction_components::{
EncryptedValue,
KernelFeatures,
OutputFeatures,
OutputFeaturesVersion,
Expand Down Expand Up @@ -115,6 +116,7 @@ fn get_igor_genesis_block_raw() -> Block {
// For genesis block: Metadata signature will never be checked
Default::default(),
Covenant::default(),
EncryptedValue::default(),
)],
vec![TransactionKernel::new_current_version(
KernelFeatures::COINBASE_KERNEL,
Expand Down Expand Up @@ -214,7 +216,7 @@ pub fn get_dibbler_genesis_block() -> ChainBlock {
// hardcode the Merkle roots once they've been computed above
block.header.kernel_mr = from_hex("5b91bebd33e18798e03e9c5d831d161ee9c3d12560f50b987e1a8c3ec53146df").unwrap();
block.header.witness_mr = from_hex("11227f6ce9ff34349d7dcab606b633f55234d5c8a73696a68c6e9ddc7cd3bc40").unwrap();
block.header.output_mr = from_hex("5e69274e72f8590e1cf91c189e24368527414aed966de62135d9273a6c14c3ef").unwrap();
block.header.output_mr = from_hex("e3d8e137e8efb476d0ef0149ec5f82441daec91847bd910c8d102d6432ce3278").unwrap();

let accumulated_data = BlockHeaderAccumulatedData {
hash: block.hash(),
Expand Down Expand Up @@ -259,7 +261,8 @@ fn get_dibbler_genesis_block_raw() -> Block {
// For genesis block: Metadata signature will never be checked
ComSignature::default(),
// Covenant
Covenant::default()
Covenant::default(),
EncryptedValue::default(),
);
let kernel = TransactionKernel::new(
TransactionKernelVersion::V0,
Expand Down
1 change: 1 addition & 0 deletions base_layer/core/src/chain_storage/blockchain_database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1510,6 +1510,7 @@ fn fetch_block<T: BlockchainBackend>(db: &T, height: u64) -> Result<HistoricalBl
output.script,
output.sender_offset_public_key,
output.covenant,
output.encrypted_value,
);
Ok(compact_input)
},
Expand Down
1 change: 1 addition & 0 deletions base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,7 @@ impl LMDBDatabase {
output.script,
output.sender_offset_public_key,
output.covenant,
output.encrypted_value,
);
},
}
Expand Down
4 changes: 4 additions & 0 deletions base_layer/core/src/proto/transaction.proto
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ message TransactionInput {
bytes covenant = 9;
// Version
uint32 version = 10;
// The encrypted value
bytes encrypted_value = 11;
}

// Output for a transaction, defining the new ownership of coins that are being transferred. The commitment is a
Expand All @@ -75,6 +77,8 @@ message TransactionOutput {
bytes covenant = 7;
// Version
uint32 version = 8;
// The encrypted value
bytes encrypted_value = 9;
}

// Options for UTXOs
Expand Down
10 changes: 10 additions & 0 deletions base_layer/core/src/proto/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ use crate::{
ContractSpecification,
ContractUpdateProposal,
ContractUpdateProposalAcceptance,
EncryptedValue,
FunctionRef,
KernelFeatures,
MintNonFungibleFeatures,
Expand Down Expand Up @@ -160,6 +161,7 @@ impl TryFrom<proto::types::TransactionInput> for TransactionInput {
script_signature,
sender_offset_public_key,
Covenant::from_bytes(&input.covenant).map_err(|err| err.to_string())?,
EncryptedValue::from_bytes(&input.encrypted_value).map_err(|err| err.to_string())?,
))
} else {
if input.output_hash.is_empty() {
Expand Down Expand Up @@ -219,6 +221,10 @@ impl TryFrom<TransactionInput> for proto::types::TransactionInput {
.map_err(|_| "Non-compact Transaction input should contain covenant".to_string())?
.to_bytes(),
version: input.version as u32,
encrypted_value: input
.encrypted_value()
.map_err(|_| "Non-compact Transaction input should contain encrypted value".to_string())?
.to_vec(),
})
}
}
Expand Down Expand Up @@ -254,6 +260,8 @@ impl TryFrom<proto::types::TransactionOutput> for TransactionOutput {

let covenant = Covenant::from_bytes(&output.covenant).map_err(|err| err.to_string())?;

let encrypted_value = EncryptedValue::from_bytes(&output.encrypted_value).map_err(|err| err.to_string())?;

Ok(Self::new(
TransactionOutputVersion::try_from(
u8::try_from(output.version).map_err(|_| "Invalid version: overflowed u8")?,
Expand All @@ -265,6 +273,7 @@ impl TryFrom<proto::types::TransactionOutput> for TransactionOutput {
sender_offset_public_key,
metadata_signature,
covenant,
encrypted_value,
))
}
}
Expand All @@ -280,6 +289,7 @@ impl From<TransactionOutput> for proto::types::TransactionOutput {
metadata_signature: Some(output.metadata_signature.into()),
covenant: output.covenant.to_bytes(),
version: output.version as u32,
encrypted_value: output.encrypted_value.to_vec(),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions base_layer/core/src/transactions/test_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,6 @@ pub fn create_stx_protocol(schema: TransactionSchema) -> (SenderTransactionProto
let commitment = factories
.commitment
.commit_value(&utxo.spending_key, utxo.value.as_u64());
let encrypted_value = EncryptedValue::todo_encrypt_from(utxo.value.as_u64());
let recovery_byte = OutputFeatures::create_unique_recovery_byte(&commitment, None);
utxo.features.set_recovery_byte(recovery_byte);
utxo.metadata_signature = TransactionOutput::create_final_metadata_signature(
Expand All @@ -715,7 +714,7 @@ pub fn create_stx_protocol(schema: TransactionSchema) -> (SenderTransactionProto
&utxo.features,
&test_params.sender_offset_private_key,
&utxo.covenant,
&encrypted_value,
&utxo.encrypted_value,
)
.unwrap();
utxo.sender_offset_public_key = test_params.sender_offset_public_key;
Expand Down Expand Up @@ -833,6 +832,7 @@ pub fn create_utxo(
offset_keys.pk,
metadata_sig,
covenant.clone(),
encrypted_value,
);
(utxo, keys.k, offset_keys.k)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,27 @@ use std::io::{self, Read, Write};
use serde::{Deserialize, Serialize};
use tari_utilities::{ByteArray, ByteArrayError};

use crate::consensus::{ConsensusDecoding, ConsensusEncoding};
use crate::consensus::{ConsensusDecoding, ConsensusEncoding, ConsensusEncodingSized};

const SIZE: usize = 24;

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct EncryptedValue {
/// value: u64 + tag: [u8; 16]
pub data: [u8; SIZE],
}
/// value: u64 + tag: [u8; 16]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Hash)]
pub struct EncryptedValue(#[serde(with = "tari_utilities::serde::hex")] pub [u8; SIZE]);

impl Default for EncryptedValue {
fn default() -> Self {
Self { data: [0; SIZE] }
Self([0; SIZE])
}
}

impl ByteArray for EncryptedValue {
fn from_bytes(bytes: &[u8]) -> Result<Self, ByteArrayError> {
if bytes.len() == SIZE {
let mut this = Self::default();
this.data.copy_from_slice(bytes);
Ok(this)
} else {
Err(ByteArrayError::IncorrectLength)
}
ByteArray::from_bytes(bytes).map(Self)
}

fn as_bytes(&self) -> &[u8] {
&self.data
self.0.as_bytes()
}
}

Expand All @@ -67,20 +59,46 @@ impl EncryptedValue {
let mut data: [u8; SIZE] = [0; SIZE];
let value = amount.into().to_le_bytes();
data[0..8].copy_from_slice(&value);
Self { data }
Self(data)
}
}

impl ConsensusEncoding for EncryptedValue {
fn consensus_encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
self.data.consensus_encode(writer)?;
self.0.consensus_encode(writer)?;
Ok(())
}
}

impl ConsensusEncodingSized for EncryptedValue {
fn consensus_encode_exact_size(&self) -> usize {
self.0.len()
}
}

impl ConsensusDecoding for EncryptedValue {
fn consensus_decode<R: Read>(reader: &mut R) -> Result<Self, io::Error> {
let data = <[u8; 24]>::consensus_decode(reader)?;
Ok(Self { data })
Ok(Self(data))
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::consensus::ToConsensusBytes;

#[test]
fn it_encodes_to_bytes() {
let bytes = EncryptedValue::todo_encrypt_from(123u64).to_consensus_bytes();
assert_eq!(&bytes[0..8], &123u64.to_le_bytes());
assert_eq!(bytes.len(), SIZE);
}

#[test]
fn it_decodes_from_bytes() {
let value = &[0; 24];
let encrypted_value = EncryptedValue::consensus_decode(&mut &value[..]).unwrap();
assert_eq!(encrypted_value, EncryptedValue::default());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub(super) fn hash_output(
commitment: &Commitment,
script: &TariScript,
covenant: &Covenant,
encrypted_value: &EncryptedValue,
) -> [u8; 32] {
match version {
TransactionOutputVersion::V0 | TransactionOutputVersion::V1 => ConsensusHashWriter::default()
Expand All @@ -111,6 +112,7 @@ pub(super) fn hash_output(
.chain(commitment)
.chain(script)
.chain(covenant)
.chain(encrypted_value)
.finalize(),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ fn range_proof_verification() {
)
.unwrap(),
Covenant::default(),
encrypted_value,
);
tx_output3.verify_range_proof(&factories.range_proof).unwrap_err();
}
Expand Down Expand Up @@ -248,6 +249,7 @@ fn check_timelocks() {
script_signature,
offset_pub_key,
Covenant::default(),
EncryptedValue::default(),
);

let mut kernel = test_helpers::create_test_kernel(0.into(), 0);
Expand Down
Loading

0 comments on commit 8490aea

Please sign in to comment.