Spawn PublishSlashReportTask

Updates it so that it'll try for every network instead of returning after any
network fails.

Uses the SlashReport type throughout the codebase.
This commit is contained in:
Luke Parker
2025-01-15 12:08:28 -05:00
parent 92a4cceeeb
commit 7312fa8d3c
10 changed files with 132 additions and 101 deletions

View File

@@ -21,7 +21,7 @@ pub enum Call {
},
report_slashes {
network: NetworkId,
slashes: BoundedVec<(SeraiAddress, u32), ConstU32<{ MAX_KEY_SHARES_PER_SET_U32 / 3 }>>,
slashes: SlashReport,
signature: Signature,
},
allocate {

View File

@@ -5,10 +5,10 @@ use sp_runtime::BoundedVec;
use serai_abi::primitives::Amount;
pub use serai_abi::validator_sets::primitives;
use primitives::{MAX_KEY_LEN, Session, ValidatorSet, KeyPair};
use primitives::{MAX_KEY_LEN, Session, ValidatorSet, KeyPair, SlashReport};
use crate::{
primitives::{EmbeddedEllipticCurve, NetworkId, SeraiAddress},
primitives::{EmbeddedEllipticCurve, NetworkId},
Transaction, Serai, TemporalSerai, SeraiError,
};
@@ -238,12 +238,7 @@ impl<'a> SeraiValidatorSets<'a> {
pub fn report_slashes(
network: NetworkId,
// TODO: This bounds a maximum length but takes more space than just publishing all the u32s
// (50 * (32 + 4)) > (150 * 4)
slashes: sp_runtime::BoundedVec<
(SeraiAddress, u32),
sp_core::ConstU32<{ primitives::MAX_KEY_SHARES_PER_SET_U32 / 3 }>,
>,
slashes: SlashReport,
signature: Signature,
) -> Transaction {
Serai::unsigned(serai_abi::Call::ValidatorSets(

View File

@@ -111,13 +111,7 @@ impl From<Call> for RuntimeCall {
serai_abi::validator_sets::Call::report_slashes { network, slashes, signature } => {
RuntimeCall::ValidatorSets(validator_sets::Call::report_slashes {
network,
slashes: <_>::try_from(
slashes
.into_iter()
.map(|(addr, slash)| (PublicKey::from(addr), slash))
.collect::<Vec<_>>(),
)
.unwrap(),
slashes,
signature,
})
}
@@ -301,17 +295,7 @@ impl TryInto<Call> for RuntimeCall {
}
}
validator_sets::Call::report_slashes { network, slashes, signature } => {
serai_abi::validator_sets::Call::report_slashes {
network,
slashes: <_>::try_from(
slashes
.into_iter()
.map(|(addr, slash)| (SeraiAddress::from(addr), slash))
.collect::<Vec<_>>(),
)
.unwrap(),
signature,
}
serai_abi::validator_sets::Call::report_slashes { network, slashes, signature }
}
validator_sets::Call::allocate { network, amount } => {
serai_abi::validator_sets::Call::allocate { network, amount }

View File

@@ -1010,7 +1010,7 @@ pub mod pallet {
pub fn report_slashes(
origin: OriginFor<T>,
network: NetworkId,
slashes: BoundedVec<(Public, u32), ConstU32<{ MAX_KEY_SHARES_PER_SET_U32 / 3 }>>,
slashes: SlashReport,
signature: Signature,
) -> DispatchResult {
ensure_none(origin)?;

View File

@@ -210,6 +210,30 @@ impl Slash {
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SlashReport(pub BoundedVec<Slash, ConstU32<{ MAX_KEY_SHARES_PER_SET_U32 }>>);
#[cfg(feature = "borsh")]
impl BorshSerialize for SlashReport {
fn serialize<W: borsh::io::Write>(&self, writer: &mut W) -> borsh::io::Result<()> {
BorshSerialize::serialize(self.0.as_slice(), writer)
}
}
#[cfg(feature = "borsh")]
impl BorshDeserialize for SlashReport {
fn deserialize_reader<R: borsh::io::Read>(reader: &mut R) -> borsh::io::Result<Self> {
let slashes = Vec::<Slash>::deserialize_reader(reader)?;
slashes
.try_into()
.map(Self)
.map_err(|_| borsh::io::Error::other("length of slash report exceeds max validators"))
}
}
impl TryFrom<Vec<Slash>> for SlashReport {
type Error = &'static str;
fn try_from(slashes: Vec<Slash>) -> Result<SlashReport, &'static str> {
slashes.try_into().map(Self).map_err(|_| "length of slash report exceeds max validators")
}
}
// This is assumed binding to the ValidatorSet via the key signed with
pub fn report_slashes_message(slashes: &SlashReport) -> Vec<u8> {
(b"ValidatorSets-report_slashes", slashes).encode()