From 6fe43bd446b25a2b954b09efd3ebbec7556789c6 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Tue, 6 Feb 2018 14:04:45 -0600 Subject: [PATCH] adjust code to reviews, abstract funcs, clean up files Former-commit-id: ec19a9de17ec38c54af49684426345056fa3fb07 [formerly a8533d2bcc036bde18583abc4a157d63e552ee06] Former-commit-id: b085ecaec184ad2c2370388c2717d1e6f8a2e04f --- password.txt | 1 - sharding/client.go | 38 ++++++++++++++++++++++++---- sharding/collator.go | 37 +++++++++++++-------------- sharding/config.go | 4 +-- sharding/vmc.go | 60 +++++++++----------------------------------- 5 files changed, 65 insertions(+), 75 deletions(-) delete mode 100644 password.txt diff --git a/password.txt b/password.txt deleted file mode 100644 index 9f358a4add..0000000000 --- a/password.txt +++ /dev/null @@ -1 +0,0 @@ -123456 diff --git a/sharding/client.go b/sharding/client.go index d89c78fe55..976288972a 100644 --- a/sharding/client.go +++ b/sharding/client.go @@ -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 } diff --git a/sharding/collator.go b/sharding/collator.go index 7d6f41f8d1..3b0d7cf580 100644 --- a/sharding/collator.go +++ b/sharding/collator.go @@ -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 } diff --git a/sharding/config.go b/sharding/config.go index 29432eeea5..05bd17757b 100644 --- a/sharding/config.go +++ b/sharding/config.go @@ -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 diff --git a/sharding/vmc.go b/sharding/vmc.go index 5184ff8e45..fee6daf48d 100644 --- a/sharding/vmc.go +++ b/sharding/vmc.go @@ -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 }