2024-08-30 01:19:29 -04:00
|
|
|
use core::marker::PhantomData;
|
|
|
|
|
use std::io::{Read, Write};
|
|
|
|
|
|
2024-09-08 23:42:18 -04:00
|
|
|
use group::GroupEncoding;
|
|
|
|
|
|
2024-08-30 01:19:29 -04:00
|
|
|
use scale::{Encode, Decode, IoReader};
|
2024-09-10 03:48:06 -04:00
|
|
|
use borsh::{BorshSerialize, BorshDeserialize};
|
2024-08-28 20:16:06 -04:00
|
|
|
use serai_db::{Get, DbTxn, create_db};
|
2024-08-28 19:58:28 -04:00
|
|
|
|
2024-08-30 01:19:29 -04:00
|
|
|
use serai_primitives::Balance;
|
2024-12-30 05:21:26 -05:00
|
|
|
use serai_validator_sets_primitives::Session;
|
2024-08-30 01:19:29 -04:00
|
|
|
|
2024-12-30 05:33:53 -05:00
|
|
|
use primitives::EncodableG;
|
2024-09-08 23:42:18 -04:00
|
|
|
use crate::{ScannerFeed, KeyFor, AddressFor};
|
2024-08-30 01:19:29 -04:00
|
|
|
|
2024-12-30 05:21:26 -05:00
|
|
|
#[derive(BorshSerialize, BorshDeserialize)]
|
2024-12-30 05:33:53 -05:00
|
|
|
pub(crate) struct BatchInfo<K: BorshSerialize> {
|
2024-12-30 05:21:26 -05:00
|
|
|
pub(crate) block_number: u64,
|
2024-12-30 05:33:53 -05:00
|
|
|
pub(crate) session_to_sign_batch: Session,
|
|
|
|
|
pub(crate) external_key_for_session_to_sign_batch: K,
|
2024-12-30 05:21:26 -05:00
|
|
|
pub(crate) in_instructions_hash: [u8; 32],
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-28 19:58:28 -04:00
|
|
|
create_db!(
|
|
|
|
|
ScannerReport {
|
|
|
|
|
// The next block to potentially report
|
|
|
|
|
NextToPotentiallyReportBlock: () -> u64,
|
2024-08-28 23:31:31 -04:00
|
|
|
// The next Batch ID to use
|
|
|
|
|
NextBatchId: () -> u32,
|
2024-08-30 01:19:29 -04:00
|
|
|
|
2024-12-30 05:21:26 -05:00
|
|
|
// The information needed to verify a batch
|
2024-12-30 05:33:53 -05:00
|
|
|
InfoForBatch: <G: GroupEncoding>(batch: u32) -> BatchInfo<EncodableG<G>>,
|
2024-09-08 23:42:18 -04:00
|
|
|
|
2024-08-30 01:19:29 -04:00
|
|
|
// The return addresses for the InInstructions within a Batch
|
|
|
|
|
SerializedReturnAddresses: (batch: u32) -> Vec<u8>,
|
2024-08-28 19:58:28 -04:00
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2024-08-30 01:19:29 -04:00
|
|
|
pub(crate) struct ReturnInformation<S: ScannerFeed> {
|
|
|
|
|
pub(crate) address: AddressFor<S>,
|
|
|
|
|
pub(crate) balance: Balance,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct ReportDb<S: ScannerFeed>(PhantomData<S>);
|
|
|
|
|
impl<S: ScannerFeed> ReportDb<S> {
|
2024-08-28 19:58:28 -04:00
|
|
|
pub(crate) fn set_next_to_potentially_report_block(
|
|
|
|
|
txn: &mut impl DbTxn,
|
|
|
|
|
next_to_potentially_report_block: u64,
|
|
|
|
|
) {
|
|
|
|
|
NextToPotentiallyReportBlock::set(txn, &next_to_potentially_report_block);
|
|
|
|
|
}
|
|
|
|
|
pub(crate) fn next_to_potentially_report_block(getter: &impl Get) -> Option<u64> {
|
|
|
|
|
NextToPotentiallyReportBlock::get(getter)
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-30 05:21:26 -05:00
|
|
|
pub(crate) fn acquire_batch_id(txn: &mut impl DbTxn) -> u32 {
|
2024-08-28 23:31:31 -04:00
|
|
|
let id = NextBatchId::get(txn).unwrap_or(0);
|
|
|
|
|
NextBatchId::set(txn, &(id + 1));
|
|
|
|
|
id
|
2024-08-28 19:58:28 -04:00
|
|
|
}
|
2024-08-30 01:19:29 -04:00
|
|
|
|
2024-12-30 05:21:26 -05:00
|
|
|
pub(crate) fn save_batch_info(
|
|
|
|
|
txn: &mut impl DbTxn,
|
|
|
|
|
id: u32,
|
|
|
|
|
block_number: u64,
|
2024-12-30 05:33:53 -05:00
|
|
|
session_to_sign_batch: Session,
|
|
|
|
|
external_key_for_session_to_sign_batch: KeyFor<S>,
|
2024-12-30 05:21:26 -05:00
|
|
|
in_instructions_hash: [u8; 32],
|
|
|
|
|
) {
|
2024-12-30 05:33:53 -05:00
|
|
|
InfoForBatch::set(
|
2024-09-08 23:42:18 -04:00
|
|
|
txn,
|
|
|
|
|
id,
|
2024-12-30 05:33:53 -05:00
|
|
|
&BatchInfo {
|
|
|
|
|
block_number,
|
|
|
|
|
session_to_sign_batch,
|
|
|
|
|
external_key_for_session_to_sign_batch: EncodableG(external_key_for_session_to_sign_batch),
|
|
|
|
|
in_instructions_hash,
|
|
|
|
|
},
|
2024-09-08 23:42:18 -04:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-30 05:33:53 -05:00
|
|
|
pub(crate) fn take_info_for_batch(
|
2024-09-08 23:42:18 -04:00
|
|
|
txn: &mut impl DbTxn,
|
|
|
|
|
id: u32,
|
2024-12-30 05:33:53 -05:00
|
|
|
) -> Option<BatchInfo<EncodableG<KeyFor<S>>>> {
|
|
|
|
|
InfoForBatch::take(txn, id)
|
2024-09-08 23:42:18 -04:00
|
|
|
}
|
|
|
|
|
|
2024-08-30 01:19:29 -04:00
|
|
|
pub(crate) fn save_return_information(
|
|
|
|
|
txn: &mut impl DbTxn,
|
|
|
|
|
id: u32,
|
|
|
|
|
return_information: &Vec<Option<ReturnInformation<S>>>,
|
|
|
|
|
) {
|
|
|
|
|
let mut buf = Vec::with_capacity(return_information.len() * (32 + 1 + 8));
|
|
|
|
|
for return_information in return_information {
|
|
|
|
|
if let Some(ReturnInformation { address, balance }) = return_information {
|
|
|
|
|
buf.write_all(&[1]).unwrap();
|
2024-09-10 03:48:06 -04:00
|
|
|
address.serialize(&mut buf).unwrap();
|
2024-08-30 01:19:29 -04:00
|
|
|
balance.encode_to(&mut buf);
|
|
|
|
|
} else {
|
|
|
|
|
buf.write_all(&[0]).unwrap();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
SerializedReturnAddresses::set(txn, id, &buf);
|
|
|
|
|
}
|
|
|
|
|
pub(crate) fn take_return_information(
|
|
|
|
|
txn: &mut impl DbTxn,
|
|
|
|
|
id: u32,
|
|
|
|
|
) -> Option<Vec<Option<ReturnInformation<S>>>> {
|
2024-09-11 09:12:00 -04:00
|
|
|
let buf = SerializedReturnAddresses::take(txn, id)?;
|
2024-08-30 01:19:29 -04:00
|
|
|
let mut buf = buf.as_slice();
|
|
|
|
|
|
|
|
|
|
let mut res = Vec::with_capacity(buf.len() / (32 + 1 + 8));
|
|
|
|
|
while !buf.is_empty() {
|
|
|
|
|
let mut opt = [0xff];
|
|
|
|
|
buf.read_exact(&mut opt).unwrap();
|
|
|
|
|
assert!((opt[0] == 0) || (opt[0] == 1));
|
|
|
|
|
|
|
|
|
|
res.push((opt[0] == 1).then(|| {
|
2024-09-10 03:48:06 -04:00
|
|
|
let address = AddressFor::<S>::deserialize_reader(&mut buf).unwrap();
|
2024-08-30 01:19:29 -04:00
|
|
|
let balance = Balance::decode(&mut IoReader(&mut buf)).unwrap();
|
|
|
|
|
ReturnInformation { address, balance }
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
Some(res)
|
|
|
|
|
}
|
2024-08-28 19:58:28 -04:00
|
|
|
}
|