Skip to content
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
6 changes: 3 additions & 3 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ crossbeam = "0.8"
tokio = { version = "1", features = ["full"] }
tower-http = { version = "0.3.0", features = ["cors"] }
axum = "0.5"
ergo-lib = { version = "0.17.0" }
ergo-lib = { version = "0.20.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 = "84ac6ed680cf3a33b4089fea5e377a07d4df64b4" }
ergo-node-interface = { git = "https://github.com/ergoplatform/ergo-node-interface-rust", rev = "f10aa6ab8392524363faa2916a2b61ad6d99cb62" }
derive_more = "0.99"
# bounded-vec = { version = "^0.5.0" }
clap = {version = "=3.1.18", features = ["derive"]}
Expand All @@ -38,7 +38,7 @@ lazy_static = "1.4.0"
[dev-dependencies]
# sigma-test-util = { version = "^0.3.0", path = "../../sigma-rust/sigma-test-util" }
# ergo-lib = { git = "https://github.com/ergoplatform/sigma-rust", rev = "3ada03f6a803a4541ae6d36c28a74efe87c2325b" , features = ["arbitrary"]}
ergo-lib = { version = "0.17.0", features = ["arbitrary"]}
ergo-lib = { version = "0.20.0", features = ["arbitrary"]}
proptest = {version = "1.0.0"}
proptest-derive = {version = "0.3.0"}
sigma-test-util = {version = "0.3.0"}
Expand Down
228 changes: 8 additions & 220 deletions core/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
/// by an oracle part of the oracle pool. These actions
/// are implemented on the `OraclePool` struct.
use crate::node_interface::sign_and_submit_transaction;
use crate::oracle_state::OraclePool;
use ergo_lib::chain::transaction::unsigned::UnsignedTransaction;
use ergo_lib::ergotree_ir::chain::ergo_box::ErgoBox;

Expand Down Expand Up @@ -50,8 +49,14 @@ pub enum ActionExecError {

pub fn execute_action(action: PoolAction) -> Result<(), ActionExecError> {
match action {
PoolAction::Refresh(action) => execute_refresh_action(action),
PoolAction::PublishDatapoint(action) => execute_publish_datapoint_action(action),
PoolAction::Refresh(action) => {
log::info!("Executing refresh action: {:?}", action);
execute_refresh_action(action)
}
PoolAction::PublishDatapoint(action) => {
log::info!("Executing publish datapoint action: {:?}", action);
execute_publish_datapoint_action(action)
}
}
}

Expand All @@ -65,223 +70,6 @@ fn execute_publish_datapoint_action(action: PublishDataPointAction) -> Result<()
Ok(())
}

impl<'a> OraclePool<'a> {
// /// Generates and submits the "Collect Funds" action tx
// pub fn action_collect_funds(&self) -> Result<String, StageError> {
// let mut req = json::parse(BASIC_TRANSACTION_SEND_REQUEST).unwrap();

// // Defining the registers of the output box
// let epoch_prep_state = self.get_preparation_state()?;
// let registers = object! {
// "R4": Constant::from(epoch_prep_state.latest_pool_datapoint as i64).base16_str().unwrap(),

// "R5": Constant::from(epoch_prep_state.next_epoch_ends as i32).base16_str().unwrap(),
// };
// // Defining the tokens to be spent
// let token_json = object! {
// "tokenId": self.oracle_pool_nft.to_string(),
// "amount": 1
// };

// // Create input boxes Vec with serialized Epoch Preparation box inside
// let mut unserialized_input_boxes = vec![self.epoch_preparation_stage.get_box()?];
// // Acquire all Pool Deposit boxes
// let mut initial_deposit_boxes = self.pool_deposit_stage.get_boxes()?;
// // Only append up to 27 boxes for now. This is to prevent exceeding execution limit for txs.
// if initial_deposit_boxes.len() > 27 {
// unserialized_input_boxes.append(&mut initial_deposit_boxes[..27].to_vec());
// } else {
// unserialized_input_boxes.append(&mut initial_deposit_boxes);
// }

// // Define the fee for the current action
// let action_fee = 500000 * unserialized_input_boxes.len() as u64;

// // Serialize boxes and add extra box for paying fee
// let mut serialized_input_boxes = serialize_boxes(&unserialized_input_boxes)?;
// serialized_input_boxes.append(&mut serialized_unspent_boxes_with_min_total(action_fee)?);

// // Sum up the new total minus tx fee
// let total_input_ergs = unserialized_input_boxes
// .iter()
// .fold(0, |acc, b| acc + b.value.as_u64());

// // Filling out the json tx request template
// req["requests"][0]["value"] = total_input_ergs.into();
// req["requests"][0]["address"] =
// self.epoch_preparation_stage.contract_address.clone().into();
// req["requests"][0]["registers"] = registers;
// req["requests"][0]["assets"] = vec![token_json].into();
// req["inputsRaw"] = serialized_input_boxes.into();
// req["fee"] = action_fee.into();

// let result = send_transaction(&req)?;
// Ok(result)
// }

// /// Generates and submits the "Start Next Epoch" action tx
// pub fn action_start_next_epoch(&self) -> Result<String, StageError> {
// let parameters = PoolParameters::new();
// let mut req = json::parse(BASIC_TRANSACTION_SEND_REQUEST)?;

// // Defining the registers of the output box
// let epoch_prep_state = self.get_preparation_state()?;
// let registers = object! {
// "R4": Constant::from(epoch_prep_state.latest_pool_datapoint as i64).base16_str().unwrap(),
// "R5": Constant::from(epoch_prep_state.next_epoch_ends as i32).base16_str().unwrap(),
// "R6": serialize_hex_encoded_string(&string_to_blake2b_hash(address_to_tree(&self.epoch_preparation_stage.contract_address)?)?)?.base16_str().unwrap(),
// };
// // Defining the tokens to be spent
// let token_json = object! {
// "tokenId": self.oracle_pool_nft.to_string(),
// "amount": 1
// };

// let mut inputs_raw = vec![self.epoch_preparation_stage.get_serialized_box()?];
// inputs_raw.append(&mut serialized_unspent_boxes_with_min_total(
// parameters.base_fee,
// )?);

// // Filling out the json tx request template
// req["requests"][0]["value"] = epoch_prep_state.funds.into();
// req["requests"][0]["address"] = self.live_epoch_stage.contract_address.clone().into();
// req["requests"][0]["registers"] = registers;
// req["requests"][0]["assets"] = vec![token_json].into();
// req["inputsRaw"] = inputs_raw.into();
// req["fee"] = parameters.base_fee.into();

// let result = send_transaction(&req)?;
// Ok(result)
// }

// /// Generates and submits the "Create New Epoch" action tx
// pub fn action_create_new_epoch(&self) -> Result<String, StageError> {
// let parameters = PoolParameters::new();
// let mut req = json::parse(BASIC_TRANSACTION_SEND_REQUEST)?;

// // Define the new epoch finish height based off of current height
// let new_finish_height = current_block_height()?
// + parameters.epoch_preparation_length
// + parameters.live_epoch_length
// + parameters.buffer_length;

// // Defining the registers of the output box
// let epoch_prep_state = self.get_preparation_state()?;
// let registers = object! {
// "R4": Constant::from(epoch_prep_state.latest_pool_datapoint as i64).base16_str().unwrap(),
// "R5": Constant::from(new_finish_height as i32).base16_str().unwrap(),
// "R6": serialize_hex_encoded_string(&string_to_blake2b_hash(address_to_tree(&self.epoch_preparation_stage.contract_address)?)?)?.base16_str().unwrap(),
// };
// // Defining the tokens to be spent
// let token_json = object! {
// "tokenId": self.oracle_pool_nft.to_string(),
// "amount": 1
// };

// let mut inputs_raw = vec![self.epoch_preparation_stage.get_serialized_box()?];
// inputs_raw.append(&mut serialized_unspent_boxes_with_min_total(
// parameters.base_fee,
// )?);

// // Filling out the json tx request template
// req["requests"][0]["value"] = epoch_prep_state.funds.into();
// req["requests"][0]["address"] = self.live_epoch_stage.contract_address.clone().into();
// req["requests"][0]["registers"] = registers;
// req["requests"][0]["assets"] = vec![token_json].into();
// req["inputsRaw"] = inputs_raw.into();
// req["fee"] = parameters.base_fee.into();

// let result = send_transaction(&req)?;
// Ok(result)
// }

/*
/// Generates and submits the "Collect Datapoints" action tx
pub fn action_collect_datapoints(&self) -> Result<String, StateError> {
let parameters = PoolParameters::new();
let mut req = json::parse(BASIC_TRANSACTION_SEND_REQUEST)?;

let live_epoch_state = self.get_live_epoch_state()?;

// Filter out Datapoint boxes not from the latest epoch
let current_epoch_datapoint_boxes =
current_epoch_boxes_filter(&self.datapoint_stage.get_boxes()?, &live_epoch_state);
// Sort Datapoint boxes in decreasing order
let sorted_datapoint_boxes = sort_datapoint_boxes(&current_epoch_datapoint_boxes);

// Acquire the finalized oracle pool datapoint and the list of successful datapoint boxes which were within the deviation range
let (finalized_datapoint, successful_boxes) = finalize_datapoint(
&sorted_datapoint_boxes,
parameters.deviation_range as i64, // Make sure to change this to config #
parameters.consensus_num as i64, // Make sure to change this to config #
)?;

// Find the index of the local oracle's Datapoint box in the successful boxes list
let local_datapoint_box_index = find_box_index_in_list(
self.local_oracle_datapoint_scan.get_box()?,
&successful_boxes,
)
.ok_or(CollectionError::LocalOracleFailedToPostDatapointWithinDeviation())?;

// Tx fee for the transaction
let tx_fee = (parameters.base_fee) * sorted_datapoint_boxes.len() as u64;
// Define the new value of the oracle pool box after payouts/tx fee
let new_box_value = live_epoch_state.funds
- (parameters.oracle_payout_price * (successful_boxes.len() as u64 + 1));
// Define the finish height of the following epoch
let new_finish_height = self.get_live_epoch_state()?.epoch_ends
+ parameters.epoch_preparation_length
+ parameters.live_epoch_length;

// Defining json request for the oracle pool box
let token_json = object! {
"tokenId": self.oracle_pool_nft.to_string(),
"amount": 1
};
let registers = object! {
"R4": Constant::from(finalized_datapoint as i64).base16_str().unwrap(),
"R5": Constant::from(new_finish_height as i32).base16_str().unwrap(),
};
let mut inputs_raw = vec![self.live_epoch_stage.get_serialized_box()?];
inputs_raw.append(&mut serialized_unspent_boxes_with_min_total(tx_fee)?);

req["requests"][0]["value"] = new_box_value.into();
req["requests"][0]["address"] =
self.epoch_preparation_stage.contract_address.clone().into();
req["requests"][0]["registers"] = registers;
req["requests"][0]["assets"] = vec![token_json].into();

// Filling out requests for the oracle payout outputs
for b in &successful_boxes {
// Get the P2PK from the hex encoded constant string minus the first two characters which are a register type descriptor
let oracle_address = raw_from_register_to_address(
&b.additional_registers.get_ordered_values()[0].base16_str().unwrap(),
)?;
req["requests"]
.push(object! {
"address": oracle_address,
"value": parameters.oracle_payout_price,
})
.ok();
}
// Add the local oracle Datapoint box index into R4 of the first oracle payout box
req["requests"][1]["registers"] = object! {
"R4": Constant::from(local_datapoint_box_index as i32).base16_str().unwrap()
};
// Pay the local oracle double due to being Collector
req["requests"][local_datapoint_box_index + 1]["value"] =
(parameters.oracle_payout_price * 2).into();
// Filling out the rest of the json request
req["inputsRaw"] = inputs_raw.into();
req["dataInputsRaw"] = serialize_boxes(&successful_boxes)?.into();
req["fee"] = tx_fee.into();

let result = send_transaction(&req)?;
Ok(result)
}
*/
}

/// Given an `ErgoBox`, find its index in the input `Vec<ErgoBox>`
/// If index cannot be found, then local oracle has not submit their
/// own datapoint, and thus the function returns `None`
Expand Down
16 changes: 10 additions & 6 deletions core/src/api.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::net::SocketAddr;

use crate::box_kind::OracleBox;
use crate::node_interface::current_block_height;
use crate::oracle_config::{get_core_api_port, get_node_ip, get_node_port, ORACLE_CONFIG};
use crate::oracle_state::{OraclePool, StageDataSource};
Expand Down Expand Up @@ -33,18 +34,21 @@ async fn oracle_status() -> impl IntoResponse {
Err(_) => false,
};
// Get latest datapoint the local oracle produced/submit
let self_datapoint = match op.get_datapoint_state() {
Ok(Some(d)) => d.datapoint,
let latest_oracle_box = op
.get_local_datapoint_box_source()
.get_local_oracle_datapoint_box();
let self_datapoint = match latest_oracle_box {
Ok(Some(ref d)) => d.rate(),
Ok(None) | Err(_) => 0,
};
// Get latest datapoint submit epoch
let datapoint_epoch = match op.get_datapoint_state() {
Ok(Some(d)) => d.origin_epoch_id,
let datapoint_epoch = match latest_oracle_box {
Ok(Some(ref d)) => d.epoch_counter(),
Ok(None) | Err(_) => 0,
};
// Get latest datapoint submit epoch
let datapoint_creation = match op.get_datapoint_state() {
Ok(Some(d)) => d.creation_height,
let datapoint_creation = match latest_oracle_box {
Ok(Some(ref d)) => d.get_box().creation_height,
Ok(None) | Err(_) => 0,
};

Expand Down
2 changes: 1 addition & 1 deletion core/src/box_kind/pool_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub enum PoolBoxError {
UnknownRewardTokenId,
}

#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct PoolBoxWrapper(ErgoBox, PoolContract);

impl PoolBoxWrapper {
Expand Down
2 changes: 1 addition & 1 deletion core/src/box_kind/refresh_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl RefreshBoxWrapperInputs {
}

impl RefreshBoxWrapper {
pub fn new(b: ErgoBox, inputs: RefreshBoxWrapperInputs) -> Result<Self, RefreshBoxError> {
pub fn new(b: ErgoBox, inputs: &RefreshBoxWrapperInputs) -> Result<Self, RefreshBoxError> {
let refresh_token_id = b
.tokens
.as_ref()
Expand Down
7 changes: 2 additions & 5 deletions core/src/cli_commands/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ pub(crate) fn perform_bootstrap_chained_transaction(
height,
tx_fee,
change_address.clone(),
BoxValue::MIN,
);
let mint_token_tx = tx_builder.build()?;
debug!("Mint token unsigned transaction: {:?}", mint_token_tx);
Expand Down Expand Up @@ -388,7 +387,7 @@ pub(crate) fn perform_bootstrap_chained_transaction(
0,
1,
pool_nft_token.clone(),
reward_tokens_for_pool_box,
reward_tokens_for_pool_box.clone(),
erg_value_per_box,
height,
)?;
Expand Down Expand Up @@ -424,7 +423,7 @@ pub(crate) fn perform_bootstrap_chained_transaction(
let box_selection = box_selector.select(
inputs,
target_balance,
&[pool_nft_token.clone(), reward_token.clone()],
&[pool_nft_token.clone(), reward_tokens_for_pool_box.clone()],
)?;
let inputs = box_selection.boxes.clone();
let tx_builder = TxBuilder::new(
Expand All @@ -433,7 +432,6 @@ pub(crate) fn perform_bootstrap_chained_transaction(
height,
tx_fee,
change_address.clone(),
BoxValue::MIN,
);
let pool_box_tx = tx_builder.build()?;
debug!("unsigned pool_box_tx: {:?}", pool_box_tx);
Expand Down Expand Up @@ -490,7 +488,6 @@ pub(crate) fn perform_bootstrap_chained_transaction(
height,
tx_fee,
change_address.clone(),
BoxValue::MIN,
);
let refresh_box_tx = tx_builder.build()?;
debug!("unsigned refresh_box_tx: {:?}", refresh_box_tx);
Expand Down
Loading