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: contract acceptance publication #4151

Merged
merged 17 commits into from
Jun 7, 2022
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
10 changes: 10 additions & 0 deletions applications/tari_app_grpc/proto/validator_node.proto
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ service ValidatorNode {
rpc InvokeReadMethod(InvokeReadMethodRequest) returns (InvokeReadMethodResponse);
rpc InvokeMethod(InvokeMethodRequest) returns (InvokeMethodResponse);
rpc GetCommitteeRequests(GetCommitteeRequestsRequest) returns (stream TransactionOutput);
rpc PublishContractAcceptance(PublishContractAcceptanceRequest) returns (PublishContractAcceptanceResponse);
}

message GetCommitteeRequestsRequest {
Expand All @@ -42,6 +43,15 @@ message GetMetadataRequest {
// empty
}

message PublishContractAcceptanceRequest {
bytes contract_id = 1;
}

message PublishContractAcceptanceResponse {
string status = 1;
uint64 tx_id = 2;
}

message GetMetadataResponse {
repeated SidechainMetadata sidechains = 1;
}
Expand Down
12 changes: 12 additions & 0 deletions applications/tari_app_grpc/proto/wallet.proto
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ service Wallet {
rpc GetOwnedTokens(GetOwnedTokensRequest) returns (GetOwnedTokensResponse);

rpc SetBaseNode(SetBaseNodeRequest) returns (SetBaseNodeResponse);

rpc SubmitContractAcceptance(SubmitContractAcceptanceRequest) returns (SubmitContractAcceptanceResponse);
}

message GetVersionRequest { }
Expand Down Expand Up @@ -297,6 +299,16 @@ message CreateCommitteeDefinitionResponse {

}

message SubmitContractAcceptanceRequest {
bytes contract_id = 1;
bytes validator_node_public_key = 2;
Signature signature = 3;
}

message SubmitContractAcceptanceResponse {
uint64 tx_id = 1;
}

message GetOwnedAssetsResponse {
repeated Asset assets = 1;
}
Expand Down
43 changes: 42 additions & 1 deletion applications/tari_console_wallet/src/grpc/wallet_grpc_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ use tari_app_grpc::{
SendShaAtomicSwapResponse,
SetBaseNodeRequest,
SetBaseNodeResponse,
SubmitContractAcceptanceRequest,
SubmitContractAcceptanceResponse,
TransactionDirection,
TransactionInfo,
TransactionStatus,
Expand All @@ -80,7 +82,7 @@ use tari_app_grpc::{
};
use tari_common_types::{
array::copy_into_fixed_array,
types::{BlockHash, PublicKey, Signature},
types::{BlockHash, FixedHash, PublicKey, Signature},
};
use tari_comms::{multiaddr::Multiaddr, types::CommsPublicKey, CommsNode};
use tari_core::transactions::{
Expand Down Expand Up @@ -656,6 +658,45 @@ impl wallet_server::Wallet for WalletGrpcServer {
Ok(Response::new(ImportUtxosResponse { tx_ids }))
}

async fn submit_contract_acceptance(
&self,
request: Request<SubmitContractAcceptanceRequest>,
) -> Result<Response<SubmitContractAcceptanceResponse>, Status> {
let mut asset_manager = self.wallet.asset_manager.clone();
let mut transaction_service = self.wallet.transaction_service.clone();
let message = request.into_inner();

let contract_id = FixedHash::try_from(message.contract_id)
.map_err(|err| Status::invalid_argument(format!("Invalid contract_id:{:?}", err)))?;

let validator_node_public_key =
PublicKey::from_bytes(message.validator_node_public_key.as_slice()).map_err(|e| {
Status::invalid_argument(format!("Validator node public key was not a valid pub key:{}", e))
})?;

let signature = message
.signature
.ok_or_else(|| Status::invalid_argument("signature not provided"))?;
let signature =
Signature::try_from(signature).map_err(|e| Status::invalid_argument(format!("Invalid signature:{}", e)))?;

let (tx_id, transaction) = asset_manager
.create_contract_acceptance(&contract_id, &validator_node_public_key, &signature)
.await
.map_err(|e| Status::internal(e.to_string()))?;

let contract_id_hex = contract_id.to_vec().to_hex();
let message = format!("Contract acceptance for contract with id={}", contract_id_hex);
transaction_service
.submit_transaction(tx_id, transaction, 0.into(), message)
.await
.map_err(|e| Status::internal(e.to_string()))?;

Ok(Response::new(SubmitContractAcceptanceResponse {
tx_id: tx_id.as_u64(),
}))
}

async fn register_asset(
&self,
request: Request<RegisterAssetRequest>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
use std::net::SocketAddr;

use async_trait::async_trait;
use tari_app_grpc::{tari_rpc as grpc, tari_rpc::CreateFollowOnAssetCheckpointRequest};
use tari_common_types::types::PublicKey;
use tari_app_grpc::{
tari_rpc as grpc,
tari_rpc::{CreateFollowOnAssetCheckpointRequest, SubmitContractAcceptanceRequest},
};
use tari_common_types::types::{FixedHash, PublicKey, Signature};
use tari_comms::types::CommsPublicKey;
use tari_crypto::tari_utilities::ByteArray;
use tari_dan_core::{models::StateRoot, services::WalletClient, DigitalAssetError};
Expand Down Expand Up @@ -79,4 +82,26 @@ impl WalletClient for GrpcWalletClient {

Ok(())
}

async fn submit_contract_acceptance(
&mut self,
contract_id: &FixedHash,
validator_node_public_key: &PublicKey,
signature: &Signature,
) -> Result<u64, DigitalAssetError> {
let inner = self.connection().await?;

let request = SubmitContractAcceptanceRequest {
contract_id: contract_id.as_bytes().to_vec(),
validator_node_public_key: validator_node_public_key.as_bytes().to_vec(),
signature: Some((*signature).clone().into()),
};

let res = inner
.submit_contract_acceptance(request)
.await
.map_err(|e| DigitalAssetError::FatalError(format!("Could not submit contract acceptance: {}", e)))?;

Ok(res.into_inner().tx_id)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,19 @@
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// 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::TryInto, time::Duration};
use std::{
convert::{TryFrom, TryInto},
time::Duration,
};

use futures::channel::mpsc;
use tari_app_grpc::tari_rpc::{self as rpc, TransactionOutput};
use tari_common_types::types::PublicKey;
use tari_common_types::types::{FixedHash, PublicKey, Signature};
use tari_comms::NodeIdentity;
use tari_crypto::tari_utilities::ByteArray;
use tari_dan_core::{
models::Instruction,
services::{AssetProcessor, AssetProxy, ServiceSpecification},
services::{AssetProcessor, AssetProxy, ServiceSpecification, WalletClient},
storage::DbFactory,
};
use tokio::{task, time};
Expand All @@ -41,6 +44,7 @@ pub struct ValidatorNodeGrpcServer<TServiceSpecification: ServiceSpecification>
db_factory: TServiceSpecification::DbFactory,
asset_processor: TServiceSpecification::AssetProcessor,
asset_proxy: TServiceSpecification::AssetProxy,
wallet_client: TServiceSpecification::WalletClient,
}

impl<TServiceSpecification: ServiceSpecification> ValidatorNodeGrpcServer<TServiceSpecification> {
Expand All @@ -49,12 +53,14 @@ impl<TServiceSpecification: ServiceSpecification> ValidatorNodeGrpcServer<TServi
db_factory: TServiceSpecification::DbFactory,
asset_processor: TServiceSpecification::AssetProcessor,
asset_proxy: TServiceSpecification::AssetProxy,
wallet_client: TServiceSpecification::WalletClient,
) -> Self {
Self {
node_identity,
db_factory,
asset_processor,
asset_proxy,
wallet_client,
}
}
}
Expand All @@ -65,6 +71,31 @@ impl<TServiceSpecification: ServiceSpecification + 'static> rpc::validator_node_
{
type GetCommitteeRequestsStream = mpsc::Receiver<Result<TransactionOutput, tonic::Status>>;

async fn publish_contract_acceptance(
&self,
request: tonic::Request<rpc::PublishContractAcceptanceRequest>,
) -> Result<Response<rpc::PublishContractAcceptanceResponse>, tonic::Status> {
let mut wallet_client = self.wallet_client.clone();
let request = request.into_inner();
let contract_id = FixedHash::try_from(request.contract_id).unwrap_or_default();
let validator_node_public_key = self.node_identity.public_key();
let signature = Signature::default();

match wallet_client
.submit_contract_acceptance(&contract_id, validator_node_public_key, &signature)
.await
{
Ok(tx_id) => Ok(Response::new(rpc::PublishContractAcceptanceResponse {
tx_id,
status: "Accepted".to_string(),
})),
Err(_) => Ok(Response::new(rpc::PublishContractAcceptanceResponse {
status: "Errored".to_string(),
tx_id: 0_u64,
})),
}
}

async fn get_committee_requests(
&self,
_request: tonic::Request<rpc::GetCommitteeRequestsRequest>,
Expand Down
8 changes: 6 additions & 2 deletions applications/tari_validator_node/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ use crate::{
config::{ApplicationConfig, ValidatorNodeConfig},
dan_node::DanNode,
default_service_specification::DefaultServiceSpecification,
grpc::{services::base_node_client::GrpcBaseNodeClient, validator_node_grpc_server::ValidatorNodeGrpcServer},
grpc::{
services::{base_node_client::GrpcBaseNodeClient, wallet_client::GrpcWalletClient},
validator_node_grpc_server::ValidatorNodeGrpcServer,
},
p2p::services::rpc_client::TariCommsValidatorNodeClientFactory,
};

Expand Down Expand Up @@ -135,12 +138,13 @@ async fn run_node(config: &ApplicationConfig) -> Result<(), ExitError> {
mempool_service.clone(),
db_factory.clone(),
);

let wallet_client = GrpcWalletClient::new(config.validator_node.wallet_grpc_address);
let grpc_server: ValidatorNodeGrpcServer<DefaultServiceSpecification> = ValidatorNodeGrpcServer::new(
node_identity.as_ref().clone(),
db_factory.clone(),
asset_processor,
asset_proxy,
wallet_client,
);

if let Some(address) = config.validator_node.grpc_address.clone() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ use blake2::{
VarBlake2b,
};
use serde::{Deserialize, Serialize};
use tari_common_types::types::{Commitment, FixedHash, PublicKey};
use tari_common_types::types::{Commitment, FixedHash, PublicKey, Signature};
use tari_crypto::ristretto::pedersen::PedersenCommitment;
use tari_utilities::ByteArray;

use super::{ContractDefinition, OutputFeaturesVersion, SideChainFeaturesBuilder};
use super::{ContractAcceptance, ContractDefinition, OutputFeaturesVersion, SideChainFeaturesBuilder};
use crate::{
consensus::{ConsensusDecoding, ConsensusEncoding, ConsensusEncodingSized, MaxSizeBytes},
transactions::{
Expand Down Expand Up @@ -296,6 +296,25 @@ impl OutputFeatures {
}
}

pub fn for_contract_acceptance(
contract_id: FixedHash,
validator_node_public_key: PublicKey,
signature: Signature,
) -> OutputFeatures {
Self {
flags: OutputFlags::CONTRACT_ACCEPT,
sidechain_features: Some(
SideChainFeatures::builder(contract_id)
.with_contract_acceptance(ContractAcceptance {
validator_node_public_key,
signature,
})
.finish(),
),
..Default::default()
}
}

pub fn unique_asset_id(&self) -> Option<&[u8]> {
self.unique_id.as_deref()
}
Expand Down
24 changes: 23 additions & 1 deletion base_layer/wallet/src/assets/asset_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
use log::*;
use tari_common_types::{
transaction::TxId,
types::{Commitment, FixedHash, PublicKey, ASSET_CHECKPOINT_ID, COMMITTEE_DEFINITION_ID},
types::{Commitment, FixedHash, PublicKey, Signature, ASSET_CHECKPOINT_ID, COMMITTEE_DEFINITION_ID},
};
use tari_core::transactions::transaction_components::{
ContractDefinition,
Expand Down Expand Up @@ -294,6 +294,28 @@ impl<T: OutputManagerBackend + 'static> AssetManager<T> {

Ok((tx_id, transaction))
}

pub async fn create_contract_acceptance(
&mut self,
contract_id: FixedHash,
validator_node_public_key: PublicKey,
signature: Signature,
) -> Result<(TxId, Transaction), WalletError> {
let output = self
.output_manager
.create_output_with_features(
0.into(),
OutputFeatures::for_contract_acceptance(contract_id, validator_node_public_key, signature),
)
.await?;

let (tx_id, transaction) = self
.output_manager
.create_send_to_self_with_output(vec![output], ASSET_FPG.into(), None, None)
.await?;

Ok((tx_id, transaction))
}
}

fn convert_to_asset(unblinded_output: DbUnblindedOutput) -> Result<Asset, WalletError> {
Expand Down
25 changes: 24 additions & 1 deletion base_layer/wallet/src/assets/asset_manager_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

use tari_common_types::{
transaction::TxId,
types::{Commitment, FixedHash, PublicKey},
types::{Commitment, FixedHash, PublicKey, Signature},
};
use tari_core::transactions::transaction_components::{
ContractDefinition,
Expand Down Expand Up @@ -217,4 +217,27 @@ impl AssetManagerHandle {
}),
}
}

pub async fn create_contract_acceptance(
&mut self,
contract_id: &FixedHash,
validator_node_public_key: &PublicKey,
signature: &Signature,
) -> Result<(TxId, Transaction), WalletError> {
match self
.handle
.call(AssetManagerRequest::CreateContractAcceptance {
contract_id: *contract_id,
validator_node_public_key: Box::new(validator_node_public_key.clone()),
signature: Box::new(signature.clone()),
})
.await??
{
AssetManagerResponse::CreateContractAcceptance { transaction, tx_id } => Ok((tx_id, *transaction)),
_ => Err(WalletError::UnexpectedApiResponse {
method: "create_contract_acceptance".to_string(),
api: "AssetManagerService".to_string(),
}),
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,20 @@ impl<T: OutputManagerBackend + 'static> AssetManagerService<T> {
tx_id,
})
},
AssetManagerRequest::CreateContractAcceptance {
contract_id,
validator_node_public_key,
signature,
} => {
let (tx_id, transaction) = self
.manager
.create_contract_acceptance(contract_id, *validator_node_public_key, *signature)
.await?;
Ok(AssetManagerResponse::CreateContractAcceptance {
transaction: Box::new(transaction),
tx_id,
})
},
}
}
}
Loading