Polygon
- date: 2023-02-04
- last updated: 2023-02-04
Overview
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
Consensus Mechanism
Polygon uses Peppermint (a modified version of tendermint) Consensus.
Following is an excerpt from Polygon Architecture.
Polygon ArchitectureHeimdall 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.
Signing Mechanism
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
Note: As of March 12th, 2023 the pepperming votes function now uses aminofunc (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
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)
}
Code Review
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.
Signing
- Peppermint secp256k1 Codebase: Peppermint ECDSA Secp256k1 curve codebase (go).
- Peppermint secp256k1 signing code: Peppermint sign function (go). Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg. The returned signature will be of the form R
||
S (in lower-S form).
- Peppermint secp256k1 signing code: Peppermint sign function (go). Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg. The returned signature will be of the form R
Consensus
References
Consensus- The latest gossip on BFT consensus: The paper presents Tendermint, a new protocol for ordering events in a distributed network under adversarial conditions.
- Heimdall Documentation: Heimdall consensus engine uses the Cosmos-SDK and a forked version of Tendermint, called Peppermint.
- Peppermint Documentation: Peppermint is a modified Tendermint. It is changed to make it compatible with Ethereum addresses and verifiable on Ethereum chain.
- Peppermint Codebase: Polygon fork of tendermint codebase (go).
- Peppermint Consensus Code: Peppermint Consensus (go). ConsensusState handles execution of the consensus algorithm. It processes votes and proposals, and upon reaching agreement, commits blocks to the chain and executes them against the application. The internal state machine receives input from peers, the internal validator, and from a timer.
- Peppermint Consenus Configuration Code: Peppermint Consensus Configuration(go). defines the configuration for the Tendermint consensus service, including timeouts and details about the Write Ahead Logs (WAL) and the block structure.
- Peppermint Validator Set Code: Peppermint Validators (go). ValidatorSet represent a set ofValidator at a given height.*
- Bor Consensus Documentation: Bor consensus is inspired by Clique consensus: https://eips.ethereum.org/EIPS/eip-225.
- EIP-225: Clique proof-of-authority consensus protocol: Clique is a proof-of-authority consensus protocol. It shadows the design of Ethereum mainnet, so it can be added to any client with minimal effort.
- Heimdall and Bor Article: Article explaining Polygon(Matic) hybrid Plasma + Proof-of-Stake (PoS) platform.
- Hemidall Staking Documentation
- Polygon Staking App: Polygon Staking Application listing 100 validators
[8] [9] See notes and links to code in Peppermint summary
[10] See Polygon validator documentations