Home | About John | Resume/CV | References | Writing | Research |
---|
Polygon is representative because it uses ECDSA on secp256k1 and a relatively fixed validator set.
The consensus protocol is based on Peppermint8, a modified version of Tendermint. Validators sign produced blocks using the ECDSA signature scheme on secp256k1 curves9. Currently, the validator set size is fixed at 100 and only changes when a current validator resigns. This restriction will change when a new auction mechanism is implemented.10
Polygon uses Peppermint (a modified version of tendermint) Consensus.
Following is an excerpt from Polygon Architecture.
Polygon Architecture
Heimdall is the proof of stake validation layer that handles the aggregation of blocks produced by Bor into a Merkle tree and publishes the Merkle root periodically to the root chain. The periodic publishing of snapshots of the Bor sidechain is called checkpoints.
- Validates all the blocks since the last checkpoint.
- Creates a Merkle tree of the block hashes.
- Publishes the Merkle root hash to the Ethereum mainnet.
Checkpoints are important for two reasons:
- Providing finality on the root chain.
- Providing proof of burn in withdrawal of assets.
An overview of the process:
- A subset of active validators from the pool is selected to act as block producers for a span. These block producers are responsible for creating blocks and broadcasting the created blocks on the network.
- A checkpoint includes the Merkle root hash of all blocks created during any given interval. All nodes validate the Merkle root hash and attach their signature to it.
- A selected proposer from the validator set is responsible for collecting all signatures for a particular checkpoint and committing the checkpoint on the Ethereum mainnet.
- The responsibility of creating blocks and proposing checkpoints is variably dependent on a validator’s stake ratio in the overall pool.
More details on Heimdall are available on the Heimdall architecture guide.
This image from Bor Architecture helps give a better understanding of how Ethereum, Heimdall and Bor work together.
Following is an excerpt from and Peppermint.md.
Peppermint is a modified Tendermint. It is changed to make it compatible with Ethereum addresses and verifiable on Ethereum chain.
Overview
- Changes to signature scheme
- Changes to
vote
to make it verifiable on Ethereum smart contract- Changes to
vote
encoding schemePeppermint uses
secp256k1
signature scheme to verify Tendermint votes on solidity smart contract.Source: https://github.com/maticnetwork/tendermint/blob/peppermint/crypto/secp256k1/secp256k1_nocgo.go
It adds
Data
field intoVote
andProposal
struct to gethash
for transactions in the block. On smart contract, it checks ifData
matches with checkpoint data hash and majority (⅔+1) of validator signatures. The idea is to verify if majority of the validator set agrees on transaction in the contract.Peppermint uses RLP to get
Vote
bytes instead of Amino encoding. HereData
isTxs.Hash()
for the block.Source: https://github.com/maticnetwork/tendermint/blob/peppermint/types/canonical.go
// [peppermint] create RLP vote to decode in contract type CanonicalRLPVote struct { ChainID string Type byte Height uint Round uint Data []byte }
And using RLP encoding lib to get byte data for signature on Vote.
Source: https://github.com/maticnetwork/tendermint/blob/peppermint/types/vote.go#L75-L82
func (vote *Vote) SignBytes(chainID string) []byte { // [peppermint] converted from amino to rlp bz, err := rlp.EncodeToBytes(CanonicalizeVote(chainID, vote)) if err != nil { panic(err) } return bz }
Complete Source: https://github.com/maticnetwork/tendermint
Note: As of March 12th, 2023 the pepperming votes function now uses amino
func (vote *Vote) SignBytes(chainID string) []byte {
// [peppermint] converted from amino to rlp
bz, err := cdc.MarshalBinaryLengthPrefixed(CanonicalizeVote(chainID, vote))
if err != nil {
panic(err)
}
return bz
}
package consensus
import (
amino "github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/types"
)
var cdc = amino.NewCodec()
func init() {
RegisterConsensusMessages(cdc)
RegisterWALMessages(cdc)
types.RegisterBlockAmino(cdc)
}
package p2p
import (
amino "github.com/tendermint/go-amino"
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc = amino.NewCodec()
func init() {
cryptoAmino.RegisterAmino(cdc)
}
Polygon’s peppermint fork of tendermint was forked from tendermint and as such the codebase has similar functions to those documented in cosmos code review.
The major changes are to the consensus and signing (see above)
Polygon’s bor is cloned from geth and as such the codebase has similar functions to those documented in ethereum 1-0 code review.
||
S (in lower-S form).Consensus
Staking
Additional
[8][9] See notes and links to code in Peppermint summary
[10] See Polygon validator documentations