Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General improvements and tech-debt #121

Merged
merged 22 commits into from
Mar 1, 2024
1 change: 0 additions & 1 deletion api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,6 @@ func handleError[T any](log zerolog.Logger, err error) (T, error) {
NOT SUPPORTED SECTION

====================================================================================================================== */
// todo check the design, maybe we don't need to even have the unsupported functions defined

// GetUncleCountByBlockHash returns number of uncles in the block for the given block hash
func (b *BlockChainAPI) GetUncleCountByBlockHash(
Expand Down
1 change: 0 additions & 1 deletion api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,6 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}

// If JSON-RPC over HTTP is enabled, try to serve the request
// todo wrap with CORS handler in main branch
rpc := recoverHandler(h.logger, h.httpHandler)
if rpc != nil {
if checkPath(r, "") {
Expand Down
37 changes: 23 additions & 14 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ package config
import (
"flag"
"fmt"
"github.com/goccy/go-json"
"github.com/onflow/flow-go/utils/io"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/goccy/go-json"
"github.com/onflow/flow-go-sdk"
"github.com/onflow/flow-go-sdk/crypto"
"github.com/onflow/flow-go/fvm/evm/emulator"
flowGo "github.com/onflow/flow-go/model/flow"
"github.com/onflow/flow-go/utils/io"
)

type Config struct {
Expand All @@ -21,12 +22,11 @@ type Config struct {
// GRPCPort for the RPC API server
RPCPort int
// GRPCHost for the RPC API server
// todo maybe merge port into host as it's for AN
RPCHost string
// EVMNetworkID provides the EVM chain ID.
EVMNetworkID *big.Int
// FlowNetworkID is the Flow network ID that the EVM is hosted on (mainnet, testnet, emulator...)
FlowNetworkID string
FlowNetworkID flowGo.ChainID
// Coinbase is EVM address that collects the EVM operator fees collected
// when transactions are being submitted.
Coinbase common.Address
Expand All @@ -45,21 +45,21 @@ type Config struct {

func FromFlags() (*Config, error) {
cfg := &Config{}
var evmNetwork, coinbase, gas, coa, key, keysPath string
var evmNetwork, coinbase, gas, coa, key, keysPath, flowChainID string

// parse from flags
flag.StringVar(&cfg.DatabaseDir, "database-dir", "./db", "path to the directory for the database")
flag.StringVar(&cfg.RPCHost, "rpc-host", "", "host for the RPC API server")
flag.IntVar(&cfg.RPCPort, "rpc-port", 8545, "port for the RPC API server")
flag.StringVar(&cfg.AccessNodeGRPCHost, "access-node-grpc-host", "localhost:3569", "host to the flow access node gRPC API")
flag.StringVar(&cfg.DatabaseDir, "database-dir", "./db", "Path to the directory for the database")
flag.StringVar(&cfg.RPCHost, "rpc-host", "", "Host for the RPC API server")
flag.IntVar(&cfg.RPCPort, "rpc-port", 8545, "Port for the RPC API server")
flag.StringVar(&cfg.AccessNodeGRPCHost, "access-node-grpc-host", "localhost:3569", "Host to the flow access node gRPC API")
flag.StringVar(&evmNetwork, "evm-network-id", "testnet", "EVM network ID (testnet, mainnet)")
flag.StringVar(&cfg.FlowNetworkID, "flow-network-id", "emulator", "EVM network ID (emulator, previewnet)")
flag.StringVar(&coinbase, "coinbase", "", "coinbase address to use for fee collection")
flag.StringVar(&gas, "gas-price", "1", "static gas price used for EVM transactions")
flag.StringVar(&flowChainID, "flow-network-id", "flow-emulator", "Flow network ID (flow-emulator, flow-previewnet)")
flag.StringVar(&coinbase, "coinbase", "", "Coinbase address to use for fee collection")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit out of context of this PR, but it occurred to me that we might better fetch this from the COA resource that resides in the coa-address. We can do this either through a script on startup and memoize the value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ohh you are right, can you open an issue for this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing 👍

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #122

flag.StringVar(&gas, "gas-price", "1", "Static gas price used for EVM transactions")
flag.StringVar(&coa, "coa-address", "", "Flow address that holds COA account used for submitting transactions")
flag.StringVar(&key, "coa-key", "", "WARNING: do not use this flag in production! private key value for the COA address used for submitting transactions")
flag.StringVar(&key, "coa-key", "", "Private key value for the COA address used for submitting transactions")
flag.StringVar(&keysPath, "coa-key-file", "", "File path that contains JSON array of COA keys used in key-rotation mechanism, this is exclusive with coa-key flag.")
flag.BoolVar(&cfg.CreateCOAResource, "coa-resource-create", false, "auto-create the COA resource in the Flow COA account provided if one doesn't exist")
flag.BoolVar(&cfg.CreateCOAResource, "coa-resource-create", false, "Auto-create the COA resource in the Flow COA account provided if one doesn't exist")
flag.Parse()

if coinbase == "" {
Expand Down Expand Up @@ -112,6 +112,15 @@ func FromFlags() (*Config, error) {
return nil, fmt.Errorf("EVM network ID not supported")
}

switch flowChainID {
case "flow-previewnet":
cfg.FlowNetworkID = flowGo.Previewnet
case "flow-emulator":
cfg.FlowNetworkID = flowGo.Emulator
default:
return nil, fmt.Errorf("flow network ID not supported, only possible to specify 'flow-previewnet' or 'flow-emulator'")
}

if cfg.FlowNetworkID != "previewnet" && cfg.FlowNetworkID != "emulator" {
return nil, fmt.Errorf("flow network ID is invalid, only allowed to set 'emulator' and 'previewnet'")
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/rs/zerolog v1.31.0
github.com/stretchr/testify v1.8.4
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
golang.org/x/sync v0.6.0
)

require (
Expand Down Expand Up @@ -171,7 +172,6 @@ require (
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.17.0 // indirect
Expand Down
22 changes: 12 additions & 10 deletions integration/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/hex"
"fmt"
"github.com/onflow/flow-go-sdk/access/grpc"
"github.com/onflow/flow-go/fvm/evm/types"
"math/big"
"testing"
"time"
Expand Down Expand Up @@ -57,17 +58,17 @@ func TestIntegration_TransferValue(t *testing.T) {
cancelIngestion()
}()

fundAmount := int64(5)
flowAmount, _ := cadence.NewUFix64("5.0")
fundWei := flowToWei(fundAmount)
fundWei := types.NewBalanceFromUFix64(flowAmount)

// step 1, 2, and 3. - create COA and fund it
res, err := fundEOA(emu, flowAmount, fundEOAAddress)
require.NoError(t, err)
require.NoError(t, res.Error)
assert.Len(t, res.Events, 9) // 7 evm events + 2 cadence events

transferWei := flowToWei(1)
flowTransfer, _ := cadence.NewUFix64("1.0")
transferWei := types.NewBalanceFromUFix64(flowTransfer)
fundEOAKey, err := crypto.HexToECDSA(fundEOARawKey)
require.NoError(t, err)

Expand All @@ -84,21 +85,21 @@ func TestIntegration_TransferValue(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, uint64(2), blk.Height)

assert.Equal(t, fundWei.Cmp(blk.TotalSupply), 0)
assert.Zero(t, blk.TotalSupply.Cmp(fundWei))
require.Len(t, blk.TransactionHashes, 1)

// block 3 comes from calling evm.call to transfer to eoa 1
blk, err = blocks.GetByHeight(3)
require.NoError(t, err)
assert.Equal(t, uint64(3), blk.Height)
assert.Equal(t, fundWei.Cmp(blk.TotalSupply), 0)
assert.Zero(t, blk.TotalSupply.Cmp(fundWei))
require.Len(t, blk.TransactionHashes, 1)

// block 5 comes from calling evm.call to transfer from eoa 1 to eoa 2
blk, err = blocks.GetByHeight(5)
require.NoError(t, err)
assert.Equal(t, uint64(5), blk.Height)
assert.Equal(t, fundWei.Cmp(blk.TotalSupply), 0)
assert.Zero(t, blk.TotalSupply.Cmp(fundWei))
require.Len(t, blk.TransactionHashes, 1)

// transaction 1 comes from evm.call to transfer from eoa 1 to eoa 2
Expand All @@ -108,7 +109,7 @@ func TestIntegration_TransferValue(t *testing.T) {
tx, err := txs.Get(transferHash)
require.NoError(t, err)
assert.Equal(t, uint64(0), tx.Nonce())
assert.Equal(t, transferWei, tx.Value())
assert.Zero(t, tx.Value().Cmp(transferWei))
assert.Equal(t, &transferEOAAdress, tx.To())
assert.Equal(t, uint64(21_000), tx.Gas())

Expand Down Expand Up @@ -426,7 +427,7 @@ func TestE2E_API_DeployEvents(t *testing.T) {
AccessNodeGRPCHost: "localhost:3569", // emulator
RPCPort: 3001,
RPCHost: "127.0.0.1",
FlowNetworkID: "emulator",
FlowNetworkID: "flow-emulator",
EVMNetworkID: emulator.FlowEVMTestnetChainID,
Coinbase: fundEOAAddress,
COAAddress: gwAddress,
Expand Down Expand Up @@ -479,7 +480,8 @@ func TestE2E_API_DeployEvents(t *testing.T) {
// check balance
balance, err := rpcTester.getBalance(fundEOAAddress)
require.NoError(t, err)
assert.Equal(t, new(big.Int).Mul(big.NewInt(4), toWei), balance.ToInt())
c, _ := cadence.NewUFix64("4.0")
assert.Zero(t, balance.ToInt().Cmp(types.NewBalanceFromUFix64(c)))

// Step 4. - deploy contract
nonce := uint64(0)
Expand Down Expand Up @@ -783,7 +785,7 @@ func TestE2E_ConcurrentTransactionSubmission(t *testing.T) {
RPCPort: 3001,
RPCHost: "127.0.0.1",
EVMNetworkID: emulator.FlowEVMTestnetChainID,
FlowNetworkID: "emulator",
FlowNetworkID: "flow-emulator",
Coinbase: fundEOAAddress,
COAAddress: *createdAddr,
COAKeys: keys,
Expand Down
38 changes: 1 addition & 37 deletions integration/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ import (
const testPrivateKey = "61ceacbdce419e25ee8e7c2beceee170a05c9cab1e725a955b15ba94dcd747d2"

var (
toWei = new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)
logger = zerolog.New(os.Stdout)
sc = systemcontracts.SystemContractsForChain(flow.Emulator)
)
Expand Down Expand Up @@ -73,43 +72,13 @@ func startEmulator() (*server.EmulatorServer, error) {
srv.Start()
}()

time.Sleep(200 * time.Millisecond) // give it some time to start, dummy but ok for test

e := srv.Emulator()
b, err := e.GetLatestBlock()
if err != nil {
return nil, err
}
// mine one block to make sure we start at height 1, which is expected on normal network
addr := flow.Address(e.ServiceKey().Address)
emptyTx := &flow.TransactionBody{
ReferenceBlockID: b.ID(),
Script: []byte(`transaction{}`),
ProposalKey: flow.ProposalKey{
Address: addr,
KeyIndex: 0,
SequenceNumber: 2,
},
Payer: addr,
}
hasher, err := crypto.NewHasher(crypto.HashAlgorithm(crypto.SHA3_256))
if err != nil {
return nil, err
}
if err := emptyTx.SignEnvelope(addr, 0, e.ServiceKey().PrivateKey, hasher); err != nil {
return nil, err
}
if err := e.SendTransaction(emptyTx); err != nil {
return nil, err
}
time.Sleep(1000 * time.Millisecond) // give it some time to start, dummy but ok for test

return srv, nil
}

// startEventIngestionEngine will start up the sdkEvent engine with the grpc subscriber
// listening for events.
// todo for now we return index storage as a way to check the data if it was correctly
// indexed this will be in future replaced with evm gateway API access
func startEventIngestionEngine(ctx context.Context, dbDir string) (
storage.BlockIndexer,
storage.ReceiptIndexer,
Expand Down Expand Up @@ -351,11 +320,6 @@ func evmHexToCadenceBytes(address string) (cadence.Array, error) {
return cadence.NewArray(res), nil
}

// todo use types.NewBalanceFromUFix64(evmAmount) when flow-go updated
func flowToWei(flow int64) *big.Int {
return new(big.Int).Mul(big.NewInt(flow), toWei)
}

type contract struct {
code string
abiJSON string
Expand Down
Loading
Loading