Skip to content

Commit

Permalink
Validator Controller solidity interface for checking when validator i…
Browse files Browse the repository at this point in the history
…s missing blocks (#163)
  • Loading branch information
deblanco authored Jan 18, 2024
1 parent 20e874c commit 7c52863
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 11 deletions.
1 change: 1 addition & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Optional environment variables:
- NODE_KEY: This environment variable allows specifying the node key to use. If not specified, the node will generate a random node key. This applies to the P2P key, not the account key.
- BOOTNODES: This environment variable allows specifying the bootnodes to use, separated by commas. If not specified, the node will use the default bootnodes for the chain spec.
- MODE: This environment variable allows the node to run in different pruning modes. Possible values are "full_node" or "archive". The default value is "full_node".
- BACKEND_TYPE: The only available option is `sql` for now. This option allows the node to use a SQL backend instead of the default `key-value` backend for faster Ethereum log queries.
- ZERO_GAS_TX_POOL: This environment variable allows the node to run with a zero gas price transaction pool. By default the feature is disabled. The expected value is a string containing an URL. Check the [Zero Gas Transaction Pool](../docs/ZERO-GAS-TRANSACTIONS.md) document for more information.
- ZERO_GAS_TX_POOL_TIMEOUT: This environment variable allows specifying the timeout for the zero gas transaction in millisecond. If not specified, the node will use the default timeout (1000ms).

Expand Down
1 change: 1 addition & 0 deletions docs/GETTING-STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Additionally, you can configure the following flags:
- `--unsafe-rpc-external --rpc-cors all`: Use if your node will be accessed from a system external to your localhost.
- `--bootnodes`: A list of p2p nodes for Stability to join the network. What is known as bootnodes
- `--base-path`: Specifies a custom base path for the data folder
- `--frontier-backend-type`: The standard database with the system can be modified to use an SQL backend. Since getting Ethereum logs is an everyday use case with a high CPU usage, SQL backend mode is optimized for this. Available options are `sql` or `key-value` (default).

## Generating the a build spec file or Genesis file

Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
- [Zero Gas Transactions](ZERO-GAS-TRANSACTIONS.md)
- [Custom RPCs](RPC.md)
- [Validator connection handling](VALIDATOR-CONNECTION-HANDLING.md)
- [Audits][AUDITS.md]
- [Audits](AUDITS.md)
4 changes: 4 additions & 0 deletions precompiles/validator-controller/ValidatorController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ interface ValidatorController {
function getValidatorList() external view returns (address[] memory);

function getActiveValidatorList() external view returns (address[] memory);

function getValidatorMissingBlocks(
address validator
) external view returns (uint256);
}
28 changes: 22 additions & 6 deletions precompiles/validator-controller/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use frame_support::storage::types::{StorageValue, ValueQuery};

use frame_support::traits::StorageInstance;
use pallet_custom_balances::AccountIdMapping;
use pallet_evm::AddressMapping;
use precompile_utils::prelude::*;

use sp_core::Get;
Expand Down Expand Up @@ -87,7 +88,8 @@ where
Runtime: pallet_validator_set::Config
+ pallet_timestamp::Config
+ pallet_evm::Config
+ pallet_custom_balances::Config,
+ pallet_custom_balances::Config
+ pallet_evm::Config,
Runtime::RuntimeCall: From<pallet_validator_set::Call<Runtime>>,
<Runtime::RuntimeCall as Dispatchable>::RuntimeOrigin: From<Option<Runtime::AccountId>>,
Runtime::RuntimeCall: Dispatchable<PostInfo = PostDispatchInfo> + GetDispatchInfo,
Expand Down Expand Up @@ -133,7 +135,7 @@ where
handle.context().address,
SELECTOR_LOG_TRANSFER_OWNER,
Into::<H256>::into(owner),
solidity::encode_event_data(Into::<H256>::into(target_new_owner))
solidity::encode_event_data(Into::<H256>::into(target_new_owner)),
)
.record(handle)?;

Expand Down Expand Up @@ -163,8 +165,9 @@ where
log1(
handle.context().address,
SELECTOR_LOG_NEW_OWNER,
solidity::encode_event_data(Into::<H256>::into(target_new_owner))
).record(handle)?;
solidity::encode_event_data(Into::<H256>::into(target_new_owner)),
)
.record(handle)?;

Ok(())
}
Expand Down Expand Up @@ -203,6 +206,19 @@ where
.collect())
}

#[precompile::public("getValidatorMissingBlocks(address)")]
#[precompile::view]
fn get_validator_missing_blocks(
handle: &mut impl PrecompileHandle,
validator: Address,
) -> EvmResult<U256> {
handle.record_cost(RuntimeHelper::<Runtime>::db_read_gas_cost())?;
let account_id =
<Runtime as pallet_evm::Config>::AddressMapping::into_account_id(validator.into());
let epochs_missed = pallet_validator_set::EpochsMissed::<Runtime>::get(account_id);
Ok(epochs_missed)
}

#[precompile::public("addValidator(address)")]
fn add_validator(handle: &mut impl PrecompileHandle, new_validator: Address) -> EvmResult {
handle.record_cost(RuntimeHelper::<Runtime>::db_read_gas_cost())?;
Expand All @@ -229,7 +245,7 @@ where
log1(
handle.context().address,
SELECTOR_VALIDATOR_ADDED,
solidity::encode_event_data(Into::<H256>::into(origin_id))
solidity::encode_event_data(Into::<H256>::into(origin_id)),
)
.record(handle)?;

Expand Down Expand Up @@ -265,7 +281,7 @@ where
log1(
handle.context().address,
SELECTOR_VALIDATOR_REMOVED,
solidity::encode_event_data(Into::<H256>::into(origin_id))
solidity::encode_event_data(Into::<H256>::into(origin_id)),
)
.record(handle)?;

Expand Down
53 changes: 49 additions & 4 deletions precompiles/validator-controller/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ fn selectors() {
assert!(PCall::add_validator_selectors().contains(&0x4d238c8e));
assert!(PCall::remove_validator_selectors().contains(&0x40a141ff));
assert!(PCall::get_validator_list_selectors().contains(&0xe35c0f7d));
assert!(PCall::get_validator_missing_blocks_selectors().contains(&0x41ee9a53));
assert_eq!(
crate::SELECTOR_LOG_NEW_OWNER,
&Keccak256::digest(b"NewOwner(address)")[..]
Expand All @@ -33,6 +34,7 @@ fn modifiers() {

tester.test_view_modifier(PCall::owner_selectors());
tester.test_view_modifier(PCall::pending_owner_selectors());
tester.test_view_modifier(PCall::get_validator_missing_blocks_selectors());
tester.test_default_modifier(PCall::transfer_ownership_selectors());
tester.test_default_modifier(PCall::claim_ownership_selectors());
tester.test_default_modifier(PCall::add_validator_selectors());
Expand Down Expand Up @@ -138,7 +140,7 @@ fn claim_ownership_if_claimable() {
.expect_log(log1(
Precompile1,
SELECTOR_LOG_NEW_OWNER,
solidity::encode_event_data(Into::<H256>::into(new_owner))
solidity::encode_event_data(Into::<H256>::into(new_owner)),
))
.execute_some();

Expand All @@ -164,7 +166,7 @@ fn add_validator() {
.expect_log(log1(
Precompile1,
SELECTOR_VALIDATOR_ADDED,
solidity::encode_event_data(account_id_to_evm_address(validator.clone()))
solidity::encode_event_data(account_id_to_evm_address(validator.clone())),
))
.execute_some();

Expand Down Expand Up @@ -217,7 +219,7 @@ fn add_validator_if_already_init() {
.expect_log(log1(
Precompile1,
SELECTOR_VALIDATOR_ADDED,
solidity::encode_event_data(account_id_to_evm_address(validator.clone()))
solidity::encode_event_data(account_id_to_evm_address(validator.clone())),
))
.execute_some();

Expand Down Expand Up @@ -302,7 +304,7 @@ fn remove_validator() {
.expect_log(log1(
Precompile1,
SELECTOR_VALIDATOR_REMOVED,
solidity::encode_event_data(account_id_to_evm_address(validator.clone()))
solidity::encode_event_data(account_id_to_evm_address(validator.clone())),
))
.execute_some();

Expand Down Expand Up @@ -369,3 +371,46 @@ fn get_default_active_validator_list() {
);
});
}

#[test]
fn checks_if_validator_is_missing_blocks() {
let sender = UnpermissionedAccount::get();
let validator = ValidatorInitial::get();
let validators = vec![validator.clone()];
ExtBuilder::default()
.with_validators(validators.clone())
.build()
.execute_with(|| {
precompiles()
.prepare_test(
sender,
Precompile1,
PCall::get_validator_missing_blocks {
validator: account_id_to_evm_address(validator.clone()),
},
)
.execute_returns(U256::zero());
});
}

#[test]
fn checks_a_validator_missing_blocks() {
let sender = UnpermissionedAccount::get();
let validator = ValidatorInitial::get();
let validators = vec![validator.clone()];
ExtBuilder::default()
.with_validators(validators.clone())
.build()
.execute_with(|| {
pallet_validator_set::EpochsMissed::<Runtime>::set(validator.clone(), U256::from(2));
precompiles()
.prepare_test(
sender,
Precompile1,
PCall::get_validator_missing_blocks {
validator: account_id_to_evm_address(validator.clone()),
},
)
.execute_returns(U256::from(2));
});
}

0 comments on commit 7c52863

Please sign in to comment.