mirror of
https://github.com/0glabs/0g-storage-node.git
synced 2024-12-24 23:35:18 +00:00
Support multiple mine submission (#124)
* Support multiple mine submission * Update
This commit is contained in:
parent
ba8d065e73
commit
cca14e246e
@ -1 +1 @@
|
|||||||
Subproject commit faee29c2343036e1172321194569639ebeed6e01
|
Subproject commit 25bc14a27441e8fb26e4d42d7c8c885f92d6c74a
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4527,6 +4527,7 @@ dependencies = [
|
|||||||
"ethers",
|
"ethers",
|
||||||
"hex",
|
"hex",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"lighthouse_metrics",
|
||||||
"network",
|
"network",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"shared_types",
|
"shared_types",
|
||||||
|
@ -10,6 +10,7 @@ zgs_spec = { path = "../../common/spec" }
|
|||||||
zgs_seal = { path = "../../common/zgs_seal" }
|
zgs_seal = { path = "../../common/zgs_seal" }
|
||||||
task_executor = { path = "../../common/task_executor" }
|
task_executor = { path = "../../common/task_executor" }
|
||||||
contract-interface = { path = "../../common/contract-interface" }
|
contract-interface = { path = "../../common/contract-interface" }
|
||||||
|
lighthouse_metrics = { path = "../../common/lighthouse_metrics" }
|
||||||
ethereum-types = "0.14"
|
ethereum-types = "0.14"
|
||||||
tokio = { version = "1.19.2", features = ["full"] }
|
tokio = { version = "1.19.2", features = ["full"] }
|
||||||
tracing = "0.1.35"
|
tracing = "0.1.35"
|
||||||
|
@ -6,6 +6,7 @@ extern crate lazy_static;
|
|||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
mod loader;
|
mod loader;
|
||||||
|
mod metrics;
|
||||||
mod mine;
|
mod mine;
|
||||||
mod miner_id;
|
mod miner_id;
|
||||||
pub mod pora;
|
pub mod pora;
|
||||||
|
32
node/miner/src/metrics.rs
Normal file
32
node/miner/src/metrics.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
use lighthouse_metrics::{try_create_int_counter, IntCounter, Result};
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref SCRATCH_PAD_ITER_COUNT: Result<IntCounter> = try_create_int_counter(
|
||||||
|
"miner_scratch_pad_iter",
|
||||||
|
"Number of scratch pad iterations for PoRA"
|
||||||
|
);
|
||||||
|
pub static ref LOADING_COUNT: Result<IntCounter> = try_create_int_counter(
|
||||||
|
"miner_loading_iter",
|
||||||
|
"Number of loading iterations for PoRA"
|
||||||
|
);
|
||||||
|
pub static ref PAD_MIX_COUNT: Result<IntCounter> = try_create_int_counter(
|
||||||
|
"miner_mix_iter",
|
||||||
|
"Number of mix sealed data with scratch pad iterations for PoRA"
|
||||||
|
);
|
||||||
|
pub static ref HIT_COUNT: Result<IntCounter> =
|
||||||
|
try_create_int_counter("miner_hit", "Number of hit for PoRA");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn report() -> String {
|
||||||
|
let s = |counter: &Result<IntCounter>| match counter {
|
||||||
|
Ok(x) => format!("{}", x.get()),
|
||||||
|
Err(_) => "n/a".to_string(),
|
||||||
|
};
|
||||||
|
format!(
|
||||||
|
"scratch pad: {}, loading: {}, pad_mix: {}, hit: {}",
|
||||||
|
s(&SCRATCH_PAD_ITER_COUNT),
|
||||||
|
s(&LOADING_COUNT),
|
||||||
|
s(&PAD_MIX_COUNT),
|
||||||
|
s(&HIT_COUNT)
|
||||||
|
)
|
||||||
|
}
|
@ -6,15 +6,16 @@ use task_executor::TaskExecutor;
|
|||||||
use tokio::sync::{broadcast, mpsc};
|
use tokio::sync::{broadcast, mpsc};
|
||||||
use tokio::time::{sleep, Duration, Instant};
|
use tokio::time::{sleep, Duration, Instant};
|
||||||
|
|
||||||
|
use storage::config::ShardConfig;
|
||||||
use zgs_spec::{SECTORS_PER_LOAD, SECTORS_PER_MAX_MINING_RANGE, SECTORS_PER_PRICING};
|
use zgs_spec::{SECTORS_PER_LOAD, SECTORS_PER_MAX_MINING_RANGE, SECTORS_PER_PRICING};
|
||||||
|
|
||||||
|
use super::metrics;
|
||||||
use crate::recall_range::RecallRange;
|
use crate::recall_range::RecallRange;
|
||||||
use crate::{
|
use crate::{
|
||||||
pora::{AnswerWithoutProof, Miner},
|
pora::{AnswerWithoutProof, Miner},
|
||||||
watcher::MineContextMessage,
|
watcher::MineContextMessage,
|
||||||
MinerConfig, MinerMessage, PoraLoader,
|
MinerConfig, MinerMessage, PoraLoader,
|
||||||
};
|
};
|
||||||
use storage::config::ShardConfig;
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -122,7 +123,6 @@ impl PoraService {
|
|||||||
let cpu_percent: u64 = self.cpu_percentage;
|
let cpu_percent: u64 = self.cpu_percentage;
|
||||||
let diastole = sleep(Duration::from_secs(0));
|
let diastole = sleep(Duration::from_secs(0));
|
||||||
tokio::pin!(diastole);
|
tokio::pin!(diastole);
|
||||||
// info!("CPU percent {}", cpu_percent);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
@ -157,19 +157,21 @@ impl PoraService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
maybe_msg = self.mine_context_receiver.recv() => {
|
maybe_msg = self.mine_context_receiver.recv() => {
|
||||||
trace!("PoraService receives context={:?}", maybe_msg);
|
|
||||||
if let Some(msg) = maybe_msg {
|
if let Some(msg) = maybe_msg {
|
||||||
debug!("Update mine service: {:?}", msg);
|
info!("Update mine service: {:?}", msg);
|
||||||
|
info!("Mine iterations statistics: {}", metrics::report());
|
||||||
self.puzzle = msg.map(|(context, target_quality)| PoraPuzzle {
|
self.puzzle = msg.map(|(context, target_quality)| PoraPuzzle {
|
||||||
context, target_quality
|
context, target_quality
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
warn!("Mine context channel closed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
() = &mut diastole, if !diastole.is_elapsed() => {
|
() = &mut diastole, if !diastole.is_elapsed() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = async {}, if mining_enabled && cpu_percent > 0 && self.as_miner().is_some() && diastole.is_elapsed() => {
|
_ = async {}, if mining_enabled && cpu_percent > 0 && self.as_miner().map_or(false, |miner| miner.range.mining_length > 0) && diastole.is_elapsed() => {
|
||||||
let nonce = H256(rand::thread_rng().gen());
|
let nonce = H256(rand::thread_rng().gen());
|
||||||
let miner = self.as_miner().unwrap();
|
let miner = self.as_miner().unwrap();
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
use super::metrics::*;
|
||||||
use crate::recall_range::RecallRange;
|
use crate::recall_range::RecallRange;
|
||||||
use crate::{MineRangeConfig, PoraLoader};
|
use crate::{MineRangeConfig, PoraLoader};
|
||||||
use blake2::{Blake2b512, Digest};
|
use blake2::{Blake2b512, Digest};
|
||||||
use contract_interface::zgs_flow::MineContext;
|
use contract_interface::zgs_flow::MineContext;
|
||||||
use ethereum_types::{H256, U256};
|
use ethereum_types::{H256, U256};
|
||||||
|
use lighthouse_metrics::inc_counter;
|
||||||
use storage::log_store::MineLoadChunk;
|
use storage::log_store::MineLoadChunk;
|
||||||
use tiny_keccak::{Hasher, Keccak};
|
use tiny_keccak::{Hasher, Keccak};
|
||||||
use zgs_spec::{BYTES_PER_SCRATCHPAD, BYTES_PER_SEAL, SECTORS_PER_LOAD, SECTORS_PER_SEAL};
|
use zgs_spec::{BYTES_PER_SCRATCHPAD, BYTES_PER_SEAL, SECTORS_PER_LOAD, SECTORS_PER_SEAL};
|
||||||
@ -58,16 +60,13 @@ impl<'a> Miner<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn iteration(&self, nonce: H256) -> Option<AnswerWithoutProof> {
|
pub async fn iteration(&self, nonce: H256) -> Option<AnswerWithoutProof> {
|
||||||
|
inc_counter(&SCRATCH_PAD_ITER_COUNT);
|
||||||
let ScratchPad {
|
let ScratchPad {
|
||||||
scratch_pad,
|
scratch_pad,
|
||||||
recall_seed,
|
recall_seed,
|
||||||
pad_seed,
|
pad_seed,
|
||||||
} = self.make_scratch_pad(&nonce);
|
} = self.make_scratch_pad(&nonce);
|
||||||
|
|
||||||
if self.range.mining_length == 0 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let recall_position = self.range.load_position(recall_seed)?;
|
let recall_position = self.range.load_position(recall_seed)?;
|
||||||
if !self.mine_range_config.is_covered(recall_position).unwrap() {
|
if !self.mine_range_config.is_covered(recall_position).unwrap() {
|
||||||
trace!(
|
trace!(
|
||||||
@ -77,6 +76,7 @@ impl<'a> Miner<'a> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inc_counter(&LOADING_COUNT);
|
||||||
let MineLoadChunk {
|
let MineLoadChunk {
|
||||||
loaded_chunk,
|
loaded_chunk,
|
||||||
avalibilities,
|
avalibilities,
|
||||||
@ -95,6 +95,7 @@ impl<'a> Miner<'a> {
|
|||||||
.zip(avalibilities.into_iter())
|
.zip(avalibilities.into_iter())
|
||||||
.filter_map(|(data, avaliable)| avaliable.then_some(data))
|
.filter_map(|(data, avaliable)| avaliable.then_some(data))
|
||||||
{
|
{
|
||||||
|
inc_counter(&PAD_MIX_COUNT);
|
||||||
// Rust can optimize this loop well.
|
// Rust can optimize this loop well.
|
||||||
for (x, y) in sealed_data.iter_mut().zip(scratch_pad.iter()) {
|
for (x, y) in sealed_data.iter_mut().zip(scratch_pad.iter()) {
|
||||||
*x ^= y;
|
*x ^= y;
|
||||||
@ -111,6 +112,7 @@ impl<'a> Miner<'a> {
|
|||||||
U256::MAX / self.target_quality,
|
U256::MAX / self.target_quality,
|
||||||
quality_scale
|
quality_scale
|
||||||
);
|
);
|
||||||
|
inc_counter(&HIT_COUNT);
|
||||||
// Undo mix data when find a valid solition
|
// Undo mix data when find a valid solition
|
||||||
for (x, y) in sealed_data.iter_mut().zip(scratch_pad.iter()) {
|
for (x, y) in sealed_data.iter_mut().zip(scratch_pad.iter()) {
|
||||||
*x ^= y;
|
*x ^= y;
|
||||||
|
@ -143,7 +143,7 @@ impl Submitter {
|
|||||||
SUBMISSION_RETIES
|
SUBMISSION_RETIES
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
info!("Submit PoRA sucess");
|
info!("Submit PoRA success");
|
||||||
debug!("Receipt: {:?}", receipt);
|
debug!("Receipt: {:?}", receipt);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -106,13 +106,13 @@ impl MineContextWatcher {
|
|||||||
|
|
||||||
async fn query_recent_context(&mut self) -> Result<(), String> {
|
async fn query_recent_context(&mut self) -> Result<(), String> {
|
||||||
let context_call = self.flow_contract.make_context_with_result();
|
let context_call = self.flow_contract.make_context_with_result();
|
||||||
let epoch_call = self.mine_contract.last_mined_epoch();
|
let valid_call = self.mine_contract.can_submit();
|
||||||
let quality_call = self.mine_contract.target_quality();
|
let quality_call = self.mine_contract.pora_target();
|
||||||
|
|
||||||
let (context, epoch, quality) =
|
let (context, can_submit, quality) =
|
||||||
try_join!(context_call.call(), epoch_call.call(), quality_call.call())
|
try_join!(context_call.call(), valid_call.call(), quality_call.call())
|
||||||
.map_err(|e| format!("Failed to query mining context: {:?}", e))?;
|
.map_err(|e| format!("Failed to query mining context: {:?}", e))?;
|
||||||
let report = if context.epoch > epoch && context.digest != EMPTY_HASH.0 {
|
let report = if can_submit && context.digest != EMPTY_HASH.0 {
|
||||||
Some((context, quality))
|
Some((context, quality))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -35,7 +35,7 @@ class MineTest(TestFramework):
|
|||||||
self.log.info("flow address: %s", self.contract.address())
|
self.log.info("flow address: %s", self.contract.address())
|
||||||
self.log.info("mine address: %s", self.mine_contract.address())
|
self.log.info("mine address: %s", self.mine_contract.address())
|
||||||
|
|
||||||
quality = int(2**256 / 400 / estimate_st_performance())
|
quality = int(2**256 / 100 / estimate_st_performance())
|
||||||
self.mine_contract.set_quality(quality)
|
self.mine_contract.set_quality(quality)
|
||||||
|
|
||||||
self.log.info("Submit the first data chunk")
|
self.log.info("Submit the first data chunk")
|
||||||
@ -49,14 +49,14 @@ class MineTest(TestFramework):
|
|||||||
self.contract.update_context()
|
self.contract.update_context()
|
||||||
|
|
||||||
self.log.info("Wait for the first mine answer")
|
self.log.info("Wait for the first mine answer")
|
||||||
wait_until(lambda: self.mine_contract.last_mined_epoch() == 1, timeout=180)
|
wait_until(lambda: self.mine_contract.last_mined_epoch() == start_epoch + 1 and not self.mine_contract.can_submit(), timeout=180)
|
||||||
|
|
||||||
self.log.info("Wait for the second mine context release")
|
self.log.info("Wait for the second mine context release")
|
||||||
wait_until(lambda: int(blockchain.eth_blockNumber(), 16) >= start_epoch + 2, timeout=180)
|
wait_until(lambda: int(blockchain.eth_blockNumber(), 16) >= start_epoch + 2, timeout=180)
|
||||||
self.contract.update_context()
|
self.contract.update_context()
|
||||||
|
|
||||||
self.log.info("Wait for the second mine answer")
|
self.log.info("Wait for the second mine answer")
|
||||||
wait_until(lambda: self.mine_contract.last_mined_epoch() == 2, timeout=180)
|
wait_until(lambda: self.mine_contract.last_mined_epoch() == start_epoch + 2 and not self.mine_contract.can_submit(), timeout=180)
|
||||||
|
|
||||||
self.nodes[0].miner_stop()
|
self.nodes[0].miner_stop()
|
||||||
self.log.info("Wait for the third mine context release")
|
self.log.info("Wait for the third mine context release")
|
||||||
@ -69,7 +69,7 @@ class MineTest(TestFramework):
|
|||||||
self.nodes[0].miner_start()
|
self.nodes[0].miner_start()
|
||||||
|
|
||||||
self.log.info("Wait for the third mine answer")
|
self.log.info("Wait for the third mine answer")
|
||||||
wait_until(lambda: self.mine_contract.last_mined_epoch() == 3, timeout=180)
|
wait_until(lambda: self.mine_contract.last_mined_epoch() == start_epoch + 3 and not self.mine_contract.can_submit(), timeout=180)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -45,8 +45,8 @@ class MineTest(TestFramework):
|
|||||||
self.log.info("flow address: %s", self.contract.address())
|
self.log.info("flow address: %s", self.contract.address())
|
||||||
self.log.info("mine address: %s", self.mine_contract.address())
|
self.log.info("mine address: %s", self.mine_contract.address())
|
||||||
|
|
||||||
quality = int(2**256 / 5 / estimate_st_performance())
|
difficulty = int(2**256 / 5 / estimate_st_performance())
|
||||||
self.mine_contract.set_quality(quality)
|
self.mine_contract.set_quality(difficulty)
|
||||||
|
|
||||||
SECTORS_PER_PRICING = int(8 * ( 2 ** 30 ) / 256)
|
SECTORS_PER_PRICING = int(8 * ( 2 ** 30 ) / 256)
|
||||||
|
|
||||||
@ -67,10 +67,10 @@ class MineTest(TestFramework):
|
|||||||
self.contract.update_context()
|
self.contract.update_context()
|
||||||
|
|
||||||
self.log.info("Wait for mine answer")
|
self.log.info("Wait for mine answer")
|
||||||
wait_until(lambda: self.mine_contract.last_mined_epoch() == start_epoch + 1, timeout=120)
|
wait_until(lambda: self.mine_contract.last_mined_epoch() == start_epoch + 1 and not self.mine_contract.can_submit(), timeout=120)
|
||||||
|
|
||||||
rewards = self.reward_contract.reward_distributes()
|
rewards = self.reward_contract.reward_distributes()
|
||||||
assert_equal(len(self.reward_contract.reward_distributes()), start_epoch + 1)
|
assert_equal(len(rewards), 2)
|
||||||
firstReward = rewards[0].args.amount
|
firstReward = rewards[0].args.amount
|
||||||
self.log.info("Received reward %d Gwei", firstReward / (10**9))
|
self.log.info("Received reward %d Gwei", firstReward / (10**9))
|
||||||
|
|
||||||
@ -87,10 +87,12 @@ class MineTest(TestFramework):
|
|||||||
self.contract.update_context()
|
self.contract.update_context()
|
||||||
|
|
||||||
self.log.info("Wait for mine answer")
|
self.log.info("Wait for mine answer")
|
||||||
wait_until(lambda: self.mine_contract.last_mined_epoch() == start_epoch + 2)
|
wait_until(lambda: self.mine_contract.last_mined_epoch() == start_epoch + 2 and not self.mine_contract.can_submit())
|
||||||
|
assert_equal(self.contract.epoch(), start_epoch + 2)
|
||||||
|
|
||||||
rewards = self.reward_contract.reward_distributes()
|
rewards = self.reward_contract.reward_distributes()
|
||||||
assert_equal(len(self.reward_contract.reward_distributes()), start_epoch + 2)
|
assert_equal(len(rewards), 4)
|
||||||
secondReward = rewards[1].args.amount
|
secondReward = rewards[2].args.amount
|
||||||
self.log.info("Received reward %d Gwei", secondReward / (10**9))
|
self.log.info("Received reward %d Gwei", secondReward / (10**9))
|
||||||
|
|
||||||
assert_greater_than(secondReward, 100 * firstReward / (start_epoch + 1))
|
assert_greater_than(secondReward, 100 * firstReward / (start_epoch + 1))
|
||||||
|
@ -285,18 +285,27 @@ class BlockchainNode(TestNode):
|
|||||||
|
|
||||||
def deploy_no_market():
|
def deploy_no_market():
|
||||||
self.log.debug("Start deploy contracts")
|
self.log.debug("Start deploy contracts")
|
||||||
|
|
||||||
dummy_market_contract, _ = deploy_contract("DummyMarket", [])
|
dummy_market_contract, _ = deploy_contract("DummyMarket", [])
|
||||||
self.log.debug("DummyMarket deployed")
|
self.log.debug("DummyMarket deployed")
|
||||||
|
|
||||||
dummy_reward_contract, _ = deploy_contract("DummyReward", [])
|
dummy_reward_contract, _ = deploy_contract("DummyReward", [])
|
||||||
self.log.debug("DummyReward deployed")
|
self.log.debug("DummyReward deployed")
|
||||||
|
|
||||||
flow_contract, _ = deploy_contract("Flow", [mine_period, 0])
|
flow_contract, _ = deploy_contract("Flow", [mine_period, 0])
|
||||||
self.log.debug("Flow deployed")
|
self.log.debug("Flow deployed")
|
||||||
|
|
||||||
mine_contract, _ = deploy_contract("PoraMineTest", [0])
|
mine_contract, _ = deploy_contract("PoraMineTest", [0])
|
||||||
self.log.debug("Mine deployed")
|
self.log.debug("Mine deployed")
|
||||||
mine_contract.functions.initialize(1, 1, flow_contract.address, dummy_reward_contract.address).transact(TX_PARAMS)
|
|
||||||
|
mine_contract.functions.initialize(1, flow_contract.address, dummy_reward_contract.address).transact(TX_PARAMS)
|
||||||
|
mine_contract.functions.setDifficultyAdjustRatio(1).transact(TX_PARAMS)
|
||||||
|
mine_contract.functions.setTargetSubmissions(2).transact(TX_PARAMS)
|
||||||
self.log.debug("Mine Initialized")
|
self.log.debug("Mine Initialized")
|
||||||
|
|
||||||
flow_initialize_hash = (flow_contract.get_function_by_signature('initialize(address)'))(dummy_market_contract.address).transact(TX_PARAMS)
|
flow_initialize_hash = (flow_contract.get_function_by_signature('initialize(address)'))(dummy_market_contract.address).transact(TX_PARAMS)
|
||||||
self.log.debug("Flow Initialized")
|
self.log.debug("Flow Initialized")
|
||||||
|
|
||||||
self.wait_for_transaction_receipt(w3, flow_initialize_hash)
|
self.wait_for_transaction_receipt(w3, flow_initialize_hash)
|
||||||
self.log.info("All contracts deployed")
|
self.log.info("All contracts deployed")
|
||||||
|
|
||||||
@ -309,22 +318,33 @@ class BlockchainNode(TestNode):
|
|||||||
LIFETIME_MONTH = 1
|
LIFETIME_MONTH = 1
|
||||||
|
|
||||||
self.log.debug("Start deploy contracts")
|
self.log.debug("Start deploy contracts")
|
||||||
|
|
||||||
mine_contract, _ = deploy_contract("PoraMineTest", [0])
|
mine_contract, _ = deploy_contract("PoraMineTest", [0])
|
||||||
self.log.debug("Mine deployed")
|
self.log.debug("Mine deployed")
|
||||||
|
|
||||||
market_contract, _ = deploy_contract("FixedPrice", [])
|
market_contract, _ = deploy_contract("FixedPrice", [])
|
||||||
self.log.debug("Market deployed")
|
self.log.debug("Market deployed")
|
||||||
|
|
||||||
reward_contract, _ =deploy_contract("OnePoolReward", [LIFETIME_MONTH])
|
reward_contract, _ =deploy_contract("OnePoolReward", [LIFETIME_MONTH])
|
||||||
self.log.debug("Reward deployed")
|
self.log.debug("Reward deployed")
|
||||||
|
|
||||||
flow_contract, _ = deploy_contract("FixedPriceFlow", [mine_period, 0])
|
flow_contract, _ = deploy_contract("FixedPriceFlow", [mine_period, 0])
|
||||||
self.log.debug("Flow deployed")
|
self.log.debug("Flow deployed")
|
||||||
mine_contract.functions.initialize(1, 1, flow_contract.address, reward_contract.address).transact(TX_PARAMS)
|
|
||||||
|
mine_contract.functions.initialize(1, flow_contract.address, reward_contract.address).transact(TX_PARAMS)
|
||||||
|
mine_contract.functions.setDifficultyAdjustRatio(1).transact(TX_PARAMS)
|
||||||
|
mine_contract.functions.setTargetSubmissions(2).transact(TX_PARAMS)
|
||||||
self.log.debug("Mine Initialized")
|
self.log.debug("Mine Initialized")
|
||||||
|
|
||||||
market_contract.functions.initialize(LIFETIME_MONTH, flow_contract.address, reward_contract.address).transact(TX_PARAMS)
|
market_contract.functions.initialize(LIFETIME_MONTH, flow_contract.address, reward_contract.address).transact(TX_PARAMS)
|
||||||
self.log.debug("Market Initialized")
|
self.log.debug("Market Initialized")
|
||||||
|
|
||||||
reward_contract.functions.initialize(market_contract.address, mine_contract.address).transact(TX_PARAMS)
|
reward_contract.functions.initialize(market_contract.address, mine_contract.address).transact(TX_PARAMS)
|
||||||
self.log.debug("Reward Initialized")
|
self.log.debug("Reward Initialized")
|
||||||
|
|
||||||
flow_initialize_hash = (flow_contract.get_function_by_signature('initialize(address)'))(market_contract.address).transact(TX_PARAMS)
|
flow_initialize_hash = (flow_contract.get_function_by_signature('initialize(address)'))(market_contract.address).transact(TX_PARAMS)
|
||||||
self.log.debug("Flow Initialized")
|
self.log.debug("Flow Initialized")
|
||||||
|
|
||||||
self.wait_for_transaction_receipt(w3, flow_initialize_hash)
|
self.wait_for_transaction_receipt(w3, flow_initialize_hash)
|
||||||
self.log.info("All contracts deployed")
|
self.log.info("All contracts deployed")
|
||||||
|
|
||||||
|
@ -90,6 +90,9 @@ class MineContractProxy(ContractProxy):
|
|||||||
def last_mined_epoch(self, node_idx=0):
|
def last_mined_epoch(self, node_idx=0):
|
||||||
return self._call("lastMinedEpoch", node_idx)
|
return self._call("lastMinedEpoch", node_idx)
|
||||||
|
|
||||||
|
def can_submit(self, node_idx=0):
|
||||||
|
return self._call("canSubmit", node_idx)
|
||||||
|
|
||||||
def set_quality(self, quality, node_idx=0):
|
def set_quality(self, quality, node_idx=0):
|
||||||
return self._send("setQuality", node_idx, _targetQuality=quality)
|
return self._send("setQuality", node_idx, _targetQuality=quality)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user