Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(coinbase-extra): add coinbase extra field #67

Merged
Merged
Show file tree
Hide file tree
Changes from 4 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
279 changes: 147 additions & 132 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sha_p2pool"
version = "0.1.8"
version = "0.1.9"
edition = "2021"

[dependencies]
Expand All @@ -10,7 +10,6 @@ tari_common_types = { git = "https://github.com/tari-project/tari.git" }
tari_common = { git = "https://github.com/tari-project/tari.git" }
tari_core = { git = "https://github.com/tari-project/tari.git" }
tari_shutdown = { git = "https://github.com/tari-project/tari.git" }

tari_crypto = "0.20.1"
tari_utilities = { version = "0.7", features = ["borsh"] }

Expand Down
23 changes: 19 additions & 4 deletions src/cli/commands/util.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2024 The Tari Project
// SPDX-License-Identifier: BSD-3-Clause

use std::{env, sync::Arc};
use std::{collections::HashMap, env, sync::Arc};

use libp2p::identity::Keypair;
use log::info;
Expand All @@ -12,6 +12,7 @@ use tari_core::{
};
use tari_shutdown::ShutdownSignal;
use tari_utilities::hex::Hex;
use tokio::sync::RwLock;

use crate::{
cli::args::{Cli, StartArgs},
Expand Down Expand Up @@ -99,14 +100,28 @@ genesis_block_hash.to_hex());
consensus_manager.clone(),
genesis_block_hash,
));
let share_chain_sha3x =
InMemoryShareChain::new(MAX_BLOCKS_COUNT, PowAlgorithm::Sha3x, None, consensus_manager.clone())?;
let coinbase_extras = Arc::new(RwLock::new(HashMap::<String, Vec<u8>>::new()));
let share_chain_sha3x = InMemoryShareChain::new(
MAX_BLOCKS_COUNT,
PowAlgorithm::Sha3x,
None,
consensus_manager.clone(),
coinbase_extras.clone(),
)?;
let share_chain_random_x = InMemoryShareChain::new(
MAX_BLOCKS_COUNT,
PowAlgorithm::RandomX,
Some(block_validation_params.clone()),
consensus_manager,
coinbase_extras.clone(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be two different hashmaps

Copy link
Collaborator Author

@ksrichard ksrichard Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, makes sense let me update

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

)?;

Ok(Server::new(config, share_chain_sha3x, share_chain_random_x, shutdown_signal).await?)
Ok(Server::new(
config,
share_chain_sha3x,
share_chain_random_x,
coinbase_extras.clone(),
shutdown_signal,
)
.await?)
}
34 changes: 26 additions & 8 deletions src/server/grpc/p2pool.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2024 The Tari Project
// SPDX-License-Identifier: BSD-3-Clause

use std::{collections::HashMap, sync::Arc, time::Instant};
use std::{collections::HashMap, str::FromStr, sync::Arc, time::Instant};

use log::{debug, error, info, warn};
use minotari_app_grpc::tari_rpc::{
Expand All @@ -16,7 +16,7 @@ use minotari_app_grpc::tari_rpc::{
SubmitBlockResponse,
};
use num_format::{Locale, ToFormattedString};
use tari_common_types::types::FixedHash;
use tari_common_types::{tari_address::TariAddress, types::FixedHash};
use tari_core::{
consensus::ConsensusManager,
proof_of_work::{randomx_difficulty, randomx_factory::RandomXFactory, sha3x_difficulty, Difficulty, PowAlgorithm},
Expand All @@ -37,6 +37,7 @@ use crate::{
P2POOL_STAT_REJECTED_BLOCKS_COUNT,
},
p2p,
p2p::Tribe,
stats_store::StatsStore,
},
sharechain::{block::Block, BlockValidationParams, ShareChain, SHARE_COUNT},
Expand Down Expand Up @@ -77,6 +78,8 @@ where S: ShareChain
stats_max_difficulty_since_last_success: Arc<RwLock<Difficulty>>,
consensus_manager: ConsensusManager,
submit_block_semaphore: Arc<Semaphore>,
tribe: Tribe,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's change this to Squad and replace all instances of tribe with Squad

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

coinbase_extras: Arc<RwLock<HashMap<String, Vec<u8>>>>,
}

impl<S> ShaP2PoolGrpc<S>
Expand All @@ -92,6 +95,8 @@ where S: ShareChain
random_x_factory: RandomXFactory,
consensus_manager: ConsensusManager,
genesis_block_hash: FixedHash,
tribe: Tribe,
coinbase_extras: Arc<RwLock<HashMap<String, Vec<u8>>>>,
) -> Result<Self, Error> {
Ok(Self {
client: Arc::new(RwLock::new(
Expand All @@ -111,6 +116,8 @@ where S: ShareChain
stats_max_difficulty_since_last_success: Arc::new(RwLock::new(Difficulty::min())),
consensus_manager,
submit_block_semaphore: Arc::new(Semaphore::new(1)),
tribe,
coinbase_extras: coinbase_extras.clone(),
})
}

Expand Down Expand Up @@ -158,11 +165,10 @@ where S: ShareChain
request: Request<GetNewBlockRequest>,
) -> Result<Response<GetNewBlockResponse>, Status> {
let timer = Instant::now();
let grpc_req = request.into_inner();

// extract pow algo
let grpc_block_header_pow = request
.into_inner()
.pow
.ok_or(Status::invalid_argument("missing pow in request"))?;
let grpc_block_header_pow = grpc_req.pow.ok_or(Status::invalid_argument("missing pow in request"))?;
let grpc_pow_algo = PowAlgos::from_i32(grpc_block_header_pow.pow_algo)
.ok_or_else(|| Status::internal("invalid block header pow algo in request"))?;
let pow_algo = match grpc_pow_algo {
Expand All @@ -187,12 +193,23 @@ where S: ShareChain
.ok_or_else(|| Status::internal("missing miner data"))?;
// let reward = miner_data.reward;

// update coinbase extras cache
let wallet_payment_address = TariAddress::from_str(grpc_req.wallet_payment_address.as_str())
.map_err(|error| Status::failed_precondition(format!("Invalid wallet payment address: {}", error)))?;
let mut coinbase_extras_lock = self.coinbase_extras.write().await;
coinbase_extras_lock.insert(
wallet_payment_address.to_base58(),
util::convert_coinbase_extra(self.tribe.clone(), grpc_req.coinbase_extra)
.map_err(|error| Status::internal(format!("failed to convert coinbase extra {error:?}")))?,
);
drop(coinbase_extras_lock);

// request new block template with shares as coinbases
let share_chain = match pow_algo {
PowAlgorithm::RandomX => self.share_chain_random_x.clone(),
PowAlgorithm::Sha3x => self.share_chain_sha3x.clone(),
};
let shares = share_chain.generate_shares().await;
let shares = share_chain.generate_shares(self.tribe.clone()).await;

let mut response = self
.client
Expand Down Expand Up @@ -257,6 +274,7 @@ where S: ShareChain
if timer.elapsed() > MAX_ACCEPTABLE_GRPC_TIMEOUT {
warn!(target: LOG_TARGET, "get_new_block took {}ms", timer.elapsed().as_millis());
}

Ok(Response::new(GetNewBlockResponse {
block: Some(response),
target_difficulty: target_difficulty.as_u64(),
Expand Down Expand Up @@ -307,7 +325,7 @@ where S: ShareChain
PowAlgorithm::Sha3x => self.share_chain_sha3x.clone(),
};
let mut block = share_chain
.new_block(grpc_block)
.new_block(grpc_block, self.tribe.clone())
.await
.map_err(|error| Status::internal(error.to_string()))?;

Expand Down
25 changes: 23 additions & 2 deletions src/server/grpc/util.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2024 The Tari Project
// SPDX-License-Identifier: BSD-3-Clause

use std::time::Duration;
use std::{num::TryFromIntError, time::Duration};

use log::error;
use minotari_app_grpc::tari_rpc::base_node_client::BaseNodeClient;
Expand All @@ -10,7 +10,10 @@ use tari_shutdown::ShutdownSignal;
use tokio::select;
use tonic::transport::Channel;

use crate::server::grpc::error::{Error, TonicError};
use crate::server::{
grpc::error::{Error, TonicError},
p2p::Tribe,
};

/// Utility function to connect to a Base node and try infinitely when it fails until gets connected.
pub async fn connect_base_node(
Expand Down Expand Up @@ -49,3 +52,21 @@ pub async fn connect_base_node(

Ok(client)
}

pub fn convert_coinbase_extra(tribe: Tribe, custom_coinbase_extra: String) -> Result<Vec<u8>, TryFromIntError> {
let type_length_value_marker = 0xFFu8;
let tribe_type_marker = 0x02u8;
let custom_message_type_marker = 0x01u8;

let mut current_tribe = tribe.as_string().into_bytes();
let current_tribe_len = u8::try_from(current_tribe.len())?;
let mut result = vec![type_length_value_marker, tribe_type_marker, current_tribe_len];
result.append(&mut current_tribe);

let mut custom_coinbase_extra_bytes = custom_coinbase_extra.into_bytes();
let custom_coinbase_extra_len = u8::try_from(custom_coinbase_extra_bytes.len())?;
ksrichard marked this conversation as resolved.
Show resolved Hide resolved
result.append(&mut vec![custom_message_type_marker, custom_coinbase_extra_len]);
result.append(&mut custom_coinbase_extra_bytes);

Ok(result)
}
35 changes: 23 additions & 12 deletions src/server/http/stats/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,25 @@ pub(crate) async fn handle_miners_with_shares(
let mut result = HashMap::with_capacity(2);
result.insert(
PowAlgorithm::Sha3x.to_string().to_lowercase(),
state.share_chain_sha3x.miners_with_shares().await.map_err(|error| {
error!(target: LOG_TARGET, "Failed to get Sha3x miners with shares: {error:?}");
StatusCode::INTERNAL_SERVER_ERROR
})?,
state
.share_chain_sha3x
.miners_with_shares(state.tribe.clone())
.await
.map_err(|error| {
error!(target: LOG_TARGET, "Failed to get Sha3x miners with shares: {error:?}");
StatusCode::INTERNAL_SERVER_ERROR
})?,
);
result.insert(
PowAlgorithm::RandomX.to_string().to_lowercase(),
state.share_chain_random_x.miners_with_shares().await.map_err(|error| {
error!(target: LOG_TARGET, "Failed to get RandomX miners with shares: {error:?}");
StatusCode::INTERNAL_SERVER_ERROR
})?,
state
.share_chain_random_x
.miners_with_shares(state.tribe.clone())
.await
.map_err(|error| {
error!(target: LOG_TARGET, "Failed to get RandomX miners with shares: {error:?}");
StatusCode::INTERNAL_SERVER_ERROR
})?,
);

if timer.elapsed() > MAX_ACCEPTABLE_HTTP_TIMEOUT {
Expand Down Expand Up @@ -140,10 +148,13 @@ async fn get_stats(state: AppState, algo: PowAlgorithm) -> Result<Stats, StatusC
// connected
let connected = state.peer_store.peer_count().await > 0;

let shares = share_chain.miners_with_shares().await.map_err(|error| {
error!(target: LOG_TARGET, "Failed to get miners with shares: {error:?}");
StatusCode::INTERNAL_SERVER_ERROR
})?;
let shares = share_chain
.miners_with_shares(state.tribe.clone())
.await
.map_err(|error| {
error!(target: LOG_TARGET, "Failed to get miners with shares: {error:?}");
StatusCode::INTERNAL_SERVER_ERROR
})?;
// collect number of miners
// let num_of_miners = chain
// .iter()
Expand Down
4 changes: 4 additions & 0 deletions src/server/p2p/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ impl Tribe {
pub fn formatted(&self) -> String {
self.inner.to_case(Case::Lower).replace("_", " ").to_case(Case::Title)
}

pub fn as_string(&self) -> String {
self.inner.to_case(Case::Lower)
}
}

impl ToValue for Tribe {
Expand Down
5 changes: 5 additions & 0 deletions src/server/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: BSD-3-Clause

use std::{
collections::HashMap,
net::{AddrParseError, SocketAddr},
str::FromStr,
sync::{atomic::AtomicBool, Arc},
Expand All @@ -13,6 +14,7 @@ use tari_common::configuration::Network;
use tari_core::{consensus::ConsensusManager, proof_of_work::randomx_factory::RandomXFactory};
use tari_shutdown::ShutdownSignal;
use thiserror::Error;
use tokio::sync::RwLock;

use crate::{
server::{
Expand Down Expand Up @@ -60,6 +62,7 @@ where S: ShareChain
config: config::Config,
share_chain_sha3x: S,
share_chain_random_x: S,
coinbase_extras: Arc<RwLock<HashMap<String, Vec<u8>>>>,
shutdown_signal: ShutdownSignal,
) -> Result<Self, Error> {
let share_chain_sha3x = Arc::new(share_chain_sha3x);
Expand Down Expand Up @@ -103,6 +106,8 @@ where S: ShareChain
randomx_factory,
consensus_manager,
genesis_block_hash,
config.p2p_service.tribe.clone(),
coinbase_extras.clone(),
)
.await
.map_err(Error::Grpc)?;
Expand Down
7 changes: 7 additions & 0 deletions src/sharechain/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub(crate) struct Block {
pub miner_wallet_address: Option<TariAddress>,
pub sent_to_main_chain: bool,
pub achieved_difficulty: Difficulty,
pub miner_coinbase_extra: Vec<u8>,
}
impl_conversions!(Block);

Expand Down Expand Up @@ -76,6 +77,7 @@ impl BlockBuilder {
miner_wallet_address: Default::default(),
sent_to_main_chain: false,
achieved_difficulty: Difficulty::min(),
miner_coinbase_extra: vec![],
},
}
}
Expand All @@ -100,6 +102,11 @@ impl BlockBuilder {
self
}

pub fn with_miner_coinbase_extra(&mut self, coinbase_extra: Vec<u8>) -> &mut Self {
self.block.miner_coinbase_extra = coinbase_extra;
self
}

pub fn with_miner_wallet_address(&mut self, miner_wallet_address: TariAddress) -> &mut Self {
self.block.miner_wallet_address = Some(miner_wallet_address);
self
Expand Down
Loading
Loading