Implement block emissions (#551)

* add genesis liquidity implementation

* add missing deposit event

* fix CI issues

* minor fixes

* make math safer

* fix fmt

* implement block emissions

* make remove liquidity an authorized call

* implement setting initial values for coins

* add genesis liquidity test & misc fixes

* updato develop latest

* fix rotation test

* fix licencing

* add fast-epoch feature

* only create the pool when adding liquidity first time

* add initial reward era test

* test whole pre ec security emissions

* fix clippy

* add swap-to-staked-sri feature

* rebase changes

* fix tests

* Remove accidentally commited ETH ABI files

* fix some pr comments

* Finish up fixing pr comments

* exclude SRI from is_allowed check

* Misc changes

---------

Co-authored-by: akildemir <aeg_asd@hotmail.com>
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
This commit is contained in:
akildemir
2024-08-15 06:12:04 +03:00
committed by GitHub
parent bf1c493d9a
commit cccc1fc7e6
36 changed files with 1279 additions and 302 deletions

View File

@@ -1,12 +1,12 @@
use sp_core::bounded_vec::BoundedVec;
use serai_abi::primitives::{SeraiAddress, Amount, Coin};
use scale::{decode_from_bytes, Encode};
use crate::{Serai, SeraiError, TemporalSerai};
use crate::{SeraiError, TemporalSerai};
pub type DexEvent = serai_abi::dex::Event;
const PALLET: &str = "Dex";
#[derive(Clone, Copy)]
pub struct SeraiDex<'a>(pub(crate) &'a TemporalSerai<'a>);
impl<'a> SeraiDex<'a> {
@@ -62,17 +62,10 @@ impl<'a> SeraiDex<'a> {
/// Returns the reserves of `coin:SRI` pool.
pub async fn get_reserves(&self, coin: Coin) -> Result<Option<(Amount, Amount)>, SeraiError> {
let reserves = self
.0
.serai
.call(
"state_call",
["DexApi_get_reserves".to_string(), hex::encode((coin, Coin::Serai).encode())],
)
.await?;
let bytes = Serai::hex_decode(reserves)?;
let result = decode_from_bytes::<Option<(u64, u64)>>(bytes.into())
.map_err(|e| SeraiError::ErrorInResponse(e.to_string()))?;
Ok(result.map(|amounts| (Amount(amounts.0), Amount(amounts.1))))
self.0.runtime_api("DexApi_get_reserves", (coin, Coin::Serai)).await
}
pub async fn oracle_value(&self, coin: Coin) -> Result<Option<Amount>, SeraiError> {
self.0.storage(PALLET, "SecurityOracleValue", coin).await
}
}

View File

@@ -62,4 +62,9 @@ impl<'a> SeraiGenesisLiquidity<'a> {
pub async fn supply(&self, coin: Coin) -> Result<LiquidityAmount, SeraiError> {
Ok(self.0.storage(PALLET, "Supply", coin).await?.unwrap_or(LiquidityAmount::zero()))
}
pub async fn genesis_complete(&self) -> Result<bool, SeraiError> {
let result: Option<()> = self.0.storage(PALLET, "GenesisComplete", ()).await?;
Ok(result.is_some())
}
}

View File

@@ -198,17 +198,6 @@ impl Serai {
Ok(())
}
// TODO: move this into substrate/client/src/validator_sets.rs
async fn active_network_validators(&self, network: NetworkId) -> Result<Vec<Public>, SeraiError> {
let validators: String = self
.call("state_call", ["SeraiRuntimeApi_validators".to_string(), hex::encode(network.encode())])
.await?;
let bytes = Self::hex_decode(validators)?;
let r = Vec::<Public>::decode(&mut bytes.as_slice())
.map_err(|e| SeraiError::ErrorInResponse(e.to_string()))?;
Ok(r)
}
pub async fn latest_finalized_block_hash(&self) -> Result<[u8; 32], SeraiError> {
let hash: String = self.call("chain_getFinalizedHead", ()).await?;
Self::hex_decode(hash)?.try_into().map_err(|_| {
@@ -378,6 +367,28 @@ impl<'a> TemporalSerai<'a> {
})?))
}
async fn runtime_api<P: Encode, R: Decode>(
&self,
method: &'static str,
params: P,
) -> Result<R, SeraiError> {
let result: String = self
.serai
.call(
"state_call",
[method.to_string(), hex::encode(params.encode()), hex::encode(self.block)],
)
.await?;
let bytes = Serai::hex_decode(result.clone())?;
R::decode(&mut bytes.as_slice()).map_err(|_| {
SeraiError::InvalidRuntime(format!(
"different type than what is expected to be returned, raw value: {}",
hex::encode(result)
))
})
}
pub fn coins(&'a self) -> SeraiCoins<'a> {
SeraiCoins(self)
}

View File

@@ -163,7 +163,7 @@ impl<'a> SeraiValidatorSets<'a> {
&self,
network: NetworkId,
) -> Result<Vec<Public>, SeraiError> {
self.0.serai.active_network_validators(network).await
self.0.runtime_api("SeraiRuntimeApi_validators", network).await
}
// TODO: Store these separately since we almost never need both at once?
@@ -178,6 +178,14 @@ impl<'a> SeraiValidatorSets<'a> {
self.0.storage(PALLET, "PendingSlashReport", network).await
}
pub async fn session_begin_block(
&self,
network: NetworkId,
session: Session,
) -> Result<Option<u64>, SeraiError> {
self.0.storage(PALLET, "SessionBeginBlock", (network, session)).await
}
pub fn set_keys(
network: NetworkId,
removed_participants: sp_runtime::BoundedVec<