Update serai-coordinator-cosign to the new serai-client-serai

This commit is contained in:
Luke Parker
2025-11-15 16:10:25 -05:00
parent 609cf06393
commit 3cfbd9add7
6 changed files with 48 additions and 19 deletions

View File

@@ -22,6 +22,7 @@ blake2 = { version = "0.11.0-rc.0", default-features = false, features = ["alloc
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] } borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
serai-abi = { path = "../../substrate/abi", default-features = false, features = ["std"] } serai-abi = { path = "../../substrate/abi", default-features = false, features = ["std"] }
serai-client-serai = { path = "../../substrate/client/serai", default-features = false }
log = { version = "0.4", default-features = false, features = ["std"] } log = { version = "0.4", default-features = false, features = ["std"] }

View File

@@ -1,10 +1,13 @@
use core::future::Future; use core::future::Future;
use std::{sync::Arc, collections::HashMap}; use std::{sync::Arc, collections::HashMap};
use blake2::{Digest, Blake2b256};
use serai_abi::primitives::{ use serai_abi::primitives::{
balance::Amount, validator_sets::ExternalValidatorSet, address::SeraiAddress, balance::Amount, validator_sets::ExternalValidatorSet, address::SeraiAddress,
merkle::IncrementalUnbalancedMerkleTree,
}; };
use serai_client::Serai; use serai_client_serai::Serai;
use serai_db::*; use serai_db::*;
use serai_task::ContinuallyRan; use serai_task::ContinuallyRan;
@@ -14,6 +17,7 @@ use crate::*;
create_db!( create_db!(
CosignIntend { CosignIntend {
ScanCosignFrom: () -> u64, ScanCosignFrom: () -> u64,
BuildsUpon: () -> IncrementalUnbalancedMerkleTree,
} }
); );
@@ -40,9 +44,9 @@ async fn block_has_events_justifying_a_cosign(
.await .await
.map_err(|e| format!("{e:?}"))? .map_err(|e| format!("{e:?}"))?
.ok_or_else(|| "couldn't get block which should've been finalized".to_string())?; .ok_or_else(|| "couldn't get block which should've been finalized".to_string())?;
let serai = serai.as_of(block.hash()); let serai = serai.as_of(block.header.hash()).await.map_err(|e| format!("{e:?}"))?;
if !serai.validator_sets().key_gen_events().await.map_err(|e| format!("{e:?}"))?.is_empty() { if !serai.validator_sets().set_keys_events().await.map_err(|e| format!("{e:?}"))?.is_empty() {
return Ok((block, HasEvents::Notable)); return Ok((block, HasEvents::Notable));
} }
@@ -66,7 +70,7 @@ impl<D: Db> ContinuallyRan for CosignIntendTask<D> {
async move { async move {
let start_block_number = ScanCosignFrom::get(&self.db).unwrap_or(1); let start_block_number = ScanCosignFrom::get(&self.db).unwrap_or(1);
let latest_block_number = let latest_block_number =
self.serai.latest_finalized_block_number().await.map_err(|e| format!("{e:?}"))?.number(); self.serai.latest_finalized_block_number().await.map_err(|e| format!("{e:?}"))?;
for block_number in start_block_number ..= latest_block_number { for block_number in start_block_number ..= latest_block_number {
let mut txn = self.db.txn(); let mut txn = self.db.txn();
@@ -76,26 +80,35 @@ impl<D: Db> ContinuallyRan for CosignIntendTask<D> {
.await .await
.map_err(|e| format!("{e:?}"))?; .map_err(|e| format!("{e:?}"))?;
let mut builds_upon =
BuildsUpon::get(&txn).unwrap_or(IncrementalUnbalancedMerkleTree::new());
// Check we are indexing a linear chain // Check we are indexing a linear chain
if (block_number > 1) && if block.header.builds_upon() !=
(<[u8; 32]>::from(block.header.parent_hash) != builds_upon.clone().calculate(serai_abi::BLOCK_HEADER_BRANCH_TAG)
SubstrateBlockHash::get(&txn, block_number - 1)
.expect("indexing a block but haven't indexed its parent"))
{ {
Err(format!( Err(format!(
"node's block #{block_number} doesn't build upon the block #{} prior indexed", "node's block #{block_number} doesn't build upon the block #{} prior indexed",
block_number - 1 block_number - 1
))?; ))?;
} }
let block_hash = block.hash(); let block_hash = block.header.hash();
SubstrateBlockHash::set(&mut txn, block_number, &block_hash); SubstrateBlockHash::set(&mut txn, block_number, &block_hash);
builds_upon.append(
serai_abi::BLOCK_HEADER_BRANCH_TAG,
Blake2b256::new_with_prefix([serai_abi::BLOCK_HEADER_LEAF_TAG])
.chain_update(block_hash.0)
.finalize()
.into(),
);
BuildsUpon::set(&mut txn, &builds_upon);
let global_session_for_this_block = LatestGlobalSessionIntended::get(&txn); let global_session_for_this_block = LatestGlobalSessionIntended::get(&txn);
// If this is notable, it creates a new global session, which we index into the database // If this is notable, it creates a new global session, which we index into the database
// now // now
if has_events == HasEvents::Notable { if has_events == HasEvents::Notable {
let serai = self.serai.as_of(block_hash); let serai = self.serai.as_of(block_hash).await.map_err(|e| format!("{e:?}"))?;
let sets_and_keys = cosigning_sets(&serai).await?; let sets_and_keys = cosigning_sets(&serai).await?;
let global_session = let global_session =
GlobalSession::id(sets_and_keys.iter().map(|(set, _key)| *set).collect()); GlobalSession::id(sets_and_keys.iter().map(|(set, _key)| *set).collect());
@@ -109,7 +122,7 @@ impl<D: Db> ContinuallyRan for CosignIntendTask<D> {
keys.insert(set.network, SeraiAddress::from(*key)); keys.insert(set.network, SeraiAddress::from(*key));
let stake = serai let stake = serai
.validator_sets() .validator_sets()
.total_allocated_stake(set.network.into()) .current_stake(set.network.into())
.await .await
.map_err(|e| format!("{e:?}"))? .map_err(|e| format!("{e:?}"))?
.unwrap_or(Amount(0)) .unwrap_or(Amount(0))

View File

@@ -11,6 +11,7 @@ use borsh::{BorshSerialize, BorshDeserialize};
use serai_abi::{ use serai_abi::{
primitives::{ primitives::{
BlockHash,
crypto::{Public, KeyPair}, crypto::{Public, KeyPair},
network_id::ExternalNetworkId, network_id::ExternalNetworkId,
validator_sets::{Session, ExternalValidatorSet}, validator_sets::{Session, ExternalValidatorSet},
@@ -18,7 +19,7 @@ use serai_abi::{
}, },
Block, Block,
}; };
use serai_client::{Serai, TemporalSerai}; use serai_client_serai::{Serai, TemporalSerai};
use serai_db::*; use serai_db::*;
use serai_task::*; use serai_task::*;
@@ -86,7 +87,7 @@ create_db! {
// The following are populated by the intend task and used throughout the library // The following are populated by the intend task and used throughout the library
// An index of Substrate blocks // An index of Substrate blocks
SubstrateBlockHash: (block_number: u64) -> [u8; 32], SubstrateBlockHash: (block_number: u64) -> BlockHash,
// A mapping from a global session's ID to its relevant information. // A mapping from a global session's ID to its relevant information.
GlobalSessions: (global_session: [u8; 32]) -> GlobalSession, GlobalSessions: (global_session: [u8; 32]) -> GlobalSession,
// The last block to be cosigned by a global session. // The last block to be cosigned by a global session.
@@ -124,7 +125,7 @@ async fn keys_for_network(
network: ExternalNetworkId, network: ExternalNetworkId,
) -> Result<Option<(Session, KeyPair)>, String> { ) -> Result<Option<(Session, KeyPair)>, String> {
let Some(latest_session) = let Some(latest_session) =
serai.validator_sets().session(network.into()).await.map_err(|e| format!("{e:?}"))? serai.validator_sets().current_session(network.into()).await.map_err(|e| format!("{e:?}"))?
else { else {
// If this network hasn't had a session declared, move on // If this network hasn't had a session declared, move on
return Ok(None); return Ok(None);
@@ -272,7 +273,10 @@ impl<D: Db> Cosigning<D> {
} }
/// Fetch a cosigned Substrate block's hash by its block number. /// Fetch a cosigned Substrate block's hash by its block number.
pub fn cosigned_block(getter: &impl Get, block_number: u64) -> Result<Option<[u8; 32]>, Faulted> { pub fn cosigned_block(
getter: &impl Get,
block_number: u64,
) -> Result<Option<BlockHash>, Faulted> {
if block_number > Self::latest_cosigned_block_number(getter)? { if block_number > Self::latest_cosigned_block_number(getter)? {
return Ok(None); return Ok(None);
} }

View File

@@ -3,7 +3,7 @@
//! Types used when cosigning Serai. For more info, please see `serai-cosign`. //! Types used when cosigning Serai. For more info, please see `serai-cosign`.
use borsh::{BorshSerialize, BorshDeserialize}; use borsh::{BorshSerialize, BorshDeserialize};
use serai_primitives::{crypto::Public, network_id::ExternalNetworkId}; use serai_primitives::{BlockHash, crypto::Public, network_id::ExternalNetworkId};
/// The schnorrkel context to used when signing a cosign. /// The schnorrkel context to used when signing a cosign.
pub const COSIGN_CONTEXT: &[u8] = b"/serai/coordinator/cosign"; pub const COSIGN_CONTEXT: &[u8] = b"/serai/coordinator/cosign";
@@ -16,7 +16,7 @@ pub struct CosignIntent {
/// The number of the block to cosign. /// The number of the block to cosign.
pub block_number: u64, pub block_number: u64,
/// The hash of the block to cosign. /// The hash of the block to cosign.
pub block_hash: [u8; 32], pub block_hash: BlockHash,
/// If this cosign must be handled before further cosigns are. /// If this cosign must be handled before further cosigns are.
pub notable: bool, pub notable: bool,
} }
@@ -29,7 +29,7 @@ pub struct Cosign {
/// The number of the block to cosign. /// The number of the block to cosign.
pub block_number: u64, pub block_number: u64,
/// The hash of the block to cosign. /// The hash of the block to cosign.
pub block_hash: [u8; 32], pub block_hash: BlockHash,
/// The actual cosigner. /// The actual cosigner.
pub cosigner: ExternalNetworkId, pub cosigner: ExternalNetworkId,
} }

View File

@@ -65,6 +65,17 @@ impl From<SeraiAddress> for Public {
} }
} }
impl From<crate::crypto::Public> for SeraiAddress {
fn from(key: crate::crypto::Public) -> Self {
Public::from(key).into()
}
}
impl From<SeraiAddress> for crate::crypto::Public {
fn from(address: SeraiAddress) -> Self {
Public::from(address).into()
}
}
// We use Bech32m to encode addresses // We use Bech32m to encode addresses
impl core::fmt::Display for SeraiAddress { impl core::fmt::Display for SeraiAddress {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {

View File

@@ -73,7 +73,7 @@ impl UnbalancedMerkleTree {
} }
/// An unbalanced Merkle tree which is incrementally created. /// An unbalanced Merkle tree which is incrementally created.
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
#[cfg_attr( #[cfg_attr(
feature = "non_canonical_scale_derivations", feature = "non_canonical_scale_derivations",
derive(scale::Encode, scale::Decode, scale::DecodeWithMemTracking) derive(scale::Encode, scale::Decode, scale::DecodeWithMemTracking)