Skip to content

Instantly share code, notes, and snippets.

@qfrank
Last active November 30, 2023 08:45
Show Gist options
  • Save qfrank/e7397ee40267e69bc86ccc924e6ebf9f to your computer and use it in GitHub Desktop.
Save qfrank/e7397ee40267e69bc86ccc924e6ebf9f to your computer and use it in GitHub Desktop.
How to setup local waku node with status-mobile

Why we need local waku node?

Sometimes to reproduce the bug rather than message delivery issue, we need three simulators: one for userA and the remaining two for userB, with the latter two simulators being paired. When userA sends a contact request to userB, due to message delivery issues, reproducing the bug can be challenging or inconsistent. However, with a local Waku node, these message delivery issues are resolved, leading to faster and more reliable bug replication.

Another purpose could be: just want to know more about waku :)

How to setup local waku node with status-mobile?

Preparation

  • any preparations needed for building status-go should be done before setup local waku node
  • domain

Build waku

Reference: https://github.com/waku-org/go-waku

git clone https://github.com/waku-org/go-waku
git checkout 351dd55a1498
cd go-waku
make

After make, we should see the output binary file: ./build/waku

Start waku

To make local waku node work, we should start up 3 instances waku nodes rather than just one.

Generate 3 keys

waku generate-key
mv nodekey nodekey1
waku generate-key
mv nodekey nodekey2
waku generate-key
mv nodekey nodekey3

Startup

open new terminal tab and run the 1st instance

waku --max-connections=100 --ext-ip=192.168.1.188 --store=true --filter=true --lightpush=true --legacy-filter=true --discv5-discovery=true --discv5-enr-auto-update=true --rpc=true --rpc-admin=false --relay=true --tcp-port=60001 --key-file=nodekey1 --store-message-db-url=sqlite3://store1.db --discv5-udp-port=9001

check terminal output, search with keywords "enr:", you should see some log like:

2023-11-22T11:40:05.406+0800	INFO	gowaku.node2	node/wakunode2.go:568	enr record	{"node": "16Uiu2HAmVqaWAdzBCtXC92iT4xNVFkto8MfRgMHqDCEmqnKPYWM3", "enr": "enr:-Ji4QB2Cst_jHvQvu1pvrsBQzaxlSWYw5Cgx0Bk1FBwmVldray1dIPTsIECer96Xqnl2j5_GQuMuMy4_eFUGJL2ARoeGAYv1HRONgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQP_TRpSYXvd4QDLBaWgMbKlyhkmLN4eCWNdnalXFrZsVoN0Y3CC6mGDdWRwgiMphXdha3"}

copy your enr record like enr:-Ji4QB2Cst_jHvQvu1pvrsBQzaxlSWYw5Cgx0Bk1FBwmVldray1dIPTsIECer96Xqnl2j5_GQuMuMy4_eFUGJL2ARoeGAYv1HRONgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQP_TRpSYXvd4QDLBaWgMbKlyhkmLN4eCWNdnalXFrZsVoN0Y3CC6mGDdWRwgiMphXdha3, let's refer it as $EnrBootNode.

open another terminal tab and run the 2nd instance

waku --max-connections=100 --ext-ip=192.168.1.188 --store=true --filter=true --lightpush=true --legacy-filter=true --discv5-discovery=true --discv5-enr-auto-update=true --rpc=false --rpc-admin=false --relay=true --tcp-port=60002 --key-file=nodekey2 --store-message-db-url=sqlite3://store2.db --discv5-udp-port=9002 --discv5-bootstrap-node="$EnrBootNode"

open another terminal tab and run the 3rd instance

waku --max-connections=100 --ext-ip=192.168.1.188 --store=true --filter=true --lightpush=true --legacy-filter=true --discv5-discovery=true --discv5-enr-auto-update=true --rpc=false --rpc-admin=false --relay=true --tcp-port=60003 --key-file=nodekey3 --store-message-db-url=sqlite3://store3.db --discv5-udp-port=9003 --discv5-bootstrap-node="$EnrBootNode"

please remember to replace $EnrBootNode with your own ENR (Ethereum Node Record). Also, make sure to replace 192.168.1.188 with your actual LAN IP address.

Generate enrtree

checkout go-ethereum

git clone git@github.com:status-im/go-ethereum.git
git checkout origin/release/v1.10.25

run TestMakeEnrTree

add test function TestMakeEnrTree into file p2p/dnsdisc/client_test.go within go-ethereum:

func TestMakeEnrTree(t *testing.T) {
	enrs := []string{
    // 1st waku instance of enr
		"enr:-Ji4QB2Cst_jHvQvu1pvrsBQzaxlSWYw5Cgx0Bk1FBwmVldray1dIPTsIECer96Xqnl2j5_GQuMuMy4_eFUGJL2ARoeGAYv1HRONgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQP_TRpSYXvd4QDLBaWgMbKlyhkmLN4eCWNdnalXFrZsVoN0Y3CC6mGDdWRwgiMphXdha3",
		// 2nd waku instance of enr
    "enr:-Ji4QO_KwQc3tUlL-Wzi4x9oUZhunbDRWDPp3katikupt9YMeUU5ojMbmDgvixroTJf_1_GRSd8FIPrddVVY1TrCpyKGAYv1HjnFgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPrNFticmJJnw31Xi3G4Zsr3hWurybfUpRLLSstzzxDPYN0Y3CC6mKDdWRwgiMqhXdha3",
		// 3rd waku instance of enr
    "enr:-Ji4QNTJnawfbcOpeJkYOM6XVDZH6d5M4v80fWAms2BaRr1jX0j7jcyABooAeu9XJtMZEDIlrnKN9ggAS9oiyE3Zc-mGAYv1HlaJgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQKk2471B7QW61bSprMVuuhE4CiIqggC1g2kW2vKBAGQaoN0Y3CC6mODdWRwgiMrhXdha3",
	}
	nodes := make([]*enode.Node, len(enrs))
	for i, enr := range enrs {
		nodes[i] = enode.MustParse(enr)
	}

	domain := "local-waku-node.test.com"
	tree, url := makeTestTree(domain, nodes, nil)
	records := tree.ToTXT(domain)
	recordsJSON, err := json.Marshal(records)
	if err != nil {
		panic(err)
	}
	println("txt records", string(recordsJSON))
	println("enrtree url", url)

  // if you're using aliyun and got ak/secret, you can uncomment following lines to add DNS TXT records automatically.
  // you also need add the dependency: require github.com/aliyun/alibaba-cloud-sdk-go v1.62.608 into go.mod
	//client, err := alidns.NewClientWithAccessKey("cn-hangzhou", "your ak", "your secret key")
	//require.NoError(t, err)
	//for k, v := range records {
	//	request := alidns.CreateAddDomainRecordRequest()
	//	request.Scheme = "https"
	//	request.Type = "TXT"
	//	request.DomainName = "test.com"
	//	request.RR = strings.Replace(k, ".test.com", "", 1)
	//	request.Value = v
	//	response, err := client.AddDomainRecord(request)
	//	require.NoError(t, err)
	//	require.True(t, response.IsSuccess())
	//}
}

you need update the 3 ENRs to yours for TestMakeEnrTree, also update test.com to your domain. if you're using other cloud provider, i hope this tutorial can help you: https://geth.ethereum.org/docs/developers/geth-developer/dns-discovery-setup after run this test, you should add corresponding TXT records to your domain manually according the test output("txt records") if you don't use aliyun.

Update status-go

update function DefaultMailservers within file services/mailservers/fleet.go like following example:

func DefaultMailservers() []Mailserver {
	return []Mailserver{
		Mailserver{
			ID:      "16Uiu2HAmVqaWAdzBCtXC92iT4xNVFkto8MfRgMHqDCEmqnKPYWM3",
			Address: "/ip4/192.168.1.188/tcp/60001/p2p/16Uiu2HAmVqaWAdzBCtXC92iT4xNVFkto8MfRgMHqDCEmqnKPYWM3",
			Fleet:   params.FleetStatusProd,
			Version: 2,
		},Mailserver{
			ID:      "16Uiu2HAmUV8TtQJ4L5qoSccNEpAWy6WwauGnxNc9PHMaxnkuVS7W",
			Address: "/ip4/192.168.1.188/tcp/60002/p2p/16Uiu2HAmUV8TtQJ4L5qoSccNEpAWy6WwauGnxNc9PHMaxnkuVS7W",
			Fleet:   params.FleetStatusProd,
			Version: 2,
		},Mailserver{
			ID:      "16Uiu2HAm6XD2Axn5QWyjDHJjSe4htHgVF6tC8Jzy26ySbEJdj8fb",
			Address: "/ip4/192.168.1.188/tcp/60003/p2p/16Uiu2HAm6XD2Axn5QWyjDHJjSe4htHgVF6tC8Jzy26ySbEJdj8fb",
			Fleet:   params.FleetStatusProd,
			Version: 2,
		},
	}
}

what's the ID and Address? it comes from waku node output, you can find it by keywords: listening , the ID is the suffix of Address. you should update it with yours.

update variable defaultWakuNodes within file api/defaults.go like following example:

var defaultWakuNodes = map[string][]string{
	statusProdFleet: []string{"enrtree://AKHFWGGJHNMMQLTAWEQ45ZOVV7FTPM5AOWOVV4QLPXBMVWVTX4PIM@local-waku-node.test.com"},
	statusTestFleet: []string{"enrtree://AKHFWGGJHNMMQLTAWEQ45ZOVV7FTPM5AOWOVV4QLPXBMVWVTX4PIM@local-waku-node.test.com"},
	wakuv2ProdFleet: []string{"enrtree://AKHFWGGJHNMMQLTAWEQ45ZOVV7FTPM5AOWOVV4QLPXBMVWVTX4PIM@local-waku-node.test.com"},
	wakuv2TestFleet: []string{"enrtree://AKHFWGGJHNMMQLTAWEQ45ZOVV7FTPM5AOWOVV4QLPXBMVWVTX4PIM@local-waku-node.test.com"},
	shardsTest:      []string{"enrtree://AKHFWGGJHNMMQLTAWEQ45ZOVV7FTPM5AOWOVV4QLPXBMVWVTX4PIM@local-waku-node.test.com"},
}

you can find your enrtree url after run TestMakeEnrTree

run status-mobile with local status-go

an example could be:

make run-ios SIMULATOR="iPhone 14 Pro" STATUS_GO_SRC_OVERRIDE=/Users/xxx/development/go/src/github.com/status-im/status-go

enjoy your local waku node!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment