Skip to content

Commit

Permalink
Genesis icm (#2154)
Browse files Browse the repository at this point in the history
* adding teleporter contract to genesis

* fixes for icm on genesis

* add icm from a given embedded file

* add function to deploy ICM registry

* creating mapping values

* add consts

* make local deploy to work

* do not print info for icm support addrs

* nit

* nit

* fix wiz stuff

* address PR comments

* filter based on balance

* add unit tests

* Update cmd/blockchaincmd/describe.go

Co-authored-by: Michael Kaplan <55204436+michaelkaplan13@users.noreply.github.com>
Signed-off-by: felipemadero <felipe.madero@gmail.com>

* lint

---------

Signed-off-by: felipemadero <felipe.madero@gmail.com>
Co-authored-by: Michael Kaplan <55204436+michaelkaplan13@users.noreply.github.com>
  • Loading branch information
felipemadero and michaelkaplan13 authored Sep 26, 2024
1 parent cd9402e commit 654a3e4
Show file tree
Hide file tree
Showing 14 changed files with 475 additions and 47 deletions.
3 changes: 3 additions & 0 deletions cmd/blockchaincmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type CreateFlags struct {
useLatestReleasedVMVersion bool
useLatestPreReleasedVMVersion bool
useExternalGasToken bool
addICMRegistryToGenesis bool
proofOfStake bool
proofOfAuthority bool
}
Expand Down Expand Up @@ -103,6 +104,7 @@ configuration, pass the -f flag.`,
cmd.Flags().BoolVar(&createFlags.useWarp, "warp", true, "generate a vm with warp support (needed for teleporter)")
cmd.Flags().BoolVar(&createFlags.useTeleporter, "teleporter", false, "interoperate with other blockchains using teleporter")
cmd.Flags().BoolVar(&createFlags.useExternalGasToken, "external-gas-token", false, "use a gas token from another blockchain")
cmd.Flags().BoolVar(&createFlags.addICMRegistryToGenesis, "icm-registry-at-genesis", false, "setup ICM registry smart contract on genesis [experimental]")
cmd.Flags().BoolVar(&createFlags.proofOfAuthority, "proof-of-authority", false, "use proof of authority for validator management")
cmd.Flags().BoolVar(&createFlags.proofOfStake, "proof-of-stake", false, "(coming soon) use proof of stake for validator management")
return cmd
Expand Down Expand Up @@ -288,6 +290,7 @@ func createBlockchainConfig(cmd *cobra.Command, args []string) error {
blockchainName,
params,
teleporterInfo,
createFlags.addICMRegistryToGenesis,
)
if err != nil {
return err
Expand Down
3 changes: 2 additions & 1 deletion cmd/blockchaincmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ so you can take your locally tested Subnet and deploy it on Fuji or Mainnet.`,
cmd.Flags().BoolVar(&icmSpec.SkipICMDeploy, "skip-local-teleporter", false, "skip automatic teleporter deploy on local networks [to be deprecated]")
cmd.Flags().BoolVar(&icmSpec.SkipICMDeploy, "skip-teleporter-deploy", false, "skip automatic teleporter deploy")
cmd.Flags().BoolVar(&icmSpec.SkipRelayerDeploy, "skip-relayer", false, "skip relayer deploy")
cmd.Flags().StringVar(&icmSpec.Version, "teleporter-version", "latest", "teleporter version to deploy")
cmd.Flags().StringVar(&icmSpec.ICMVersion, "teleporter-version", "latest", "teleporter version to deploy")
cmd.Flags().StringVar(&icmSpec.RelayerVersion, "relayer-version", "latest", "relayer version to deploy")
cmd.Flags().StringVar(&icmSpec.MessengerContractAddressPath, "teleporter-messenger-contract-address-path", "", "path to an interchain messenger contract address file")
cmd.Flags().StringVar(&icmSpec.MessengerDeployerAddressPath, "teleporter-messenger-deployer-address-path", "", "path to an interchain messenger deployer address file")
cmd.Flags().StringVar(&icmSpec.MessengerDeployerTxPath, "teleporter-messenger-deployer-tx-path", "", "path to an interchain messenger deployer tx file")
Expand Down
35 changes: 33 additions & 2 deletions cmd/blockchaincmd/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/ava-labs/avalanche-cli/pkg/models"
"github.com/ava-labs/avalanche-cli/pkg/networkoptions"
"github.com/ava-labs/avalanche-cli/pkg/subnet"
icmgenesis "github.com/ava-labs/avalanche-cli/pkg/teleporter/genesis"
"github.com/ava-labs/avalanche-cli/pkg/txutils"
"github.com/ava-labs/avalanche-cli/pkg/utils"
"github.com/ava-labs/avalanche-cli/pkg/ux"
Expand Down Expand Up @@ -216,6 +217,7 @@ func PrintSubnetInfo(blockchainName string, onlyLocalnetInfo bool) error {
if err := printAllocations(sc, genesis); err != nil {
return err
}
printSmartContracts(genesis)
printPrecompiles(genesis)
}

Expand Down Expand Up @@ -275,8 +277,12 @@ func printAllocations(sc models.Sidecar, genesis core.Genesis) error {
t.Style().Options.SeparateRows = true
t.SetTitle("Initial Token Allocation")
t.AppendHeader(table.Row{"Description", "Address and Private Key", "Amount (10^18)", "Amount (wei)"})
for address := range genesis.Alloc {
amount := genesis.Alloc[address].Balance
for address, allocation := range genesis.Alloc {
amount := allocation.Balance
// we are only interested in supply distribution here
if amount == nil || big.NewInt(0).Cmp(amount) == 0 {
continue
}
formattedAmount := new(big.Int).Div(amount, big.NewInt(params.Ether))
description := ""
privKey := ""
Expand All @@ -298,6 +304,31 @@ func printAllocations(sc models.Sidecar, genesis core.Genesis) error {
return nil
}

func printSmartContracts(genesis core.Genesis) {
if len(genesis.Alloc) == 0 {
return
}
ux.Logger.PrintToUser("")
t := table.NewWriter()
t.Style().Title.Align = text.AlignCenter
t.Style().Title.Format = text.FormatUpper
t.Style().Options.SeparateRows = true
t.SetTitle("Smart Contracts")
t.AppendHeader(table.Row{"Description", "Address", "Deployer"})
for address, allocation := range genesis.Alloc {
if len(allocation.Code) == 0 {
continue
}
var description, deployer string
if address == common.HexToAddress(icmgenesis.MessengerContractAddress) {
description = "ICM Messenger"
deployer = icmgenesis.MessengerDeployerAddress
}
t.AppendRow(table.Row{description, address.Hex(), deployer})
}
ux.Logger.PrintToUser(t.Render())
}

func printPrecompiles(genesis core.Genesis) {
ux.Logger.PrintToUser("")
t := table.NewWriter()
Expand Down
1 change: 1 addition & 0 deletions cmd/nodecmd/wiz.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ func wiz(cmd *cobra.Command, args []string) error {
},
DeployMessenger: deployTeleporterMessenger,
DeployRegistry: deployTeleporterRegistry,
ForceRegistryDeploy: true,
Version: teleporterVersion,
MessengerContractAddressPath: teleporterMessengerContractAddressPath,
MessengerDeployerAddressPath: teleporterMessengerDeployerAddressPath,
Expand Down
4 changes: 4 additions & 0 deletions cmd/teleportercmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type DeployFlags struct {
GenesisKey bool
DeployMessenger bool
DeployRegistry bool
ForceRegistryDeploy bool
RPCURL string
Version string
MessengerContractAddressPath string
Expand Down Expand Up @@ -62,6 +63,7 @@ func newDeployCmd() *cobra.Command {
deployFlags.ChainFlags.AddToCmd(cmd, "deploy ICM", true)
cmd.Flags().BoolVar(&deployFlags.DeployMessenger, "deploy-messenger", true, "deploy Teleporter Messenger")
cmd.Flags().BoolVar(&deployFlags.DeployRegistry, "deploy-registry", true, "deploy Teleporter Registry")
cmd.Flags().BoolVar(&deployFlags.ForceRegistryDeploy, "force-registry-deploy", false, "deploy Teleporter Registry even if Messenger has already been deployed")
cmd.Flags().StringVar(&deployFlags.RPCURL, "rpc-url", "", "use the given RPC URL to connect to the subnet")
cmd.Flags().StringVar(&deployFlags.Version, "version", "latest", "version to deploy")
cmd.Flags().StringVar(&deployFlags.MessengerContractAddressPath, "messenger-contract-address-path", "", "path to a messenger contract address file")
Expand Down Expand Up @@ -188,6 +190,7 @@ func CallDeploy(_ []string, flags DeployFlags) error {
privateKey,
flags.DeployMessenger,
flags.DeployRegistry,
flags.ForceRegistryDeploy,
)
if err != nil {
return err
Expand Down Expand Up @@ -224,6 +227,7 @@ func CallDeploy(_ []string, flags DeployFlags) error {
ewoq.PrivKeyHex(),
flags.DeployMessenger,
flags.DeployRegistry,
false,
)
if err != nil {
return err
Expand Down
16 changes: 16 additions & 0 deletions pkg/contract/allocations.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,19 @@ func GetEVMSubnetGenesisNativeMinterAdmin(
}
return getGenesisNativeMinterAdmin(app, network, genesisData)
}

func ContractAddressIsInGenesisData(
genesisData []byte,
contractAddress common.Address,
) (bool, error) {
genesis, err := utils.ByteSliceToSubnetEvmGenesis(genesisData)
if err != nil {
return false, err
}
for address, allocation := range genesis.Alloc {
if address == contractAddress {
return len(allocation.Code) > 0, nil
}
}
return false, nil
}
194 changes: 194 additions & 0 deletions pkg/contract/allocations_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
// Copyright (C) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package contract

import (
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)

func TestContractAddressIsInGenesisData(t *testing.T) {
require := require.New(t)

type test struct {
desc string
genesisData []byte
contractAddress common.Address
expected bool
shouldErr bool
}

tests := []test{
{
desc: "nil data",
genesisData: nil,
contractAddress: common.Address{},
expected: false,
shouldErr: true,
},
{
desc: "not json",
genesisData: []byte("not json"),
contractAddress: common.Address{},
expected: false,
shouldErr: true,
},
{
desc: "not evm",
genesisData: []byte("{}"),
contractAddress: common.Address{},
expected: false,
shouldErr: true,
},
{
desc: "no allocs",
genesisData: []byte(`
{
"config": {
"byzantiumBlock": 0, "chainId": 1, "constantinopleBlock": 0, "eip150Block": 0,
"eip155Block": 0, "eip158Block": 0,
"feeConfig": {
"gasLimit": 12000000, "targetBlockRate": 2, "minBaseFee": 25000000000,
"targetGas": 60000000, "baseFeeChangeDenominator": 36, "minBlockGasCost": 0,
"maxBlockGasCost": 1000000, "blockGasCostStep": 200000
},
"homesteadBlock": 0, "istanbulBlock": 0, "muirGlacierBlock": 0, "petersburgBlock": 0,
"warpConfig": {
"blockTimestamp": 1727309619, "quorumNumerator": 67
}
},
"nonce": "0x0", "timestamp": "0x66f4a733", "extraData": "0x", "gasLimit": "0xb71b00", "difficulty": "0x0",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"airdropHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"airdropAmount": null, "number": "0x0", "gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"baseFeePerGas": null, "excessBlobGas": null, "blobGasUsed": null,
"alloc": {}
}
`),
contractAddress: common.Address{},
expected: false,
shouldErr: false,
},
{
desc: "good path",
genesisData: []byte(`
{
"config": {
"byzantiumBlock": 0, "chainId": 1, "constantinopleBlock": 0, "eip150Block": 0,
"eip155Block": 0, "eip158Block": 0,
"feeConfig": {
"gasLimit": 12000000, "targetBlockRate": 2, "minBaseFee": 25000000000,
"targetGas": 60000000, "baseFeeChangeDenominator": 36, "minBlockGasCost": 0,
"maxBlockGasCost": 1000000, "blockGasCostStep": 200000
},
"homesteadBlock": 0, "istanbulBlock": 0, "muirGlacierBlock": 0, "petersburgBlock": 0,
"warpConfig": {
"blockTimestamp": 1727309619, "quorumNumerator": 67
}
},
"nonce": "0x0", "timestamp": "0x66f4a733", "extraData": "0x", "gasLimit": "0xb71b00", "difficulty": "0x0",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"airdropHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"airdropAmount": null, "number": "0x0", "gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"baseFeePerGas": null, "excessBlobGas": null, "blobGasUsed": null,
"alloc": {
"253b2784c75e510dd0ff1da844684a1ac0aa5fcf": {
"code": "0xfe",
"balance": "0x2086ac351052600000"
}
}
}
`),
contractAddress: common.HexToAddress("0x253b2784c75e510dd0ff1da844684a1ac0aa5fcf"),
expected: true,
shouldErr: false,
},
{
desc: "no code",
genesisData: []byte(`
{
"config": {
"byzantiumBlock": 0, "chainId": 1, "constantinopleBlock": 0, "eip150Block": 0,
"eip155Block": 0, "eip158Block": 0,
"feeConfig": {
"gasLimit": 12000000, "targetBlockRate": 2, "minBaseFee": 25000000000,
"targetGas": 60000000, "baseFeeChangeDenominator": 36, "minBlockGasCost": 0,
"maxBlockGasCost": 1000000, "blockGasCostStep": 200000
},
"homesteadBlock": 0, "istanbulBlock": 0, "muirGlacierBlock": 0, "petersburgBlock": 0,
"warpConfig": {
"blockTimestamp": 1727309619, "quorumNumerator": 67
}
},
"nonce": "0x0", "timestamp": "0x66f4a733", "extraData": "0x", "gasLimit": "0xb71b00", "difficulty": "0x0",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"airdropHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"airdropAmount": null, "number": "0x0", "gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"baseFeePerGas": null, "excessBlobGas": null, "blobGasUsed": null,
"alloc": {
"253b2784c75e510dd0ff1da844684a1ac0aa5fcf": {
"balance": "0x2086ac351052600000"
}
}
}
`),
contractAddress: common.HexToAddress("0x253b2784c75e510dd0ff1da844684a1ac0aa5fcf"),
expected: false,
shouldErr: false,
},
{
desc: "diff addr",
genesisData: []byte(`
{
"config": {
"byzantiumBlock": 0, "chainId": 1, "constantinopleBlock": 0, "eip150Block": 0,
"eip155Block": 0, "eip158Block": 0,
"feeConfig": {
"gasLimit": 12000000, "targetBlockRate": 2, "minBaseFee": 25000000000,
"targetGas": 60000000, "baseFeeChangeDenominator": 36, "minBlockGasCost": 0,
"maxBlockGasCost": 1000000, "blockGasCostStep": 200000
},
"homesteadBlock": 0, "istanbulBlock": 0, "muirGlacierBlock": 0, "petersburgBlock": 0,
"warpConfig": {
"blockTimestamp": 1727309619, "quorumNumerator": 67
}
},
"nonce": "0x0", "timestamp": "0x66f4a733", "extraData": "0x", "gasLimit": "0xb71b00", "difficulty": "0x0",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"airdropHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"airdropAmount": null, "number": "0x0", "gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"baseFeePerGas": null, "excessBlobGas": null, "blobGasUsed": null,
"alloc": {
"253b2784c75e510dd0ff1da844684a1ac0aa5fcf": {
"code": "0xfe",
"balance": "0x2086ac351052600000"
}
}
}
`),
contractAddress: common.HexToAddress("0x253b2724c75e510dd0ff1da844684a1ac0aa5fcc"),
expected: false,
shouldErr: false,
},
}

for _, t := range tests {
b, err := ContractAddressIsInGenesisData(t.genesisData, t.contractAddress)
if t.shouldErr {
require.Error(err, t.desc)
} else {
require.NoError(err, t.desc)
}
require.Equal(t.expected, b, t.desc)
}
}
Loading

0 comments on commit 654a3e4

Please sign in to comment.