mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Start light server for testing
This commit is contained in:
parent
976a0f5558
commit
ddc7d7a0a4
3 changed files with 281 additions and 0 deletions
247
cmd/geth/les_test.go
Normal file
247
cmd/geth/les_test.go
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
/*
|
||||
var rpcArgs = []string{"--rpc", "--rpcapi=admin,eth,les"}
|
||||
|
||||
var port int = 30303
|
||||
var rpcPort int = 8545
|
||||
|
||||
type gethNode struct {
|
||||
datadir string
|
||||
args []string
|
||||
cmd *exec.Cmd
|
||||
rpc *rpc.Client
|
||||
}
|
||||
|
||||
func startGeth(datadir string, keepDatadir bool, args ...string) (*gethNode, error) {
|
||||
g := &gethNode{datadir, args, nil, nil}
|
||||
if !keepDatadir {
|
||||
err := os.RemoveAll(datadir)
|
||||
if err != nil {
|
||||
return g, err
|
||||
}
|
||||
}
|
||||
allArgs := []string{"--datadir", datadir, "--port", fmt.Sprintf("%d", port), "--rpcport", fmt.Sprintf("%d", rpcPort)}
|
||||
port += 1
|
||||
rpcPort += 1
|
||||
allArgs = append(allArgs, rpcArgs...)
|
||||
allArgs = append(allArgs, args...)
|
||||
cmd := exec.Command("geth", allArgs...)
|
||||
log.Println("to start", cmd.String())
|
||||
var err error
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
g.cmd = cmd
|
||||
time.Sleep(1 * time.Second) // wait before we can attach to it
|
||||
// TODO: probe for it properly
|
||||
g.rpc, err = rpc.Dial(g.ipcpath())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return g, nil
|
||||
}
|
||||
|
||||
|
||||
// Start and wait for it to finish
|
||||
func runGeth(datadir string, keepDatadir bool, args ...string) error {
|
||||
if !keepDatadir {
|
||||
if err := os.RemoveAll(datadir); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
allArgs := []string{"--datadir", datadir}
|
||||
allArgs = append(allArgs, args...)
|
||||
cmd := exec.Command("geth", allArgs...)
|
||||
log.Println("to run", cmd.String())
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Start(); err != nil {
|
||||
return fmt.Errorf("starting but %s", err)
|
||||
}
|
||||
if err := cmd.Wait(); err != nil {
|
||||
return fmt.Errorf("waiting but %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *gethNode) ipcpath() string {
|
||||
return filepath.Join(g.datadir, "geth.ipc")
|
||||
}
|
||||
|
||||
func (g *gethNode) kill() error {
|
||||
err := g.cmd.Process.Kill()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = g.cmd.Process.Wait()
|
||||
return err
|
||||
}
|
||||
|
||||
func (g *gethNode) addPeer(enode string) error {
|
||||
peerCh := make(chan *p2p.PeerEvent)
|
||||
sub, err := g.rpc.Subscribe(context.Background(), "admin", peerCh, "peerEvents")
|
||||
if err != nil {
|
||||
return fmt.Errorf("subscribe: %v", err)
|
||||
}
|
||||
defer sub.Unsubscribe()
|
||||
if err := g.rpc.Call(nil, "admin_addPeer", enode); err != nil {
|
||||
return fmt.Errorf("admin_addPeer: %v", err)
|
||||
}
|
||||
select {
|
||||
case ev := <-peerCh:
|
||||
fmt.Print("event", ev)
|
||||
|
||||
case err := <-sub.Err():
|
||||
return fmt.Errorf("notification: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *gethNode) waitSynced() error {
|
||||
ch := make(chan interface{})
|
||||
sub, err := g.rpc.Subscribe(context.Background(), "eth", ch, "syncing")
|
||||
if err != nil {
|
||||
return fmt.Errorf("syncing: %v", err)
|
||||
}
|
||||
defer sub.Unsubscribe()
|
||||
timeout := time.After(40 * time.Second)
|
||||
for {
|
||||
select {
|
||||
case ev := <-ch:
|
||||
syncing, ok := ev.(bool)
|
||||
if ok && !syncing {
|
||||
return nil
|
||||
}
|
||||
case err := <-sub.Err():
|
||||
return fmt.Errorf("notification: %v", err)
|
||||
case <-timeout:
|
||||
return fmt.Errorf("timeout syncing")
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func startLightServer(t *testing.T) *rpc.Client {
|
||||
// Create a temporary data directory to use
|
||||
datadir := tmpdir(t)
|
||||
defer os.RemoveAll(datadir)
|
||||
ipcpath := filepath.Join(datadir, "geth.ipc")
|
||||
|
||||
t.Log("server datadir", datadir)
|
||||
runGeth(t, "--datadir", datadir, "init", "./testdata/genesis.json").WaitExit()
|
||||
t.Log("init done")
|
||||
runGeth(t, "--datadir", datadir, "--gcmode=archive", "import", "./testdata/blockchain.blocks").WaitExit()
|
||||
t.Log("import done")
|
||||
geth := runGeth(t, "--datadir", datadir, "--networkid=42", "--port=0", "--rpcport=0", "--rpc", "--rpcapi=admin,eth,les", "--light.serve=100", "--light.maxpeers=1", "--nodiscover", "--nat=extip:127.0.0.1")
|
||||
defer geth.WaitExit()
|
||||
defer geth.Kill()
|
||||
t.Log("started lightserver")
|
||||
|
||||
// wait before we can attach to it. TODO: probe for it properly
|
||||
time.Sleep(1 * time.Second)
|
||||
rpc, err := rpc.Dial(ipcpath)
|
||||
if err != nil {
|
||||
t.Fatalf("rpc connect: %v", err)
|
||||
}
|
||||
return rpc
|
||||
}
|
||||
|
||||
func TestPriorityClient(t *testing.T) {
|
||||
// Init and start server
|
||||
server := startLightServer(t)
|
||||
nodeInfo := make(map[string]interface{})
|
||||
if err := server.Call(&nodeInfo, "admin_nodeInfo"); err != nil {
|
||||
t.Fatal("nodeInfo:", err)
|
||||
}
|
||||
enode := nodeInfo["enode"].(string)
|
||||
t.Log("enode", enode)
|
||||
/*
|
||||
if err := runGeth(datadir, true, "--gcmode=archive", "import", "./initdata/testBlockchain.blocks"); err != nil {
|
||||
t.Fatal("import", err)
|
||||
}
|
||||
t.Log("import done")
|
||||
server, err := startGeth(datadir, true, "--networkid=42", "--light.serve=100", "--light.maxpeers=1", "--nodiscover", "--nat=extip:127.0.0.1")
|
||||
defer server.kill()
|
||||
if err != nil {
|
||||
t.Fatal("start server", err)
|
||||
}
|
||||
nodeInfo := make(map[string]interface{})
|
||||
if err := server.rpc.Call(&nodeInfo, "admin_nodeInfo"); err != nil {
|
||||
t.Fatal("nodeInfo:", err)
|
||||
}
|
||||
enode := nodeInfo["enode"].(string)
|
||||
t.Log("enode", enode)
|
||||
|
||||
// Client
|
||||
clientdir := "/tmp/client"
|
||||
if err := runGeth(clientdir, false, "init", "./initdata/testGenesis.json"); err != nil {
|
||||
t.Fatal("init client", err)
|
||||
}
|
||||
client, err := startGeth(clientdir, true, "--networkid=42", "--syncmode=light", "--nodiscover")
|
||||
defer client.kill()
|
||||
if err != nil {
|
||||
t.Fatal("start client", err)
|
||||
}
|
||||
if err := client.addPeer(enode); err != nil {
|
||||
t.Fatal("addPeer", err)
|
||||
}
|
||||
var peers []interface{}
|
||||
if err := client.rpc.Call(&peers, "admin_peers"); err != nil {
|
||||
t.Fatal("peers", err)
|
||||
}
|
||||
if len(peers) != 1 {
|
||||
t.Log("Expected: # of client peers == 1")
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
// Priority client
|
||||
priodir := "/tmp/prio"
|
||||
if err := runGeth(priodir, false, "init", "./initdata/testGenesis.json"); err != nil {
|
||||
t.Fatal("init prio", err)
|
||||
}
|
||||
prio, err := startGeth(priodir, true, "--networkid=42", "--syncmode=light", "--nodiscover")
|
||||
defer prio.kill()
|
||||
if err != nil {
|
||||
t.Fatal(prio.cmd.String(), err)
|
||||
}
|
||||
prioNodeInfo := make(map[string]interface{})
|
||||
if err := prio.rpc.Call(&prioNodeInfo, "admin_nodeInfo"); err != nil {
|
||||
t.Fatal("prio nodeInfo:", err)
|
||||
}
|
||||
nodeID := prioNodeInfo["id"].(string)
|
||||
t.Log("nodeID", nodeID)
|
||||
tokens := 3_000_000_000
|
||||
if err := server.rpc.Call(nil, "les_addBalance", nodeID, tokens, "foobar"); err != nil {
|
||||
t.Fatal("addBalance:", err)
|
||||
}
|
||||
if err := prio.addPeer(enode); err != nil {
|
||||
t.Fatal("addPeer", err)
|
||||
}
|
||||
|
||||
// Check if priority client is actually syncing and the regular client got kicked out
|
||||
if err := prio.rpc.Call(&peers, "admin_peers"); err != nil {
|
||||
t.Fatal("prio peers", err)
|
||||
}
|
||||
if len(peers) != 1 {
|
||||
t.Fatal("Expected: # of prio peers == 1")
|
||||
}
|
||||
|
||||
if err := client.rpc.Call(&peers, "admin_peers"); err != nil {
|
||||
t.Fatal("client peers", err)
|
||||
}
|
||||
if len(peers) > 0 {
|
||||
t.Fatal("Expected: # of client peers == 0")
|
||||
}
|
||||
*/
|
||||
}
|
||||
BIN
cmd/geth/testdata/blockchain.blocks
vendored
Normal file
BIN
cmd/geth/testdata/blockchain.blocks
vendored
Normal file
Binary file not shown.
34
cmd/geth/testdata/genesis.json
vendored
Normal file
34
cmd/geth/testdata/genesis.json
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"version": "1",
|
||||
"params":{
|
||||
"petersburgForkBlock":"0x0",
|
||||
"chainId":"0xdeadbeef",
|
||||
"miningMethod":"ethash"
|
||||
},
|
||||
"genesis":{
|
||||
"author":"0x0000000000000000000000000000000000000000",
|
||||
"difficulty":"0x1",
|
||||
"extraData":"0xdeadbeef",
|
||||
"gasLimit":"0x900000",
|
||||
"nonce":"0x00000000deadbeef",
|
||||
"timestamp":"0x0"
|
||||
},
|
||||
"config": {
|
||||
"chainId": 42,
|
||||
"ethash": {
|
||||
}
|
||||
},
|
||||
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
|
||||
"difficulty" : "0x020000",
|
||||
"gasLimit" : "0x2fefd8",
|
||||
"timestamp" : "0x54c98c81",
|
||||
"extraData" : "0x42",
|
||||
"mixHash" : "0x2c85bcbce56429100b2108254bb56906257582aeafcbd682bc9af67a9f5aee46",
|
||||
"nonce" : "0x78cc16f7b4f65485",
|
||||
"alloc" : {
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance" : "0x09184e72a000"
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue