mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 07:58:22 -05:00
sharding: get_eligible_collator with tests
Former-commit-id: 19bcd3b213dec79c4fa634e31105c7e09cd7ffd2 [formerly be97e08143820904c399eff1f9b27dccc84bf3c0] Former-commit-id: e1c18d06271f0df5c667823372ff8f314a6d9f82
This commit is contained in:
@@ -87,10 +87,10 @@ contract SMC {
|
||||
uint constant PROPOSER_DEPOSIT = 1 ether;
|
||||
// The minimum balance of a proposer (for collators)
|
||||
uint constant MIN_PROPOSER_BALANCE = 0.1 ether;
|
||||
// Time the ether is locked by collators
|
||||
uint constant COLLATOR_LOCKUP_LENGTH = 16128;
|
||||
// Time the ether is locked by proposers
|
||||
uint constant PROPOSER_LOCKUP_LENGTH = 48;
|
||||
// Time the ether is locked by collators (Not constant for testing)
|
||||
uint COLLATOR_LOCKUP_LENGTH = 16128;
|
||||
// Time the ether is locked by proposers (Not constant for testing)
|
||||
uint PROPOSER_LOCKUP_LENGTH = 48;
|
||||
// Number of periods ahead of current period, which the contract
|
||||
// is able to return the collator of that period
|
||||
uint constant LOOKAHEAD_LENGTH = 4;
|
||||
@@ -98,25 +98,31 @@ contract SMC {
|
||||
// Log the latest period number of the shard
|
||||
mapping (int => int) public period_head;
|
||||
|
||||
function SMC() public {
|
||||
function SMC(uint collator_lockup_length, uint proposer_lockup_length) public {
|
||||
COLLATOR_LOCKUP_LENGTH = collator_lockup_length;
|
||||
PROPOSER_LOCKUP_LENGTH = proposer_lockup_length;
|
||||
}
|
||||
|
||||
event LOG(uint L);
|
||||
// Uses a block hash as a seed to pseudorandomly select a signer from the collator pool.
|
||||
// [TODO] Chance of being selected should be proportional to the collator's deposit.
|
||||
// Should be able to return a value for the current period or any future period up to.
|
||||
function get_eligible_collator(uint256 shard_id, uint256 period) public view returns(address) {
|
||||
require(period >= LOOKAHEAD_LENGTH);
|
||||
require((period - LOOKAHEAD_LENGTH) * PERIOD_LENGTH < block.number);
|
||||
function get_eligible_collator(uint shard_id, uint period) public view returns(address) {
|
||||
uint current_period = block.number / PERIOD_LENGTH;
|
||||
uint period_to_look = ((period - LOOKAHEAD_LENGTH) * PERIOD_LENGTH);
|
||||
require(period >= current_period);
|
||||
require(period <= (current_period + LOOKAHEAD_LENGTH));
|
||||
require(collator_pool_len > 0);
|
||||
// [TODO] Should check further if this safe or not
|
||||
return collator_pool[
|
||||
uint(
|
||||
keccak256(
|
||||
uint(block.blockhash((period - LOOKAHEAD_LENGTH) * PERIOD_LENGTH)),
|
||||
shard_id
|
||||
)
|
||||
) %
|
||||
collator_pool_len
|
||||
if (period <= LOOKAHEAD_LENGTH)
|
||||
period_to_look = period;
|
||||
require(period_to_look < block.number);
|
||||
return collator_pool[uint(
|
||||
keccak256(
|
||||
block.blockhash(period_to_look),
|
||||
shard_id
|
||||
)
|
||||
) %
|
||||
collator_pool_len
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package contracts
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
@@ -12,23 +13,32 @@ import (
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
type SMCConfig struct {
|
||||
collatorLockupLenght *big.Int
|
||||
proposerLockupLength *big.Int
|
||||
}
|
||||
|
||||
var (
|
||||
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
addr = crypto.PubkeyToAddress(key.PublicKey)
|
||||
mainKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
accountBalance1001Eth, _ = new(big.Int).SetString("1001000000000000000000", 10)
|
||||
collatorDeposit, _ = new(big.Int).SetString("1000000000000000000000", 10)
|
||||
smcConfig = SMCConfig{
|
||||
collatorLockupLenght: new(big.Int).SetInt64(1),
|
||||
proposerLockupLength: new(big.Int).SetInt64(1),
|
||||
}
|
||||
)
|
||||
|
||||
func deploySMCContract(backend *backends.SimulatedBackend) (common.Address, *types.Transaction, *SMC, error) {
|
||||
func deploySMCContract(backend *backends.SimulatedBackend, key *ecdsa.PrivateKey) (common.Address, *types.Transaction, *SMC, error) {
|
||||
transactOpts := bind.NewKeyedTransactor(key)
|
||||
defer backend.Commit()
|
||||
return DeploySMC(transactOpts, backend)
|
||||
return DeploySMC(transactOpts, backend, smcConfig.collatorLockupLenght, smcConfig.proposerLockupLength)
|
||||
}
|
||||
|
||||
// Test creating the SMC contract
|
||||
func TestContractCreation(t *testing.T) {
|
||||
addr := crypto.PubkeyToAddress(mainKey.PublicKey)
|
||||
backend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: accountBalance1001Eth}})
|
||||
_, _, _, err := deploySMCContract(backend)
|
||||
_, _, _, err := deploySMCContract(backend, mainKey)
|
||||
backend.Commit()
|
||||
if err != nil {
|
||||
t.Fatalf("can't deploy SMC: %v", err)
|
||||
@@ -37,12 +47,13 @@ func TestContractCreation(t *testing.T) {
|
||||
|
||||
// Test register collator
|
||||
func TestCollatorDeposit(t *testing.T) {
|
||||
addr := crypto.PubkeyToAddress(mainKey.PublicKey)
|
||||
backend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: accountBalance1001Eth}})
|
||||
transactOpts := bind.NewKeyedTransactor(key)
|
||||
_, _, smc, _ := deploySMCContract(backend)
|
||||
transactOpts := bind.NewKeyedTransactor(mainKey)
|
||||
_, _, smc, _ := deploySMCContract(backend, mainKey)
|
||||
|
||||
// Test register_collator() function
|
||||
// Deposit 100 Eth
|
||||
// Deposit 1000 Eth
|
||||
transactOpts.Value = collatorDeposit
|
||||
|
||||
if _, err := smc.Register_collator(transactOpts); err != nil {
|
||||
@@ -84,11 +95,12 @@ func TestCollatorDeposit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test collator withdraw from the pool
|
||||
func TestCollatorWithdraw(t *testing.T) {
|
||||
// Test collator deregister from pool
|
||||
func TestCollatorDeregister(t *testing.T) {
|
||||
addr := crypto.PubkeyToAddress(mainKey.PublicKey)
|
||||
backend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: accountBalance1001Eth}})
|
||||
transactOpts := bind.NewKeyedTransactor(key)
|
||||
_, _, smc, _ := deploySMCContract(backend)
|
||||
transactOpts := bind.NewKeyedTransactor(mainKey)
|
||||
_, _, smc, _ := deploySMCContract(backend, mainKey)
|
||||
|
||||
transactOpts.Value = collatorDeposit
|
||||
// Register collator
|
||||
@@ -113,13 +125,50 @@ func TestCollatorWithdraw(t *testing.T) {
|
||||
if withdrawsEventsIterator.Event.Pool_index.Cmp(big.NewInt(0)) != 0 {
|
||||
t.Fatalf("Collator index mismatch: %d should be 0", withdrawsEventsIterator.Event.Pool_index)
|
||||
}
|
||||
// for i := 0; i < 16128*5+1; i++ {
|
||||
// backend.Commit()
|
||||
// }
|
||||
|
||||
// Release collator
|
||||
// _, err = smc.Release_collator(transactOpts)
|
||||
// if err != nil {
|
||||
// t.Fatalf("Failed to release collator: %v", err)
|
||||
// }
|
||||
}
|
||||
|
||||
func TestGetEligibleCollator(t *testing.T) {
|
||||
const numberCollators = 20
|
||||
var collatorPoolAddr [numberCollators]common.Address
|
||||
var collatorPoolPrivKeys [numberCollators]*ecdsa.PrivateKey
|
||||
var transactOpts [numberCollators]*bind.TransactOpts
|
||||
genesis := make(core.GenesisAlloc)
|
||||
|
||||
for i := 0; i < numberCollators; i++ {
|
||||
key, _ := crypto.GenerateKey()
|
||||
collatorPoolPrivKeys[i] = key
|
||||
collatorPoolAddr[i] = crypto.PubkeyToAddress(key.PublicKey)
|
||||
transactOpts[i] = bind.NewKeyedTransactor(key)
|
||||
transactOpts[i].Value = collatorDeposit
|
||||
|
||||
genesis[collatorPoolAddr[i]] = core.GenesisAccount{
|
||||
Balance: accountBalance1001Eth,
|
||||
}
|
||||
}
|
||||
|
||||
backend := backends.NewSimulatedBackend(genesis)
|
||||
_, _, smc, _ := deploySMCContract(backend, collatorPoolPrivKeys[0])
|
||||
|
||||
// Register collator
|
||||
for i := 0; i < numberCollators; i++ {
|
||||
smc.Register_collator(transactOpts[i])
|
||||
}
|
||||
|
||||
// Move blockchain 4 blocks further (Head is at 5 after) : period 1
|
||||
for i := 0; i < 4; i++ {
|
||||
backend.Commit()
|
||||
}
|
||||
|
||||
_, err := smc.Get_eligible_collator(&bind.CallOpts{}, big.NewInt(0), big.NewInt(4))
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot get eligible collator: %v", err)
|
||||
}
|
||||
// after: Head is 11, period 2
|
||||
for i := 0; i < 6; i++ {
|
||||
backend.Commit()
|
||||
}
|
||||
_, err = smc.Get_eligible_collator(&bind.CallOpts{}, big.NewInt(1), big.NewInt(6))
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot get eligible collator: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user