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

[gateway api] Replace TransactionSigner with two steps call #897

Merged
merged 4 commits into from
Mar 23, 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
80 changes: 49 additions & 31 deletions sui/src/rest_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ use sui::gateway::{EmbeddedGatewayConfig, GatewayType};
use sui::keystore::Keystore;
use sui::sui_commands;
use sui::sui_json::{resolve_move_function_args, SuiJsonValue};
use sui::wallet_commands::SimpleTransactionSigner;
use sui_core::gateway_state::GatewayClient;
use sui_types::base_types::*;
use sui_types::committee::Committee;
use sui_types::event::Event;
use sui_types::messages::{ExecutionStatus, TransactionEffects};
use sui_types::messages::{ExecutionStatus, Transaction, TransactionEffects};
use sui_types::move_package::resolve_and_type_check;
use sui_types::object::Object as SuiObject;
use sui_types::object::ObjectRead;
Expand Down Expand Up @@ -751,15 +750,25 @@ async fn transfer_object(
)
})?;

let tx_signer = Box::pin(SimpleTransactionSigner {
keystore: state.keystore.clone(),
});
let response: Result<_, anyhow::Error> = async {
let data = state
.gateway
.transfer_coin(owner, object_id, gas_object_id, to_address)
.await?;
let signature = state
.keystore
.read()
.unwrap()
.sign(&owner, &data.to_bytes())?;
Ok(state
.gateway
.execute_transaction(Transaction::new(data, signature))
.await?
.to_effect_response()?)
}
.await;

let (cert, effects, gas_used) = match state
.gateway
.transfer_coin(owner, object_id, gas_object_id, to_address, tx_signer)
.await
{
let (cert, effects, gas_used) = match response {
Ok((cert, effects)) => {
let gas_used = match effects.status {
// TODO: handle the actual return value stored in
Expand Down Expand Up @@ -1143,28 +1152,37 @@ async fn handle_move_call(
object_args_refs.push(object_ref);
}

let tx_signer = Box::pin(SimpleTransactionSigner {
keystore: state.keystore.clone(),
});
let response: Result<_, anyhow::Error> = async {
let data = state
.gateway
.move_call(
sender,
package_object_ref,
module.to_owned(),
function.to_owned(),
type_args.clone(),
gas_obj_ref,
object_args_refs,
// TODO: Populate shared object args. sui/issue#719
vec![],
pure_args,
gas_budget,
)
.await?;
let signature = state
.keystore
.read()
.unwrap()
.sign(&sender, &data.to_bytes())?;
Ok(state
.gateway
.execute_transaction(Transaction::new(data, signature))
.await?
.to_effect_response()?)
}
.await;

let (cert, effects, gas_used) = match state
.gateway
.move_call(
sender,
package_object_ref,
module.to_owned(),
function.to_owned(),
type_args.clone(),
gas_obj_ref,
object_args_refs,
// TODO: Populate shared object args. sui/issue#719
vec![],
pure_args,
gas_budget,
tx_signer,
)
.await
{
let (cert, effects, gas_used) = match response {
Ok((cert, effects)) => {
let gas_used = match effects.status {
// TODO: handle the actual return value stored in
Expand Down
120 changes: 64 additions & 56 deletions sui/src/wallet_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ use std::sync::{Arc, RwLock};
use std::time::Instant;

use anyhow::anyhow;
use async_trait::async_trait;
use colored::Colorize;
use ed25519_dalek::ed25519::signature;
use move_core_types::identifier::Identifier;
use move_core_types::language_storage::TypeTag;
use move_core_types::parser::parse_type_tag;
Expand All @@ -22,14 +20,11 @@ use tracing::info;
use sui_core::gateway_state::gateway_responses::{
MergeCoinResponse, PublishResponse, SplitCoinResponse,
};
use sui_core::gateway_state::{AsyncTransactionSigner, GatewayClient};
use sui_core::gateway_state::GatewayClient;
use sui_framework::build_move_package_to_bytes;
use sui_types::base_types::{decode_bytes_hex, ObjectID, ObjectRef, SuiAddress};
use sui_types::crypto::{Signable, Signature};
use sui_types::gas_coin::GasCoin;
use sui_types::messages::{
CertifiedTransaction, ExecutionStatus, TransactionData, TransactionEffects,
};
use sui_types::messages::{CertifiedTransaction, ExecutionStatus, Transaction, TransactionEffects};
use sui_types::move_package::resolve_and_type_check;
use sui_types::object::ObjectRead;
use sui_types::object::ObjectRead::Exists;
Expand Down Expand Up @@ -187,30 +182,11 @@ pub struct SimpleTransactionSigner {
pub keystore: Arc<RwLock<Box<dyn Keystore>>>,
}

// A simple signer callback implementation, which signs the content without validation.
#[async_trait]
impl AsyncTransactionSigner for SimpleTransactionSigner {
async fn sign(
&self,
address: &SuiAddress,
data: TransactionData,
) -> Result<Signature, signature::Error> {
let keystore = self.keystore.read().unwrap();
let mut msg = Vec::new();
data.write(&mut msg);
keystore.sign(address, &msg)
}
}

impl WalletCommands {
pub async fn execute(
&mut self,
context: &mut WalletContext,
) -> Result<WalletCommandResult, anyhow::Error> {
let tx_signer = Box::pin(SimpleTransactionSigner {
keystore: context.keystore.clone(),
});

Ok(match self {
WalletCommands::Publish {
path,
Expand All @@ -223,16 +199,20 @@ impl WalletCommands {
let gas_obj_ref = gas_object.compute_object_reference();

let compiled_modules = build_move_package_to_bytes(Path::new(path))?;
let response = context
let data = context
.gateway
.publish(
sender,
compiled_modules,
gas_obj_ref,
*gas_budget,
tx_signer,
)
.publish(sender, compiled_modules, gas_obj_ref, *gas_budget)
.await?;
let signature = context
.keystore
.read()
.unwrap()
.sign(&sender, &data.to_bytes())?;
let response = context
.gateway
.execute_transaction(Transaction::new(data, signature))
.await?
.to_publish_response()?;

WalletCommandResult::Publish(response)
}
Expand Down Expand Up @@ -306,7 +286,7 @@ impl WalletCommands {
object_args_refs.push(obj_info.object()?.compute_object_reference());
}

let (cert, effects) = context
let data = context
.gateway
.move_call(
sender,
Expand All @@ -319,9 +299,19 @@ impl WalletCommands {
vec![],
pure_args,
*gas_budget,
tx_signer,
)
.await?;
let signature = context
.keystore
.read()
.unwrap()
.sign(&sender, &data.to_bytes())?;
let (cert, effects) = context
.gateway
.execute_transaction(Transaction::new(data, signature))
.await?
.to_effect_response()?;

if matches!(effects.status, ExecutionStatus::Failure { .. }) {
return Err(anyhow!("Error calling module: {:#?}", effects.status));
}
Expand All @@ -335,10 +325,21 @@ impl WalletCommands {

let time_start = Instant::now();

let (cert, effects) = context
let data = context
.gateway
.transfer_coin(from, *object_id, *gas, *to, tx_signer)
.transfer_coin(from, *object_id, *gas, *to)
.await?;
let signature = context
.keystore
.read()
.unwrap()
.sign(&from, &data.to_bytes())?;
let (cert, effects) = context
.gateway
.execute_transaction(Transaction::new(data, signature))
.await?
.to_effect_response()?;

let time_total = time_start.elapsed().as_micros();

if matches!(effects.status, ExecutionStatus::Failure { .. }) {
Expand Down Expand Up @@ -395,17 +396,20 @@ impl WalletCommands {
let gas_object = gas_object_info.object()?;
let signer = gas_object.owner.get_owner_address()?;

let response = context
let data = context
.gateway
.split_coin(
signer,
*coin_id,
amounts.clone(),
*gas,
*gas_budget,
tx_signer,
)
.split_coin(signer, *coin_id, amounts.clone(), *gas, *gas_budget)
.await?;
let signature = context
.keystore
.read()
.unwrap()
.sign(&signer, &data.to_bytes())?;
let response = context
.gateway
.execute_transaction(Transaction::new(data, signature))
.await?
.to_split_coin_response()?;
WalletCommandResult::SplitCoin(response)
}
WalletCommands::MergeCoin {
Expand All @@ -417,17 +421,21 @@ impl WalletCommands {
let gas_object_info = context.gateway.get_object_info(*gas).await?;
let gas_object = gas_object_info.object()?;
let signer = gas_object.owner.get_owner_address()?;
let response = context
let data = context
.gateway
.merge_coins(
signer,
*primary_coin,
*coin_to_merge,
*gas,
*gas_budget,
tx_signer,
)
.merge_coins(signer, *primary_coin, *coin_to_merge, *gas, *gas_budget)
.await?;
let signature = context
.keystore
.read()
.unwrap()
.sign(&signer, &data.to_bytes())?;
let response = context
.gateway
.execute_transaction(Transaction::new(data, signature))
.await?
.to_merge_coin_response()?;

WalletCommandResult::MergeCoin(response)
}
})
Expand Down
Loading