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

test(solver): add ephemeral load gen #2676

Merged
merged 1 commit into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions contracts/allocs/scripts/genallocs_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ func TestBridgeBalance(t *testing.T) {
mp = add(mp, th.TargetBalance())
}

mp = add(mp, ether(100)) // 100 OMNI: genesis validator 1
mp = add(mp, ether(100)) // 100 OMNI: genesis validator 2
mp = add(mp, ether(1000)) // 1000 OMNI: genesis validator 1
mp = add(mp, ether(1000)) // 1000 OMNI: genesis validator 2

tests := []struct {
name string
Expand Down
29 changes: 22 additions & 7 deletions e2e/app/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,9 @@ func writeSolverConfig(ctx context.Context, def Definition, logCfg log.Config) e
confRoot := filepath.Join(def.Testnet.Dir, "solver")

const (
privKeyFile = "privatekey"
configFile = "solver.toml"
privKeyFile = "privatekey"
loadGenKeyFile = "loadgenkey"
configFile = "solver.toml"
)

if err := os.MkdirAll(confRoot, 0o755); err != nil {
Expand All @@ -518,24 +519,38 @@ func writeSolverConfig(ctx context.Context, def Definition, logCfg log.Config) e
endpoints = ExternalEndpoints(def)
}

// Save private key (use random keys for non-ephemeral)
// Save solver private key (use random keys for non-ephemeral)
// TODO(corver): Switch to proper keys once ready.
privKey, err := ethcrypto.GenerateKey()
solverPrivKey, err := ethcrypto.GenerateKey()
if err != nil {
return errors.Wrap(err, "generate private key")
} else if def.Testnet.Network.IsEphemeral() {
privKey, err = eoa.PrivateKey(ctx, def.Testnet.Network, eoa.RoleSolver)
solverPrivKey, err = eoa.PrivateKey(ctx, def.Testnet.Network, eoa.RoleSolver)
if err != nil {
return errors.Wrap(err, "get solver key")
}
}
if err := ethcrypto.SaveECDSA(filepath.Join(confRoot, privKeyFile), solverPrivKey); err != nil {
return errors.Wrap(err, "write private key")
}

if err := ethcrypto.SaveECDSA(filepath.Join(confRoot, privKeyFile), privKey); err != nil {
// Save loadgen private key (use random keys for non-ephemeral)
loadGenPrivKey, err := ethcrypto.GenerateKey()
if err != nil {
return errors.Wrap(err, "generate loadgen private key")
} else if def.Testnet.Network.IsEphemeral() {
loadGenPrivKey, err = eoa.PrivateKey(ctx, def.Testnet.Network, eoa.RoleXCaller)
if err != nil {
return errors.Wrap(err, "get loadgen key")
}
}
if err := ethcrypto.SaveECDSA(filepath.Join(confRoot, loadGenKeyFile), loadGenPrivKey); err != nil {
return errors.Wrap(err, "write private key")
}

solverCfg := solverapp.DefaultConfig()
solverCfg.PrivateKey = privKeyFile
solverCfg.SolverPrivKey = privKeyFile
solverCfg.LoadGenPrivKey = loadGenKeyFile
solverCfg.Network = def.Testnet.Network
solverCfg.RPCEndpoints = endpoints

Expand Down
35 changes: 21 additions & 14 deletions e2e/solve/devapp/deposits.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
)

type DepositReq struct {
Expand Down Expand Up @@ -53,7 +54,7 @@ func TestFlow(ctx context.Context, network netconf.Network, endpoints xchain.RPC
}

for deposit := range toCheck {
ok, err := isDeposited(ctx, backends, deposit)
ok, err := IsDeposited(ctx, backends, deposit)
if err != nil {
return err
} else if ok {
Expand Down Expand Up @@ -117,8 +118,11 @@ func makeTestDeposits(ctx context.Context, backends ethbackend.Backends) ([]Depo
return nil, errors.Wrap(err, "make depositors")
}

depositAmount := big.NewInt(1e18)
fundAmount := new(big.Int).Add(depositAmount, big.NewInt(params.GWei)) // Add gas

// fund for gas
if err := anvil.FundAccounts(ctx, backend, big.NewInt(1e18), depositors...); err != nil {
if err := anvil.FundAccounts(ctx, backend, fundAmount, depositors...); err != nil {
return nil, errors.Wrap(err, "fund accounts")
}

Expand All @@ -127,15 +131,23 @@ func makeTestDeposits(ctx context.Context, backends ethbackend.Backends) ([]Depo
return nil, errors.Wrap(err, "get addresses")
}

reqs, err := requestDeposits(ctx, backend, addrs.SolveInbox, depositors)
var deposits []DepositArgs
for _, depositor := range depositors {
deposits = append(deposits, DepositArgs{
OnBehalfOf: depositor,
Amount: depositAmount,
})
}

reqs, err := RequestDeposits(ctx, backend, addrs.SolveInbox, deposits...)
if err != nil {
return nil, errors.Wrap(err, "request deposits")
}

return reqs, nil
}

func isDeposited(ctx context.Context, backends ethbackend.Backends, req DepositReq) (bool, error) {
func IsDeposited(ctx context.Context, backends ethbackend.Backends, req DepositReq) (bool, error) {
app := MustGetApp(netconf.Devnet)

backend, err := backends.Backend(app.L1.ChainID)
Expand Down Expand Up @@ -209,14 +221,9 @@ func addRandomDepositors(n int, backend *ethbackend.Backend) ([]common.Address,
return depositors, nil
}

func requestDeposits(ctx context.Context, backend *ethbackend.Backend, inbox common.Address, depositors []common.Address) ([]DepositReq, error) {
var reqs []DepositReq
for _, depositor := range depositors {
deposit := DepositArgs{
OnBehalfOf: depositor,
Amount: big.NewInt(1e18),
}

func RequestDeposits(ctx context.Context, backend *ethbackend.Backend, inbox common.Address, deposits ...DepositArgs) ([]DepositReq, error) {
var resp []DepositReq
for _, deposit := range deposits {
if err := mintAndApprove(ctx, backend, inbox, deposit); err != nil {
return nil, errors.Wrap(err, "mint and approve")
}
Expand All @@ -226,10 +233,10 @@ func requestDeposits(ctx context.Context, backend *ethbackend.Backend, inbox com
return nil, errors.Wrap(err, "request at inbox")
}

reqs = append(reqs, req)
resp = append(resp, req)
}

return reqs, nil
return resp, nil
}

func requestAtInbox(ctx context.Context, backend *ethbackend.Backend, addr common.Address, deposit DepositArgs) (DepositReq, error) {
Expand Down
4 changes: 4 additions & 0 deletions e2e/solve/devapp/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ type DepositArgs struct {
Amount *big.Int
}

func (App) Name() string {
return "devapp"
}

func (App) ChainID() uint64 {
return evmchain.IDMockL1
}
Expand Down
4 changes: 4 additions & 0 deletions e2e/solve/symbiotic/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ type DepositArgs struct {
Amount *big.Int
}

func (App) Name() string {
return "symbiotic"
}

func (t App) ChainID() uint64 {
return t.L1.ChainID
}
Expand Down
4 changes: 2 additions & 2 deletions halo/genutil/genutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ import (
// since Omni block period (+-1s) is very fast, roughly 10x normal period of 10s.
const slashingBlocksWindow = 1000

// ValidatorPower is the default power assigned to genesis validators.
const ValidatorPower = 100
// ValidatorPower is the default power assigned to ephemeral genesis validators.
const ValidatorPower = 1000

func MakeGenesis(
network netconf.ID,
Expand Down
10 changes: 5 additions & 5 deletions halo/genutil/testdata/TestMakeGenesis.golden
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"coins": [
{
"denom": "stake",
"amount": "100000000000000000000"
"amount": "1000000000000000000000"
}
]
},
Expand All @@ -51,15 +51,15 @@
"coins": [
{
"denom": "stake",
"amount": "100000000000000000000"
"amount": "1000000000000000000000"
}
]
}
],
"supply": [
{
"denom": "stake",
"amount": "200000000000000000000"
"amount": "2000000000000000000000"
}
],
"denom_metadata": [],
Expand Down Expand Up @@ -118,7 +118,7 @@
},
"value": {
"denom": "stake",
"amount": "100000000000000000000"
"amount": "1000000000000000000000"
}
}
],
Expand Down Expand Up @@ -165,7 +165,7 @@
},
"value": {
"denom": "stake",
"amount": "100000000000000000000"
"amount": "1000000000000000000000"
}
}
],
Expand Down
15 changes: 15 additions & 0 deletions lib/ethclient/ethbackend/backends.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,21 @@ func (b Backends) All() map[uint64]*Backend {
return b.backends
}

// AddAccount adds a in-memory private key account to all backends.
// Note this can be called even if other accounts are fireblocks based.
func (b Backends) AddAccount(privkey *ecdsa.PrivateKey) (common.Address, error) {
var addr common.Address
for _, backend := range b.backends {
var err error
addr, err = backend.AddAccount(privkey)
if err != nil {
return common.Address{}, err
}
}

return addr, nil
}

func (b Backends) Clients() map[uint64]ethclient.Client {
clients := make(map[uint64]ethclient.Client)
for chainID, backend := range b.backends {
Expand Down
23 changes: 20 additions & 3 deletions solver/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ import (
)

// confLevel of solver streamers.
const confLevel = xchain.ConfLatest
const (
confLevel = xchain.ConfLatest
unknown = "unknown"
)

func chainVerFromID(id uint64) xchain.ChainVersion {
return xchain.ChainVersion{ID: id, ConfLevel: confLevel}
Expand All @@ -52,10 +55,10 @@ func Run(ctx context.Context, cfg Config) error {
return err
}

if cfg.PrivateKey == "" {
if cfg.SolverPrivKey == "" {
return errors.New("private key not set")
}
privKey, err := ethcrypto.LoadECDSA(cfg.PrivateKey)
privKey, err := ethcrypto.LoadECDSA(cfg.SolverPrivKey)
if err != nil {
return errors.Wrap(err, "load private key")
}
Expand All @@ -67,6 +70,10 @@ func Run(ctx context.Context, cfg Config) error {
return err
}

if err := maybeStartLoadGen(ctx, cfg, network, backends); err != nil {
return err
}

xprov := xprovider.New(network, backends.Clients(), nil)

db, err := newSolverDB(cfg.DBDir)
Expand Down Expand Up @@ -223,6 +230,15 @@ func startEventStreams(
return cursors.Set(ctx, chainVerFromID(chainID), height)
}

targetNamer := func(req bindings.SolveRequest) string {
target, err := getTarget(network.ID, req.Call)
if err != nil {
return unknown
}

return target.Name()
}

deps := procDeps{
ParseID: newIDParser(inboxContracts),
GetRequest: newRequestGetter(inboxContracts),
Expand All @@ -233,6 +249,7 @@ func startEventStreams(
Claim: newClaimer(inboxContracts, backends, solverAddr),
SetCursor: cursorSetter,
ChainName: network.ChainName,
TargetName: targetNamer,
}

for _, chain := range inboxChains {
Expand Down
2 changes: 1 addition & 1 deletion solver/app/bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func statusString(status uint8) string {
case statusClaimed:
return "claimed"
default:
return "unknown"
return unknown
}
}

Expand Down
5 changes: 3 additions & 2 deletions solver/app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ type Config struct {
RPCEndpoints xchain.RPCEndpoints
Network netconf.ID
MonitoringAddr string
PrivateKey string
SolverPrivKey string
LoadGenPrivKey string
DBDir string
}

func DefaultConfig() Config {
return Config{
PrivateKey: "solver.key",
SolverPrivKey: "solver.key",
MonitoringAddr: ":26660",
DBDir: "./db",
}
Expand Down
7 changes: 5 additions & 2 deletions solver/app/config.toml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ network = "{{ .Network }}"
### Solver Options ###
#######################################################################

# Path to the ethereum private key used to sign avs omni sync transactions.
private-key = "{{ .PrivateKey }}"
# Path to the ethereum private key used to for inbox and outbox request state transitions.
private-key = "{{ .SolverPrivKey }}"

# Path to the ethereum private key used to generate deposit load on ephemeral networks only.
loadgen-key = "{{ .LoadGenPrivKey }}"

# The address that the solver listens for metric scrape requests.
monitoring-addr = "{{ .MonitoringAddr }}"
Expand Down
1 change: 1 addition & 0 deletions solver/app/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func TestDefaultConfigReference(t *testing.T) {
tempDir := t.TempDir()

cfg := solver.DefaultConfig()
cfg.LoadGenPrivKey = "loadgen.key"

path := filepath.Join(tempDir, "solver.toml")

Expand Down
Loading
Loading