Skip to content

Commit

Permalink
Merge pull request #596 from Phala-Network/instantiate-native
Browse files Browse the repository at this point in the history
Instantiate native contract
  • Loading branch information
kvinwang authored Jan 17, 2022
2 parents 776c06c + 4f446a9 commit 1c740ad
Show file tree
Hide file tree
Showing 57 changed files with 1,467 additions and 728 deletions.
585 changes: 408 additions & 177 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 0 additions & 4 deletions crates/phactory/src/contracts/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,6 @@ impl contracts::NativeContract for Assets {
type QReq = Request;
type QResp = Response;

fn id(&self) -> contracts::ContractId {
contracts::id256(contracts::ASSETS)
}

fn handle_command(
&mut self,
origin: MessageOrigin,
Expand Down
4 changes: 0 additions & 4 deletions crates/phactory/src/contracts/balances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ impl contracts::NativeContract for Balances {
type QReq = Request;
type QResp = Response;

fn id(&self) -> contracts::ContractId {
contracts::id256(contracts::BALANCES)
}

fn handle_command(
&mut self,
origin: MessageOrigin,
Expand Down
5 changes: 0 additions & 5 deletions crates/phactory/src/contracts/btc_lottery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,6 @@ impl contracts::NativeContract for BtcLottery {
type QReq = Request;
type QResp = Response;

// Returns the contract id
fn id(&self) -> contracts::ContractId {
contracts::id256(contracts::BTC_LOTTERY)
}

fn handle_command(
&mut self,
origin: MessageOrigin,
Expand Down
5 changes: 0 additions & 5 deletions crates/phactory/src/contracts/btc_price_bot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,6 @@ impl contracts::NativeContract for BtcPriceBot {
type QReq = Request;
type QResp = Result<Response, Error>;

/// Return the contract id which uniquely identifies the contract
fn id(&self) -> contracts::ContractId {
contracts::id256(contracts::BTC_PRICE_BOT)
}

/// Handle the Commands from transactions on the blockchain. This method doesn't respond.
fn handle_command(
&mut self,
Expand Down
4 changes: 0 additions & 4 deletions crates/phactory/src/contracts/data_plaza.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,6 @@ impl contracts::NativeContract for DataPlaza {
type QReq = Request;
type QResp = Response;

fn id(&self) -> contracts::ContractId {
contracts::id256(contracts::DATA_PLAZA)
}

fn handle_command(
&mut self,
origin: MessageOrigin,
Expand Down
4 changes: 0 additions & 4 deletions crates/phactory/src/contracts/diem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,10 +514,6 @@ impl contracts::NativeContract for Diem {
type QReq = Request;
type QResp = Response;

fn id(&self) -> contracts::ContractId {
contracts::id256(contracts::DIEM)
}

fn handle_command(
&mut self,
_context: &NativeContext,
Expand Down
4 changes: 0 additions & 4 deletions crates/phactory/src/contracts/geolocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,6 @@ impl contracts::NativeContract for Geolocation {
type QReq = Request;
type QResp = Result<Response, Error>;

fn id(&self) -> contracts::ContractId {
contracts::id256(contracts::GEOLOCATION)
}

fn handle_command(
&mut self,
origin: MessageOrigin,
Expand Down
5 changes: 0 additions & 5 deletions crates/phactory/src/contracts/guess_number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,6 @@ impl contracts::NativeContract for GuessNumber {
type QReq = Request;
type QResp = Result<Response, Error>;

/// Return the contract id which uniquely identifies the contract
fn id(&self) -> contracts::ContractId {
contracts::id256(contracts::GUESS_NUMBER)
}

/// Handle the Commands from transactions on the blockchain. This method doesn't respond.
///
/// # Arguments
Expand Down
110 changes: 71 additions & 39 deletions crates/phactory/src/contracts/pink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ use crate::contracts;
use crate::system::{TransactionError, TransactionResult};
use anyhow::{anyhow, Result};
use parity_scale_codec::{Decode, Encode};
use phala_mq::{ContractClusterId, ContractId, MessageOrigin};
use phala_mq::{ContractClusterId, MessageOrigin};
use pink::runtime::ExecSideEffects;
use runtime::{AccountId, BlockNumber};

use super::NativeContractMore;

#[derive(Debug, Encode, Decode)]
pub enum Command {
InkMessage { nonce: Vec<u8>, message: Vec<u8> },
Expand Down Expand Up @@ -54,15 +56,24 @@ impl Pink {
now,
)
.map_err(|err| anyhow!("Instantiate contract failed: {:?} origin={:?}", err, origin,))?;
Ok((Self { cluster_id, instance }, effects))
Ok((
Self {
cluster_id,
instance,
},
effects,
))
}

pub fn from_address(address: AccountId, cluster_id: ContractClusterId) -> Self {
let instance = pink::Contract::from_address(address);
Self { instance, cluster_id }
Self {
instance,
cluster_id,
}
}

pub fn address_to_id(address: &AccountId) -> ContractId {
pub fn address_to_id(address: &AccountId) -> contracts::ContractId {
let inner: &[u8; 32] = address.as_ref();
inner.into()
}
Expand All @@ -75,14 +86,6 @@ impl contracts::NativeContract for Pink {

type QResp = Result<Response, QueryError>;

fn id(&self) -> ContractId {
Pink::address_to_id(&self.instance.address)
}

fn cluster_id(&self) -> Option<phala_mq::ContractClusterId> {
Some(self.cluster_id.clone())
}

fn handle_query(
&mut self,
origin: Option<&AccountId>,
Expand Down Expand Up @@ -127,22 +130,19 @@ impl contracts::NativeContract for Pink {
let storage = cluster_storage(&mut context.contract_clusters, &self.cluster_id)
.expect("Pink cluster should always exists!");

let (result, effects) = self
.instance
.bare_call(
storage,
origin.clone(),
message,
false,
context.block.block_number,
context.block.now_ms,
);

let ret = pink::transpose_contract_result(&result)
.map_err(|err| {
log::error!("Pink [{:?}] command exec error: {:?}", self.id(), err);
TransactionError::Other(format!("Call contract method failed: {:?}", err))
})?;
let (result, effects) = self.instance.bare_call(
storage,
origin.clone(),
message,
false,
context.block.block_number,
context.block.now_ms,
);

let ret = pink::transpose_contract_result(&result).map_err(|err| {
log::error!("Pink [{:?}] command exec error: {:?}", self.id(), err);
TransactionError::Other(format!("Call contract method failed: {:?}", err))
})?;

// TODO.kevin: store the output to some where.
let _ = ret;
Expand All @@ -163,6 +163,12 @@ impl contracts::NativeContract for Pink {
})?;
Ok(effects)
}
}

impl NativeContractMore for Pink {
fn id(&self) -> phala_mq::ContractId {
Pink::address_to_id(&self.instance.address)
}

fn set_on_block_end_selector(&mut self, selector: u32) {
self.instance.set_on_block_end_selector(selector)
Expand All @@ -184,10 +190,14 @@ pub mod cluster {
use anyhow::Result;
use phala_mq::{ContractClusterId, ContractId};
use phala_serde_more as more;
use pink::{runtime::ExecSideEffects, types::AccountId};
use pink::{
runtime::ExecSideEffects,
types::{AccountId, Hash},
};
use runtime::BlockNumber;
use serde::{Deserialize, Serialize};
use sp_core::sr25519;
use sp_runtime::DispatchError;
use std::collections::{BTreeMap, BTreeSet};

#[derive(Default, Serialize, Deserialize)]
Expand All @@ -207,14 +217,7 @@ pub mod cluster {
block_number: BlockNumber,
now: u64,
) -> Result<ExecSideEffects> {
let cluster = self
.clusters
.entry(cluster_id.clone())
.or_insert_with(|| Cluster {
storage: Default::default(),
contracts: Default::default(),
key: contract_key.clone(),
});
let cluster = self.get_cluster_or_default_mut(&cluster_id, contract_key);
let (_, effects) = Pink::instantiate(
cluster_id,
&mut cluster.storage,
Expand All @@ -239,6 +242,22 @@ pub mod cluster {
self.clusters.get_mut(cluster_id)
}

pub fn get_cluster_or_default_mut(
&mut self,
cluster_id: &ContractClusterId,
contract_key: &sr25519::Pair,
) -> &mut Cluster {
self.clusters.entry(cluster_id.clone()).or_insert_with(|| {
let mut cluster = Cluster {
storage: Default::default(),
contracts: Default::default(),
key: contract_key.clone(),
};
cluster.set_id(cluster_id);
cluster
})
}

pub fn commit_changes(&mut self) -> anyhow::Result<()> {
for cluster in self.clusters.values_mut() {
cluster.commit_changes()?;
Expand All @@ -256,8 +275,9 @@ pub mod cluster {
}

impl Cluster {
pub fn add_contract(&mut self, address: ContractId) {
self.contracts.insert(address);
/// Add a new contract to the cluster. Returns true if the contract is new.
pub fn add_contract(&mut self, address: ContractId) -> bool {
self.contracts.insert(address)
}

pub fn key(&self) -> &sr25519::Pair {
Expand All @@ -268,5 +288,17 @@ pub mod cluster {
self.storage.commit_changes();
Ok(())
}

pub fn set_id(&mut self, id: &ContractClusterId) {
self.storage.set_cluster_id(id.as_bytes());
}

pub fn upload_code(
&mut self,
origin: AccountId,
code: Vec<u8>,
) -> Result<Hash, DispatchError> {
self.storage.upload_code(origin, code)
}
}
}
5 changes: 0 additions & 5 deletions crates/phactory/src/contracts/substrate_kitties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,6 @@ impl contracts::NativeContract for SubstrateKitties {
type QReq = Request;
type QResp = Response;

// Returns the contract id
fn id(&self) -> contracts::ContractId {
contracts::id256(contracts::SUBSTRATE_KITTIES)
}

// Handles the commands from transactions on the blockchain. This method doesn't respond.
fn handle_command(
&mut self,
Expand Down
Loading

0 comments on commit 1c740ad

Please sign in to comment.