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

fix/testnet #2557

Merged
merged 5 commits into from
Dec 16, 2024
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
91 changes: 42 additions & 49 deletions data_structures/src/superblock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,69 +441,62 @@ impl SuperBlockState {

self.update_ars_identities(ars_identities);

// During synchronization we use the superblock received as consensus by our outbounds
// to have the right value of the signing committee size. From now on, we have all the values
// to construct our own superblocks.
let superblock = if let Some(sb) = sync_superblock {
// Before updating the superblock_beacon, calculate the signing committee
let signing_committee = calculate_superblock_signing_committee(
// Before updating the superblock_beacon, calculate the signing committee
let signing_committee = if let Some(ref sb) = sync_superblock {
calculate_superblock_signing_committee(
self.ars_previous_identities.clone(),
sb.signing_committee_length,
superblock_index,
self.current_superblock_beacon.hash_prev_block,
block_epoch,
);

// Override superblock signing committee during each of the different emergency periods
self.signing_committee =
if let Some(ars_ids) = in_emergency_period(superblock_index, get_environment()) {
ars_ids.into_iter().collect()
} else {
signing_committee
};

// Override superblock signing committee during the bootstrapping of wit/2
self.signing_committee = match get_environment() {
Environment::Mainnet => {
// wit/2 activates at 2_922_240 + 14 x 1_920 (TAPI delay) + 7 x 1_920 (instant activation delay) = 2_962_560
// disabling the activation committee at 299_712 implies we add an extra 8 weeks worth of time (8 x 4320)
// to inplement a decentralized superblock committee selection mechanism. Note that any delay in activating
// wit/2 will essentially be subtracted from the extra 8 weeks,
if (292_224..299_712).contains(&superblock_index) {
WIT2_BOOTSTRAP_COMMITTEE
.iter()
.map(|address| address.parse().expect("Malformed signing committee"))
.collect()
} else {
self.signing_committee.clone()
}
}
Environment::Testnet => WIT2_BOOTSTRAP_COMMITTEE_TEST
.iter()
.map(|address| address.parse().expect("Malformed signing committee"))
.collect(),
_ => self.signing_committee.clone(),
};

sb
)
} else {
// Before updating the superblock_beacon, calculate the signing committee
let signing_committee = calculate_superblock_signing_committee(
calculate_superblock_signing_committee(
self.ars_previous_identities.clone(),
signing_committee_size,
superblock_index,
self.current_superblock_beacon.hash_prev_block,
block_epoch,
);
)
};

// Override superblock signing committee during each of the different emergency periods
let emergency_committee =
if let Some(ars_ids) = in_emergency_period(superblock_index, get_environment()) {
ars_ids.into_iter().collect()
} else {
signing_committee
};

// Override superblock signing committee during each of the different emergency periods
self.signing_committee =
if let Some(ars_ids) = in_emergency_period(superblock_index, get_environment()) {
ars_ids.into_iter().collect()
// Override superblock signing committee during the bootstrapping of wit/2
self.signing_committee = match get_environment() {
Environment::Mainnet => {
// wit/2 activates at 2_922_240 + 14 x 1_920 (TAPI delay) + 7 x 1_920 (instant activation delay) = 2_962_560
// disabling the activation committee at 299_712 implies we add an extra 8 weeks worth of time (8 x 4320)
// to inplement a decentralized superblock committee selection mechanism. Note that any delay in activating
// wit/2 will essentially be subtracted from the extra 8 weeks,
if (292_224..299_712).contains(&superblock_index) {
WIT2_BOOTSTRAP_COMMITTEE
.iter()
.map(|address| address.parse().expect("Malformed signing committee"))
.collect()
} else {
signing_committee
};
emergency_committee
}
}
Environment::Testnet => WIT2_BOOTSTRAP_COMMITTEE_TEST
.iter()
.map(|address| address.parse().expect("Malformed signing committee"))
.collect(),
_ => emergency_committee,
};

// During synchronization we use the superblock received as consensus by our outbounds
// to have the right value of the signing committee size. From now on, we have all the values
// to construct our own superblocks.
let superblock = if let Some(sb) = sync_superblock {
sb
} else {
mining_build_superblock(
block_headers,
&key_leaves,
Expand Down
41 changes: 33 additions & 8 deletions node/src/actors/chain_manager/mining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use witnet_data_structures::{
chain::{
tapi::{after_second_hard_fork, ActiveWips},
Block, BlockHeader, BlockMerkleRoots, BlockTransactions, Bn256PublicKey, CheckpointBeacon,
CheckpointVRF, ConsensusConstantsWit2, DataRequestOutput, EpochConstants, Hash, Hashable,
Input, PublicKeyHash, RADTally, TransactionsPool, ValueTransferOutput,
CheckpointVRF, ConsensusConstantsWit2, DataRequestOutput, DataRequestStage, EpochConstants,
Hash, Hashable, Input, PublicKeyHash, RADTally, TransactionsPool, ValueTransferOutput,
},
data_request::{
calculate_witness_reward, calculate_witness_reward_before_second_hard_fork, create_tally,
Expand Down Expand Up @@ -358,6 +358,18 @@ impl ChainManager {
.data_request_state(&dr_pointer)
.map(|dr_state| (dr_pointer, dr_state.clone()))
}) {
// It's possible a data request requesting too many witnesses are in our local data
// request pool (e.g., when we failed to validate a proposed block). Do not attempt
// to solve this data request.
let validator_count = self.chain_state.stakes.validator_count();
if data_request_has_too_many_witnesses(
&dr_state.data_request,
validator_count,
Some(current_epoch),
) {
continue;
}

let (checkpoint_period, max_rounds) = match &self.chain_state.chain_info {
Some(x) => (
// Unwraps should be safe if we have a chain_info object
Expand Down Expand Up @@ -1097,12 +1109,25 @@ pub fn build_block(
checkpoint_zero_timestamp,
);

// Number of data request witnesses should be at most the number of validators divided by four
if data_request_has_too_many_witnesses(
&dr_tx.body.dr_output,
validator_count,
Some(epoch),
) {
// Check the current data request state
// If his data request was already included in a previous local block which was not consolidated
// we will have set the state to TALLY already. In the current block, we will already have built
// a tally transaction using the normal flow and we do not want to include it a second time here.
let data_request_not_in_tally_stage =
if let Some(dr_state) = dr_pool.data_request_state(&dr_tx.hash()) {
dr_state.stage != DataRequestStage::TALLY
} else {
true
};
// Number of data request witnesses is limited by a fraction of the number of validators
// If the requested witnesses exceed this fraction, resolve the data request with an error
if data_request_not_in_tally_stage
&& data_request_has_too_many_witnesses(
&dr_tx.body.dr_output,
validator_count,
Some(epoch),
)
{
log::debug!("Data request {} has too many witnesses", dr_tx.hash());

// Temporarily insert the data request into the dr_pool
Expand Down
32 changes: 25 additions & 7 deletions src/cli/node/json_rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use witnet_data_structures::{
SupplyInfo, SyncStatus, ValueTransferOutput,
},
fee::Fee,
get_environment,
get_environment, get_protocol_version,
proto::{
versioning::{ProtocolInfo, ProtocolVersion},
ProtobufConvert,
Expand Down Expand Up @@ -1328,6 +1328,7 @@ pub fn data_request_report(
let response = send_request(&mut stream, &request)?;
let transaction: GetTransactionOutput = parse_response(&response)?;

let data_request_transaction_epoch = transaction.block_epoch.clone();
let data_request_transaction_block_hash = transaction.block_hash.clone();
let transaction_block_hash = if transaction.block_hash == "pending" {
None
Expand All @@ -1340,6 +1341,19 @@ pub fn data_request_report(
bail!("This is not a data request transaction");
};

let request = r#"{"jsonrpc": "2.0","method": "protocol", "id": "1"}"#;
let response = send_request(&mut stream, request)?;
let protocol_info: Option<ProtocolInfo> = parse_response(&response)?;

let version_at_epoch = if let Some(info) = protocol_info {
match data_request_transaction_epoch {
Some(epoch) => info.all_versions.version_for_epoch(epoch),
None => ProtocolVersion::default(),
}
} else {
ProtocolVersion::default()
};

let mut dr_output = dr_tx.body.dr_output;
let dr_creator_pkh = dr_tx.signatures[0].public_key.pkh();

Expand Down Expand Up @@ -1448,12 +1462,16 @@ pub fn data_request_report(
{
format!("-{}", dr_output.collateral)
} else {
let reward = tally
.outputs
.iter()
.find(|vto| vto.pkh == pkh)
.map(|vto| vto.value)
.unwrap();
let reward = if version_at_epoch >= ProtocolVersion::V2_0 {
dr_output.witness_reward + dr_output.collateral
} else {
tally
.outputs
.iter()
.find(|vto| vto.pkh == pkh)
.map(|vto| vto.value)
.unwrap()
};

let reward = reward - dr_output.collateral;

Expand Down
13 changes: 11 additions & 2 deletions validations/src/validations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2157,6 +2157,7 @@ pub fn validate_block_transactions(
}

let mut dr_weight: u32 = 0;
let mut too_many_witnesses_drs = HashSet::<Hash>::new();
if active_wips.wip_0008() {
// Calculate data request not solved weight
let mut dr_pointers: HashSet<Hash> = dr_pool
Expand All @@ -2172,6 +2173,10 @@ pub fn validate_block_transactions(
dr_weight = dr_weight
.saturating_add(dro.weight())
.saturating_add(dro.extra_weight());

if data_request_has_too_many_witnesses(&dro, stakes.validator_count(), Some(epoch)) {
too_many_witnesses_drs.insert(dr);
}
}
}
}
Expand Down Expand Up @@ -2209,9 +2214,13 @@ pub fn validate_block_transactions(
let Hash::SHA256(sha) = txn_hash;
dr_mt.push(Sha256(sha));

// Update dr weight
// Update dr weight, but prevent double counting data requests with too many witnesses
let weight = transaction.weight();
let acc_weight = dr_weight.saturating_add(weight);
let acc_weight = if too_many_witnesses_drs.contains(&txn_hash) {
dr_weight
} else {
dr_weight.saturating_add(weight)
};
if acc_weight > consensus_constants.max_dr_weight {
return Err(BlockError::TotalDataRequestWeightLimitExceeded {
weight: acc_weight,
Expand Down
Loading