Skip to content
This repository has been archived by the owner on Feb 20, 2025. It is now read-only.

Commit

Permalink
Cleanup of load generator code base (#280)
Browse files Browse the repository at this point in the history
  • Loading branch information
HerbertJordan authored Nov 8, 2024
1 parent 15afe93 commit 6583bd2
Show file tree
Hide file tree
Showing 28 changed files with 1,168 additions and 527 deletions.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pull-prometheus-image:
build-sonic-docker-image:
DOCKER_BUILDKIT=1 docker build . -t sonic

generate-abi: load/contracts/abi/Counter.abi load/contracts/abi/ERC20.abi load/contracts/abi/Store.abi load/contracts/abi/UniswapV2Pair.abi load/contracts/abi/UniswapRouter.abi # requires installed solc and Ethereum abigen - check README.md
generate-abi: load/contracts/abi/Counter.abi load/contracts/abi/ERC20.abi load/contracts/abi/Store.abi load/contracts/abi/UniswapV2Pair.abi load/contracts/abi/UniswapRouter.abi load/contracts/abi/Helper.abi # requires installed solc and Ethereum abigen - check README.md

load/contracts/abi/Counter.abi: load/contracts/Counter.sol
solc --evm-version london -o ./load/contracts/abi --overwrite --pretty-json --optimize --optimize-runs 200 --abi --bin ./load/contracts/Counter.sol
Expand All @@ -54,6 +54,10 @@ load/contracts/abi/UniswapRouter.abi: load/contracts/UniswapRouter.sol
solc --evm-version london -o ./load/contracts/abi --overwrite --pretty-json --optimize --optimize-runs 200 --abi --bin ./load/contracts/UniswapRouter.sol
abigen --type UniswapRouter --pkg abi --abi load/contracts/abi/UniswapRouter.abi --bin load/contracts/abi/UniswapRouter.bin --out load/contracts/abi/UniswapRouter.go

load/contracts/abi/Helper.abi: load/contracts/Helper.sol
solc --evm-version london -o ./load/contracts/abi --overwrite --pretty-json --optimize --optimize-runs 200 --abi --bin ./load/contracts/Helper.sol
abigen --type Helper --pkg abi --abi load/contracts/abi/Helper.abi --bin load/contracts/abi/Helper.bin --out load/contracts/abi/Helper.go

generate-mocks: # requires installed mockgen
go generate ./...

Expand Down
29 changes: 21 additions & 8 deletions driver/network/local/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ type LocalNetwork struct {
listenerMutex sync.Mutex

rpcWorkerPool *rpc.RpcWorkerPool

// a context for app management operations on the network
appContext app.AppContext
}

func NewLocalNetwork(config *driver.NetworkConfig) (*LocalNetwork, error) {
Expand Down Expand Up @@ -136,14 +139,20 @@ func NewLocalNetwork(config *driver.NetworkConfig) (*LocalNetwork, error) {
wg.Wait()

// If starting the validators failed, the network startup should fail.
if errors.Join(errs...) != nil {
err := net.Shutdown()
if err != nil {
errs = append(errs, err)
}
return nil, errors.Join(errs...)
if err := errors.Join(errs...); err != nil {
return nil, errors.Join(err, net.Shutdown())
}

// Setup infrastructure for managing applications on the network.
appContext, err := app.NewContext(net, primaryAccount)
if err != nil {
return nil, errors.Join(
fmt.Errorf("failed to create app context; %w", err),
net.Shutdown(),
)
}
net.appContext = appContext

return net, nil
}

Expand Down Expand Up @@ -390,7 +399,7 @@ func (n *LocalNetwork) CreateApplication(config *driver.ApplicationConfig) (driv
defer rpcClient.Close()

appId := n.nextAppId.Add(1)
application, err := app.NewApplication(config.Type, rpcClient, n.primaryAccount, config.Users, 0, appId)
application, err := app.NewApplication(config.Type, n.appContext, 0, appId)
if err != nil {
return nil, fmt.Errorf("failed to initialize on-chain app; %v", err)
}
Expand All @@ -400,7 +409,7 @@ func (n *LocalNetwork) CreateApplication(config *driver.ApplicationConfig) (driv
return nil, fmt.Errorf("failed to parse shaper; %v", err)
}

appController, err := controller.NewAppController(application, sh, config.Users, rpcClient, n)
appController, err := controller.NewAppController(application, sh, config.Users, n.appContext, n)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -467,6 +476,10 @@ func (n *LocalNetwork) Shutdown() error {
}
n.apps = n.apps[:0]

if n.appContext != nil {
n.appContext.Close()
}

// Second, shut down the nodes.
for _, node := range n.nodes {
// TODO: shutdown nodes in parallel.
Expand Down
6 changes: 6 additions & 0 deletions driver/rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rpc"
)
Expand All @@ -33,6 +34,11 @@ type RpcClient interface {
Call(result interface{}, method string, args ...interface{}) error
NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error)
BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error)

// -- ethereum client methods --
ChainID(ctx context.Context) (*big.Int, error)
TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)

Close()
}

Expand Down
46 changes: 38 additions & 8 deletions driver/rpc/rpc_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions load/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ import (
//go:generate mockgen -source app.go -destination app_mock.go -package app

type Application interface {
// CreateUser creates a new user generating transactions for this application.
CreateUser(rpcClient rpc.RpcClient) (User, error)

WaitUntilApplicationIsDeployed(rpcClient rpc.RpcClient) error
// CreateUsers creates a number of users for this application that
// can generate transactions for this application.
CreateUsers(context AppContext, numUsers int) ([]User, error)

// GetReceivedTransactions returns the total number of transactions
// received by this application up to the current point in time.
GetReceivedTransactions(rpcClient rpc.RpcClient) (uint64, error)
}

Expand Down
36 changes: 11 additions & 25 deletions load/app/app_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 33 additions & 21 deletions load/app/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import (
"github.com/Fantom-foundation/Norma/driver"
"github.com/Fantom-foundation/Norma/driver/network"
"github.com/Fantom-foundation/Norma/driver/network/local"
"github.com/Fantom-foundation/Norma/driver/rpc"
"github.com/Fantom-foundation/Norma/load/app"
"github.com/ethereum/go-ethereum/core/types"
)

const PrivateKey = "163f5f0f9a621d72fedd85ffca3d08d131ab4e812181e0d30ffd1c885d20aac7" // Fakenet validator 1
Expand All @@ -40,74 +40,86 @@ func TestGenerators(t *testing.T) {
}
t.Cleanup(func() { net.Shutdown() })

rpcClient, err := net.DialRandomRpc()
primaryAccount, err := app.NewAccount(0, PrivateKey, nil, FakeNetworkID)
if err != nil {
t.Fatal("unable to connect the the rpc")
t.Fatal(err)
}

primaryAccount, err := app.NewAccount(0, PrivateKey, nil, FakeNetworkID)
context, err := app.NewContext(net, primaryAccount)
if err != nil {
t.Fatal(err)
}

t.Run("Counter", func(t *testing.T) {
counterApp, err := app.NewCounterApplication(rpcClient, primaryAccount, 1, 0, 0)
counterApp, err := app.NewCounterApplication(context, 0, 0)
if err != nil {
t.Fatal(err)
}
testGenerator(t, counterApp, rpcClient)
testGenerator(t, counterApp, context)
})
t.Run("ERC20", func(t *testing.T) {
erc20app, err := app.NewERC20Application(rpcClient, primaryAccount, 1, 0, 0)
erc20app, err := app.NewERC20Application(context, 0, 0)
if err != nil {
t.Fatal(err)
}
testGenerator(t, erc20app, rpcClient)
testGenerator(t, erc20app, context)
})
t.Run("Store", func(t *testing.T) {
storeApp, err := app.NewStoreApplication(rpcClient, primaryAccount, 1, 0, 0)
storeApp, err := app.NewStoreApplication(context, 0, 0)
if err != nil {
t.Fatal(err)
}
testGenerator(t, storeApp, rpcClient)
testGenerator(t, storeApp, context)
})
t.Run("Uniswap", func(t *testing.T) {
uniswapApp, err := app.NewUniswapApplication(rpcClient, primaryAccount, 1, 0, 0)
uniswapApp, err := app.NewUniswapApplication(context, 0, 0)
if err != nil {
t.Fatal(err)
}
testGenerator(t, uniswapApp, rpcClient)
testGenerator(t, uniswapApp, context)
})
}

func testGenerator(t *testing.T, app app.Application, rpcClient rpc.RpcClient) {
gen, err := app.CreateUser(rpcClient)
func testGenerator(t *testing.T, app app.Application, ctxt app.AppContext) {
users, err := app.CreateUsers(ctxt, 1)
if err != nil {
t.Fatal(err)
}
err = app.WaitUntilApplicationIsDeployed(rpcClient)
if err != nil {
t.Fatal(err)
if len(users) != 1 {
t.Fatalf("unexpected number of users created, wanted 1, got %d", len(users))
}
user := users[0]

rpcClient := ctxt.GetClient()
numTransactions := 10
for i := 0; i < numTransactions; i++ {
transactions := []*types.Transaction{}
for range numTransactions {
price, err := rpcClient.SuggestGasPrice(context.Background())
if err != nil {
return
}
tx, err := gen.GenerateTx(price)
tx, err := user.GenerateTx(price)
if err != nil {
t.Fatal(err)
}
if err := rpcClient.SendTransaction(context.Background(), tx); err != nil {
t.Fatal(err)
}
transactions = append(transactions, tx)
}

time.Sleep(2 * time.Second) // wait for txs in TxPool
// wait for the transactions to be processed
for _, tx := range transactions {
receipt, err := ctxt.GetReceipt(tx.Hash())
if err != nil {
t.Fatal(err)
}
if receipt.Status != types.ReceiptStatusSuccessful {
t.Fatalf("transaction failed, receipt status: %v", receipt.Status)
}
}

if got, want := gen.GetSentTransactions(), numTransactions; got != uint64(want) {
if got, want := user.GetSentTransactions(), numTransactions; got != uint64(want) {
t.Errorf("invalid number of sent transactions reported, wanted %d, got %d", want, got)
}

Expand Down
Loading

0 comments on commit 6583bd2

Please sign in to comment.