Skip to content

Commit

Permalink
refactor: remove legacy factory address and bytecode check (#4568)
Browse files Browse the repository at this point in the history
  • Loading branch information
acha-bill authored Feb 6, 2024
1 parent b92c048 commit ee249af
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 426 deletions.
128 changes: 63 additions & 65 deletions cmd/bee/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,70 +22,69 @@ import (
)

const (
optionNameDataDir = "data-dir"
optionNameCacheCapacity = "cache-capacity"
optionNameDBOpenFilesLimit = "db-open-files-limit"
optionNameDBBlockCacheCapacity = "db-block-cache-capacity"
optionNameDBWriteBufferSize = "db-write-buffer-size"
optionNameDBDisableSeeksCompaction = "db-disable-seeks-compaction"
optionNamePassword = "password"
optionNamePasswordFile = "password-file"
optionNameAPIAddr = "api-addr"
optionNameP2PAddr = "p2p-addr"
optionNameNATAddr = "nat-addr"
optionNameP2PWSEnable = "p2p-ws-enable"
optionNameDebugAPIEnable = "debug-api-enable"
optionNameDebugAPIAddr = "debug-api-addr"
optionNameBootnodes = "bootnode"
optionNameNetworkID = "network-id"
optionWelcomeMessage = "welcome-message"
optionCORSAllowedOrigins = "cors-allowed-origins"
optionNameTracingEnabled = "tracing-enable"
optionNameTracingEndpoint = "tracing-endpoint"
optionNameTracingHost = "tracing-host"
optionNameTracingPort = "tracing-port"
optionNameTracingServiceName = "tracing-service-name"
optionNameVerbosity = "verbosity"
optionNamePaymentThreshold = "payment-threshold"
optionNamePaymentTolerance = "payment-tolerance-percent"
optionNamePaymentEarly = "payment-early-percent"
optionNameResolverEndpoints = "resolver-options"
optionNameBootnodeMode = "bootnode-mode"
optionNameClefSignerEnable = "clef-signer-enable"
optionNameClefSignerEndpoint = "clef-signer-endpoint"
optionNameClefSignerEthereumAddress = "clef-signer-ethereum-address"
optionNameSwapEndpoint = "swap-endpoint" // deprecated: use rpc endpoint instead
optionNameBlockchainRpcEndpoint = "blockchain-rpc-endpoint"
optionNameSwapFactoryAddress = "swap-factory-address"
optionNameSwapLegacyFactoryAddresses = "swap-legacy-factory-addresses"
optionNameSwapInitialDeposit = "swap-initial-deposit"
optionNameSwapEnable = "swap-enable"
optionNameChequebookEnable = "chequebook-enable"
optionNameSwapDeploymentGasPrice = "swap-deployment-gas-price"
optionNameFullNode = "full-node"
optionNamePostageContractAddress = "postage-stamp-address"
optionNamePostageContractStartBlock = "postage-stamp-start-block"
optionNamePriceOracleAddress = "price-oracle-address"
optionNameRedistributionAddress = "redistribution-address"
optionNameStakingAddress = "staking-address"
optionNameBlockTime = "block-time"
optionWarmUpTime = "warmup-time"
optionNameMainNet = "mainnet"
optionNameRetrievalCaching = "cache-retrieval"
optionNameDevReserveCapacity = "dev-reserve-capacity"
optionNameResync = "resync"
optionNamePProfBlock = "pprof-profile"
optionNamePProfMutex = "pprof-mutex"
optionNameStaticNodes = "static-nodes"
optionNameAllowPrivateCIDRs = "allow-private-cidrs"
optionNameSleepAfter = "sleep-after"
optionNameRestrictedAPI = "restricted"
optionNameTokenEncryptionKey = "token-encryption-key"
optionNameAdminPasswordHash = "admin-password"
optionNameUsePostageSnapshot = "use-postage-snapshot"
optionNameStorageIncentivesEnable = "storage-incentives-enable"
optionNameStateStoreCacheCapacity = "statestore-cache-capacity"
optionNameTargetNeighborhood = "target-neighborhood"
optionNameDataDir = "data-dir"
optionNameCacheCapacity = "cache-capacity"
optionNameDBOpenFilesLimit = "db-open-files-limit"
optionNameDBBlockCacheCapacity = "db-block-cache-capacity"
optionNameDBWriteBufferSize = "db-write-buffer-size"
optionNameDBDisableSeeksCompaction = "db-disable-seeks-compaction"
optionNamePassword = "password"
optionNamePasswordFile = "password-file"
optionNameAPIAddr = "api-addr"
optionNameP2PAddr = "p2p-addr"
optionNameNATAddr = "nat-addr"
optionNameP2PWSEnable = "p2p-ws-enable"
optionNameDebugAPIEnable = "debug-api-enable"
optionNameDebugAPIAddr = "debug-api-addr"
optionNameBootnodes = "bootnode"
optionNameNetworkID = "network-id"
optionWelcomeMessage = "welcome-message"
optionCORSAllowedOrigins = "cors-allowed-origins"
optionNameTracingEnabled = "tracing-enable"
optionNameTracingEndpoint = "tracing-endpoint"
optionNameTracingHost = "tracing-host"
optionNameTracingPort = "tracing-port"
optionNameTracingServiceName = "tracing-service-name"
optionNameVerbosity = "verbosity"
optionNamePaymentThreshold = "payment-threshold"
optionNamePaymentTolerance = "payment-tolerance-percent"
optionNamePaymentEarly = "payment-early-percent"
optionNameResolverEndpoints = "resolver-options"
optionNameBootnodeMode = "bootnode-mode"
optionNameClefSignerEnable = "clef-signer-enable"
optionNameClefSignerEndpoint = "clef-signer-endpoint"
optionNameClefSignerEthereumAddress = "clef-signer-ethereum-address"
optionNameSwapEndpoint = "swap-endpoint" // deprecated: use rpc endpoint instead
optionNameBlockchainRpcEndpoint = "blockchain-rpc-endpoint"
optionNameSwapFactoryAddress = "swap-factory-address"
optionNameSwapInitialDeposit = "swap-initial-deposit"
optionNameSwapEnable = "swap-enable"
optionNameChequebookEnable = "chequebook-enable"
optionNameSwapDeploymentGasPrice = "swap-deployment-gas-price"
optionNameFullNode = "full-node"
optionNamePostageContractAddress = "postage-stamp-address"
optionNamePostageContractStartBlock = "postage-stamp-start-block"
optionNamePriceOracleAddress = "price-oracle-address"
optionNameRedistributionAddress = "redistribution-address"
optionNameStakingAddress = "staking-address"
optionNameBlockTime = "block-time"
optionWarmUpTime = "warmup-time"
optionNameMainNet = "mainnet"
optionNameRetrievalCaching = "cache-retrieval"
optionNameDevReserveCapacity = "dev-reserve-capacity"
optionNameResync = "resync"
optionNamePProfBlock = "pprof-profile"
optionNamePProfMutex = "pprof-mutex"
optionNameStaticNodes = "static-nodes"
optionNameAllowPrivateCIDRs = "allow-private-cidrs"
optionNameSleepAfter = "sleep-after"
optionNameRestrictedAPI = "restricted"
optionNameTokenEncryptionKey = "token-encryption-key"
optionNameAdminPasswordHash = "admin-password"
optionNameUsePostageSnapshot = "use-postage-snapshot"
optionNameStorageIncentivesEnable = "storage-incentives-enable"
optionNameStateStoreCacheCapacity = "statestore-cache-capacity"
optionNameTargetNeighborhood = "target-neighborhood"
)

// nolint:gochecknoinits
Expand Down Expand Up @@ -277,7 +276,6 @@ func (c *command) setAllFlags(cmd *cobra.Command) {
cmd.Flags().String(optionNameSwapEndpoint, "", "swap blockchain endpoint") // deprecated: use rpc endpoint instead
cmd.Flags().String(optionNameBlockchainRpcEndpoint, "", "rpc blockchain endpoint")
cmd.Flags().String(optionNameSwapFactoryAddress, "", "swap factory addresses")
cmd.Flags().StringSlice(optionNameSwapLegacyFactoryAddresses, nil, "legacy swap factory addresses")
cmd.Flags().String(optionNameSwapInitialDeposit, "0", "initial deposit if deploying a new chequebook")
cmd.Flags().Bool(optionNameSwapEnable, false, "enable swap")
cmd.Flags().Bool(optionNameChequebookEnable, true, "enable chequebook")
Expand Down
9 changes: 1 addition & 8 deletions cmd/bee/cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,7 @@ func (c *command) initDeployCmd() error {
defer swapBackend.Close()
defer transactionMonitor.Close()

chequebookFactory, err := node.InitChequebookFactory(
logger,
swapBackend,
chainID,
transactionService,
factoryAddress,
nil,
)
chequebookFactory, err := node.InitChequebookFactory(logger, swapBackend, chainID, transactionService, factoryAddress)
if err != nil {
return err
}
Expand Down
1 change: 0 additions & 1 deletion cmd/bee/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,6 @@ func buildBeeNode(ctx context.Context, c *command, cmd *cobra.Command, logger lo
BootnodeMode: bootNode,
BlockchainRpcEndpoint: blockchainRpcEndpoint,
SwapFactoryAddress: c.config.GetString(optionNameSwapFactoryAddress),
SwapLegacyFactoryAddresses: c.config.GetStringSlice(optionNameSwapLegacyFactoryAddresses),
SwapInitialDeposit: c.config.GetString(optionNameSwapInitialDeposit),
SwapEnable: c.config.GetBool(optionNameSwapEnable),
ChequebookEnable: c.config.GetBool(optionNameChequebookEnable),
Expand Down
1 change: 0 additions & 1 deletion pkg/config/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ type ChainConfig struct {
RedistributionAddress common.Address
SwapPriceOracleAddress common.Address
CurrentFactoryAddress common.Address
LegacyFactoryAddresses []common.Address

// ABIs.
StakingABI string
Expand Down
33 changes: 3 additions & 30 deletions pkg/node/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,20 +100,11 @@ func InitChain(

// InitChequebookFactory will initialize the chequebook factory with the given
// chain backend.
func InitChequebookFactory(
logger log.Logger,
backend transaction.Backend,
chainID int64,
transactionService transaction.Service,
factoryAddress string,
legacyFactoryAddresses []string,
) (chequebook.Factory, error) {
func InitChequebookFactory(logger log.Logger, backend transaction.Backend, chainID int64, transactionService transaction.Service, factoryAddress string) (chequebook.Factory, error) {
var currentFactory common.Address
var legacyFactories []common.Address

chainCfg, found := config.GetByChainID(chainID)

foundFactory, foundLegacyFactories := chainCfg.CurrentFactoryAddress, chainCfg.LegacyFactoryAddresses
foundFactory := chainCfg.CurrentFactoryAddress
if factoryAddress == "" {
if !found {
return nil, fmt.Errorf("no known factory address for this network (chain id: %d)", chainID)
Expand All @@ -127,25 +118,7 @@ func InitChequebookFactory(
logger.Info("using custom factory address", "factory_address", currentFactory)
}

if len(legacyFactoryAddresses) == 0 {
if found {
legacyFactories = foundLegacyFactories
}
} else {
for _, legacyAddress := range legacyFactoryAddresses {
if !common.IsHexAddress(legacyAddress) {
return nil, errors.New("malformed factory address")
}
legacyFactories = append(legacyFactories, common.HexToAddress(legacyAddress))
}
}

return chequebook.NewFactory(
backend,
transactionService,
currentFactory,
legacyFactories,
), nil
return chequebook.NewFactory(backend, transactionService, currentFactory), nil
}

// InitChequebookService will initialize the chequebook service with the given
Expand Down
14 changes: 1 addition & 13 deletions pkg/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ type Options struct {
BootnodeMode bool
BlockchainRpcEndpoint string
SwapFactoryAddress string
SwapLegacyFactoryAddresses []string
SwapInitialDeposit string
SwapEnable bool
ChequebookEnable bool
Expand Down Expand Up @@ -504,22 +503,11 @@ func NewBee(
}

if o.SwapEnable {
chequebookFactory, err = InitChequebookFactory(
logger,
chainBackend,
chainID,
transactionService,
o.SwapFactoryAddress,
o.SwapLegacyFactoryAddresses,
)
chequebookFactory, err = InitChequebookFactory(logger, chainBackend, chainID, transactionService, o.SwapFactoryAddress)
if err != nil {
return nil, err
}

if err = chequebookFactory.VerifyBytecode(ctx); err != nil {
return nil, fmt.Errorf("factory fail: %w", err)
}

erc20Address, err := chequebookFactory.ERC20Address(ctx)
if err != nil {
return nil, fmt.Errorf("factory fail: %w", err)
Expand Down
6 changes: 0 additions & 6 deletions pkg/settlement/swap/chequebook/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ type factoryMock struct {
erc20Address func(ctx context.Context) (common.Address, error)
deploy func(ctx context.Context, issuer common.Address, defaultHardDepositTimeoutDuration *big.Int, nonce common.Hash) (common.Hash, error)
waitDeployed func(ctx context.Context, txHash common.Hash) (common.Address, error)
verifyBytecode func(ctx context.Context) error
verifyChequebook func(ctx context.Context, chequebook common.Address) error
}

Expand All @@ -41,11 +40,6 @@ func (m *factoryMock) WaitDeployed(ctx context.Context, txHash common.Hash) (com
return m.waitDeployed(ctx, txHash)
}

// VerifyBytecode checks that the factory is valid.
func (m *factoryMock) VerifyBytecode(ctx context.Context) error {
return m.verifyBytecode(ctx)
}

// VerifyChequebook checks that the supplied chequebook has been deployed by this factory.
func (m *factoryMock) VerifyChequebook(ctx context.Context, chequebook common.Address) error {
return m.verifyChequebook(ctx, chequebook)
Expand Down
58 changes: 2 additions & 56 deletions pkg/settlement/swap/chequebook/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package chequebook

import (
"bytes"
"errors"
"fmt"
"math/big"
Expand Down Expand Up @@ -36,38 +35,26 @@ type Factory interface {
Deploy(ctx context.Context, issuer common.Address, defaultHardDepositTimeoutDuration *big.Int, nonce common.Hash) (common.Hash, error)
// WaitDeployed waits for the deployment transaction to confirm and returns the chequebook address
WaitDeployed(ctx context.Context, txHash common.Hash) (common.Address, error)
// VerifyBytecode checks that the factory is valid.
VerifyBytecode(ctx context.Context) error
// VerifyChequebook checks that the supplied chequebook has been deployed by this factory.
VerifyChequebook(ctx context.Context, chequebook common.Address) error
}

type factory struct {
backend transaction.Backend
transactionService transaction.Service
address common.Address // address of the factory to use for deployments
legacyAddresses []common.Address // addresses of old factories which were allowed for deployment
address common.Address // address of the factory to use for deployments
}

type simpleSwapDeployedEvent struct {
ContractAddress common.Address
}

// the bytecode of factories which can be used for deployment
var currentDeployVersion = common.FromHex(sw3abi.SimpleSwapFactoryDeployedBinv0_6_5)

// the bytecode of factories from which we accept chequebooks
var supportedVersions = [][]byte{
currentDeployVersion,
}

// NewFactory creates a new factory service for the provided factory contract.
func NewFactory(backend transaction.Backend, transactionService transaction.Service, address common.Address, legacyAddresses []common.Address) Factory {
func NewFactory(backend transaction.Backend, transactionService transaction.Service, address common.Address) Factory {
return &factory{
backend: backend,
transactionService: transactionService,
address: address,
legacyAddresses: legacyAddresses,
}
}

Expand Down Expand Up @@ -111,36 +98,6 @@ func (c *factory) WaitDeployed(ctx context.Context, txHash common.Hash) (common.
return event.ContractAddress, nil
}

// VerifyBytecode checks that the factory is valid.
func (c *factory) VerifyBytecode(ctx context.Context) (err error) {
code, err := c.backend.CodeAt(ctx, c.address, nil)
if err != nil {
return err
}

if !bytes.Equal(code, currentDeployVersion) {
return ErrInvalidFactory
}

LOOP:
for _, factoryAddress := range c.legacyAddresses {
code, err := c.backend.CodeAt(ctx, factoryAddress, nil)
if err != nil {
return err
}

for _, referenceCode := range supportedVersions {
if bytes.Equal(code, referenceCode) {
continue LOOP
}
}

return fmt.Errorf("failed to find matching bytecode for factory %x: %w", factoryAddress, ErrInvalidFactory)
}

return nil
}

func (c *factory) verifyChequebookAgainstFactory(ctx context.Context, factory, chequebook common.Address) (bool, error) {
callData, err := factoryABI.Pack("deployedContracts", chequebook)
if err != nil {
Expand Down Expand Up @@ -183,17 +140,6 @@ func (c *factory) VerifyChequebook(ctx context.Context, chequebook common.Addres
if deployed {
return nil
}

for _, factoryAddress := range c.legacyAddresses {
deployed, err := c.verifyChequebookAgainstFactory(ctx, factoryAddress, chequebook)
if err != nil {
return err
}
if deployed {
return nil
}
}

return ErrNotDeployedByFactory
}

Expand Down
Loading

0 comments on commit ee249af

Please sign in to comment.