mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 23:18:15 -05:00
adjust code to reviews, abstract funcs, clean up files
Former-commit-id: ec19a9de17ec38c54af49684426345056fa3fb07 [formerly a8533d2bcc036bde18583abc4a157d63e552ee06] Former-commit-id: b085ecaec184ad2c2370388c2717d1e6f8a2e04f
This commit is contained in:
@@ -1 +0,0 @@
|
||||
123456
|
||||
@@ -1,13 +1,17 @@
|
||||
package sharding
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
@@ -78,7 +82,7 @@ func (c *Client) Start() error {
|
||||
//
|
||||
// TODO: this function should store the validator's VMC index as a property
|
||||
// in the client's struct
|
||||
if err := initVMCValidator(c); err != nil {
|
||||
if err := joinValidatorSet(c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -95,6 +99,13 @@ func (c *Client) Wait() {
|
||||
// TODO: Blocking lock.
|
||||
}
|
||||
|
||||
// WatchCollationHeaders checks the logs for add_header func calls
|
||||
// and updates the head collation of the client. We can probably store
|
||||
// this as a property of the client struct
|
||||
func (c *Client) WatchCollationHeaders() {
|
||||
|
||||
}
|
||||
|
||||
// dialRPC endpoint to node.
|
||||
func dialRPC(endpoint string) (*rpc.Client, error) {
|
||||
if endpoint == "" {
|
||||
@@ -119,9 +130,26 @@ func (c *Client) unlockAccount(account accounts.Account) error {
|
||||
return c.keystore.Unlock(account, pass)
|
||||
}
|
||||
|
||||
// TODO: Watch logs for add_header func calls and update the head collation
|
||||
// of the client. We can probably store this as a property of the client
|
||||
// struct
|
||||
func (c *Client) watchHeaders() {
|
||||
func (c *Client) createTXOps() (bind.TransactOpts, error) {
|
||||
|
||||
accounts := c.keystore.Accounts()
|
||||
if len(accounts) == 0 {
|
||||
return bind.TransactOpts{}, fmt.Errorf("no accounts found")
|
||||
}
|
||||
|
||||
if err := c.unlockAccount(accounts[0]); err != nil {
|
||||
return bind.TransactOpts{}, fmt.Errorf("unable to unlock account 0: %v", err)
|
||||
}
|
||||
|
||||
return bind.TransactOpts{
|
||||
From: accounts[0].Address,
|
||||
Signer: func(signer types.Signer, addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
|
||||
networkID, err := c.client.NetworkID(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to fetch networkID: %v", err)
|
||||
}
|
||||
return c.keystore.SignTx(accounts[0], tx, networkID /* chainID */)
|
||||
},
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -22,26 +22,27 @@ func subscribeBlockHeaders(c *Client) error {
|
||||
return fmt.Errorf("unable to subscribe to incoming headers. %v", err)
|
||||
}
|
||||
|
||||
log.Info("listening for new headers...")
|
||||
log.Info("Listening for new headers...")
|
||||
|
||||
for {
|
||||
// TODO: Error handling for getting disconnected from the client
|
||||
select {
|
||||
case head := <-headerChan:
|
||||
// Query the current state to see if we are an eligible proposer
|
||||
log.Info(fmt.Sprintf("received new header %v", head.Number.String()))
|
||||
log.Info(fmt.Sprintf("Received new header: %v", head.Number.String()))
|
||||
// TODO: Only run this code on certain periods?
|
||||
err := watchShards(c, head)
|
||||
if err != nil {
|
||||
if err := checkShardsForProposal(c, head); err != nil {
|
||||
return fmt.Errorf("unable to watch shards. %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// watchShards checks if we are an eligible proposer for collation for
|
||||
// the available shards in the VMC. The function calls getEligibleProposer from
|
||||
// the VMC and proposes a collation if conditions are met
|
||||
func watchShards(c *Client, head *types.Header) error {
|
||||
// checkShardsForProposal checks if we are an eligible proposer for
|
||||
// collation for the available shards in the VMC. The function calls
|
||||
// getEligibleProposer from the VMC and proposes a collation if
|
||||
// conditions are met
|
||||
func checkShardsForProposal(c *Client, head *types.Header) error {
|
||||
|
||||
accounts := c.keystore.Accounts()
|
||||
if len(accounts) == 0 {
|
||||
@@ -52,31 +53,29 @@ func watchShards(c *Client, head *types.Header) error {
|
||||
return fmt.Errorf("cannot unlock account. %v", err)
|
||||
}
|
||||
|
||||
log.Info(fmt.Sprint("watching shards..."))
|
||||
s := 0
|
||||
for s < shardCount {
|
||||
log.Info("Watching shards...")
|
||||
for s := int64(0); s < shardCount; s++ {
|
||||
// Checks if we are an eligible proposer according to the VMC
|
||||
ops := bind.CallOpts{}
|
||||
period := head.Number.Div(head.Number, big.NewInt(int64(periodLength)))
|
||||
addr, err := c.vmc.VMCCaller.GetEligibleProposer(&ops, big.NewInt(int64(s)), period)
|
||||
period := head.Number.Div(head.Number, big.NewInt(periodLength))
|
||||
addr, err := c.vmc.VMCCaller.GetEligibleProposer(&bind.CallOpts{}, big.NewInt(s), period)
|
||||
// TODO: When we are not a proposer, we get the error of being unable to
|
||||
// unmarshal empty output. Open issue to deal with this.
|
||||
|
||||
// If output is non-empty and the addr == coinbase
|
||||
if err == nil && addr == accounts[0].Address {
|
||||
log.Info(fmt.Sprintf("selected as collator on shard %d", s))
|
||||
log.Info(fmt.Sprintf("Selected as collator on shard: %d", s))
|
||||
err := proposeCollation(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not propose collation. %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
s++
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// proposeCollation interacts with the VMC directly to add a collation header
|
||||
func proposeCollation(shardID int) error {
|
||||
func proposeCollation(shardID int64) error {
|
||||
// TODO: Adds a collation header to the VMC with the following fields:
|
||||
// [
|
||||
// shard_id: uint256,
|
||||
@@ -101,6 +100,6 @@ func proposeCollation(shardID int) error {
|
||||
// This functions will fetch the transactions in the txpool and and apply
|
||||
// them to finish up the collation. It will then need to broadcast the
|
||||
// collation to the main chain using JSON-RPC.
|
||||
log.Info(fmt.Sprint("propose collation called"))
|
||||
log.Info("Propose collation function called")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ import (
|
||||
|
||||
var (
|
||||
// Number of network shards
|
||||
shardCount = 100
|
||||
shardCount = int64(100)
|
||||
// Address of the validator management contract
|
||||
validatorManagerAddress = common.HexToAddress("0x0") // TODO
|
||||
// Gas limit for verifying signatures
|
||||
sigGasLimit = 40000
|
||||
// Number of blocks in a period
|
||||
periodLength = 5
|
||||
periodLength = int64(5)
|
||||
// Number of periods ahead of current period which the contract is able to return the collator of that period.
|
||||
lookaheadPeriods = 4
|
||||
// Required deposit size in wei
|
||||
|
||||
@@ -5,9 +5,6 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/sharding/contracts"
|
||||
)
|
||||
@@ -17,32 +14,18 @@ import (
|
||||
func initVMC(c *Client) error {
|
||||
b, err := c.client.CodeAt(context.Background(), validatorManagerAddress, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get contract code at %s. %v", validatorManagerAddress, err)
|
||||
return fmt.Errorf("unable to get contract code at %s: %v", validatorManagerAddress, err)
|
||||
}
|
||||
|
||||
if len(b) == 0 {
|
||||
log.Info(fmt.Sprintf("No validator management contract found at %s. Deploying new contract.", validatorManagerAddress.String()))
|
||||
|
||||
accounts := c.keystore.Accounts()
|
||||
if len(accounts) == 0 {
|
||||
return fmt.Errorf("no accounts found")
|
||||
txOps, err := c.createTXOps()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to intiate the transaction: %v", err)
|
||||
}
|
||||
|
||||
if err := c.unlockAccount(accounts[0]); err != nil {
|
||||
return fmt.Errorf("unable to unlock account 0: %v", err)
|
||||
}
|
||||
ops := bind.TransactOpts{
|
||||
From: accounts[0].Address,
|
||||
Signer: func(signer types.Signer, addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
|
||||
networkID, err := c.client.NetworkID(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to fetch networkID: %v", err)
|
||||
}
|
||||
return c.keystore.SignTx(accounts[0], tx, networkID /* chainID */)
|
||||
},
|
||||
}
|
||||
|
||||
addr, tx, contract, err := contracts.DeployVMC(&ops, c.client)
|
||||
addr, tx, contract, err := contracts.DeployVMC(&txOps, c.client)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to deploy validator management contract: %v", err)
|
||||
}
|
||||
@@ -67,41 +50,22 @@ func initVMC(c *Client) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// initVMCValidator checks if the account is a validator in the VMC. If
|
||||
// joinValidatorSet checks if the account is a validator in the VMC. If
|
||||
// the account is not in the set, it will deposit 100ETH into contract.
|
||||
func initVMCValidator(c *Client) error {
|
||||
func joinValidatorSet(c *Client) error {
|
||||
|
||||
// TODO: Check if account is already in validator set. Fetch this From
|
||||
// the VMC contract's validator set
|
||||
|
||||
// Unlocks the current account from the keystore
|
||||
accounts := c.keystore.Accounts()
|
||||
if len(accounts) == 0 {
|
||||
return fmt.Errorf("no accounts found")
|
||||
txOps, err := c.createTXOps()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to intiate the deposit transaction: %v", err)
|
||||
}
|
||||
|
||||
if err := c.unlockAccount(accounts[0]); err != nil {
|
||||
return fmt.Errorf("unable to unlock account 0: %v", err)
|
||||
}
|
||||
|
||||
// Deposits 100ETH into the VMC from the current account
|
||||
ops := bind.TransactOpts{
|
||||
From: accounts[0].Address,
|
||||
Value: depositSize,
|
||||
Signer: func(signer types.Signer, addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
|
||||
networkID, err := c.client.NetworkID(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to fetch networkID: %v", err)
|
||||
}
|
||||
return c.keystore.SignTx(accounts[0], tx, networkID /* chainID */)
|
||||
},
|
||||
}
|
||||
|
||||
_, err := c.vmc.VMCTransactor.Deposit(&ops)
|
||||
tx, err := c.vmc.VMCTransactor.Deposit(&txOps)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to deposit eth and become a validator: %v", err)
|
||||
}
|
||||
log.Info(fmt.Sprintf("deposited 100ETH into contract"))
|
||||
log.Info(fmt.Sprintf("Deposited 100ETH into contract with transaction hash: %v", tx.Hash()))
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user