add method to commit states

This commit is contained in:
Jaynti Kanani 2019-10-27 01:50:57 +05:30
parent a4d92f8e30
commit 0d86eed2c3
No known key found for this signature in database
GPG key ID: 4396982C976BAE5E
5 changed files with 155 additions and 25 deletions

View file

@ -108,11 +108,12 @@ func (w *wizard) makeGenesis() {
genesis.Difficulty = big.NewInt(1)
genesis.GasLimit = 10000000
genesis.Config.Bor = &params.BorConfig{
Period: 1,
ProducerDelay: 5,
Sprint: 60,
ValidatorContract: "0x0000000000000000000000000000000000001000",
Heimdall: "http://localhost:1317",
Period: 1,
ProducerDelay: 5,
Sprint: 60,
ValidatorContract: "0x0000000000000000000000000000000000001000",
StateReceiverContract: "0x0000000000000000000000000000000000001001",
Heimdall: "http://localhost:1317",
}
// We also need the initial list of signers

View file

@ -40,7 +40,8 @@ import (
"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":"newSpan","type":"uint256"},{"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":false,"inputs":[],"name":"proposeSpan","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":"spanProposalPending","outputs":[{"name":"","type":"bool"}],"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":true,"inputs":[{"name":"span","type":"uint256"},{"name":"signer","type":"address"}],"name":"isProducer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newSpan","type":"uint256"},{"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":"span","type":"uint256"},{"name":"signer","type":"address"}],"name":"isValidator","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"proposeSpan","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":"spanProposalPending","outputs":[{"name":"","type":"bool"}],"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 stateReceiverABI = `[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"states","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPendingStates","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"validatorSet","outputs":[{"name":"","type":"address"}],"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"},{"constant":true,"inputs":[],"name":"isValidatorSetContract","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"stateId","type":"uint256"}],"name":"proposeState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"signer","type":"address"}],"name":"isProducer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"signer","type":"address"}],"name":"isValidator","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}]`
const (
checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database
@ -246,9 +247,10 @@ type Bor struct {
signFn SignerFn // Signer function to authorize hashes with
lock sync.RWMutex // Protects the signer fields
ethAPI *ethapi.PublicBlockChainAPI
validatorSetABI abi.ABI
httpClient http.Client
ethAPI *ethapi.PublicBlockChainAPI
validatorSetABI abi.ABI
stateReceiverABI abi.ABI
httpClient http.Client
// The fields below are for testing only
fakeDiff bool // Skip difficulty verifications
@ -272,14 +274,16 @@ func New(
recents, _ := lru.NewARC(inmemorySnapshots)
signatures, _ := lru.NewARC(inmemorySignatures)
vABI, _ := abi.JSON(strings.NewReader(validatorsetABI))
sABI, _ := abi.JSON(strings.NewReader(stateReceiverABI))
c := &Bor{
chainConfig: chainConfig,
config: borConfig,
db: db,
ethAPI: ethAPI,
recents: recents,
signatures: signatures,
validatorSetABI: vABI,
chainConfig: chainConfig,
config: borConfig,
db: db,
ethAPI: ethAPI,
recents: recents,
signatures: signatures,
validatorSetABI: vABI,
stateReceiverABI: sABI,
httpClient: http.Client{
Timeout: time.Duration(5 * time.Second),
},
@ -663,10 +667,19 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error {
func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) {
// commit span
if header.Number.Uint64()%c.config.Sprint == 0 {
if err := c.checkAndCommitSpan(state, header, chainContext{Chain: chain, Bor: c}); err != nil {
cx := chainContext{Chain: chain, Bor: c}
// check and commit span
if err := c.checkAndCommitSpan(state, header, cx); err != nil {
fmt.Println("Error while committing span", err)
// return nil, err
}
// commit statees
if err := c.CommitStates(state, header, cx); err != nil {
fmt.Println("Error while committing states", err)
// return nil, err
}
}
// No block rewards in PoA, so the state remains as is and uncles are dropped
@ -679,11 +692,20 @@ func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state
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
if header.Number.Uint64()%c.config.Sprint == 0 {
err := c.checkAndCommitSpan(state, header, chainContext{Chain: chain, Bor: c})
cx := chainContext{Chain: chain, Bor: c}
// check and commit span
err := c.checkAndCommitSpan(state, header, cx)
if err != nil {
fmt.Println("Error while committing span", err)
// return nil, err
}
// commit statees
if err := c.CommitStates(state, header, cx); err != nil {
fmt.Println("Error while committing states", err)
// return nil, err
}
}
// No block rewards in PoA, so the state remains as is and uncles are dropped
@ -1083,6 +1105,100 @@ func (c *Bor) commitSpan(
return applyMessage(msg, state, header, c.chainConfig, chain)
}
// GetPendingStateProposals get pending state proposals
func (c *Bor) GetPendingStateProposals(snapshotNumber uint64) ([]*big.Int, error) {
// block
blockNr := rpc.BlockNumber(snapshotNumber)
// method
method := "getPendingStates"
data, err := c.stateReceiverABI.Pack(method)
if err != nil {
fmt.Println("Unable to pack tx for getPendingStates", "error", err)
return nil, err
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // cancel when we are finished consuming integers
msgData := (hexutil.Bytes)(data)
toAddress := common.HexToAddress(c.config.StateReceiverContract)
gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{
Gas: &gas,
To: &toAddress,
Data: &msgData,
}, blockNr)
if err != nil {
return nil, err
}
var ret = new([]*big.Int)
if err := c.stateReceiverABI.Unpack(ret, method, result); err != nil {
return nil, err
}
return *ret, nil
}
// CommitStates commit states
func (c *Bor) CommitStates(
state *state.StateDB,
header *types.Header,
chain core.ChainContext,
) error {
// get pending state proposals
stateIds, err := c.GetPendingStateProposals(header.Number.Uint64() - 1)
if err != nil {
return err
}
// state ids
if len(stateIds) > 0 {
fmt.Println("Found new proposed states", len(stateIds))
}
method := "commitState"
// itereate through state ids
for _, stateID := range stateIds {
// fetch from heimdall
response, err := FetchFromHeimdall(c.httpClient, c.chainConfig.Bor.Heimdall, "clerk", "event-record", strconv.FormatUint(stateID.Uint64(), 10))
if err != nil {
return err
}
// get event record
var eventRecord EventRecord
if err := json.Unmarshal(response.Result, &eventRecord); err != nil {
return err
}
recordBytes, err := rlp.EncodeToBytes(eventRecord)
if err != nil {
return err
}
// get packed data for commit state
data, err := c.stateReceiverABI.Pack(method, recordBytes)
if err != nil {
fmt.Println("Unable to pack tx for commitState", "error", err)
return err
}
// get system message
msg := getSystemMessage(common.HexToAddress(c.config.StateReceiverContract), data)
// apply message
if err := applyMessage(msg, state, header, c.chainConfig, chain); err != nil {
return err
}
}
return nil
}
//
// Private methods
//

14
consensus/bor/clerk.go Normal file
View file

@ -0,0 +1,14 @@
package bor
import (
"github.com/ethereum/go-ethereum/common"
)
// EventRecord represents state record
type EventRecord struct {
ID uint64 `json:"id" yaml:"id"`
Contract common.Address `json:"contract" yaml:"contract"`
Data []byte `json:"data" yaml:"data"`
TxHash common.Hash `json:"tx_hash" yaml:"tx_hash"`
LogIndex uint64 `json:"log_index" yaml:"log_index"`
}

View file

@ -241,8 +241,6 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
// add recents
snap.Recents[number] = signer
// TODO remove
fmt.Println("Recent signer", "number", number, "signer", signer.Hex())
}
snap.Number += uint64(len(headers))
snap.Hash = headers[len(headers)-1].Hash()

View file

@ -316,11 +316,12 @@ func (c *CliqueConfig) String() string {
// BorConfig is the consensus engine configs for Matic bor based sealing.
type BorConfig struct {
Period uint64 `json:"period"` // Number of seconds between blocks to enforce
ProducerDelay uint64 `json:"producerDelay"` // Number of seconds delay between two producer interval
Sprint uint64 `json:"sprint"` // Epoch length to proposer
ValidatorContract string `json:"validatorContract"` // Validator set contract
Heimdall string `json:"heimdall"` // heimdall light client url
Period uint64 `json:"period"` // Number of seconds between blocks to enforce
ProducerDelay uint64 `json:"producerDelay"` // Number of seconds delay between two producer interval
Sprint uint64 `json:"sprint"` // Epoch length to proposer
ValidatorContract string `json:"validatorContract"` // Validator set contract
StateReceiverContract string `json:"stateReceiverContract"` // State receiver contract
Heimdall string `json:"heimdall"` // heimdall light client url
}
// String implements the stringer interface, returning the consensus engine details.