Skip to content

Commit

Permalink
Re-introduce proxy contracts integration (#1921)
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan-Ethernal authored Sep 27, 2023
1 parent cf7c675 commit 32047b4
Show file tree
Hide file tree
Showing 28 changed files with 673 additions and 194 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/deploy.nightly.devnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ jobs:
{% endfor %}
BURN_CONTRACT_ADDRESS=0x0000000000000000000000000000000000000000
PROXY_CONTRACTS_ADMIN=0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed
polygon-edge genesis \
--consensus polybft \
Expand All @@ -138,16 +139,19 @@ jobs:
--block-time {{ block_time }}s \
{% 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:0x0000000000000000000000000000000000001010
--native-token-config MyToken:MTK:18:true:{{ loadtest_account }} \
--proxy-contracts-admin $PROXY_CONTRACTS_ADMIN
polygon-edge polybft stake-manager-deploy \
--jsonrpc {{ rootchain_json_rpc }} \
--proxy-contracts-admin $PROXY_CONTRACTS_ADMIN \
--test
polygon-edge rootchain deploy \
--stake-manager $(cat genesis.json | jq -r '.params.engine.polybft.bridge.stakeManagerAddr') \
--stake-token $(cat genesis.json | jq -r '.params.engine.polybft.bridge.stakeTokenAddr') \
--json-rpc {{ rootchain_json_rpc }} \
--proxy-contracts-admin $PROXY_CONTRACTS_ADMIN \
--test
polygon-edge rootchain fund \
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"
"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 All @@ -40,6 +41,7 @@ const (
rewardTokenCodeFlag = "reward-token-code"
rewardWalletFlag = "reward-wallet"
blockTrackerPollIntervalFlag = "block-tracker-poll-interval"
proxyContractsAdminFlag = "proxy-contracts-admin"

defaultNativeTokenName = "Polygon"
defaultNativeTokenSymbol = "MATIC"
Expand Down Expand Up @@ -134,6 +136,8 @@ type genesisParams struct {
rewardWallet string

blockTrackerPollInterval time.Duration

proxyContractsAdmin string
}

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

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

// Check if the genesis file already exists
Expand Down Expand Up @@ -549,6 +557,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
89 changes: 58 additions & 31 deletions command/genesis/polybft_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,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 @@ -153,6 +158,7 @@ func (p *genesisParams) generatePolyBftChainConfig(o command.OutputFormatter) er
},
BlockTimeDrift: p.blockTimeDrift,
BlockTrackerPollInterval: common.Duration{Duration: p.blockTrackerPollInterval},
ProxyContractsAdmin: types.StringToAddress(p.proxyContractsAdmin),
}

// Disable london hardfork if burn contract address is not provided
Expand Down Expand Up @@ -313,16 +319,18 @@ func (p *genesisParams) deployContracts(
polybftConfig *polybft.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 @@ -342,33 +350,33 @@ 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,
},
}

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 @@ -379,12 +387,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 @@ -393,95 +403,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 @@ -547,3 +561,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
}
14 changes: 14 additions & 0 deletions command/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/0xPolygon/polygon-edge/server"
"github.com/0xPolygon/polygon-edge/server/proto"
txpoolOp "github.com/0xPolygon/polygon-edge/txpool/proto"
"github.com/0xPolygon/polygon-edge/types"
"github.com/ryanuber/columnize"
"github.com/spf13/cobra"
"google.golang.org/grpc"
Expand Down Expand Up @@ -262,3 +263,16 @@ func ParseAmount(amount string) (*big.Int, error) {

return result, nil
}

func ValidateProxyContractsAdmin(proxyContractsAdmin string) error {
if err := types.IsValidAddress(proxyContractsAdmin); err != nil {
return fmt.Errorf("proxy contracts admin address is not valid: %w", err)
}

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

return nil
}
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
3 changes: 2 additions & 1 deletion command/rootchain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ $ polygon-edge rootchain deploy \
--deployer-key <hex_encoded_rootchain_deployer_private_key> \
--stake-manager <stake_manager_address> \
--stake-token <stake_token_address> \
--json-rpc <json_rpc_endpoint>
--json-rpc <json_rpc_endpoint> \
--proxy-contracts-admin <address of proxy contracts admin>
```

**Note:** In case `test` flag is provided, it engages test mode, which uses predefined test account private key to send transactions to the rootchain.
Loading

0 comments on commit 32047b4

Please sign in to comment.