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

simulators: integrate les light client into the RPC test suite #432

Closed
wants to merge 16 commits into from
Closed
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
10 changes: 8 additions & 2 deletions clients/go-ethereum/geth.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@
# - HIVE_MINER enable mining. value is coinbase address.
# - HIVE_MINER_EXTRA extra-data field to set for newly minted blocks
# - HIVE_SKIP_POW if set, skip PoW verification during block import
# - HIVE_LOGLEVEL client loglevel (0-5)
# - HIVE_LOGLEVEL client loglevel (0-5)
# - HIVE_GRAPHQL_ENABLED enables graphql on port 8545
# - HIVE_LIGHTSERVE maximum percentage of time allowed for serving LES requests (0 for disabling)

# Immediately abort the script on any error encountered
set -e
Expand Down Expand Up @@ -129,14 +130,19 @@ if [ "$HIVE_CLIQUE_PRIVATEKEY" != "" ]; then
fi

# Configure any mining operation
if [ "$HIVE_MINER" != "" ]; then
if [ "$HIVE_MINER" != "" ] && [ "$HIVE_NODETYPE" != "light" ]; then
FLAGS="$FLAGS --mine --miner.threads 1 --miner.etherbase $HIVE_MINER"
fi
if [ "$HIVE_MINER_EXTRA" != "" ]; then
FLAGS="$FLAGS --extradata $HIVE_MINER_EXTRA"
fi
FLAGS="$FLAGS --miner.gasprice 16000000000"

# Configure any les flags
if [ "$HIVE_LIGHTSERVE" != "" ]; then
FLAGS="$FLAGS --light.serve $HIVE_LIGHTSERVE --light.nosyncserve "
fi

# Configure RPC.
FLAGS="$FLAGS --http --http.addr=0.0.0.0 --http.port=8545 --http.api=admin,debug,eth,miner,net,personal,txpool,web3"
FLAGS="$FLAGS --ws --ws.addr=0.0.0.0 --ws.origins \"*\" --ws.api=admin,debug,eth,miner,net,personal,txpool,web3"
Expand Down
62 changes: 61 additions & 1 deletion simulators/ethereum/rpc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"math/big"
"strings"
"time"

"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/hive/hivesim"
Expand Down Expand Up @@ -98,14 +99,73 @@ The RPC test suite runs a set of RPC related tests against a running node. It te
several real-world scenarios such as sending value transactions, deploying a contract or
interacting with one.`[1:],
}
// Add testing for general full nodes
suite.Add(&hivesim.ClientTestSpec{
Name: "client launch",
Description: `This test launches the client and collects its logs.`,
Parameters: clientEnv,
Files: files,
Run: runAllTests,
})
hivesim.MustRunSuite(hivesim.New(), suite)
// Add testing les light client. This only works with geth for now.
var (
clients []string
sim = hivesim.New()
)
clientTypes, err := sim.ClientTypes()
if err != nil {
panic(err)
}
for _, name := range clientTypes {
if !strings.HasPrefix(name, "go-ethereum") {
continue
}
clients = append(clients, name)
}
for _, client := range clients {
name := client
suite.Add(hivesim.TestSpec{
Name: fmt.Sprintf("%s as LES server", name),
Description: "This loads the test chain into the les server and verifies whether the light client can sync correctly.",
Run: func(t *hivesim.T) { runLESTests(t, name, clients) },
})
}
hivesim.MustRunSuite(sim, suite)
}

func runLESTests(t *hivesim.T, serverType string, clientTypes []string) {
// Start the LES server
serverParams := clientEnv.Set("HIVE_NODETYPE", "full")
serverParams = serverParams.Set("HIVE_LIGHTSERVE", "100")
client := t.StartClient(serverType, serverParams, files)

// Configure sink to connect to the source node.
clientParams := clientEnv.Set("HIVE_NODETYPE", "light")
enode, err := client.EnodeURL()
if err != nil {
t.Fatal("can't get node peer-to-peer endpoint:", enode)
}

// Sync all sink nodes against the source.
for _, sinkType := range clientTypes {
name := sinkType
t.Run(hivesim.TestSpec{
Name: fmt.Sprintf("%s as LES server", name),
Description: "This loads the test chain into the les server and verifies whether the light client can sync correctly.",
Run: func(t *hivesim.T) {
client := t.StartClient(name, clientParams, files)

// todo(rjl493456442) Wait the initialization of light client
time.Sleep(time.Second * 10)

err := client.RPC().Call(nil, "admin_addPeer", enode)
if err != nil {
t.Fatalf("connection failed:", err)
}
runAllTests(t, client)
},
})
}
}

// runAllTests runs the tests against a client instance.
Expand Down
2 changes: 1 addition & 1 deletion simulators/ethereum/rpc/vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func (v *vault) createAccountWithSubscription(t *TestEnv, amount *big.Int) commo
addressTopic := common.BytesToHash(common.LeftPadBytes(address[:], 32))
q := ethereum.FilterQuery{
Addresses: []common.Address{predeployedVaultAddr},
Topics: [][]common.Hash{[]common.Hash{eventTopic}, []common.Hash{addressTopic}},
Topics: [][]common.Hash{{eventTopic}, {addressTopic}},
}
logsSub, err = t.Eth.SubscribeFilterLogs(ctx, q, logs)
if err != nil {
Expand Down
80 changes: 75 additions & 5 deletions simulators/ethereum/sync/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"context"
"fmt"
"strings"
"time"

"github.com/ethereum/go-ethereum/common"
Expand All @@ -21,7 +22,6 @@ var (
"HIVE_FORK_TANGERINE": "0",
"HIVE_FORK_SPURIOUS": "0",
"HIVE_FORK_BYZANTIUM": "0",
"HIVE_NODETYPE": "full",
}
sourceFiles = map[string]string{
"genesis.json": "./simplechain/genesis.json",
Expand All @@ -43,17 +43,46 @@ func main() {
Description: `This suite of tests verifies that clients can sync from each other in different modes.
For each client, we test if it can serve as a sync source for all other clients (including itself).`,
}

// SYNC by ETH protocol
ethParams := params.Set("HIVE_NODETYPE", "full")
suite.Add(hivesim.ClientTestSpec{
Name: "CLIENT as sync source",
Description: "This loads the test chain into the client and verifies whether it was imported correctly.",
Parameters: params,
Parameters: ethParams,
Files: sourceFiles,
Run: runSourceTest,
Run: runETHSyncTest,
})
hivesim.MustRunSuite(hivesim.New(), suite)

// SYNC by LES protocol
//
// Add the light client sync test. This only works with geth for now.
var (
clients []string
sim = hivesim.New()
)
clientTypes, err := sim.ClientTypes()
if err != nil {
panic(err)
}
for _, name := range clientTypes {
if !strings.HasPrefix(name, "go-ethereum") {
continue
}
clients = append(clients, name)
}
for _, client := range clients {
name := client
suite.Add(hivesim.TestSpec{
Name: fmt.Sprintf("%s as LES server", name),
Description: "This loads the test chain into the les server and verifies whether the light client can sync correctly.",
Run: func(t *hivesim.T) { runLESSyncTest(t, name, clients) },
})
}
hivesim.MustRunSuite(sim, suite)
}

func runSourceTest(t *hivesim.T, c *hivesim.Client) {
func runETHSyncTest(t *hivesim.T, c *hivesim.Client) {
// Check whether the source has imported its chain.rlp correctly.
source := &node{c}
if err := source.checkHead(testchainHeadNumber, testchainHeadHash); err != nil {
Expand All @@ -77,6 +106,47 @@ func runSourceTest(t *hivesim.T, c *hivesim.Client) {
})
}

func runLESSyncTest(t *hivesim.T, sourceType string, sinkTypes []string) {
// Start the LES server
serverParams := params.Set("HIVE_NODETYPE", "full")
serverParams = serverParams.Set("HIVE_LIGHTSERVE", "100")
client := t.StartClient(sourceType, serverParams, sourceFiles)

// Check whether the source has imported its chain.rlp correctly.
source := &node{client}
if err := source.checkHead(testchainHeadNumber, testchainHeadHash); err != nil {
t.Fatal(err)
}

// Configure sink to connect to the source node.
clientParams := params.Set("HIVE_NODETYPE", "light")
enode, err := source.EnodeURL()
if err != nil {
t.Fatal("can't get node peer-to-peer endpoint:", enode)
}

// Sync all sink nodes against the source.
for _, sinkType := range sinkTypes {
name := sinkType
t.Run(hivesim.TestSpec{
Name: fmt.Sprintf("%s as LES server", name),
Description: "This loads the test chain into the les server and verifies whether the light client can sync correctly.",
Run: func(t *hivesim.T) {
client := t.StartClient(name, clientParams, sinkFiles)

// todo(rjl493456442) Wait the initialization of light client
time.Sleep(time.Second * 10)

err := client.RPC().Call(nil, "admin_addPeer", enode)
if err != nil {
t.Fatalf("connection failed:", err)
}
runSyncTest(t, client)
},
})
}
}

func runSyncTest(t *hivesim.T, c *hivesim.Client) {
node := &node{c}
err := node.checkSync(t, testchainHeadNumber, testchainHeadHash)
Expand Down