Skip to content

Commit aef46bc

Browse files
MitchTurnerxgreenxAurelienFT
authored
Add preconfirmation signature verification to tx status manager (#2856)
## Linked Issues/PRs <!-- List of related issues/PRs --> Closes #2823 ## Description <!-- List of detailed changes --> Adds generic logic to the tx status manager task to accept delegate keys and check signatures with them. The logic of actually tracking the delegate keys and doing verification is behind the `SignatureVerification` trait, which will be implemented in a follow-up PR. ## Checklist - [x] New behavior is reflected in tests ### Before requesting review - [ ] I have reviewed the code myself --------- Co-authored-by: Green Baneling <[email protected]> Co-authored-by: AurelienFT <[email protected]>
1 parent b759e4d commit aef46bc

File tree

12 files changed

+729
-56
lines changed

12 files changed

+729
-56
lines changed

.changes/added/2856.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add generic logic for managing the signatures and delegate keys for pre-confirmations signatures

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/chain-config/src/config/consensus.rs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,17 @@ pub struct PoAV2 {
3737

3838
impl PoAV2 {
3939
pub fn new(
40-
genesis_signing_key: Address,
41-
signing_key_overrides: BTreeMap<BlockHeight, Address>,
40+
genesis_signing_key_address: Address,
41+
signing_key_address_overrides: BTreeMap<BlockHeight, Address>,
4242
) -> Self {
4343
PoAV2 {
44-
genesis_signing_key,
45-
signing_key_overrides,
44+
genesis_signing_key: genesis_signing_key_address,
45+
signing_key_overrides: signing_key_address_overrides,
4646
}
4747
}
4848

49-
/// Returns the signing key for the given block height.
50-
pub fn signing_key_at(&self, height: BlockHeight) -> Address {
49+
/// Returns the address for the signing key at block height.
50+
pub fn address_for_height(&self, height: BlockHeight) -> Address {
5151
if self.signing_key_overrides.is_empty() {
5252
self.genesis_signing_key
5353
} else {
@@ -60,6 +60,15 @@ impl PoAV2 {
6060
}
6161
}
6262

63+
/// Returns the address of the latest signing key for the given block height.
64+
pub fn latest_address(&self) -> Address {
65+
self.signing_key_overrides
66+
.last_key_value()
67+
.map(|(_, key)| key)
68+
.cloned()
69+
.unwrap_or(self.genesis_signing_key)
70+
}
71+
6372
/// Returns overrides for all the signing keys.
6473
pub fn get_all_overrides(&self) -> &BTreeMap<BlockHeight, Address> {
6574
&self.signing_key_overrides
@@ -73,10 +82,12 @@ impl PoAV2 {
7382

7483
#[cfg(test)]
7584
mod tests {
85+
#![allow(non_snake_case)]
86+
7687
use super::*;
7788

7889
#[test]
79-
fn signing_key_at_works() {
90+
fn address_at_height__returns_expected_values() {
8091
// Given
8192
let genesis_signing_key = Address::from([1; 32]);
8293
let signing_key_after_10 = Address::from([2; 32]);
@@ -95,16 +106,16 @@ mod tests {
95106
};
96107

97108
// When/Then
98-
assert_eq!(poa.signing_key_at(0u32.into()), genesis_signing_key);
99-
assert_eq!(poa.signing_key_at(9u32.into()), genesis_signing_key);
100-
assert_eq!(poa.signing_key_at(10u32.into()), signing_key_after_10);
101-
assert_eq!(poa.signing_key_at(19u32.into()), signing_key_after_10);
102-
assert_eq!(poa.signing_key_at(20u32.into()), signing_key_after_20);
103-
assert_eq!(poa.signing_key_at(29u32.into()), signing_key_after_20);
104-
assert_eq!(poa.signing_key_at(30u32.into()), signing_key_after_30);
105-
assert_eq!(poa.signing_key_at(40u32.into()), signing_key_after_30);
109+
assert_eq!(poa.address_for_height(0u32.into()), genesis_signing_key);
110+
assert_eq!(poa.address_for_height(9u32.into()), genesis_signing_key);
111+
assert_eq!(poa.address_for_height(10u32.into()), signing_key_after_10);
112+
assert_eq!(poa.address_for_height(19u32.into()), signing_key_after_10);
113+
assert_eq!(poa.address_for_height(20u32.into()), signing_key_after_20);
114+
assert_eq!(poa.address_for_height(29u32.into()), signing_key_after_20);
115+
assert_eq!(poa.address_for_height(30u32.into()), signing_key_after_30);
116+
assert_eq!(poa.address_for_height(40u32.into()), signing_key_after_30);
106117
assert_eq!(
107-
poa.signing_key_at(4_000_000u32.into()),
118+
poa.address_for_height(4_000_000u32.into()),
108119
signing_key_after_30
109120
);
110121
}

crates/fuel-core/src/service/adapters/tx_status_manager.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
use fuel_core_services::stream::BoxStream;
2-
use fuel_core_tx_status_manager::ports::P2PPreConfirmationGossipData;
3-
41
use super::P2PAdapter;
2+
use fuel_core_chain_config::ConsensusConfig;
3+
use fuel_core_services::stream::BoxStream;
4+
use fuel_core_tx_status_manager::{
5+
ports::P2PPreConfirmationGossipData,
6+
service::ProtocolPublicKey,
7+
};
8+
use fuel_core_types::fuel_tx::Address;
59

610
#[cfg(feature = "p2p")]
711
impl fuel_core_tx_status_manager::ports::P2PSubscriptions for P2PAdapter {
@@ -32,3 +36,22 @@ impl fuel_core_tx_status_manager::ports::P2PSubscriptions for P2PAdapter {
3236
Box::pin(fuel_core_services::stream::pending())
3337
}
3438
}
39+
40+
pub struct ConsensusConfigProtocolPublicKey {
41+
inner: ConsensusConfig,
42+
}
43+
44+
impl ConsensusConfigProtocolPublicKey {
45+
pub fn new(inner: ConsensusConfig) -> Self {
46+
Self { inner }
47+
}
48+
}
49+
50+
impl ProtocolPublicKey for ConsensusConfigProtocolPublicKey {
51+
fn latest_address(&self) -> Address {
52+
match &self.inner {
53+
ConsensusConfig::PoA { signing_key } => *signing_key,
54+
ConsensusConfig::PoAV2(poa_v2) => poa_v2.latest_address(),
55+
}
56+
}
57+
}

crates/fuel-core/src/service/sub_services.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ use crate::service::adapters::consensus_module::poa::pre_confirmation_signature:
4141
tx_receiver::PreconfirmationsReceiver,
4242
};
4343

44+
use super::{
45+
adapters::{
46+
FuelBlockSigner,
47+
P2PAdapter,
48+
TxStatusManagerAdapter,
49+
},
50+
genesis::create_genesis_block,
51+
DbType,
52+
};
4453
use crate::{
4554
combined_database::CombinedDatabase,
4655
database::Database,
@@ -58,6 +67,7 @@ use crate::{
5867
graphql_api::GraphQLBlockImporter,
5968
import_result_provider::ImportResultProvider,
6069
ready_signal::ReadySignal,
70+
tx_status_manager::ConsensusConfigProtocolPublicKey,
6171
BlockImporterAdapter,
6272
BlockProducerAdapter,
6373
ChainStateInfoProvider,
@@ -76,16 +86,6 @@ use crate::{
7686
},
7787
};
7888

79-
use super::{
80-
adapters::{
81-
FuelBlockSigner,
82-
P2PAdapter,
83-
TxStatusManagerAdapter,
84-
},
85-
genesis::create_genesis_block,
86-
DbType,
87-
};
88-
8989
pub type PoAService = fuel_core_poa::Service<
9090
TxPoolAdapter,
9191
BlockProducerAdapter,
@@ -257,9 +257,13 @@ pub fn init_sub_services(
257257
universal_gas_price_provider.clone(),
258258
);
259259

260+
let protocol_pubkey =
261+
ConsensusConfigProtocolPublicKey::new(chain_config.consensus.clone());
262+
260263
let tx_status_manager = fuel_core_tx_status_manager::new_service(
261264
p2p_adapter.clone(),
262265
config.tx_status_manager.clone(),
266+
protocol_pubkey,
263267
);
264268
let tx_status_manager_adapter =
265269
TxStatusManagerAdapter::new(tx_status_manager.shared.clone());

crates/services/consensus_module/poa/src/verifier.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub fn verify_consensus(
3131
ConsensusConfig::PoAV2(poa) => {
3232
let id = header.id();
3333
let m = id.as_message();
34-
let signing_key = poa.signing_key_at(*header.height());
34+
let signing_key = poa.address_for_height(*header.height());
3535
consensus
3636
.signature
3737
.recover(m)

crates/services/tx_status_manager/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ async-trait = { workspace = true }
1414
derive_more = { workspace = true }
1515
fuel-core-metrics = { workspace = true }
1616
fuel-core-services = { workspace = true }
17-
fuel-core-types = { workspace = true, features = ["std"] }
17+
fuel-core-types = { workspace = true, features = ["std", "serde"] }
1818
futures = { workspace = true }
1919
parking_lot = { workspace = true }
20+
postcard = { workspace = true }
2021
tokio = { workspace = true }
2122
tokio-stream = { workspace = true }
2223
tracing = { workspace = true }

crates/services/tx_status_manager/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub mod config;
99
mod error;
1010
mod manager;
1111
pub mod ports;
12-
mod service;
12+
pub mod service;
1313
mod subscriptions;
1414
mod tx_status_stream;
1515
mod update_sender;

0 commit comments

Comments
 (0)