good morning!!!!

Skip to content
Snippets Groups Projects
Unverified Commit 26ce6db0 authored by Jaynti Kanani's avatar Jaynti Kanani
Browse files

WIP span sync

parent 15aeef09
Branches
No related tags found
No related merge requests found
...@@ -1670,7 +1670,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai ...@@ -1670,7 +1670,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
if config.Clique != nil { if config.Clique != nil {
engine = clique.New(config.Clique, chainDb) engine = clique.New(config.Clique, chainDb)
} else if config.Bor != nil { } else if config.Bor != nil {
engine = bor.New(config.Bor, chainDb, nil) engine = bor.New(config, chainDb, nil)
} else { } else {
engine = ethash.NewFaker() engine = ethash.NewFaker()
if !ctx.GlobalBool(FakePoWFlag.Name) { if !ctx.GlobalBool(FakePoWFlag.Name) {
......
...@@ -13,14 +13,17 @@ import ( ...@@ -13,14 +13,17 @@ import (
"sync" "sync"
"time" "time"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/ethapi"
...@@ -33,7 +36,7 @@ import ( ...@@ -33,7 +36,7 @@ import (
"golang.org/x/crypto/sha3" "golang.org/x/crypto/sha3"
) )
const validatorsetABI = `[{"constant":true,"inputs":[{"name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"bytes"},{"name":"sigs","type":"bytes"},{"name":"txBytes","type":"bytes"},{"name":"proof","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"bytes"},{"name":"sigs","type":"bytes"},{"name":"txBytes","type":"bytes"},{"name":"proof","type":"bytes"}],"name":"validateValidatorSet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]` const validatorsetABI = `[{"constant":true,"inputs":[{"name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"proposeSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newSpan","type":"uint256"},{"name":"proposer","type":"address"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"},{"name":"validatorBytes","type":"bytes"},{"name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"bytes"},{"name":"sigs","type":"bytes"},{"name":"txBytes","type":"bytes"},{"name":"proof","type":"bytes"}],"name":"validateValidatorSet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]`
const ( const (
checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database
...@@ -56,6 +59,7 @@ var ( ...@@ -56,6 +59,7 @@ var (
diffNoTurn = big.NewInt(1) // Block difficulty for out-of-turn signatures diffNoTurn = big.NewInt(1) // Block difficulty for out-of-turn signatures
validatorHeaderBytesLength = common.AddressLength + 20 // address + power validatorHeaderBytesLength = common.AddressLength + 20 // address + power
systemAddress = common.HexToAddress("0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE")
) )
// Various error messages to mark blocks invalid. These should be private to // Various error messages to mark blocks invalid. These should be private to
...@@ -227,6 +231,7 @@ func BorRLP(header *types.Header) []byte { ...@@ -227,6 +231,7 @@ func BorRLP(header *types.Header) []byte {
// Bor is the matic-bor consensus engine // Bor is the matic-bor consensus engine
type Bor struct { type Bor struct {
chainConfig *params.ChainConfig // Chain config
config *params.BorConfig // Consensus engine configuration parameters for bor consensus config *params.BorConfig // Consensus engine configuration parameters for bor consensus
db ethdb.Database // Database to store and retrieve snapshot checkpoints db ethdb.Database // Database to store and retrieve snapshot checkpoints
...@@ -247,11 +252,17 @@ type Bor struct { ...@@ -247,11 +252,17 @@ type Bor struct {
} }
// New creates a Matic Bor consensus engine. // New creates a Matic Bor consensus engine.
func New(config *params.BorConfig, db ethdb.Database, ethAPI *ethapi.PublicBlockChainAPI) *Bor { func New(
chainConfig *params.ChainConfig,
db ethdb.Database,
ethAPI *ethapi.PublicBlockChainAPI,
) *Bor {
// get bor config
borConfig := chainConfig.Bor
// Set any missing consensus parameters to their defaults // Set any missing consensus parameters to their defaults
conf := *config if borConfig != nil && borConfig.Sprint == 0 {
if conf.Sprint == 0 { borConfig.Sprint = defaultSprintLength
conf.Sprint = defaultSprintLength
} }
// Allocate the snapshot caches and create the engine // Allocate the snapshot caches and create the engine
...@@ -259,7 +270,8 @@ func New(config *params.BorConfig, db ethdb.Database, ethAPI *ethapi.PublicBlock ...@@ -259,7 +270,8 @@ func New(config *params.BorConfig, db ethdb.Database, ethAPI *ethapi.PublicBlock
signatures, _ := lru.NewARC(inmemorySignatures) signatures, _ := lru.NewARC(inmemorySignatures)
vABI, _ := abi.JSON(strings.NewReader(validatorsetABI)) vABI, _ := abi.JSON(strings.NewReader(validatorsetABI))
c := &Bor{ c := &Bor{
config: &conf, chainConfig: chainConfig,
config: borConfig,
db: db, db: db,
ethAPI: ethAPI, ethAPI: ethAPI,
recents: recents, recents: recents,
...@@ -267,6 +279,7 @@ func New(config *params.BorConfig, db ethdb.Database, ethAPI *ethapi.PublicBlock ...@@ -267,6 +279,7 @@ func New(config *params.BorConfig, db ethdb.Database, ethAPI *ethapi.PublicBlock
proposals: make(map[common.Address]bool), proposals: make(map[common.Address]bool),
validatorSetABI: vABI, validatorSetABI: vABI,
} }
return c return c
} }
...@@ -646,6 +659,9 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error { ...@@ -646,6 +659,9 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error {
// Finalize implements consensus.Engine, ensuring no uncles are set, nor block // Finalize implements consensus.Engine, ensuring no uncles are set, nor block
// rewards given. // rewards given.
func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) {
// commit span
// c.commitSpan(state, header, chainContext{Chain: chain, Bor: c})
// No block rewards in PoA, so the state remains as is and uncles are dropped // No block rewards in PoA, so the state remains as is and uncles are dropped
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.UncleHash = types.CalcUncleHash(nil) header.UncleHash = types.CalcUncleHash(nil)
...@@ -654,6 +670,9 @@ func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state ...@@ -654,6 +670,9 @@ func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state
// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, // FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
// nor block rewards given, and returns the final block. // nor block rewards given, and returns the final block.
func (c *Bor) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { func (c *Bor) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
// commit span
// c.commitSpan(state, header, chainContext{Chain: chain, Bor: c})
// No block rewards in PoA, so the state remains as is and uncles are dropped // No block rewards in PoA, so the state remains as is and uncles are dropped
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.UncleHash = types.CalcUncleHash(nil) header.UncleHash = types.CalcUncleHash(nil)
...@@ -792,21 +811,13 @@ func (c *Bor) Close() error { ...@@ -792,21 +811,13 @@ func (c *Bor) Close() error {
// GetCurrentValidators get current validators // GetCurrentValidators get current validators
func (c *Bor) GetCurrentValidators(snapshotNumber uint64, blockNumber uint64) ([]*Validator, error) { func (c *Bor) GetCurrentValidators(snapshotNumber uint64, blockNumber uint64) ([]*Validator, error) {
return GetValidators(snapshotNumber, blockNumber, c.config.Sprint, c.config.ValidatorContract, c.ethAPI)
}
// GetValidators get current validators
func GetValidators(snapshotNumber uint64, blockNumber uint64, sprint uint64, validatorContract string, ethAPI *ethapi.PublicBlockChainAPI) ([]*Validator, error) {
// block // block
blockNr := rpc.BlockNumber(snapshotNumber) blockNr := rpc.BlockNumber(snapshotNumber)
// validator set ABI
validatorSetABI, _ := abi.JSON(strings.NewReader(validatorsetABI))
// method // method
method := "getBorValidators" method := "getBorValidators"
data, err := validatorSetABI.Pack(method, big.NewInt(0).SetUint64(blockNumber)) data, err := c.validatorSetABI.Pack(method, big.NewInt(0).SetUint64(blockNumber))
if err != nil { if err != nil {
fmt.Println("Unable to pack tx for getValidator", "error", err) fmt.Println("Unable to pack tx for getValidator", "error", err)
return nil, err return nil, err
...@@ -817,9 +828,9 @@ func GetValidators(snapshotNumber uint64, blockNumber uint64, sprint uint64, val ...@@ -817,9 +828,9 @@ func GetValidators(snapshotNumber uint64, blockNumber uint64, sprint uint64, val
// call // call
msgData := (hexutil.Bytes)(data) msgData := (hexutil.Bytes)(data)
toAddress := common.HexToAddress(validatorContract) toAddress := common.HexToAddress(c.config.ValidatorContract)
gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
result, err := ethAPI.Call(ctx, ethapi.CallArgs{ result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{
Gas: &gas, Gas: &gas,
To: &toAddress, To: &toAddress,
Data: &msgData, Data: &msgData,
...@@ -838,7 +849,7 @@ func GetValidators(snapshotNumber uint64, blockNumber uint64, sprint uint64, val ...@@ -838,7 +849,7 @@ func GetValidators(snapshotNumber uint64, blockNumber uint64, sprint uint64, val
ret1, ret1,
} }
if err := validatorSetABI.Unpack(out, method, result); err != nil { if err := c.validatorSetABI.Unpack(out, method, result); err != nil {
return nil, err return nil, err
} }
...@@ -853,6 +864,107 @@ func GetValidators(snapshotNumber uint64, blockNumber uint64, sprint uint64, val ...@@ -853,6 +864,107 @@ func GetValidators(snapshotNumber uint64, blockNumber uint64, sprint uint64, val
return valz, nil return valz, nil
} }
func (c *Bor) commitSpan(
state *state.StateDB,
header *types.Header,
chain core.ChainContext,
) error {
// method
method := "commitSpan"
// get packed data
data, err := c.validatorSetABI.Pack(method)
if err != nil {
fmt.Println("Unable to pack tx for commitSpan", "error", err)
return err
}
// get system message
msg := getSystemMessage(common.HexToAddress(c.config.ValidatorContract), data)
// apply message
return applyMessage(msg, state, header, c.chainConfig, chain)
}
//
// Private methods
//
//
// Chain context
//
// chain context
type chainContext struct {
Chain consensus.ChainReader
Bor consensus.Engine
}
func (c chainContext) Engine() consensus.Engine {
return c.Bor
}
func (c chainContext) GetHeader(hash common.Hash, number uint64) *types.Header {
return c.Chain.GetHeader(hash, number)
}
// callmsg implements core.Message to allow passing it as a transaction simulator.
type callmsg struct {
ethereum.CallMsg
}
func (m callmsg) From() common.Address { return m.CallMsg.From }
func (m callmsg) Nonce() uint64 { return 0 }
func (m callmsg) CheckNonce() bool { return false }
func (m callmsg) To() *common.Address { return m.CallMsg.To }
func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
func (m callmsg) Gas() uint64 { return m.CallMsg.Gas }
func (m callmsg) Value() *big.Int { return m.CallMsg.Value }
func (m callmsg) Data() []byte { return m.CallMsg.Data }
// get system message
func getSystemMessage(toAddress common.Address, data []byte) callmsg {
return callmsg{
ethereum.CallMsg{
From: systemAddress,
Gas: math.MaxUint64 / 2,
GasPrice: big.NewInt(0),
Value: big.NewInt(0),
To: &toAddress,
Data: data,
},
}
}
// apply message
func applyMessage(
msg callmsg,
state *state.StateDB,
header *types.Header,
chainConfig *params.ChainConfig,
chainContext core.ChainContext,
) error {
// Create a new context to be used in the EVM environment
context := core.NewEVMContext(msg, header, chainContext, &header.Coinbase)
// Create a new environment which holds all relevant information
// about the transaction and calling mechanisms.
vmenv := vm.NewEVM(context, state, chainConfig, vm.Config{})
// Apply the transaction to the current state (included in the env)
_, _, err := vmenv.Call(
vm.AccountRef(msg.From()),
*msg.To(),
msg.Data(),
msg.Gas(),
msg.Value(),
)
// Update the state with pending changes
if err != nil {
state.Finalise(true)
}
return nil
}
func validatorContains(a []*Validator, x *Validator) (*Validator, bool) { func validatorContains(a []*Validator, x *Validator) (*Validator, bool) {
for _, n := range a { for _, n := range a {
if bytes.Compare(n.Address.Bytes(), x.Address.Bytes()) == 0 { if bytes.Compare(n.Address.Bytes(), x.Address.Bytes()) == 0 {
......
...@@ -257,7 +257,7 @@ func CreateConsensusEngine(ctx *node.ServiceContext, chainConfig *params.ChainCo ...@@ -257,7 +257,7 @@ func CreateConsensusEngine(ctx *node.ServiceContext, chainConfig *params.ChainCo
// If Matic Bor is requested, set it up // If Matic Bor is requested, set it up
if chainConfig.Bor != nil { if chainConfig.Bor != nil {
return bor.New(chainConfig.Bor, db, ee) return bor.New(chainConfig, db, ee)
} }
// Otherwise assume proof-of-work // Otherwise assume proof-of-work
......
...@@ -320,6 +320,7 @@ type BorConfig struct { ...@@ -320,6 +320,7 @@ type BorConfig struct {
ProducerDelay uint64 `json:"producerDelay"` // Number of seconds delay between two producer interval ProducerDelay uint64 `json:"producerDelay"` // Number of seconds delay between two producer interval
Sprint uint64 `json:"sprint"` // Epoch length to proposer Sprint uint64 `json:"sprint"` // Epoch length to proposer
ValidatorContract string `json:"validatorContract"` // Validator set contract ValidatorContract string `json:"validatorContract"` // Validator set contract
Heimdall string `json:"heimdall"` // heimdall light client url
} }
// String implements the stringer interface, returning the consensus engine details. // String implements the stringer interface, returning the consensus engine details.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment