Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: provide a compact form of TransactionInput #3460

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions applications/tari_app_grpc/proto/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ message TransactionInput {
ComSignature script_signature = 7;
// The offset public key, K_O
bytes sender_offset_public_key = 8;
// The hash of the output this input is spending
bytes output_hash = 9;
}

// Output for a transaction, defining the new ownership of coins that are being transferred. The commitment is a
Expand Down
14 changes: 8 additions & 6 deletions applications/tari_app_grpc/src/conversions/aggregate_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ use tari_utilities::convert::try_convert_all;

use crate::tari_rpc as grpc;

impl From<AggregateBody> for grpc::AggregateBody {
fn from(source: AggregateBody) -> Self {
Self {
impl TryFrom<AggregateBody> for grpc::AggregateBody {
type Error = String;

fn try_from(source: AggregateBody) -> Result<Self, Self::Error> {
Ok(Self {
inputs: source
.inputs()
.iter()
.map(|input| grpc::TransactionInput::from(input.clone()))
.collect(),
.map(|input| grpc::TransactionInput::try_from(input.clone()))
.collect::<Result<Vec<grpc::TransactionInput>, _>>()?,
outputs: source
.outputs()
.iter()
Expand All @@ -45,7 +47,7 @@ impl From<AggregateBody> for grpc::AggregateBody {
.iter()
.map(|kernel| grpc::TransactionKernel::from(kernel.clone()))
.collect(),
}
})
}
}

Expand Down
12 changes: 7 additions & 5 deletions applications/tari_app_grpc/src/conversions/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ use tari_core::blocks::Block;

use crate::tari_rpc as grpc;

impl From<tari_core::blocks::Block> for grpc::Block {
fn from(block: Block) -> Self {
Self {
body: Some(block.body.into()),
impl TryFrom<tari_core::blocks::Block> for grpc::Block {
type Error = String;

fn try_from(block: Block) -> Result<Self, Self::Error> {
Ok(Self {
body: Some(block.body.try_into()?),
header: Some(block.header.into()),
}
})
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::convert::TryFrom;
use std::convert::{TryFrom, TryInto};

use tari_core::{blocks::HistoricalBlock, chain_storage::ChainStorageError};

Expand All @@ -32,7 +32,11 @@ impl TryFrom<HistoricalBlock> for grpc::HistoricalBlock {
fn try_from(hb: HistoricalBlock) -> Result<Self, Self::Error> {
Ok(Self {
confirmations: hb.confirmations,
block: Some(hb.try_into_block()?.into()),
block: Some(
hb.try_into_block()?
.try_into()
.map_err(ChainStorageError::ConversionError)?,
),
})
}
}
14 changes: 8 additions & 6 deletions applications/tari_app_grpc/src/conversions/new_block_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ use tari_utilities::ByteArray;

use crate::tari_rpc as grpc;

impl From<NewBlockTemplate> for grpc::NewBlockTemplate {
fn from(block: NewBlockTemplate) -> Self {
impl TryFrom<NewBlockTemplate> for grpc::NewBlockTemplate {
type Error = String;

fn try_from(block: NewBlockTemplate) -> Result<Self, Self::Error> {
let header = grpc::NewBlockHeaderTemplate {
version: block.header.version as u32,
height: block.header.height,
Expand All @@ -44,14 +46,14 @@ impl From<NewBlockTemplate> for grpc::NewBlockTemplate {
pow_data: block.header.pow.pow_data,
}),
};
Self {
Ok(Self {
body: Some(grpc::AggregateBody {
inputs: block
.body
.inputs()
.iter()
.map(|input| grpc::TransactionInput::from(input.clone()))
.collect(),
.map(|input| grpc::TransactionInput::try_from(input.clone()))
.collect::<Result<Vec<grpc::TransactionInput>, _>>()?,
outputs: block
.body
.outputs()
Expand All @@ -66,7 +68,7 @@ impl From<NewBlockTemplate> for grpc::NewBlockTemplate {
.collect(),
}),
header: Some(header),
}
})
}
}
impl TryFrom<grpc::NewBlockTemplate> for NewBlockTemplate {
Expand Down
12 changes: 7 additions & 5 deletions applications/tari_app_grpc/src/conversions/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ use tari_utilities::ByteArray;

use crate::tari_rpc as grpc;

impl From<Transaction> for grpc::Transaction {
fn from(source: Transaction) -> Self {
Self {
impl TryFrom<Transaction> for grpc::Transaction {
type Error = String;

fn try_from(source: Transaction) -> Result<Self, Self::Error> {
Ok(Self {
offset: Vec::from(source.offset.as_bytes()),
body: Some(source.body.into()),
body: Some(source.body.try_into()?),
script_offset: Vec::from(source.script_offset.as_bytes()),
}
})
}
}

Expand Down
116 changes: 80 additions & 36 deletions applications/tari_app_grpc/src/conversions/transaction_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use tari_common_types::types::{Commitment, PublicKey};
use tari_core::transactions::transaction::TransactionInput;
use tari_crypto::{
script::{ExecutionStack, TariScript},
tari_utilities::{ByteArray, Hashable},
tari_utilities::ByteArray,
};

use crate::tari_rpc as grpc;
Expand All @@ -35,51 +35,95 @@ impl TryFrom<grpc::TransactionInput> for TransactionInput {
type Error = String;

fn try_from(input: grpc::TransactionInput) -> Result<Self, Self::Error> {
let features = input
.features
.map(TryInto::try_into)
.ok_or_else(|| "transaction output features not provided".to_string())??;

let commitment = Commitment::from_bytes(&input.commitment)
.map_err(|err| format!("Could not convert input commitment:{}", err))?;

let script_signature = input
.script_signature
.ok_or_else(|| "script_signature not provided".to_string())?
.try_into()
.map_err(|_| "script_signature could not be converted".to_string())?;

let sender_offset_public_key =
PublicKey::from_bytes(input.sender_offset_public_key.as_bytes()).map_err(|err| format!("{:?}", err))?;
let script = TariScript::from_bytes(input.script.as_slice()).map_err(|err| format!("{:?}", err))?;
let input_data = ExecutionStack::from_bytes(input.input_data.as_slice()).map_err(|err| format!("{:?}", err))?;
// Check if the received Transaction input is in compact form or not
if !input.commitment.is_empty() {
let commitment = Commitment::from_bytes(&input.commitment).map_err(|e| e.to_string())?;
let features = input
.features
.map(TryInto::try_into)
.ok_or_else(|| "transaction output features not provided".to_string())??;

Ok(Self {
features,
commitment,
script,
input_data,
script_signature,
sender_offset_public_key,
})
let sender_offset_public_key =
PublicKey::from_bytes(input.sender_offset_public_key.as_bytes()).map_err(|err| format!("{:?}", err))?;

Ok(TransactionInput::new_with_output_data(
features,
commitment,
TariScript::from_bytes(input.script.as_slice()).map_err(|err| format!("{:?}", err))?,
ExecutionStack::from_bytes(input.input_data.as_slice()).map_err(|err| format!("{:?}", err))?,
script_signature,
sender_offset_public_key,
))
} else {
if input.output_hash.is_empty() {
return Err("Compact Transaction Input does not contain `output_hash`".to_string());
}
Ok(TransactionInput::new_with_output_hash(
input.output_hash,
ExecutionStack::from_bytes(input.input_data.as_slice()).map_err(|err| format!("{:?}", err))?,
script_signature,
))
}
}
}

impl From<TransactionInput> for grpc::TransactionInput {
fn from(input: TransactionInput) -> Self {
let hash = input.hash();
Self {
features: Some(input.features.into()),
commitment: Vec::from(input.commitment.as_bytes()),
hash,
script: input.script.as_bytes(),
input_data: input.input_data.as_bytes(),
script_signature: Some(grpc::ComSignature {
public_nonce_commitment: Vec::from(input.script_signature.public_nonce().as_bytes()),
signature_u: Vec::from(input.script_signature.u().as_bytes()),
signature_v: Vec::from(input.script_signature.v().as_bytes()),
}),
sender_offset_public_key: input.sender_offset_public_key.as_bytes().to_vec(),
impl TryFrom<TransactionInput> for grpc::TransactionInput {
type Error = String;

fn try_from(input: TransactionInput) -> Result<Self, Self::Error> {
let script_signature = Some(grpc::ComSignature {
public_nonce_commitment: Vec::from(input.script_signature.public_nonce().as_bytes()),
signature_u: Vec::from(input.script_signature.u().as_bytes()),
signature_v: Vec::from(input.script_signature.v().as_bytes()),
});
if input.is_compact() {
let output_hash = input.output_hash();
Ok(Self {
features: None,
commitment: Vec::new(),
hash: Vec::new(),
script: Vec::new(),
input_data: Vec::new(),
script_signature,
sender_offset_public_key: Vec::new(),
output_hash,
})
} else {
let features = input
.features()
.map_err(|_| "Non-compact Transaction input should contain features".to_string())?;

Ok(Self {
features: Some(features.clone().into()),
commitment: input
.commitment()
.map_err(|_| "Non-compact Transaction input should contain commitment".to_string())?
.clone()
.as_bytes()
.to_vec(),
hash: input
.canonical_hash()
.map_err(|_| "Non-compact Transaction input should be able to be hashed".to_string())?,

script: input
.script()
.map_err(|_| "Non-compact Transaction input should contain script".to_string())?
.as_bytes(),
input_data: input.input_data.as_bytes(),
script_signature,
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(),
})
}
}
}
23 changes: 20 additions & 3 deletions applications/tari_base_node/src/grpc/base_node_grpc_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,26 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer {
Ok(data) => data,
};
for transaction in transactions.unconfirmed_pool {
let transaction = match tari_rpc::Transaction::try_from(transaction) {
Ok(t) => t,
Err(e) => {
warn!(
target: LOG_TARGET,
"Error sending converting transaction for GRPC: {}", e
);
match tx.send(Err(Status::internal("Error converting transaction"))).await {
Ok(_) => (),
Err(send_err) => {
warn!(target: LOG_TARGET, "Error sending error to GRPC client: {}", send_err)
},
}
return;
},
};

match tx
.send(Ok(tari_rpc::GetMempoolTransactionsResponse {
transaction: Some(transaction.into()),
transaction: Some(transaction),
}))
.await
{
Expand Down Expand Up @@ -638,7 +655,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer {
total_fees: new_template.total_fees.into(),
algo: Some(tari_rpc::PowAlgo { pow_algo: pow }),
}),
new_block_template: Some(new_template.into()),
new_block_template: Some(new_template.try_into().map_err(Status::internal)?),

initial_sync_achieved: (*status_watch.borrow()).bootstrapped,
};
Expand Down Expand Up @@ -677,7 +694,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer {
// construct response
let block_hash = new_block.hash();
let mining_hash = new_block.header.merged_mining_hash();
let block: Option<tari_rpc::Block> = Some(new_block.into());
let block: Option<tari_rpc::Block> = Some(new_block.try_into().map_err(Status::internal)?);

let response = tari_rpc::GetNewBlockResult {
block_hash,
Expand Down
6 changes: 5 additions & 1 deletion applications/tari_console_wallet/src/automation/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ use tari_crypto::{
};
use tari_utilities::hex::Hex;
use tari_wallet::{
error::WalletError,
output_manager_service::handle::OutputManagerHandle,
transaction_service::handle::{TransactionEvent, TransactionServiceHandle},
WalletSqlite,
Expand Down Expand Up @@ -941,7 +942,10 @@ fn write_utxos_to_csv_file(utxos: Vec<UnblindedOutput>, file_path: String) -> Re
i + 1,
utxo.value.0,
utxo.spending_key.to_hex(),
utxo.as_transaction_input(&factory)?.commitment.to_hex(),
utxo.as_transaction_input(&factory)?
.commitment()
.map_err(|e| CommandError::WalletError(WalletError::TransactionError(e)))?
.to_hex(),
utxo.features.flags,
utxo.features.maturity,
utxo.script.to_hex(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ impl wallet_server::Wallet for WalletGrpcServer {

match response {
Ok(resp) => Ok(Response::new(GetCoinbaseResponse {
transaction: Some(resp.into()),
transaction: Some(resp.try_into().map_err(Status::internal)?),
})),
Err(err) => Err(Status::unknown(err.to_string())),
}
Expand Down
6 changes: 4 additions & 2 deletions applications/tari_console_wallet/src/ui/state/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -969,8 +969,10 @@ pub struct CompletedTransactionInfo {
fn first_unique_id(tx: &CompletedTransaction) -> String {
let body = tx.transaction.body();
for input in body.inputs() {
if let Some(ref unique_id) = input.features.unique_id {
return unique_id.to_hex();
if let Ok(features) = input.features() {
if let Some(ref unique_id) = features.unique_id {
return unique_id.to_hex();
}
}
}
for output in body.outputs() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::convert::TryFrom;
use std::convert::{TryFrom, TryInto};

use tari_app_grpc::tari_rpc as grpc;
use tari_core::{
Expand All @@ -42,5 +42,5 @@ pub fn add_coinbase(
.map_err(MmProxyError::MissingDataError)?;
block_template.body.add_output(output);
block_template.body.add_kernel(kernel);
Ok(block_template.into())
block_template.try_into().map_err(MmProxyError::ConversionError)
}
2 changes: 2 additions & 0 deletions applications/tari_merge_mining_proxy/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ pub enum MmProxyError {
InvalidHeaderValue(#[from] InvalidHeaderValue),
#[error("Block was lost due to a failed precondition, and should be retried")]
FailedPreconditionBlockLostRetry,
#[error("Could not convert data:{0}")]
ConversionError(String),
#[error("No reachable servers in configuration")]
ServersUnavailable,
}
Expand Down
Loading