Skip to content

Commit

Permalink
[wallet + gateway] refactored wallet to use GatewayClient (MystenLabs…
Browse files Browse the repository at this point in the history
…#682)

* * Added `GatewayClient` type
* Refactored wallet to use `GatewayClient` instead of using `ClientAddressManager` directly
* Added GatewayType in config for preparation of different gateway types
* `ClientAddressManager` now creates client state implicitly

* * improve Gateway type display

* add docs

* fixup after rebase
  • Loading branch information
patrickkuo authored Mar 8, 2022
1 parent 9e74c61 commit 47e7bce
Show file tree
Hide file tree
Showing 14 changed files with 367 additions and 343 deletions.
64 changes: 39 additions & 25 deletions doc/src/wallet.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ can be used subsequently to start the network. `wallet.conf` and `wallet.key` ar
also created to be used by the Sui wallet to manage the
newly created accounts.

### View created accounts
### Wallet configuration
The genesis process creates a configuration file `wallet.conf`, and a keystore file `wallet.key` for the
Sui wallet. The config file contains information of the accounts and
the Sui network. The keystore file contains all the public-private key pair of the created accounts.
the Sui network gateway. The keystore file contains all the public-private key pair of the created accounts.
Sui wallet uses the network information in `wallet.conf` to communicate
with the Sui network authorities and create transactions using the key
pairs residing in the keystore file.
Expand All @@ -57,43 +57,57 @@ in the wallet configuration (with some values omitted):
```json
{
"accounts": [
{
"address": "a4c0a493ce9879ea06bac93461810cf947823bb3"
},
"48cf013a76d583c027720f7f9852deac7c84b923",
...
],
"authorities": [
{
"name": "d72e7bd8f435fa56af47c8d0a0b8738c48f446762d620863ac328605325692f7",
"host": "127.0.0.1",
"base_port": 10000
},
...
],
"send_timeout": {
"secs": 4,
"nanos": 0
},
"recv_timeout": {
"secs": 4,
"nanos": 0
},
"buffer_size": 65507,
"db_folder_path": "./client_db",
"keystore": {
"File": "./wallet.key"
},
"gateway": {
"embedded": {
"authorities": [
{
"name": "5f9701f4bd2cd7c2f1f23ac6d05515407879f0acf2611517ff188e59c5f61743",
"host": "127.0.0.1",
"base_port": 10000
},
...
],
"send_timeout": {
"secs": 4,
"nanos": 0
},
"recv_timeout": {
"secs": 4,
"nanos": 0
},
"buffer_size": 65507,
"db_folder_path": "./client_db"
}
}
}
```
The `accounts` variable contains the account's address the wallet manages.
The `authorities` variable contains Sui network authorities' name, host and port information.
It is used to establish connections to the Sui network.
`gateway` contains the information of the Sui network that the wallet will be connecting to,
currently only `Embedded` gateway type is supported.

The `authorities` variable is part of the embedded gateway configuration, it contains Sui network
authorities' name, host and port information. It is used to establish connections to the Sui network.

Note `send_timeout`, `recv_timeout` and `buffer_size` are the network
parameters and `db_folder_path` is the path to the account's client state
database. This database stores all the transaction data, certificates
and object data belonging to the account.

#### Sui Network Gateway
The Sui network gateway is an abstraction layer that acts as the entry point to the Sui network.
Different gateway implementation can be use by the application layer base on their use cases.

##### Embedded Gateway
As the name suggests, embedded gateway embeds the gateway logic into the application;
all data will be stored locally and the application will make direct
connection to the authorities.

#### Key management
The key pairs are stored in `wallet.key`. However, this is not secure
and shouldn't be used in a production environment. We have plans to
Expand Down
3 changes: 2 additions & 1 deletion network_utils/src/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ use tracing::*;
mod transport_tests;

/// Suggested buffer size
pub const DEFAULT_MAX_DATAGRAM_SIZE: &str = "65507";
pub const DEFAULT_MAX_DATAGRAM_SIZE: usize = 65507;
pub const DEFAULT_MAX_DATAGRAM_SIZE_STR: &str = "65507";

/// The handler required to create a service.
pub trait MessageHandler {
Expand Down
2 changes: 1 addition & 1 deletion sui/src/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ struct ClientServerBenchmark {
#[structopt(long, default_value = "4000000")]
recv_timeout_us: u64,
/// Maximum size of datagrams received and sent (bytes)
#[structopt(long, default_value = transport::DEFAULT_MAX_DATAGRAM_SIZE)]
#[structopt(long, default_value = transport::DEFAULT_MAX_DATAGRAM_SIZE_STR)]
buffer_size: usize,
/// Which execution path to track. TransactionsAndCerts or TransactionsOnly or CertsOnly
#[structopt(long, default_value = "TransactionsAndCerts")]
Expand Down
63 changes: 15 additions & 48 deletions sui/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Copyright (c) 2022, Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use crate::gateway::{EmbeddedGatewayConfig, GatewayType};
use crate::keystore::KeystoreType;
use anyhow::anyhow;
use once_cell::sync::Lazy;
Expand All @@ -10,19 +11,16 @@ use serde::{Deserialize, Serialize};
use serde_json::Value;
use serde_with::hex::Hex;
use serde_with::serde_as;
use std::collections::BTreeMap;
use std::fmt::Write;
use std::fmt::{Display, Formatter};
use std::fs::{self, File};
use std::io::BufReader;
use std::path::{Path, PathBuf};
use std::sync::Mutex;
use std::time::Duration;
use sui_core::authority_client::AuthorityClient;
use sui_framework::DEFAULT_FRAMEWORK_PATH;
use sui_network::network::{NetworkClient, PortAllocator};
use sui_network::network::PortAllocator;
use sui_network::transport;
use sui_types::base_types::*;
use sui_types::committee::Committee;
use sui_types::crypto::{get_key_pair, KeyPair};
use tracing::log::trace;

Expand Down Expand Up @@ -107,12 +105,8 @@ impl<'de> Deserialize<'de> for AuthorityPrivateInfo {
pub struct WalletConfig {
#[serde_as(as = "Vec<Hex>")]
pub accounts: Vec<SuiAddress>,
pub authorities: Vec<AuthorityInfo>,
pub send_timeout: Duration,
pub recv_timeout: Duration,
pub buffer_size: usize,
pub db_folder_path: PathBuf,
pub keystore: KeystoreType,
pub gateway: GatewayType,

#[serde(skip)]
config_path: PathBuf,
Expand All @@ -125,12 +119,11 @@ impl Config for WalletConfig {
.ok_or(anyhow!("Cannot determine parent directory."))?;
Ok(WalletConfig {
accounts: Vec::new(),
authorities: Vec::new(),
send_timeout: Duration::from_micros(4000000),
recv_timeout: Duration::from_micros(4000000),
buffer_size: transport::DEFAULT_MAX_DATAGRAM_SIZE.to_string().parse()?,
db_folder_path: working_dir.join("client_db"),
keystore: KeystoreType::File(working_dir.join("wallet.ks")),
gateway: GatewayType::Embedded(EmbeddedGatewayConfig {
db_folder_path: working_dir.join("client_db"),
..Default::default()
}),
config_path: path.to_path_buf(),
})
}
Expand All @@ -144,41 +137,15 @@ impl Config for WalletConfig {
}
}

impl WalletConfig {
pub fn make_committee(&self) -> Committee {
let voting_rights = self
.authorities
.iter()
.map(|authority| (authority.name, 1))
.collect();
Committee::new(voting_rights)
}

pub fn make_authority_clients(&self) -> BTreeMap<AuthorityName, AuthorityClient> {
let mut authority_clients = BTreeMap::new();
for authority in &self.authorities {
let client = AuthorityClient::new(NetworkClient::new(
authority.host.clone(),
authority.base_port,
self.buffer_size,
self.send_timeout,
self.recv_timeout,
));
authority_clients.insert(authority.name, client);
}
authority_clients
}
}

impl Display for WalletConfig {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Config path : {:?}\nClient state DB folder path : {:?}\nManaged addresses : {}",
self.config_path,
self.db_folder_path,
self.accounts.len()
)
let mut writer = String::new();

writeln!(writer, "Config path : {:?}", self.config_path)?;
writeln!(writer, "Managed addresses : {}", self.accounts.len())?;
writeln!(writer, "{}", self.gateway)?;

write!(f, "{}", writer)
}
}

Expand Down
125 changes: 125 additions & 0 deletions sui/src/gateway.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// Copyright (c) 2022, Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use std::collections::BTreeMap;
use std::fmt::Write;
use std::fmt::{Display, Formatter};
use std::path::PathBuf;
use std::time::Duration;

use serde::Deserialize;
use serde::Serialize;

use sui_core::authority_client::AuthorityClient;
use sui_core::client::{ClientAddressManager, GatewayClient};
use sui_network::network::NetworkClient;
use sui_network::transport;
use sui_types::base_types::AuthorityName;
use sui_types::committee::Committee;

use crate::config::AuthorityInfo;

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum GatewayType {
Embedded(EmbeddedGatewayConfig),
Rest(String),
}

impl Display for GatewayType {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut writer = String::new();

match self {
GatewayType::Embedded(config) => {
writeln!(writer, "Gateway Type : Embedded")?;
writeln!(
writer,
"Client state DB folder path : {:?}",
config.db_folder_path
)?;
let authorities = config
.authorities
.iter()
.map(|info| format!("{}:{}", info.host, info.base_port));
writeln!(
writer,
"Authorities : {:?}",
authorities.collect::<Vec<_>>()
)?;
}
GatewayType::Rest(url) => {
writeln!(writer, "Gateway Type : RestAPI")?;
writeln!(writer, "Gateway URL : {}", url)?;
}
}
write!(f, "{}", writer)
}
}

impl GatewayType {
pub fn init(&self) -> GatewayClient {
match self {
GatewayType::Embedded(config) => {
let path = config.db_folder_path.clone();
let committee = config.make_committee();
let authority_clients = config.make_authority_clients();
Box::new(ClientAddressManager::new(
path,
committee,
authority_clients,
))
}
_ => {
panic!("Unsupported gateway type")
}
}
}
}

#[derive(Serialize, Deserialize)]
pub struct EmbeddedGatewayConfig {
pub authorities: Vec<AuthorityInfo>,
pub send_timeout: Duration,
pub recv_timeout: Duration,
pub buffer_size: usize,
pub db_folder_path: PathBuf,
}

impl EmbeddedGatewayConfig {
pub fn make_committee(&self) -> Committee {
let voting_rights = self
.authorities
.iter()
.map(|authority| (authority.name, 1))
.collect();
Committee::new(voting_rights)
}

pub fn make_authority_clients(&self) -> BTreeMap<AuthorityName, AuthorityClient> {
let mut authority_clients = BTreeMap::new();
for authority in &self.authorities {
let client = AuthorityClient::new(NetworkClient::new(
authority.host.clone(),
authority.base_port,
self.buffer_size,
self.send_timeout,
self.recv_timeout,
));
authority_clients.insert(authority.name, client);
}
authority_clients
}
}

impl Default for EmbeddedGatewayConfig {
fn default() -> Self {
Self {
authorities: vec![],
send_timeout: Duration::from_micros(4000000),
recv_timeout: Duration::from_micros(4000000),
buffer_size: transport::DEFAULT_MAX_DATAGRAM_SIZE,
db_folder_path: Default::default(),
}
}
}
1 change: 1 addition & 0 deletions sui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
extern crate core;

pub mod config;
pub mod gateway;
pub mod keystore;
pub mod shell;
pub mod sui_commands;
Expand Down
Loading

0 comments on commit 47e7bce

Please sign in to comment.