Skip to content

Commit

Permalink
Closes #18 - key extraction from storage on each block and update if …
Browse files Browse the repository at this point in the history
…different from previous one
  • Loading branch information
35359595 committed Dec 20, 2021
1 parent 21a2afe commit 6b3eee8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 32 deletions.
21 changes: 15 additions & 6 deletions pallets/ethereum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ pub mod pallet {
withdrawals.transaction = Some(tx);
<Withdrawals<T>>::insert(n_1, withdrawals);
// check and submit Thea controlling key update for the contract
handle_thea_key_update_for_ethereum::<T>(to, n);
let key = pallet_thea::Pallet::<T>::public_keys(<ValidatorSetId<T>>::get());
handle_thea_key_update_for_ethereum::<T>(to, key.as_ref(), n);
// TODO: Use something like this T::WeightInfo::on_initialize(num_of_withdrawls)
return Weight::from(20000u64)
}
Expand All @@ -198,17 +199,21 @@ pub mod pallet {
}
}

fn handle_thea_key_update_for_ethereum<T: Config>(contract_addr: H160, n: BlockNumberFor<T>) {
let new_key = pallet_thea::Pallet::<T>::next_controlling_key_keccak256();
if new_key != [0u8; 32] {
let mut key_update_transaction = ethereum_primitives::types::TransactionRequest::new();
fn handle_thea_key_update_for_ethereum<T: Config>(
contract_addr: H160,
key: &[u8],
n: BlockNumberFor<T>,
) {
let current = <ControllingKey<T>>::get();
if &current != key {
let key_update_transaction = ethereum_primitives::types::TransactionRequest::new();
let nonce = <Nonce<T>>::get(<ValidatorSetId<T>>::get());
pallet_thea::Pallet::<T>::submit_payload_for_signing(
n,
Network::ETHEREUM,
key_update_transaction
.to(contract_addr)
.data(H256::from_slice(&new_key).as_bytes().to_vec())
.data(H256::from_slice(&key).as_bytes().to_vec())
.nonce(nonce)
.sighash()
.0,
Expand Down Expand Up @@ -270,6 +275,10 @@ pub mod pallet {
/// Finalized Ethereum block available
pub(super) type FinalizedBlock<T: Config> = StorageValue<_, EthereumBlock, OptionQuery>;

#[pallet::storage]
#[pallet::getter(fn next_controlling_key_keccak256)]
pub(super) type ControllingKey<T: Config> = StorageValue<_, [u8; 32], ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn blocks_seen)]
/// BlockNumber, Block Hash => EthereumBlockWithApprovals
Expand Down
42 changes: 16 additions & 26 deletions pallets/thea/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,18 +207,19 @@ pub mod pallet {
valid_tx((authority_id, payload.auth_idx))
};

let valid_auth_clean_keygen = |authorities: Vec<T::TheaId>,
auth_idx: AuthorityIndex,
signature: &<T::TheaId as RuntimeAppPublic>::Signature|
-> TransactionValidity{
let authority_id = authorities[auth_idx as usize].clone();
let message_hash = sp_io::hashing::keccak_256(&auth_idx.encode());
// verify if a valid authority signed this transaction
if !authority_id.verify(&message_hash, signature) {
return InvalidTransaction::BadProof.into()
}
valid_tx((authority_id, auth_idx))
};
let valid_auth_clean_keygen =
|authorities: Vec<T::TheaId>,
auth_idx: AuthorityIndex,
signature: &<T::TheaId as RuntimeAppPublic>::Signature|
-> TransactionValidity {
let authority_id = authorities[auth_idx as usize].clone();
let message_hash = sp_io::hashing::keccak_256(&auth_idx.encode());
// verify if a valid authority signed this transaction
if !authority_id.verify(&message_hash, signature) {
return InvalidTransaction::BadProof.into()
}
valid_tx((authority_id, auth_idx))
};

let valid_auth_offline = |authorities: Vec<T::TheaId>,
payload: &TheaPayload<T::TheaId, OfflineStageRound>,
Expand Down Expand Up @@ -311,9 +312,8 @@ pub mod pallet {
// TODO: Is this okay? Anyone can now sent this extrinsic,
// There should be some kind of check in validate unsigned that will prevent spam
Call::submit_ecdsa_public_key(ref _set_id, ref _public_key) => valid_inherent(),
Call::clean_keygen_messages(ref auth_idx, ref signature) => {
valid_auth_clean_keygen(Self::authorities(), *auth_idx, signature)
}
Call::clean_keygen_messages(ref auth_idx, ref signature) =>
valid_auth_clean_keygen(Self::authorities(), *auth_idx, signature),
_ => InvalidTransaction::Call.into(),
}
}
Expand Down Expand Up @@ -530,13 +530,10 @@ pub mod pallet {
StorageMap<_, Blake2_128Concat, T::AccountId, T::AccountId, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn next_controlling_key_keccak256)]
pub(super) type NextControllingKeyKeccak256<T: Config> = StorageValue<_, [u8; 32], ValueQuery>;
#[pallet::storage]
#[pallet::getter(fn validator_set_changed)]
pub(super) type IsValidatorSetChanged<T: Config> = StorageValue<_, bool, ValueQuery>;

#[pallet::genesis_config]
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config> {
pub authorities: Vec<T::TheaId>,
}
Expand Down Expand Up @@ -645,7 +642,6 @@ impl<T: Config> Pallet<T> {
Self::validator_set_changed()
}


fn change_authorities(new: Vec<T::TheaId>, queued: Vec<T::TheaId>) {
// As in GRANDPA, we trigger a validator set change only if the the validator
// set has actually changed.
Expand Down Expand Up @@ -715,12 +711,6 @@ impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
if next_queued_authorities != next_authorities {
<IsValidatorSetChanged<T>>::put(true);
<NextAuthorities<T>>::put(next_queued_authorities);
if let Some(next_key) = Self::next_validator_set().public_key {
let hashed = sp_io::hashing::keccak_256(next_key.as_ref());
<NextControllingKeyKeccak256<T>>::mutate(|v| *v = hashed);
} else if <NextControllingKeyKeccak256<T>>::get() != EMPTY_32B_ARRAY {
<NextControllingKeyKeccak256<T>>::mutate(|v| *v = EMPTY_32B_ARRAY);
}
} else {
<IsValidatorSetChanged<T>>::put(false);
}
Expand Down

0 comments on commit 6b3eee8

Please sign in to comment.