A simple implementation of the contract validator_manager with its tester. The contract spec is in doc.md
Validator Manager Contract (in sharding/contracts/validator_manager.v.py)
Written in viper, with three main functions.
deposit(address validationCodeAddr, address returnAddr) returns uint256: adds a validator to the validator set, with the validator's size being the msg.value (ie. amount of ETH deposited) in the function call. Returns the validator index. validationCodeAddr stores the address of the validation code; the function fails if this address's code has not been purity-verified.
withdraw(uint256 validatorIndex, bytes sig) returns bool: verifies that the signature is correct (ie. a call with 200000 gas, validationCodeAddr as destination, 0 value and sha3("withdraw") + sig as data returns 1).
sample(uint256 block_number, uint256 shardId, uint256 sigIndex) returns uint256: uses the block hash of the given block number as a seed to pseudorandomly select a signer from the validator set. Chance of being selected should be proportional to the validator's deposit.
Implementation details
In deposit and withdraw, we use a stack to maintain the indexes of the empty slots in array validators in order to make good use of spaces and keep the time complexity of deposit and withdraw O(1)
In sample, though we try to make use of all empty slots caused by withdraw, there are still some existing. In order to avoid sampling empty slots, we perform resampling once we get a empty slot, until a non-empty one sampled.
Current deposit size for a valid validator is 100 ETH. All validators should deposit with 100 ETH, otherwise fail.
Validator Manager Tester (in sharding/contracts/validator_manager_tester.py)
Use pyethereum.tester to test each functions
Test cases
deposit should fail when msg.value != deposit_size
withdraw should fails when no corresponding validator record exists
deposit should work fine when msg.value == deposit_size
deposit should make use of empty slots caused by withdraw
deposit should use the last empty slots caused by withdraw due to the fact that we use stack to stack indexes of the empty slots in validators
withdraw should fail when the signature is not correct
sample should return a non-empty validator when num_validators > 0
sample should return a empty validator(whose validation_code_addr == 0x00) when num_validators == 0
How to run the test
cd sharding/contracts && python validator_manager_tester.py
Description
A simple implementation of the contract
validator_manager
with its tester. The contract spec is in doc.mdValidator Manager Contract (in
sharding/contracts/validator_manager.v.py
)Written in viper, with three main functions.
deposit(address validationCodeAddr, address returnAddr) returns uint256
: adds a validator to the validator set, with the validator's size being the msg.value (ie. amount of ETH deposited) in the function call. Returns the validator index. validationCodeAddr stores the address of the validation code; the function fails if this address's code has not been purity-verified.withdraw(uint256 validatorIndex, bytes sig) returns bool
: verifies that the signature is correct (ie. a call with 200000 gas, validationCodeAddr as destination, 0 value and sha3("withdraw") + sig as data returns 1).sample(uint256 block_number, uint256 shardId, uint256 sigIndex) returns uint256
: uses the block hash of the given block number as a seed to pseudorandomly select a signer from the validator set. Chance of being selected should be proportional to the validator's deposit.Implementation details
deposit
andwithdraw
, we use a stack to maintain the indexes of the empty slots in arrayvalidators
in order to make good use of spaces and keep the time complexity ofdeposit
andwithdraw
O(1)sample
, though we try to make use of all empty slots caused bywithdraw
, there are still some existing. In order to avoid sampling empty slots, we perform resampling once we get a empty slot, until a non-empty one sampled.100 ETH
. All validators should deposit with100 ETH
, otherwise fail.Validator Manager Tester (in
sharding/contracts/validator_manager_tester.py
)Use
pyethereum.tester
to test each functionsTest cases
deposit
should fail when msg.value != deposit_sizewithdraw
should fails when no corresponding validator record existsdeposit
should work fine when msg.value == deposit_sizedeposit
should make use of empty slots caused bywithdraw
deposit
should use the last empty slots caused bywithdraw
due to the fact that we use stack to stack indexes of the empty slots invalidators
withdraw
should fail when the signature is not correctsample
should return a non-empty validator whennum_validators > 0
sample
should return a empty validator(whosevalidation_code_addr == 0x00
) whennum_validators == 0
How to run the test
TODO