Skip to content

Commit

Permalink
Merge pull request #59 from ergoplatform/i52-test-complex
Browse files Browse the repository at this point in the history
Complex scenarios testing
  • Loading branch information
kettlebell authored Jul 1, 2022
2 parents 4de4325 + 00ba9a5 commit 9172084
Show file tree
Hide file tree
Showing 13 changed files with 431 additions and 129 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[workspace]
members = [
"core",
"ergo-chain-sim",
]
6 changes: 4 additions & 2 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ log4rs = "1.1.1"
crossbeam = "0.7.3"
ergo-lib = { version = "0.17.0" }
# ergo-lib = { git = "https://github.com/ergoplatform/sigma-rust", rev = "3ada03f6a803a4541ae6d36c28a74efe87c2325b" }
ergo-node-interface = { git = "https://github.com/ergoplatform/ergo-node-interface-rust", rev = "a260923c4b14b2b08a330e0391f6b7f34eb57242" }
ergo-node-interface = { git = "https://github.com/ergoplatform/ergo-node-interface-rust", rev = "2263442a2722bebedfd2fdb3e230614efbb1c7f9" }
derive_more = "0.99"
# bounded-vec = { version = "^0.5.0" }
clap = {version = "=3.1.18", features = ["derive"]}
Expand All @@ -39,4 +39,6 @@ lazy_static = "1.4.0"
ergo-lib = { version = "0.17.0", features = ["arbitrary"]}
proptest = {version = "1.0.0"}
proptest-derive = {version = "0.3.0"}
sigma-test-util = {version = "^0.3.0"}
sigma-test-util = {version = "0.3.0"}
ergo-chain-sim = {version = "0.1.0", path="../ergo-chain-sim"}
env_logger = {version = "0.9.0"}
104 changes: 20 additions & 84 deletions core/src/cli_commands/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,37 +33,10 @@ use yaml_rust::{Yaml, YamlEmitter, YamlLoader};
use crate::{
box_kind::{make_pool_box_candidate, make_refresh_box_candidate},
contracts::{pool::PoolContract, refresh::RefreshContract},
node_interface::SubmitTransaction,
wallet::{WalletDataSource, WalletSign},
node_interface::{SignTransaction, SubmitTransaction},
wallet::WalletDataSource,
};

// Note that we need the following trait implementations for `NodeInterface` because we can't rely
// on any of the functions in the `crate::node_interface` module since they all implicitly rely on
// the existence of an oracle-pool `yaml` config file.

impl SubmitTransaction for NodeInterface {
fn submit_transaction(&self, tx: &Transaction) -> crate::node_interface::Result<String> {
self.submit_transaction(tx)
}
}

impl WalletSign for NodeInterface {
fn sign_transaction_with_inputs(
&self,
unsigned_tx: &ergo_lib::chain::transaction::unsigned::UnsignedTransaction,
_inputs: ergo_lib::chain::transaction::TxIoVec<ErgoBox>,
_data_boxes: Option<ergo_lib::chain::transaction::TxIoVec<ErgoBox>>,
) -> Result<Transaction, NodeError> {
self.sign_transaction(unsigned_tx)
}
}

impl WalletDataSource for NodeInterface {
fn get_unspent_wallet_boxes(&self) -> Result<Vec<ErgoBox>, NodeError> {
self.unspent_boxes()
}
}

/// Loads bootstrap configuration file and performs the chain-transactions for minting of tokens and
/// box creations. An oracle configuration file is then created which contains the `TokenId`s of the
/// minted tokens.
Expand All @@ -90,9 +63,9 @@ pub fn bootstrap(yaml_config_file_name: String) -> Result<(), BootstrapError> {
let change_address = AddressEncoder::new(prefix).parse_address_from_str(&change_address_str)?;
let input = BootstrapInput {
config,
wallet: &node,
wallet_sign: &node,
submit_tx: &node,
wallet: &node as &dyn WalletDataSource,
tx_signer: &node as &dyn SignTransaction,
submit_tx: &node as &dyn SubmitTransaction,
tx_fee: BoxValue::SAFE_USER_MIN,
erg_value_per_box: BoxValue::SAFE_USER_MIN,
change_address,
Expand All @@ -109,7 +82,7 @@ pub fn bootstrap(yaml_config_file_name: String) -> Result<(), BootstrapError> {
pub struct BootstrapInput<'a> {
pub config: BootstrapConfig,
pub wallet: &'a dyn WalletDataSource,
pub wallet_sign: &'a dyn WalletSign,
pub tx_signer: &'a dyn SignTransaction,
pub submit_tx: &'a dyn SubmitTransaction,
pub tx_fee: BoxValue,
pub erg_value_per_box: BoxValue,
Expand All @@ -120,13 +93,13 @@ pub struct BootstrapInput<'a> {
/// Perform and submit to the mempool the chained-transaction to boostrap the oracle pool. We first
/// mint the oracle-pool tokens then create the pool and refresh boxes as described in EIP-23:
/// https://github.com/ergoplatform/eips/blob/eip23/eip-0023.md#tokens
pub fn perform_bootstrap_chained_transaction(
pub(crate) fn perform_bootstrap_chained_transaction(
input: BootstrapInput,
) -> Result<OracleConfigFields, BootstrapError> {
let BootstrapInput {
config,
wallet,
wallet_sign,
tx_signer: wallet_sign,
submit_tx,
tx_fee,
erg_value_per_box,
Expand Down Expand Up @@ -451,7 +424,7 @@ pub fn perform_bootstrap_chained_transaction(

let target_balance = calc_target_balance(num_transactions_left)?;
let box_selector = SimpleBoxSelector::new();
let mut inputs = filter_tx_outputs(signed_mint_reward_tokens_tx.outputs.clone());
let mut inputs = filter_tx_outputs(signed_pool_box_tx.outputs.clone());

// Need to find the box containing the refresh NFT, and transfer this token to the refresh box.
let box_with_refresh_nft = signed_mint_refresh_nft_tx
Expand Down Expand Up @@ -709,24 +682,18 @@ where
#[cfg(test)]
mod tests {
use ergo_lib::{
chain::{
ergo_state_context::ErgoStateContext,
transaction::{unsigned::UnsignedTransaction, TxId, TxIoVec},
},
chain::{ergo_state_context::ErgoStateContext, transaction::TxId},
ergotree_interpreter::sigma_protocol::private_input::DlogProverInput,
ergotree_ir::{
chain::{
address::AddressEncoder,
ergo_box::{ErgoBox, NonMandatoryRegisters},
},
ergo_tree::ErgoTree,
ergotree_ir::chain::{
address::AddressEncoder,
ergo_box::{ErgoBox, NonMandatoryRegisters},
},
wallet::{signing::TransactionContext, Wallet},
wallet::Wallet,
};
use sigma_test_util::force_any_val;

use super::*;
use crate::pool_commands::test_utils::WalletDataMock;
use crate::pool_commands::test_utils::{LocalTxSigner, WalletDataMock};

struct SubmitTxMock {}

Expand All @@ -740,36 +707,6 @@ mod tests {
}
}

struct TestWallet {
ctx: ErgoStateContext,
wallet: Wallet,
guard: ErgoTree,
}

impl WalletSign for TestWallet {
fn sign_transaction_with_inputs(
&self,
unsigned_tx: &UnsignedTransaction,
inputs: TxIoVec<ErgoBox>,
data_boxes: Option<TxIoVec<ErgoBox>>,
) -> Result<ergo_lib::chain::transaction::Transaction, NodeError> {
let tx = self
.wallet
.sign_transaction(
TransactionContext::new(
unsigned_tx.clone(),
inputs.as_vec().clone(),
data_boxes.map_or(Vec::new(), |bv| bv.as_vec().clone()),
)
.unwrap(),
&self.ctx,
None,
)
.unwrap();
Ok(tx)
}
}

#[test]
fn test_bootstrap() {
let ctx = force_any_val::<ErgoStateContext>();
Expand All @@ -785,7 +722,7 @@ mod tests {
value,
ergo_tree.clone(),
None,
NonMandatoryRegisters::new(vec![].into_iter().collect()).unwrap(),
NonMandatoryRegisters::empty(),
height - 9,
force_any_val::<TxId>(),
0,
Expand Down Expand Up @@ -851,12 +788,11 @@ mod tests {
wallet: &WalletDataMock {
unspent_boxes: unspent_boxes.clone(),
},
wallet_sign: &mut TestWallet {
ctx,
wallet,
guard: ergo_tree,
tx_signer: &mut LocalTxSigner {
ctx: &ctx,
wallet: &wallet,
},
submit_tx: &SubmitTxMock {},
submit_tx: &mut SubmitTxMock {},
tx_fee: BoxValue::SAFE_USER_MIN,
erg_value_per_box: BoxValue::SAFE_USER_MIN,
change_address,
Expand Down
4 changes: 2 additions & 2 deletions core/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ mod pool_commands;
mod scans;
mod state;
mod templates;
#[cfg(test)]
mod tests;
mod wallet;

use actions::execute_action;
Expand All @@ -56,8 +58,6 @@ use wallet::WalletData;
pub type P2PKAddress = String;
/// A Base58 encoded String of a Ergo P2S address. Using this type def until sigma-rust matures further with the actual Address type.
pub type P2SAddress = String;
/// Transaction ID
pub type TxId = String;
/// The smallest unit of the Erg currency.
pub type NanoErg = u64;
/// A block height of the chain.
Expand Down
63 changes: 53 additions & 10 deletions core/src/node_interface.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,66 @@
use crate::oracle_config::{get_node_api_key, get_node_ip, get_node_port};
use crate::{
oracle_config::{get_node_api_key, get_node_ip, get_node_port},
wallet::WalletDataSource,
};
use ergo_lib::{
chain::transaction::{unsigned::UnsignedTransaction, Transaction},
chain::transaction::{unsigned::UnsignedTransaction, Transaction, TxIoVec},
ergotree_ir::chain::ergo_box::ErgoBox,
};
use ergo_node_interface::{
node_interface::{NodeError, NodeInterface, WalletStatus},
BlockHeight,
};

pub trait SubmitTransaction {
fn submit_transaction(&self, tx: &Transaction) -> Result<String>;
}

pub type Result<T> = std::result::Result<T, NodeError>;
pub type ScanID = String;
pub type TxId = String;
pub type P2PKAddressString = String;
pub type P2SAddressString = String;

pub trait SubmitTransaction {
fn submit_transaction(&self, tx: &Transaction) -> Result<String>;
}

pub trait SignTransaction {
fn sign_transaction_with_inputs(
&self,
unsigned_tx: &UnsignedTransaction,
inputs: TxIoVec<ErgoBox>,
data_boxes: Option<TxIoVec<ErgoBox>>,
) -> Result<Transaction>;
}

// Note that we need the following trait implementations for `NodeInterface` because we can't rely
// on any of the functions in the `crate::node_interface` module since they all implicitly rely on
// the existence of an oracle-pool `yaml` config file.

impl SubmitTransaction for NodeInterface {
fn submit_transaction(&self, tx: &Transaction) -> crate::node_interface::Result<String> {
self.submit_transaction(tx)
}
}

impl SignTransaction for NodeInterface {
fn sign_transaction_with_inputs(
&self,
unsigned_tx: &ergo_lib::chain::transaction::unsigned::UnsignedTransaction,
inputs: ergo_lib::chain::transaction::TxIoVec<ErgoBox>,
data_boxes: Option<ergo_lib::chain::transaction::TxIoVec<ErgoBox>>,
) -> Result<Transaction> {
self.sign_transaction(
unsigned_tx,
Some(inputs.as_vec().clone()),
data_boxes.map(|bs| bs.as_vec().clone()),
)
}
}

impl WalletDataSource for NodeInterface {
fn get_unspent_wallet_boxes(&self) -> Result<Vec<ErgoBox>> {
self.unspent_boxes()
}
}

pub fn new_node_interface() -> NodeInterface {
NodeInterface::new(&get_node_api_key(), &get_node_ip(), &get_node_port())
}
Expand Down Expand Up @@ -128,10 +171,10 @@ pub fn get_wallet_status() -> Result<WalletStatus> {
new_node_interface().wallet_status()
}

/// Sign an `UnsignedTransaction`.
pub fn sign_transaction(unsigned_tx: &UnsignedTransaction) -> Result<Transaction> {
new_node_interface().sign_transaction(unsigned_tx)
}
// /// Sign an `UnsignedTransaction`.
// pub fn sign_transaction(unsigned_tx: &UnsignedTransaction) -> Result<Transaction> {
// new_node_interface().sign_transaction(unsigned_tx)
// }

/// Submit a `Transaction` to the mempool.
pub fn submit_transaction(signed_tx: &Transaction) -> Result<TxId> {
Expand Down
39 changes: 39 additions & 0 deletions core/src/pool_commands/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
use std::convert::TryFrom;
use std::convert::TryInto;

use ergo_lib::chain::ergo_state_context::ErgoStateContext;
use ergo_lib::chain::transaction::unsigned::UnsignedTransaction;
use ergo_lib::chain::transaction::TxId;
use ergo_lib::chain::transaction::TxIoVec;
use ergo_lib::ergo_chain_types::EcPoint;
use ergo_lib::ergotree_ir::chain::ergo_box::box_value::BoxValue;
use ergo_lib::ergotree_ir::chain::ergo_box::ErgoBox;
Expand All @@ -15,13 +17,16 @@ use ergo_lib::ergotree_ir::ergo_tree::ErgoTree;
use ergo_lib::ergotree_ir::mir::constant::Constant;
use ergo_lib::ergotree_ir::mir::expr::Expr;
use ergo_lib::ergotree_ir::sigma_protocol::sigma_boolean::ProveDlog;
use ergo_lib::wallet::signing::TransactionContext;
use ergo_lib::wallet::Wallet;
use ergo_node_interface::node_interface::NodeError;
use sigma_test_util::force_any_val;

use crate::box_kind::OracleBoxWrapper;
use crate::box_kind::PoolBoxWrapper;
use crate::contracts::oracle::OracleContract;
use crate::contracts::pool::PoolContract;
use crate::node_interface::SignTransaction;
use crate::oracle_state::{LocalDatapointBoxSource, PoolBoxSource, StageError};

use super::*;
Expand Down Expand Up @@ -161,3 +166,37 @@ pub(crate) fn find_input_boxes(
.as_vec()
.clone()
}

pub struct LocalTxSigner<'a> {
pub ctx: &'a ErgoStateContext,
pub wallet: &'a Wallet,
}

impl<'a> SignTransaction for LocalTxSigner<'a> {
fn sign_transaction_with_inputs(
&self,
unsigned_tx: &UnsignedTransaction,
inputs: TxIoVec<ErgoBox>,
data_boxes: Option<TxIoVec<ErgoBox>>,
) -> Result<ergo_lib::chain::transaction::Transaction, NodeError> {
let tx = self
.wallet
.sign_transaction(
TransactionContext::new(
unsigned_tx.clone(),
inputs.as_vec().clone(),
data_boxes.map(|bs| bs.as_vec().clone()).unwrap_or_default(),
)
.unwrap(),
self.ctx,
None,
)
.unwrap();
Ok(tx)
}
}

pub fn init_log_tests() {
// set log level via RUST_LOG=info env var
let _ = env_logger::builder().is_test(true).try_init().unwrap();
}
1 change: 1 addition & 0 deletions core/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod bootstrap_and_run;
Loading

0 comments on commit 9172084

Please sign in to comment.