Skip to content

Commit

Permalink
Deploy proxy contracts on genesis (#1855)
Browse files Browse the repository at this point in the history
* Deploy child chain proxy contracts on genesis
  • Loading branch information
stana-miric committed Sep 11, 2023
1 parent 478b56c commit 6d848ed
Show file tree
Hide file tree
Showing 17 changed files with 313 additions and 84 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/deploy.nightly.devnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ jobs:
{% endfor %}
BURN_CONTRACT_ADDRESS=0x0000000000000000000000000000000000000000
PROXY_CONTRACTS_ADMIN=0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed
polygon-edge genesis \
--consensus polybft \
Expand All @@ -142,7 +143,8 @@ jobs:
{% for item in hostvars %}{% if (hostvars[item].tags.Role == "validator") %} --validators /dns4/{{ hostvars[item].tags["Name"] }}/tcp/{{ edge_p2p_port }}/p2p/$(cat {{ hostvars[item].tags["Name"] }}.json | jq -r '.[0].node_id'):$(cat {{ hostvars[item].tags["Name"] }}.json | jq -r '.[0].address' | sed 's/^0x//'):$(cat {{ hostvars[item].tags["Name"] }}.json | jq -r '.[0].bls_pubkey') {% endif %}{% endfor %} \
--epoch-size 10 \
--native-token-config MyToken:MTK:18:true:{{ loadtest_account }} \
--governor-admin {{ loadtest_account }}
--governor-admin {{ loadtest_account }} \
--proxy-contracts-admin $PROXY_CONTRACTS_ADMIN
polygon-edge polybft stake-manager-deploy \
--jsonrpc {{ rootchain_json_rpc }} \
Expand Down
7 changes: 7 additions & 0 deletions command/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ func setFlags(cmd *cobra.Command) {
"the epoch size for the chain",
)

cmd.Flags().StringVar(
&params.proxyContractsAdmin,
proxyContractsAdminFlag,
"",
"admin for proxy contracts",
)

// IBFT Validators
{
cmd.Flags().StringVar(
Expand Down
25 changes: 25 additions & 0 deletions command/genesis/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/0xPolygon/polygon-edge/consensus/ibft/fork"
"github.com/0xPolygon/polygon-edge/consensus/ibft/signer"
"github.com/0xPolygon/polygon-edge/consensus/polybft/common"
"github.com/0xPolygon/polygon-edge/contracts"
"github.com/0xPolygon/polygon-edge/contracts/staking"
stakingHelper "github.com/0xPolygon/polygon-edge/helper/staking"
"github.com/0xPolygon/polygon-edge/server"
Expand Down Expand Up @@ -46,6 +47,7 @@ const (
voteProposalThresholdFlag = "vote-proposal-threshold"
governorAdminFlag = "governor-admin"
proposalQuorumFlag = "proposal-quorum"
proxyContractsAdminFlag = "proxy-contracts-admin"

defaultNativeTokenName = "Polygon"
defaultNativeTokenSymbol = "MATIC"
Expand Down Expand Up @@ -150,6 +152,8 @@ type genesisParams struct {
proposalThreshold string
proposalQuorum uint64
governorAdmin string

proxyContractsAdmin string
}

func (p *genesisParams) validateFlags() error {
Expand Down Expand Up @@ -189,6 +193,10 @@ func (p *genesisParams) validateFlags() error {
if err := p.validateGovernorAdminAddr(); err != nil {
return err
}

if err := p.validateProxyContractsAdmin(); err != nil {
return err
}
}

// Check if the genesis file already exists
Expand Down Expand Up @@ -568,6 +576,23 @@ func (p *genesisParams) validateBurnContract() error {
return nil
}

func (p *genesisParams) validateProxyContractsAdmin() error {
if strings.TrimSpace(p.proxyContractsAdmin) == "" {
return errors.New("proxy contracts admin address must be set")
}

proxyContractsAdminAddr := types.StringToAddress(p.proxyContractsAdmin)
if proxyContractsAdminAddr == types.ZeroAddress {
return errors.New("proxy contracts admin address must not be zero address")
}

if proxyContractsAdminAddr == contracts.SystemCaller {
return errors.New("proxy contracts admin address must not be system caller address")
}

return nil
}

// isBurnContractEnabled returns true in case burn contract info is provided
func (p *genesisParams) isBurnContractEnabled() bool {
return p.burnContract != ""
Expand Down
99 changes: 63 additions & 36 deletions command/genesis/polybft_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ var (
"except for zero address and reward wallet if native token is used as reward token")
)

type contractInfo struct {
artifact *artifact.Artifact
address types.Address
}

// generatePolyBftChainConfig creates and persists polybft chain configuration to the provided file path
func (p *genesisParams) generatePolyBftChainConfig(o command.OutputFormatter) error {
// populate premine balance map
Expand Down Expand Up @@ -195,7 +200,8 @@ func (p *genesisParams) generatePolyBftChainConfig(o command.OutputFormatter) er
WalletAddress: walletPremineInfo.address,
WalletAmount: walletPremineInfo.amount,
},
BlockTimeDrift: p.blockTimeDrift,
BlockTimeDrift: p.blockTimeDrift,
ProxyContractsAdmin: types.StringToAddress(p.proxyContractsAdmin),
GovernanceConfig: &polyCommon.GovernanceConfig{
VotingDelay: voteDelay,
VotingPeriod: votingPeriod,
Expand Down Expand Up @@ -373,16 +379,18 @@ func (p *genesisParams) deployContracts(
polybftConfig *polyCommon.PolyBFTConfig,
chainConfig *chain.Chain,
burnContractAddr types.Address) (map[types.Address]*chain.GenesisAccount, error) {
type contractInfo struct {
artifact *artifact.Artifact
address types.Address
proxyToImplAddrMap := contracts.GetProxyImplementationMapping()
proxyAddresses := make([]types.Address, 0, len(proxyToImplAddrMap))

for proxyAddr := range proxyToImplAddrMap {
proxyAddresses = append(proxyAddresses, proxyAddr)
}

genesisContracts := []*contractInfo{
{
// State receiver contract
artifact: contractsapi.StateReceiver,
address: contracts.StateReceiverContract,
address: contracts.StateReceiverContractV1,
},
{
// ChildERC20 token contract
Expand All @@ -402,49 +410,49 @@ func (p *genesisParams) deployContracts(
{
// BLS contract
artifact: contractsapi.BLS,
address: contracts.BLSContract,
address: contracts.BLSContractV1,
},
{
// Merkle contract
artifact: contractsapi.Merkle,
address: contracts.MerkleContract,
address: contracts.MerkleContractV1,
},
{
// L2StateSender contract
artifact: contractsapi.L2StateSender,
address: contracts.L2StateSenderContract,
address: contracts.L2StateSenderContractV1,
},
{
artifact: contractsapi.ValidatorSet,
address: contracts.ValidatorSetContract,
address: contracts.ValidatorSetContractV1,
},
{
artifact: contractsapi.RewardPool,
address: contracts.RewardPoolContract,
address: contracts.RewardPoolContractV1,
},
{
artifact: contractsapi.NetworkParams,
address: contracts.NetworkParamsContract,
address: contracts.NetworkParamsContractV1,
},
{
artifact: contractsapi.ForkParams,
address: contracts.ForkParamsContract,
address: contracts.ForkParamsContractV1,
},
{
artifact: contractsapi.ChildGovernor,
address: contracts.ChildGovernorContract,
address: contracts.ChildGovernorContractV1,
},
{
artifact: contractsapi.ChildTimelock,
address: contracts.ChildTimelockContract,
address: contracts.ChildTimelockContractV1,
},
}

if !params.nativeTokenConfig.IsMintable {
genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.NativeERC20,
address: contracts.NativeERC20TokenContract,
address: contracts.NativeERC20TokenContractV1,
})

// burn contract can be set only for non-mintable native token. If burn contract is set,
Expand All @@ -455,12 +463,14 @@ func (p *genesisParams) deployContracts(
artifact: contractsapi.EIP1559Burn,
address: burnContractAddr,
})

proxyAddresses = append(proxyAddresses, contracts.DefaultBurnContract)
}
} else {
genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.NativeERC20Mintable,
address: contracts.NativeERC20TokenContract,
address: contracts.NativeERC20TokenContractV1,
})
}

Expand All @@ -469,95 +479,99 @@ func (p *genesisParams) deployContracts(
genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.ChildERC20PredicateACL,
address: contracts.ChildERC20PredicateContract,
address: contracts.ChildERC20PredicateContractV1,
})

genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.ChildERC721PredicateACL,
address: contracts.ChildERC721PredicateContract,
address: contracts.ChildERC721PredicateContractV1,
})

genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.ChildERC1155PredicateACL,
address: contracts.ChildERC1155PredicateContract,
address: contracts.ChildERC1155PredicateContractV1,
})

// childchain originated tokens predicates (with access lists)
genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.RootMintableERC20PredicateACL,
address: contracts.RootMintableERC20PredicateContract,
address: contracts.RootMintableERC20PredicateContractV1,
})

genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.RootMintableERC721PredicateACL,
address: contracts.RootMintableERC721PredicateContract,
address: contracts.RootMintableERC721PredicateContractV1,
})

genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.RootMintableERC1155PredicateACL,
address: contracts.RootMintableERC1155PredicateContract,
address: contracts.RootMintableERC1155PredicateContractV1,
})
} else {
// rootchain originated tokens predicates
genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.ChildERC20Predicate,
address: contracts.ChildERC20PredicateContract,
address: contracts.ChildERC20PredicateContractV1,
})

genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.ChildERC721Predicate,
address: contracts.ChildERC721PredicateContract,
address: contracts.ChildERC721PredicateContractV1,
})

genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.ChildERC1155Predicate,
address: contracts.ChildERC1155PredicateContract,
address: contracts.ChildERC1155PredicateContractV1,
})

// childchain originated tokens predicates
genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.RootMintableERC20Predicate,
address: contracts.RootMintableERC20PredicateContract,
address: contracts.RootMintableERC20PredicateContractV1,
})

genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.RootMintableERC721Predicate,
address: contracts.RootMintableERC721PredicateContract,
address: contracts.RootMintableERC721PredicateContractV1,
})

genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.RootMintableERC1155Predicate,
address: contracts.RootMintableERC1155PredicateContract,
address: contracts.RootMintableERC1155PredicateContractV1,
})
}

allocations := make(map[types.Address]*chain.GenesisAccount, len(genesisContracts)+1)

for _, contract := range genesisContracts {
allocations[contract.address] = &chain.GenesisAccount{
Balance: big.NewInt(0),
Code: contract.artifact.DeployedBytecode,
}
}

if rewardTokenByteCode != nil {
// if reward token is provided in genesis then, add it to allocations
// to RewardTokenContract address and update Polybft config
allocations[contracts.RewardTokenContract] = &chain.GenesisAccount{
allocations[contracts.RewardTokenContractV1] = &chain.GenesisAccount{
Balance: big.NewInt(0),
Code: rewardTokenByteCode,
}

proxyAddresses = append(proxyAddresses, contracts.RewardTokenContract)
}

genesisContracts = append(genesisContracts, getProxyContractsInfo(proxyAddresses)...)

for _, contract := range genesisContracts {
allocations[contract.address] = &chain.GenesisAccount{
Balance: big.NewInt(0),
Code: contract.artifact.DeployedBytecode,
}
}

return allocations, nil
Expand Down Expand Up @@ -623,3 +637,16 @@ func stringSliceToAddressSlice(addrs []string) []types.Address {

return res
}

func getProxyContractsInfo(addresses []types.Address) []*contractInfo {
result := make([]*contractInfo, len(addresses))

for i, proxyAddress := range addresses {
result[i] = &contractInfo{
artifact: contractsapi.GenesisProxy,
address: proxyAddress,
}
}

return result
}
1 change: 1 addition & 0 deletions command/regenesis/howtotest.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ This document outlines step necessary to perform a regenesis data migration.
```bash
./polygon-edge genesis --consensus polybft \
--block-gas-limit 10000000 \
--proxy-contracts-admin 0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed \
--epoch-size 10 --trieroot 0xf5ef1a28c82226effb90f4465180ec3469226747818579673f4be929f1cd8663

[GENESIS SUCCESS]
Expand Down
2 changes: 2 additions & 0 deletions consensus/polybft/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ It has a native support for running bridge, which enables running cross-chain tr

```bash
$ polygon-edge genesis --block-gas-limit 10000000 --epoch-size 10 \
--proxy-contracts-admin 0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed \
[--validators-path ./] [--validators-prefix test-chain-] \
[--consensus polybft] \
[--reward-wallet address:amount]
Expand All @@ -38,6 +39,7 @@ It has a native support for running bridge, which enables running cross-chain tr

```bash
$ polygon-edge genesis --block-gas-limit 10000000 --epoch-size 10 \
--proxy-contracts-admin 0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed \
--validators /ip4/127.0.0.1/tcp/30301/p2p/16Uiu2HAmV5hqAp77untfJRorxqKmyUxgaVn8YHFjBJm9gKMms3mr:0xDcBe0024206ec42b0Ef4214Ac7B71aeae1A11af0:1cf134e02c6b2afb2ceda50bf2c9a01da367ac48f7783ee6c55444e1cab418ec0f52837b90a4d8cf944814073fc6f2bd96f35366a3846a8393e3cb0b19197cde23e2b40c6401fa27ff7d0c36779d9d097d1393cab6fc1d332f92fb3df850b78703b2989d567d1344e219f0667a1863f52f7663092276770cf513f9704b5351c4:11b18bde524f4b02258a8d196b687f8d8e9490d536718666dc7babca14eccb631c238fb79aa2b44a5a4dceccad2dd797f537008dda185d952226a814c1acf7c2
[--validators /ip4/127.0.0.1/tcp/30302/p2p/16Uiu2HAmGmidRQY5BGJPGVRF8p1pYFdfzuf1StHzXGLDizuxJxex:0x2da750eD4AE1D5A7F7c996Faec592F3d44060e90:088d92c25b5f278750534e8a902da604a1aa39b524b4511f5f47c3a386374ca3031b667beb424faef068a01cee3428a1bc8c1c8bab826f30a1ee03fbe90cb5f01abcf4abd7af3bbe83eaed6f82179b9cbdc417aad65d919b802d91c2e1aaefec27ba747158bc18a0556e39bfc9175c099dd77517a85731894bbea3d191a622bc:08dc3006352fdc01b331907fd3a68d4d68ed40329032598c1c0faa260421d66720965ace3ba29c6d6608ec1facdbf4624bca72df36c34afd4bdd753c4dfe049c]
```
Expand Down
4 changes: 4 additions & 0 deletions consensus/polybft/common/polybft_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ type PolyBFTConfig struct {

// GovernanceConfig defines on chain governance configuration
GovernanceConfig *GovernanceConfig `json:"governanceConfig,omitempty"`

// ProxyContractsAdmin is the address that will have the privilege to change both the proxy
// implementation address and the admin
ProxyContractsAdmin types.Address `json:"proxyContractsAdmin,omitempty"`
}

// LoadPolyBFTConfig loads chain config from provided path and unmarshals PolyBFTConfig
Expand Down
4 changes: 4 additions & 0 deletions consensus/polybft/contractsapi/artifacts-gen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ func main() {
"child/governance/ChildTimelock.sol",
"ChildTimelock",
},
{
"lib/GenesisProxy.sol",
"GenesisProxy",
},
}

str := `// This is auto-generated file. DO NOT EDIT.
Expand Down
Loading

0 comments on commit 6d848ed

Please sign in to comment.