mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 14:01:02 +00:00
Allow claim to be not signed by receiver account (#266)
* claim unsigned * more test * fix * Update claims.rs * Update runtime/src/claims.rs * Update runtime/src/claims.rs * Update runtime/src/claims.rs
This commit is contained in:
@@ -20,10 +20,12 @@ use rstd::prelude::*;
|
|||||||
use sr_io::{keccak_256, secp256k1_ecdsa_recover};
|
use sr_io::{keccak_256, secp256k1_ecdsa_recover};
|
||||||
use srml_support::{StorageValue, StorageMap};
|
use srml_support::{StorageValue, StorageMap};
|
||||||
use srml_support::traits::Currency;
|
use srml_support::traits::Currency;
|
||||||
use system::ensure_signed;
|
use system::ensure_none;
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use sr_primitives::traits::Zero;
|
use sr_primitives::traits::Zero;
|
||||||
|
use sr_primitives::traits::ValidateUnsigned;
|
||||||
|
use sr_primitives::transaction_validity::{TransactionLongevity, TransactionValidity};
|
||||||
use system;
|
use system;
|
||||||
|
|
||||||
type BalanceOf<T> = <<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;
|
type BalanceOf<T> = <<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;
|
||||||
@@ -118,13 +120,11 @@ decl_module! {
|
|||||||
fn deposit_event<T>() = default;
|
fn deposit_event<T>() = default;
|
||||||
|
|
||||||
/// Make a claim.
|
/// Make a claim.
|
||||||
fn claim(origin, ethereum_signature: EcdsaSignature) {
|
fn claim(origin, dest: T::AccountId, ethereum_signature: EcdsaSignature) {
|
||||||
// This is a public call, so we ensure that the origin is some signed account.
|
ensure_none(origin)?;
|
||||||
let sender = ensure_signed(origin)?;
|
|
||||||
|
|
||||||
let signer = sender.using_encoded(|data|
|
let signer = dest.using_encoded(|data| eth_recover(ðereum_signature, data))
|
||||||
eth_recover(ðereum_signature, data)
|
.ok_or("Invalid Ethereum signature")?;
|
||||||
).ok_or("Invalid Ethereum signature")?;
|
|
||||||
|
|
||||||
let balance_due = <Claims<T>>::take(&signer)
|
let balance_due = <Claims<T>>::take(&signer)
|
||||||
.ok_or("Ethereum address has no claim")?;
|
.ok_or("Ethereum address has no claim")?;
|
||||||
@@ -135,10 +135,46 @@ decl_module! {
|
|||||||
*t -= balance_due
|
*t -= balance_due
|
||||||
});
|
});
|
||||||
|
|
||||||
T::Currency::deposit_creating(&sender, balance_due);
|
T::Currency::deposit_creating(&dest, balance_due);
|
||||||
|
|
||||||
// Let's deposit an event to let the outside world know this happened.
|
// Let's deposit an event to let the outside world know this happened.
|
||||||
Self::deposit_event(RawEvent::Claimed(sender, signer, balance_due));
|
Self::deposit_event(RawEvent::Claimed(dest, signer, balance_due));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Trait> ValidateUnsigned for Module<T> {
|
||||||
|
type Call = Call<T>;
|
||||||
|
|
||||||
|
fn validate_unsigned(call: &Self::Call) -> TransactionValidity {
|
||||||
|
// Note errors > 0 are from ApplyError
|
||||||
|
const INVALID_ETHEREUM_SIGNATURE: i8 = -10;
|
||||||
|
const SIGNER_HAS_NO_CLAIM: i8 = -20;
|
||||||
|
const INVALID_CALL: i8 = -30;
|
||||||
|
|
||||||
|
const PRIORITY: u64 = 100;
|
||||||
|
|
||||||
|
match call {
|
||||||
|
Call::claim(account, ethereum_signature) => {
|
||||||
|
let signer = account.using_encoded(|data| eth_recover(ðereum_signature, data));
|
||||||
|
let signer = if let Some(signer) = signer {
|
||||||
|
signer
|
||||||
|
} else {
|
||||||
|
return TransactionValidity::Invalid(INVALID_ETHEREUM_SIGNATURE);
|
||||||
|
};
|
||||||
|
|
||||||
|
if !<Claims<T>>::exists(&signer) {
|
||||||
|
return TransactionValidity::Invalid(SIGNER_HAS_NO_CLAIM);
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionValidity::Valid {
|
||||||
|
priority: PRIORITY,
|
||||||
|
requires: vec![],
|
||||||
|
provides: vec![],
|
||||||
|
longevity: TransactionLongevity::max_value(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => TransactionValidity::Invalid(INVALID_CALL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,17 +285,26 @@ mod tests {
|
|||||||
fn claiming_works() {
|
fn claiming_works() {
|
||||||
with_externalities(&mut new_test_ext(), || {
|
with_externalities(&mut new_test_ext(), || {
|
||||||
assert_eq!(Balances::free_balance(&42), 0);
|
assert_eq!(Balances::free_balance(&42), 0);
|
||||||
assert_ok!(Claims::claim(Origin::signed(42), alice_sig(&42u64.encode())));
|
assert_ok!(Claims::claim(Origin::NONE, 42, alice_sig(&42u64.encode())));
|
||||||
assert_eq!(Balances::free_balance(&42), 100);
|
assert_eq!(Balances::free_balance(&42), 100);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn origin_signed_claiming_fail() {
|
||||||
|
with_externalities(&mut new_test_ext(), || {
|
||||||
|
assert_eq!(Balances::free_balance(&42), 0);
|
||||||
|
assert_err!(Claims::claim(Origin::signed(42), 42, alice_sig(&42u64.encode())),
|
||||||
|
"bad origin: expected to be no origin");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn double_claiming_doesnt_work() {
|
fn double_claiming_doesnt_work() {
|
||||||
with_externalities(&mut new_test_ext(), || {
|
with_externalities(&mut new_test_ext(), || {
|
||||||
assert_eq!(Balances::free_balance(&42), 0);
|
assert_eq!(Balances::free_balance(&42), 0);
|
||||||
assert_ok!(Claims::claim(Origin::signed(42), alice_sig(&42u64.encode())));
|
assert_ok!(Claims::claim(Origin::NONE, 42, alice_sig(&42u64.encode())));
|
||||||
assert_noop!(Claims::claim(Origin::signed(42), alice_sig(&42u64.encode())), "Ethereum address has no claim");
|
assert_noop!(Claims::claim(Origin::NONE, 42, alice_sig(&42u64.encode())), "Ethereum address has no claim");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +312,7 @@ mod tests {
|
|||||||
fn non_sender_sig_doesnt_work() {
|
fn non_sender_sig_doesnt_work() {
|
||||||
with_externalities(&mut new_test_ext(), || {
|
with_externalities(&mut new_test_ext(), || {
|
||||||
assert_eq!(Balances::free_balance(&42), 0);
|
assert_eq!(Balances::free_balance(&42), 0);
|
||||||
assert_noop!(Claims::claim(Origin::signed(42), alice_sig(&69u64.encode())), "Ethereum address has no claim");
|
assert_noop!(Claims::claim(Origin::NONE, 42, alice_sig(&69u64.encode())), "Ethereum address has no claim");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +320,7 @@ mod tests {
|
|||||||
fn non_claimant_doesnt_work() {
|
fn non_claimant_doesnt_work() {
|
||||||
with_externalities(&mut new_test_ext(), || {
|
with_externalities(&mut new_test_ext(), || {
|
||||||
assert_eq!(Balances::free_balance(&42), 0);
|
assert_eq!(Balances::free_balance(&42), 0);
|
||||||
assert_noop!(Claims::claim(Origin::signed(42), bob_sig(&69u64.encode())), "Ethereum address has no claim");
|
assert_noop!(Claims::claim(Origin::NONE, 42, bob_sig(&69u64.encode())), "Ethereum address has no claim");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,4 +332,31 @@ mod tests {
|
|||||||
let signer = eth_recover(&sig, &who).unwrap();
|
let signer = eth_recover(&sig, &who).unwrap();
|
||||||
assert_eq!(signer, hex!["DF67EC7EAe23D2459694685257b6FC59d1BAA1FE"]);
|
assert_eq!(signer, hex!["DF67EC7EAe23D2459694685257b6FC59d1BAA1FE"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn validate_unsigned_works() {
|
||||||
|
with_externalities(&mut new_test_ext(), || {
|
||||||
|
assert_eq!(
|
||||||
|
<Module<Test>>::validate_unsigned(&Call::claim(1, alice_sig(&1u64.encode()))),
|
||||||
|
TransactionValidity::Valid {
|
||||||
|
priority: 100,
|
||||||
|
requires: vec![],
|
||||||
|
provides: vec![],
|
||||||
|
longevity: TransactionLongevity::max_value(),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
<Module<Test>>::validate_unsigned(&Call::claim(0, EcdsaSignature::from_blob(&[0; 65]))),
|
||||||
|
TransactionValidity::Invalid(-10)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
<Module<Test>>::validate_unsigned(&Call::claim(1, bob_sig(&1u64.encode()))),
|
||||||
|
TransactionValidity::Invalid(-20)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
<Module<Test>>::validate_unsigned(&Call::claim(0, bob_sig(&1u64.encode()))),
|
||||||
|
TransactionValidity::Invalid(-20)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user