Skip to content

Commit

Permalink
Merge pull request #1 from maticnetwork/span-sync
Browse files Browse the repository at this point in the history
MAT-156 Span sync
  • Loading branch information
jdkanani authored Nov 10, 2019
2 parents 223f6a8 + dc16740 commit ae1b056
Show file tree
Hide file tree
Showing 15 changed files with 610 additions and 592 deletions.
10 changes: 6 additions & 4 deletions cmd/puppeth/wizard_genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +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",
Period: 1,
ProducerDelay: 5,
Sprint: 60,
ValidatorContract: "0x0000000000000000000000000000000000001000",
StateReceiverContract: "0x0000000000000000000000000000000000001001",
Heimdall: "http://localhost:1317",
}

// We also need the initial list of signers
Expand Down
2 changes: 1 addition & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1670,7 +1670,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
if config.Clique != nil {
engine = clique.New(config.Clique, chainDb)
} else if config.Bor != nil {
engine = bor.New(config.Bor, chainDb, nil)
engine = bor.New(config, chainDb, nil)
} else {
engine = ethash.NewFaker()
if !ctx.GlobalBool(FakePoWFlag.Name) {
Expand Down
30 changes: 0 additions & 30 deletions consensus/bor/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,33 +87,3 @@ func (api *API) GetSignersAtHash(hash common.Hash) ([]common.Address, error) {
}
return snap.signers(), nil
}

// Proposals returns the current proposals the node tries to uphold and vote on.
func (api *API) Proposals() map[common.Address]bool {
api.bor.lock.RLock()
defer api.bor.lock.RUnlock()

proposals := make(map[common.Address]bool)
for address, auth := range api.bor.proposals {
proposals[address] = auth
}
return proposals
}

// Propose injects a new authorization proposal that the signer will attempt to
// push through.
func (api *API) Propose(address common.Address, auth bool) {
api.bor.lock.Lock()
defer api.bor.lock.Unlock()

api.bor.proposals[address] = auth
}

// Discard drops a currently running proposal, stopping the signer from casting
// further votes (either for or against).
func (api *API) Discard(address common.Address) {
api.bor.lock.Lock()
defer api.bor.lock.Unlock()

delete(api.bor.proposals, address)
}
493 changes: 456 additions & 37 deletions consensus/bor/bor.go

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions consensus/bor/clerk.go
Original file line number Diff line number Diff line change
@@ -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"`
}
56 changes: 56 additions & 0 deletions consensus/bor/rest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package bor

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"path"
)

// ResponseWithHeight defines a response object type that wraps an original
// response with a height.
type ResponseWithHeight struct {
Height string `json:"height"`
Result json.RawMessage `json:"result"`
}

// FetchFromHeimdall returns data from heimdall
func FetchFromHeimdall(client http.Client, urlString string, paths ...string) (*ResponseWithHeight, error) {
u, err := url.Parse(urlString)
if err != nil {
return nil, err
}

for _, e := range paths {
if e != "" {
u.Path = path.Join(u.Path, e)
}
}

res, err := client.Get(u.String())
if err != nil {
return nil, err
}
defer res.Body.Close()

// check status code
if res.StatusCode != 200 {
return nil, fmt.Errorf("Error while fetching data from Heimdall")
}

// get response
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}

// unmarshall data from buffer
var response ResponseWithHeight
if err := json.Unmarshal(body, &response); err != nil {
return nil, err
}

return &response, nil
}
108 changes: 12 additions & 96 deletions consensus/bor/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,6 @@ import (
lru "github.com/hashicorp/golang-lru"
)

// Vote represents a single vote that an authorized signer made to modify the
// list of authorizations.
type Vote struct {
Signer common.Address `json:"signer"` // Authorized signer that cast this vote
Block uint64 `json:"block"` // Block number the vote was cast in (expire old votes)
Address common.Address `json:"address"` // Account being voted on to change its authorization
Authorize bool `json:"authorize"` // Whether to authorize or deauthorize the voted account
}

// Tally is a simple vote tally to keep the current score of votes. Votes that
// go against the proposal aren't counted since it's equivalent to not voting.
type Tally struct {
Authorize bool `json:"authorize"` // Whether the vote is about authorizing or kicking someone
Votes int `json:"votes"` // Number of votes until now wanting to pass the proposal
}

// Snapshot is the state of the authorization voting at a given point in time.
type Snapshot struct {
config *params.BorConfig // Consensus engine parameters to fine tune behavior
Expand All @@ -55,8 +39,6 @@ type Snapshot struct {
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
ValidatorSet *ValidatorSet `json:"validatorSet"` // Validator set at this moment
Recents map[uint64]common.Address `json:"recents"` // Set of recent signers for spam protections
// Votes []*Vote `json:"votes"` // List of votes cast in chronological order
// Tally map[common.Address]Tally `json:"tally"` // Current vote tally to avoid recalculating
}

// signersAscending implements the sort interface to allow sorting a list of addresses
Expand All @@ -69,7 +51,14 @@ func (s signersAscending) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// newSnapshot creates a new snapshot with the specified startup parameters. This
// method does not initialize the set of recent signers, so only ever use if for
// the genesis block.
func newSnapshot(config *params.BorConfig, sigcache *lru.ARCCache, number uint64, hash common.Hash, validators []*Validator, ethAPI *ethapi.PublicBlockChainAPI) *Snapshot {
func newSnapshot(
config *params.BorConfig,
sigcache *lru.ARCCache,
number uint64,
hash common.Hash,
validators []*Validator,
ethAPI *ethapi.PublicBlockChainAPI,
) *Snapshot {
snap := &Snapshot{
config: config,
ethAPI: ethAPI,
Expand All @@ -78,7 +67,6 @@ func newSnapshot(config *params.BorConfig, sigcache *lru.ARCCache, number uint64
Hash: hash,
ValidatorSet: NewValidatorSet(validators),
Recents: make(map[uint64]common.Address),
// Tally: make(map[common.Address]Tally),
}
return snap
}
Expand Down Expand Up @@ -122,8 +110,6 @@ func (s *Snapshot) copy() *Snapshot {
Hash: s.Hash,
ValidatorSet: s.ValidatorSet.Copy(),
Recents: make(map[uint64]common.Address),
// Votes: make([]*Vote, len(s.Votes)),
// Tally: make(map[common.Address]Tally),
}
for block, signer := range s.Recents {
cpy.Recents[block] = signer
Expand All @@ -132,50 +118,6 @@ func (s *Snapshot) copy() *Snapshot {
return cpy
}

// // validVote returns whether it makes sense to cast the specified vote in the
// // given snapshot context (e.g. don't try to add an already authorized signer).
// func (s *Snapshot) validVote(address common.Address, authorize bool) bool {
// _, signer := s.Signers[address]
// return (signer && !authorize) || (!signer && authorize)
// }

// // cast adds a new vote into the tally.
// func (s *Snapshot) cast(address common.Address, authorize bool) bool {
// // Ensure the vote is meaningful
// if !s.validVote(address, authorize) {
// return false
// }
// // Cast the vote into an existing or new tally
// if old, ok := s.Tally[address]; ok {
// old.Votes++
// s.Tally[address] = old
// } else {
// s.Tally[address] = Tally{Authorize: authorize, Votes: 1}
// }
// return true
// }

// // uncast removes a previously cast vote from the tally.
// func (s *Snapshot) uncast(address common.Address, authorize bool) bool {
// // If there's no tally, it's a dangling vote, just drop
// tally, ok := s.Tally[address]
// if !ok {
// return false
// }
// // Ensure we only revert counted votes
// if tally.Authorize != authorize {
// return false
// }
// // Otherwise revert the vote
// if tally.Votes > 1 {
// tally.Votes--
// s.Tally[address] = tally
// } else {
// delete(s.Tally, address)
// }
// return true
// }

func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
// Allow passing in no headers for cleaner code
if len(headers) == 0 {
Expand Down Expand Up @@ -212,11 +154,14 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
if number > 0 && (number+1)%s.config.Sprint == 0 {
validatorBytes := header.Extra[extraVanity : len(header.Extra)-extraSeal]

// newVals, _ := GetValidators(number, number+1, s.config.Sprint, s.config.ValidatorContract, snap.ethAPI)
// get validators from headers and use that for new validator set
newVals, _ := ParseValidators(validatorBytes)
v := getUpdatedValidatorSet(snap.ValidatorSet.Copy(), newVals)
v.IncrementProposerPriority(1)
snap.ValidatorSet = v

// log new validator set
fmt.Println("Current validator set", "number", snap.Number, "validatorSet", snap.ValidatorSet)
}

// check if signer is in validator set
Expand All @@ -231,9 +176,6 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
validators := snap.ValidatorSet.Validators
// proposer will be the last signer if block is not epoch block
proposer := snap.ValidatorSet.GetProposer().Address
// if number%s.config.Sprint != 0 {
// proposer = snap.Recents[number-1]
// }
proposerIndex, _ := snap.ValidatorSet.GetByAddress(proposer)
signerIndex, _ := snap.ValidatorSet.GetByAddress(signer)
limit := len(validators) - (len(validators)/2 + 1)
Expand All @@ -252,14 +194,10 @@ 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()

fmt.Println("Current validator set", "number", snap.Number, "validatorSet", snap.ValidatorSet)

return snap, nil
}

Expand All @@ -283,11 +221,6 @@ func (s *Snapshot) inturn(number uint64, signer common.Address, epoch uint64) ui
proposer := s.ValidatorSet.GetProposer().Address
totalValidators := len(validators)

// proposer will be the last signer if block is not epoch block
// proposer := snap.ValidatorSet.GetProposer().Address
// if number%epoch != 0 {
// proposer = snap.Recents[number-1]
// }
proposerIndex, _ := s.ValidatorSet.GetByAddress(proposer)
signerIndex, _ := s.ValidatorSet.GetByAddress(signer)

Expand All @@ -298,21 +231,4 @@ func (s *Snapshot) inturn(number uint64, signer common.Address, epoch uint64) ui
}

return uint64(totalValidators - (tempIndex - proposerIndex))

// signers, offset := s.signers(), 0
// for offset < len(signers) && signers[offset] != signer {
// offset++
// }
// return ((number / producerPeriod) % uint64(len(signers))) == uint64(offset)

// // if block is epoch start block, proposer will be inturn signer
// if s.Number%epoch == 0 {
// if bytes.Compare(proposer.Address.Bytes(), signer.Bytes()) == 0 {
// return true
// }
// // if block is not epoch block, last block signer will be inturn
// } else if bytes.Compare(lastSigner.Bytes(), signer.Bytes()) == 0 {
// return false
// }
// return false
}
16 changes: 16 additions & 0 deletions consensus/bor/span.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package bor

// Span represents a current bor span
type Span struct {
ID uint64 `json:"span_id" yaml:"span_id"`
StartBlock uint64 `json:"start_block" yaml:"start_block"`
EndBlock uint64 `json:"end_block" yaml:"end_block"`
}

// HeimdallSpan represents span from heimdall APIs
type HeimdallSpan struct {
Span
ValidatorSet ValidatorSet `json:"validator_set" yaml:"validator_set"`
SelectedProducers []Validator `json:"selected_producers" yaml:"selected_producers"`
ChainID string `json:"bor_chain_id" yaml:"bor_chain_id"`
}
Loading

0 comments on commit ae1b056

Please sign in to comment.