mirror of
https://github.com/serai-dex/serai.git
synced 2024-12-22 11:39:35 +00:00
Various simplifications re: Serai transactions
Removes PairSigner for the pair directly. Resets spec_version to 1. Defines the extrinsic without its length prefix, only prefixing during publish.
This commit is contained in:
parent
c6cf33e370
commit
372149c2cc
9 changed files with 36 additions and 67 deletions
|
@ -40,6 +40,8 @@ impl<'a> SeraiInInstructions<'a> {
|
|||
}
|
||||
|
||||
pub fn execute_batch(batch: SignedBatch) -> Vec<u8> {
|
||||
Serai::unsigned::<InInstructions, _>(&in_instructions::Call::<Runtime>::execute_batch { batch })
|
||||
Serai::unsigned(&serai_runtime::RuntimeCall::InInstructions(
|
||||
in_instructions::Call::<Runtime>::execute_batch { batch },
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ pub use sp_core::{
|
|||
sr25519::{Public, Pair},
|
||||
};
|
||||
|
||||
pub use subxt;
|
||||
use subxt::{
|
||||
error::Error as SubxtError,
|
||||
config::{
|
||||
|
@ -21,7 +20,6 @@ use subxt::{
|
|||
substrate::{BlakeTwo256, SubstrateHeader},
|
||||
extrinsic_params::BaseExtrinsicParams,
|
||||
},
|
||||
tx::Signer,
|
||||
rpc::types::{ChainBlock, ChainBlockExtrinsic},
|
||||
Config as SubxtConfig, OnlineClient,
|
||||
};
|
||||
|
@ -150,41 +148,32 @@ impl Serai {
|
|||
Ok(Serai(OnlineClient::<SeraiConfig>::from_url(url).await.map_err(SeraiError::RpcError)?))
|
||||
}
|
||||
|
||||
fn unsigned<P: 'static, C: Encode>(call: &C) -> Vec<u8> {
|
||||
fn unsigned(call: &serai_runtime::RuntimeCall) -> Vec<u8> {
|
||||
// TODO: Should Serai purge the old transaction code AND set this to 0/1?
|
||||
const TRANSACTION_VERSION: u8 = 4;
|
||||
const EXTRINSIC_FORMAT_VERSION: u8 = 4;
|
||||
|
||||
// Protocol version
|
||||
let mut bytes = vec![TRANSACTION_VERSION];
|
||||
|
||||
// Pallet index
|
||||
bytes.push(u8::try_from(PalletInfo::index::<P>().unwrap()).unwrap());
|
||||
// Call
|
||||
let mut bytes = vec![EXTRINSIC_FORMAT_VERSION];
|
||||
bytes.extend(call.encode());
|
||||
|
||||
// Prefix the length
|
||||
let mut complete_bytes = Compact(u32::try_from(bytes.len()).unwrap()).encode();
|
||||
complete_bytes.extend(bytes);
|
||||
complete_bytes
|
||||
bytes
|
||||
}
|
||||
|
||||
pub fn sign<S: Send + Sync + Signer<SeraiConfig>>(
|
||||
pub fn sign(
|
||||
&self,
|
||||
signer: &S,
|
||||
signer: &Pair,
|
||||
call: &serai_runtime::RuntimeCall,
|
||||
nonce: u32,
|
||||
tip: Tip,
|
||||
) -> Vec<u8> {
|
||||
const SPEC_VERSION: u32 = 100;
|
||||
const IMPL_VERSION: u32 = 1;
|
||||
const TRANSACTION_VERSION: u8 = 4;
|
||||
const SPEC_VERSION: u32 = 1;
|
||||
const TX_VERSION: u32 = 1;
|
||||
const EXTRINSIC_FORMAT_VERSION: u8 = 4;
|
||||
|
||||
let era = subxt::config::substrate::Era::Immortal;
|
||||
let extra = (era, Compact(nonce), tip);
|
||||
let genesis = self.0.genesis_hash();
|
||||
let mortality_checkpoint = genesis;
|
||||
let mut signature_payload =
|
||||
(call, extra, SPEC_VERSION, IMPL_VERSION, genesis, mortality_checkpoint).encode();
|
||||
(call, extra, SPEC_VERSION, TX_VERSION, genesis, mortality_checkpoint).encode();
|
||||
if signature_payload.len() > 256 {
|
||||
use subxt::config::Hasher;
|
||||
signature_payload = BlakeTwo256::hash(&signature_payload).0.to_vec();
|
||||
|
@ -192,19 +181,20 @@ impl Serai {
|
|||
let signature = signer.sign(&signature_payload);
|
||||
|
||||
let signed = 1 << 7;
|
||||
let extrinsic =
|
||||
(signed + TRANSACTION_VERSION, signer.address(), signature, extra, call).encode();
|
||||
let mut res = Compact(u32::try_from(extrinsic.len()).unwrap()).encode();
|
||||
res.extend(&extrinsic);
|
||||
res
|
||||
(signed + EXTRINSIC_FORMAT_VERSION, signer.public(), signature, extra, call).encode()
|
||||
}
|
||||
|
||||
pub async fn publish(&self, tx: &[u8]) -> Result<(), SeraiError> {
|
||||
let mut length_prefixed = Compact(u32::try_from(tx.len()).unwrap()).encode();
|
||||
length_prefixed.extend(tx);
|
||||
self
|
||||
.0
|
||||
.rpc()
|
||||
.deref()
|
||||
.request::<String>("author_submitExtrinsic", subxt::rpc::rpc_params![hex::encode(tx)])
|
||||
.request::<String>(
|
||||
"author_submitExtrinsic",
|
||||
subxt::rpc::rpc_params![hex::encode(length_prefixed)],
|
||||
)
|
||||
.await
|
||||
// Drop the hash, which is the hash of the raw extrinsic, as extrinsics are allowed to share
|
||||
// hashes and this hash is accordingly useless/unsafe
|
||||
|
@ -386,23 +376,3 @@ impl<'a> TemporalSerai<'a> {
|
|||
SeraiValidatorSets(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PairSigner(Pair, <SeraiConfig as SubxtConfig>::AccountId);
|
||||
impl PairSigner {
|
||||
pub fn new(pair: Pair) -> Self {
|
||||
let id = pair.public();
|
||||
PairSigner(pair, id)
|
||||
}
|
||||
}
|
||||
impl Signer<SeraiConfig> for PairSigner {
|
||||
fn account_id(&self) -> &<SeraiConfig as SubxtConfig>::AccountId {
|
||||
&self.1
|
||||
}
|
||||
fn address(&self) -> <SeraiConfig as SubxtConfig>::Address {
|
||||
self.1.into()
|
||||
}
|
||||
fn sign(&self, payload: &[u8]) -> <SeraiConfig as SubxtConfig>::Signature {
|
||||
self.0.sign(payload)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,10 +81,8 @@ impl<'a> SeraiValidatorSets<'a> {
|
|||
}
|
||||
|
||||
pub fn set_keys(network: NetworkId, key_pair: KeyPair, signature: Signature) -> Vec<u8> {
|
||||
Serai::unsigned::<ValidatorSets, _>(&validator_sets::Call::<Runtime>::set_keys {
|
||||
network,
|
||||
key_pair,
|
||||
signature,
|
||||
})
|
||||
Serai::unsigned(&serai_runtime::RuntimeCall::ValidatorSets(
|
||||
validator_sets::Call::<Runtime>::set_keys { network, key_pair, signature },
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use serai_client::{
|
|||
primitives::{InInstruction, InInstructionWithBalance, Batch},
|
||||
},
|
||||
coins::{primitives::OutInstruction, CoinsEvent},
|
||||
PairSigner, Serai, SeraiCoins,
|
||||
Serai, SeraiCoins,
|
||||
};
|
||||
|
||||
mod common;
|
||||
|
@ -91,7 +91,7 @@ serai_test!(
|
|||
serai,
|
||||
&serai
|
||||
.sign(
|
||||
&PairSigner::new(pair),
|
||||
&pair,
|
||||
&SeraiCoins::burn_with_instruction(instruction.clone()),
|
||||
0,
|
||||
Default::default(),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use serai_runtime::primitives::{Coin, Amount};
|
||||
|
||||
use serai_client::{Serai, SeraiDex, PairSigner};
|
||||
use serai_client::{Serai, SeraiDex};
|
||||
use sp_core::{sr25519::Pair, Pair as PairTrait};
|
||||
|
||||
use crate::common::tx::publish_tx;
|
||||
|
@ -17,7 +17,7 @@ pub async fn add_liquidity(
|
|||
let address = pair.public();
|
||||
|
||||
let tx = serai.sign(
|
||||
&PairSigner::new(pair),
|
||||
&pair,
|
||||
&SeraiDex::add_liquidity(coin, coin_amount, sri_amount, Amount(1), Amount(1), address.into()),
|
||||
nonce,
|
||||
Default::default(),
|
||||
|
@ -39,7 +39,7 @@ pub async fn swap(
|
|||
let address = pair.public();
|
||||
|
||||
let tx = serai.sign(
|
||||
&PairSigner::new(pair),
|
||||
&pair,
|
||||
&SeraiDex::swap(from_coin, to_coin, amount_in, amount_out_min, address.into()),
|
||||
nonce,
|
||||
Default::default(),
|
||||
|
|
|
@ -34,7 +34,7 @@ pub async fn publish_tx(serai: &Serai, tx: &[u8]) -> [u8; 32] {
|
|||
};
|
||||
|
||||
for transaction in block.transactions() {
|
||||
if transaction.0 == tx[2 ..] {
|
||||
if transaction.0 == tx {
|
||||
return block.hash();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,8 +88,7 @@ pub mod opaque {
|
|||
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
spec_name: create_runtime_str!("serai"),
|
||||
impl_name: create_runtime_str!("core"),
|
||||
// TODO: 1? Do we prefer some level of compatibility or our own path?
|
||||
spec_version: 100,
|
||||
spec_version: 1,
|
||||
impl_version: 1,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
transaction_version: 1,
|
||||
|
|
|
@ -12,7 +12,7 @@ use ciphersuite::{group::GroupEncoding, Ciphersuite, Secp256k1};
|
|||
use dkg::Participant;
|
||||
|
||||
use serai_client::{
|
||||
PairTrait, PairSigner,
|
||||
PairTrait,
|
||||
primitives::{
|
||||
NetworkId, Coin, Amount, Balance, BlockHash, SeraiAddress, ExternalAddress,
|
||||
insecure_pair_from_name,
|
||||
|
@ -211,7 +211,7 @@ async fn sign_test() {
|
|||
let balance = Balance { coin: Coin::Serai, amount: Amount(1_000_000_000) };
|
||||
serai
|
||||
.publish(&serai.sign(
|
||||
&PairSigner::new(insecure_pair_from_name("Ferdie")),
|
||||
&insecure_pair_from_name("Ferdie"),
|
||||
&SeraiCoins::transfer(address, balance),
|
||||
0,
|
||||
Default::default(),
|
||||
|
@ -219,7 +219,7 @@ async fn sign_test() {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
(PairSigner::new(pair), address)
|
||||
(pair, address)
|
||||
};
|
||||
|
||||
#[allow(clippy::inconsistent_digit_grouping)]
|
||||
|
|
|
@ -16,7 +16,7 @@ use serai_client::{
|
|||
validator_sets::primitives::{Session, ValidatorSet},
|
||||
in_instructions::primitives::Shorthand,
|
||||
coins::primitives::{OutInstruction, OutInstructionWithBalance},
|
||||
PairTrait, PairSigner, SeraiCoins,
|
||||
PairTrait, SeraiCoins,
|
||||
};
|
||||
|
||||
use crate::tests::*;
|
||||
|
@ -249,7 +249,7 @@ async fn mint_and_burn_test() {
|
|||
let balance = Balance { coin: Coin::Serai, amount: Amount(1_000_000_000) };
|
||||
serai
|
||||
.publish(&serai.sign(
|
||||
&PairSigner::new(insecure_pair_from_name("Ferdie")),
|
||||
&insecure_pair_from_name("Ferdie"),
|
||||
&SeraiCoins::transfer(address, balance),
|
||||
0,
|
||||
Default::default(),
|
||||
|
@ -257,7 +257,7 @@ async fn mint_and_burn_test() {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
(PairSigner::new(pair), address)
|
||||
(pair, address)
|
||||
};
|
||||
|
||||
// Send in BTC
|
||||
|
|
Loading…
Reference in a new issue