Skip to content

Commit

Permalink
genesis, params: add Miko hardfork on mainnet (#402)
Browse files Browse the repository at this point in the history
* precompiled: add procompiled contract to verify proof of possession BLS

* cmd, entrypoint: add an account cmd to generate BLS proof of possession

* consortium/v2: upgrade ronin trusted org contract

* genesis/testnet: add Miko hardfork on testnet

* params/version: bump Ronin to version 2.7.0

* state_processor: fix out-of-order system txs

The current way that transactions are processed by Consortium V2 engine
allows a system transaction to be placed before a common transaction in
a block. However, the generated logs and receipts are ordered so that
those of system transactions are stored at the end (see
`core/state_processor.go/Process`). This leads to mismatching betwwen
logs/receipts and their corresponding transactions because the handler
of `eth_getLogs` assume that receipts are stored in the same order with
that of `block.Transactions()` (see `core/rawdb/accessors_chain.go/deriveLogFields`).

* state_processor, consortium-v2: test out of order system transactions

* state_processor: adjust out-of-order tx check

The check for out-of-order transactions is applied to Miko blocks only.

* genesis, params: add Miko hardfork on mainnet

* params/version: bump Ronin to version 2.7.1

---------

Co-authored-by: NganSM <ngan.nguyen@skymavis.com>
  • Loading branch information
minh-bq and NganSM authored Feb 7, 2024
1 parent 9767790 commit c64ddd3
Show file tree
Hide file tree
Showing 20 changed files with 594 additions and 54 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ENV BLS_PRIVATE_KEY ''
ENV BLS_PASSWORD ''
ENV BLS_AUTO_GENERATE 'false'
ENV BLS_SHOW_PRIVATE_KEY 'false'
ENV GENERATE_BLS_PROOF 'false'

COPY --from=builder /opt/build/bin/ronin /usr/local/bin/ronin
COPY --from=builder /opt/genesis/ ./
Expand Down
57 changes: 56 additions & 1 deletion cmd/ronin/accountcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,24 @@ The keyfile is assumed to contain an unencrypted private key in hexadecimal form
},
Description: `ronin account generatebls [--secret]`,
},
{
Name: "generate-bls-proof",
Usage: "Generate BLS proof of possession",
Action: utils.MigrateFlags(blsProofGenerate),
Flags: []cli.Flag{
utils.BlsWalletPath,
utils.BlsPasswordPath,
},
ArgsUsage: "[keyFile]",
Description: `
ronin account generate-bls-proof [keyFile] [--finality.blswalletpath walletpath] [--finality.blspasswordpath passwordpath]
Generate proof from keyfile or stored encrypted wallet
The keyfile is assumed to contain an unencrypted private key in hexadecimal format.
You must input either keyfile or a pair of walletpath and passwordpath.
`,
},
},
}
)
Expand Down Expand Up @@ -490,7 +508,7 @@ func loadKeyManager(ctx *cli.Context) (*bls.KeyManager, []blsCommon.PublicKey, e
func loadBlsSecretKey(ctx *cli.Context) (blsCommon.SecretKey, error) {
keyfile := ctx.Args().First()
if len(keyfile) == 0 {
utils.Fatalf("keyfile must be given as argument")
return nil, fmt.Errorf("keyfile must be given as argument")
}

secretKeyHex, err := ioutil.ReadFile(keyfile)
Expand Down Expand Up @@ -627,3 +645,40 @@ func blsAccountGenerate(ctx *cli.Context) error {

return nil
}

func blsProofGenerate(ctx *cli.Context) error {
var (
keyManager *bls.KeyManager
secretKeys []blsCommon.SecretKey
)

secretKey, err := loadBlsSecretKey(ctx)
if err != nil {
keyManager, _, err = loadKeyManager(ctx)
if err != nil {
utils.Fatalf("Either keyfile or path to wallet must be provided, err: %s", err)
}
rawSecretKeys, err := keyManager.FetchValidatingSecretKeys(context.Background())
if err != nil {
utils.Fatalf("Failed to fetch BLS secret key, err %s", err)
}
for _, rawSecretKey := range rawSecretKeys {
secretKey, err := blst.SecretKeyFromBytes(rawSecretKey[:])
if err != nil {
utils.Fatalf("Failed to decode BLS secret key, err %s", err)
}
secretKeys = append(secretKeys, secretKey)
}
} else {
secretKeys = append(secretKeys, secretKey)
}

for i, secretKey := range secretKeys {
rawPublicKey := secretKey.PublicKey().Marshal()
proof := secretKey.SignProof(rawPublicKey)
fmt.Printf("BLS public key #%d: {%x}\n", i, rawPublicKey)
fmt.Printf("BLS proof #%d: {%x}\n", i, proof.Marshal())
}

return nil
}
17 changes: 17 additions & 0 deletions consensus/consortium/v2/consortium.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ var (

diffInTurn = big.NewInt(7) // Block difficulty for in-turn signatures
diffNoTurn = big.NewInt(3) // Block difficulty for out-of-turn signatures

// The proxy contract's implementation slot
// https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/v4.7.3/contracts/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol#L34
implementationSlot = common.HexToHash("360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc")
)

var (
Expand Down Expand Up @@ -840,6 +844,17 @@ func (c *Consortium) processSystemTransactions(chain consensus.ChainHeaderReader
return nil
}

func (c *Consortium) upgradeRoninTrustedOrg(blockNumber *big.Int, state *state.StateDB) {
// The upgrade only happens in 1 block: Miko hardfork block
if c.chainConfig.MikoBlock != nil && c.chainConfig.MikoBlock.Cmp(blockNumber) == 0 {
state.SetState(
c.chainConfig.RoninTrustedOrgUpgrade.ProxyAddress,
implementationSlot,
c.chainConfig.RoninTrustedOrgUpgrade.ImplementationAddress.Hash(),
)
}
}

// Finalize implements consensus.Engine that calls three methods from smart contracts:
// - WrapUpEpoch at epoch to distribute rewards and sort the validators set
// - Slash the validator who does not sign if it is in-turn
Expand Down Expand Up @@ -901,6 +916,7 @@ func (c *Consortium) Finalize(chain consensus.ChainHeaderReader, header *types.H
if err := c.processSystemTransactions(chain, header, transactOpts, false); err != nil {
return err
}
c.upgradeRoninTrustedOrg(header.Number, state)
if len(*transactOpts.EVMContext.InternalTransactions) > 0 {
*internalTxs = append(*internalTxs, *transactOpts.EVMContext.InternalTransactions...)
}
Expand Down Expand Up @@ -946,6 +962,7 @@ func (c *Consortium) FinalizeAndAssemble(chain consensus.ChainHeaderReader, head
if err := c.processSystemTransactions(chain, header, transactOpts, true); err != nil {
return nil, nil, err
}
c.upgradeRoninTrustedOrg(header.Number, state)

// should not happen. Once happen, stop the node is better than broadcast the block
if header.GasLimit < header.GasUsed {
Expand Down
Loading

0 comments on commit c64ddd3

Please sign in to comment.