Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PoS milestones update & additional PoS contents Outline #17

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ rest of the site. You will get full credit for your work.
A section for those who passed the basics of dapp development on the Polygon
stack and are ready to take full advantage of some Polygon stack USPs.

- PoS advanced
- [x] PoS Milestones to speed up finality
- [ ] Max Code Size
- [ ] Replay Failed State Sync
- Miden advanced
- [ ] Deep dive into Miden architecture
- [ ] Advanced contract development techniques
Expand All @@ -78,6 +82,7 @@ stack and are ready to take full advantage of some Polygon stack USPs.
- [ ] Let’s build a private-voting DAO step-by-step
- [ ] Ensuring security and privacy: implications and tradeoffs
- AggLayer
- [ ] Global Exit Root and Local Exit Root, how do they work?
- [ ] Chaining cross-chain calls with `BridgeAndCall`
- [ ] CCIP vs AggLayer for cross chain calls
- [ ] Sequencing: centralization tradeoffs and future solutions
Expand Down
Binary file modified docs/images/milestones_01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/milestones_04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/milestones_05.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/milestones_06.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/milestones_07.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
84 changes: 65 additions & 19 deletions docs/pos/tutorials/milestones.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ responsible for:
### What is Heimdall?

Heimdall acts as the proof of stake layer and uses Tendermint BFT consensus. It
decides which validators should be producing blocks in Bor in each span (based
decides which validators should be producing blocks in Bor in each span (based
on their stake). It also:

- Submits checkpoints to the Ethereum mainnet, securing the Polygon chain.
Expand Down Expand Up @@ -72,7 +72,7 @@ With the introduction of milestones:

- Finality is **deterministic** even before a checkpoint is submitted to L1.
After a certain number of blocks (minimum 12), a milestone is proposed and
validated by Heimdall. Once 2/3+ of the network agrees, the milestone is
voted by Heimdall. Once 2/3+ of the network agrees, the milestone is
finalized, and all transactions up to that milestone are considered final,
with no chance of reorganization.

Expand Down Expand Up @@ -106,12 +106,10 @@ async function pre_milestones_checkFinality(client: any, txHash: string): Promis
if (!tx || !tx.blockNumber) return false
const latestBlock: Block = await client.getBlock({ blockTag: 'finalized' })

console.log(`Latest finalized block: ${latestBlock.number}`)
console.log(`Latest block: \t\t${latestBlock.number}`)
console.log(`Your transaction block: ${tx.blockNumber}`)

// Checking whether there has been 256 blocks since the transaction was included in a block
if (latestBlock.number !== null && latestBlock.number - tx.blockNumber >= 256) {
console.log("Your transaction block has been confirmed after 256 blocks");
return true
} else {
return false
Expand All @@ -125,21 +123,62 @@ Here's the implementation of Checking Transaction Finality AFTER Milestones Impl
async function milestones_checkFinality(client: any, txHash: string): Promise<boolean> {
const tx = await client.getTransaction({ hash: `0x${txHash}` })
if (!tx || !tx.blockNumber) return false
const latestBlock: Block = await client.getBlock({ blockTag: 'finalized' })
const latestBlock: Block = await client.getBlock({ blockTag: 'latest' })
const finalizedBlock: Block = await client.getBlock({ blockTag: 'finalized' })

console.log(`Latest finalized block: ${latestBlock.number}`)
console.log(`Latest block: \t\t${latestBlock.number}`)
console.log(`Latest Finalized block: ${finalizedBlock.number}`)
console.log(`Your transaction block: ${tx.blockNumber}`)

// Checking whether the finalized block number via milestones has reached the transaction block number.
if (latestBlock.number !== null && latestBlock.number > tx.blockNumber) {
console.log("Your transaction block has been confirmed after 16 blocks");
if (finalizedBlock.number !== null && finalizedBlock.number > tx.blockNumber) {
return true
} else {
return false
}
}
```

Lastly, adding this command line interface to run the code:
```ts
async function main() {
program
.requiredOption('-t, --txHash <string>', 'Transaction hash')
.requiredOption('-f, --function <string>', 'Function to call', (value) => {
if (!['pre_milestones', 'milestones'].includes(value)) {
throw new Error('Invalid function. Allowed values are: pre_milestones, milestones');
}
return value;
})
.requiredOption('-n, --network <string>', 'Network to use', (value) => {
if (!['polygon', 'amoy'].includes(value)) {
throw new Error('Invalid network. Allowed values are: polygon, amoy');
}
return value;
})
.parse(process.argv);

const { function: functionName, txHash, network } = program.opts();

const chain = network === 'polygon' ? polygon : polygonAmoy;
const client = createPublicClient({
chain,
transport: http(),
});

if (functionName === 'pre_milestones') {
const result = await pre_milestones_checkFinality(client, txHash)
console.log(`Pre-milestones finality check result: ${result}`)
} else if (functionName === 'milestones') {
const result = await milestones_checkFinality(client, txHash)
console.log(`Milestones finality check result: ${result}`)
}
}

main().catch((error) => {
console.error('Error:', error)
})
```

> Please note that this is just a demo purpose to show the previous
> implementations, since Milestones has already been implemented in the
> protocol, therefore, 16 blocks is the minimum time for finality, the
Expand Down Expand Up @@ -172,21 +211,28 @@ async function milestones_checkFinality(client: any, txHash: string): Promise<bo

### Results

The results should show whether the transaction has been finalized based on the
selected milestone mechanism and network. Usually Milestones will take 1-2
minutes to finalize the transaction. Result as follows:
The results should show whether the transaction has been finalized based on the selected milestone mechanism and network.
Usually Milestones will taking 1-2 minutes to finalize the transaction. Result as follows:

#### Milestones Example

When the transaction is still pending, the `milestones_checkFinality` function will show the following:
![milestones_result](../../images/milestones_04.png)

Here's a screenshot of the `pre_milestones_checkFinality` function, where it
shows that the new blocks are not yet 256:
When the transaction is finalized, the `milestones_checkFinality` function will show the following:
![milestones_result](../../images/milestones_05.png)

As you can see, there's always few blocks difference between latest block and finalized block, which is the buffer and the voting period for the milestone. Once the finalized block is higher than the transaction block, the transaction is considered finalized.

#### Pre-Milestones Example

![pre_milestones_result](../../images/milestones_05.png)
Here's a screenshot of the `pre_milestones_checkFinality` function, where it shows that the new blocks are not yet 256:
![pre_milestones_result](../../images/milestones_06.png)

Here's a screenshot of the `pre_milestones_checkFinality` function, where it
shows that the new blocks are 256:
Here's a screenshot of the `pre_milestones_checkFinality` function, where it shows that the new blocks are 256:
![pre_milestones_finalized](../../images/milestones_07.png)

![pre_milestones_finalized](../../images/milestones_06.png)
As you can see, there's no finalized block in the pre-milestones implementation, so the transaction is considered finalized once the new blocks are 256, aka the latest block is 256 blocks higher than the transaction block.

### Experimenting Further

Expand Down