mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Define a proper Topic (Zone + ID)
Removes the inefficiency of recognized_topic for attempt returning None if the topic isn't recognized.
This commit is contained in:
@@ -8,20 +8,19 @@ use serai_client::validator_sets::primitives::{ValidatorSet, KeyPair};
|
||||
|
||||
pub use serai_db::*;
|
||||
|
||||
// Used to determine if an ID is acceptable
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub enum Zone {
|
||||
pub enum Topic {
|
||||
Dkg,
|
||||
Batch,
|
||||
Sign,
|
||||
Batch([u8; 32]),
|
||||
Sign([u8; 32]),
|
||||
}
|
||||
|
||||
impl Zone {
|
||||
fn label(&self) -> &'static str {
|
||||
impl Topic {
|
||||
fn as_key(&self, genesis: [u8; 32]) -> Vec<u8> {
|
||||
match self {
|
||||
Zone::Dkg => "dkg",
|
||||
Zone::Batch => "batch",
|
||||
Zone::Sign => "sign",
|
||||
Topic::Dkg => [genesis.as_slice(), b"dkg".as_ref()].concat(),
|
||||
Topic::Batch(id) => [genesis.as_slice(), b"batch".as_ref(), id.as_ref()].concat(),
|
||||
Topic::Sign(id) => [genesis.as_slice(), b"sign".as_ref(), id.as_ref()].concat(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,9 +28,8 @@ impl Zone {
|
||||
// A struct to refer to a piece of data all validators will presumably provide a value for.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct DataSpecification {
|
||||
pub zone: Zone,
|
||||
pub topic: Topic,
|
||||
pub label: &'static str,
|
||||
pub id: [u8; 32],
|
||||
pub attempt: u32,
|
||||
}
|
||||
|
||||
@@ -39,10 +37,8 @@ impl DataSpecification {
|
||||
fn as_key(&self, genesis: [u8; 32]) -> Vec<u8> {
|
||||
// TODO: Use a proper transcript here to avoid conflicts?
|
||||
[
|
||||
genesis.as_ref(),
|
||||
self.zone.label().as_bytes(),
|
||||
self.topic.as_key(genesis).as_ref(),
|
||||
self.label.as_bytes(),
|
||||
self.id.as_ref(),
|
||||
self.attempt.to_le_bytes().as_ref(),
|
||||
]
|
||||
.concat()
|
||||
@@ -60,18 +56,24 @@ impl<D: Db> TributaryDb<D> {
|
||||
D::key(b"coordinator_tributary", dst, key)
|
||||
}
|
||||
|
||||
fn block_key(genesis: [u8; 32]) -> Vec<u8> {
|
||||
// Last block scanned
|
||||
fn last_block_key(genesis: [u8; 32]) -> Vec<u8> {
|
||||
Self::tributary_key(b"block", genesis)
|
||||
}
|
||||
pub fn set_last_block(&mut self, genesis: [u8; 32], block: [u8; 32]) {
|
||||
let mut txn = self.0.txn();
|
||||
txn.put(Self::block_key(genesis), block);
|
||||
txn.put(Self::last_block_key(genesis), block);
|
||||
txn.commit();
|
||||
}
|
||||
pub fn last_block(&self, genesis: [u8; 32]) -> [u8; 32] {
|
||||
self.0.get(Self::block_key(genesis)).map(|last| last.try_into().unwrap()).unwrap_or(genesis)
|
||||
self
|
||||
.0
|
||||
.get(Self::last_block_key(genesis))
|
||||
.map(|last| last.try_into().unwrap())
|
||||
.unwrap_or(genesis)
|
||||
}
|
||||
|
||||
// If a validator has been fatally slashed
|
||||
fn fatal_slash_key(genesis: [u8; 32]) -> Vec<u8> {
|
||||
Self::tributary_key(b"fatal_slash", genesis)
|
||||
}
|
||||
@@ -79,7 +81,7 @@ impl<D: Db> TributaryDb<D> {
|
||||
let key = Self::fatal_slash_key(genesis);
|
||||
let mut existing = txn.get(&key).unwrap_or(vec![]);
|
||||
|
||||
// don't append if we already have it.
|
||||
// Don't append if we already have it
|
||||
if existing.chunks(32).any(|ex_id| ex_id == id) {
|
||||
return;
|
||||
}
|
||||
@@ -88,6 +90,7 @@ impl<D: Db> TributaryDb<D> {
|
||||
txn.put(key, existing);
|
||||
}
|
||||
|
||||
// The plan IDs associated with a Substrate block
|
||||
fn plan_ids_key(genesis: &[u8], block: u64) -> Vec<u8> {
|
||||
Self::tributary_key(b"plan_ids", [genesis, block.to_le_bytes().as_ref()].concat())
|
||||
}
|
||||
@@ -112,6 +115,7 @@ impl<D: Db> TributaryDb<D> {
|
||||
})
|
||||
}
|
||||
|
||||
// The key pair which we're actively working on completing
|
||||
fn currently_completing_key_pair_key(genesis: [u8; 32]) -> Vec<u8> {
|
||||
Self::tributary_key(b"currently_completing_key_pair", genesis)
|
||||
}
|
||||
@@ -128,6 +132,7 @@ impl<D: Db> TributaryDb<D> {
|
||||
.map(|bytes| KeyPair::decode(&mut bytes.as_slice()).unwrap())
|
||||
}
|
||||
|
||||
// The key pair confirmed for this Tributary
|
||||
pub fn key_pair_key(set: ValidatorSet) -> Vec<u8> {
|
||||
Self::tributary_key(b"key_pair", set.encode())
|
||||
}
|
||||
@@ -138,33 +143,27 @@ impl<D: Db> TributaryDb<D> {
|
||||
Some(KeyPair::decode(&mut getter.get(Self::key_pair_key(set))?.as_slice()).unwrap())
|
||||
}
|
||||
|
||||
fn recognized_id_key(genesis: [u8; 32], zone: Zone, id: [u8; 32]) -> Vec<u8> {
|
||||
Self::tributary_key(
|
||||
b"recognized",
|
||||
[genesis.as_ref(), zone.label().as_bytes(), id.as_ref()].concat(),
|
||||
)
|
||||
// The current attempt to resolve a topic
|
||||
fn attempt_key(genesis: [u8; 32], topic: Topic) -> Vec<u8> {
|
||||
Self::tributary_key(b"attempt", topic.as_key(genesis))
|
||||
}
|
||||
pub fn recognized_id<G: Get>(getter: &G, genesis: [u8; 32], zone: Zone, id: [u8; 32]) -> bool {
|
||||
getter.get(Self::recognized_id_key(genesis, zone, id)).is_some()
|
||||
pub fn recognize_topic(txn: &mut D::Transaction<'_>, genesis: [u8; 32], topic: Topic) {
|
||||
txn.put(Self::attempt_key(genesis, topic), 0u32.to_le_bytes())
|
||||
}
|
||||
pub fn recognize_id(txn: &mut D::Transaction<'_>, genesis: [u8; 32], zone: Zone, id: [u8; 32]) {
|
||||
txn.put(Self::recognized_id_key(genesis, zone, id), [])
|
||||
}
|
||||
|
||||
fn attempt_key(genesis: [u8; 32], id: [u8; 32]) -> Vec<u8> {
|
||||
let genesis_ref: &[u8] = genesis.as_ref();
|
||||
Self::tributary_key(b"attempt", [genesis_ref, id.as_ref()].concat())
|
||||
}
|
||||
pub fn attempt<G: Get>(getter: &G, genesis: [u8; 32], id: [u8; 32]) -> u32 {
|
||||
u32::from_le_bytes(
|
||||
getter.get(Self::attempt_key(genesis, id)).unwrap_or(vec![0; 4]).try_into().unwrap(),
|
||||
)
|
||||
pub fn attempt<G: Get>(getter: &G, genesis: [u8; 32], topic: Topic) -> Option<u32> {
|
||||
let attempt_bytes = getter.get(Self::attempt_key(genesis, topic));
|
||||
// DKGs start when the chain starts
|
||||
if attempt_bytes.is_none() && (topic == Topic::Dkg) {
|
||||
return Some(0);
|
||||
}
|
||||
Some(u32::from_le_bytes(attempt_bytes?.try_into().unwrap()))
|
||||
}
|
||||
|
||||
// Key for the amount of instances received thus far
|
||||
fn data_received_key(genesis: [u8; 32], data_spec: &DataSpecification) -> Vec<u8> {
|
||||
Self::tributary_key(b"data_received", data_spec.as_key(genesis))
|
||||
}
|
||||
// Key for an instance of data from a specific validator
|
||||
fn data_key(
|
||||
genesis: [u8; 32],
|
||||
data_spec: &DataSpecification,
|
||||
|
||||
Reference in New Issue
Block a user