From 2708d025583c9550057b8e0682384249ad888c97 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Mon, 9 Oct 2023 19:22:42 +0530 Subject: [PATCH 01/12] Run Nitro node as part of serve command --- cmd/serve.go | 13 +++++++++++++ go.mod | 4 +++- pkg/nitro/node.go | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 pkg/nitro/node.go diff --git a/cmd/serve.go b/cmd/serve.go index a1fb8621..8a4f110a 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -26,6 +26,7 @@ import ( "time" "github.com/cerc-io/ipld-eth-server/v5/pkg/log" + "github.com/cerc-io/ipld-eth-server/v5/pkg/nitro" "github.com/ethereum/go-ethereum/rpc" "github.com/mailgun/groupcache/v2" "github.com/spf13/cobra" @@ -95,6 +96,14 @@ func serve() { logWithCommand.Debug("state validator disabled") } + // TODO: Create required config for Nitro node + + // TODO: Create a new Nitro node using the config + nitro, _ := nitro.NewNitroNode() + + // TODO: Start the Nitro node, pass wg + nitro.Start(wg) + shutdown := make(chan os.Signal, 1) signal.Notify(shutdown, os.Interrupt) <-shutdown @@ -102,6 +111,10 @@ func serve() { graphQL.Stop() } server.Stop() + + // TODO: Stop nitro node + nitro.Stop() + wg.Wait() } diff --git a/go.mod b/go.mod index a61f89fc..feb9346a 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/cerc-io/ipfs-ethdb/v5 v5.0.0-alpha github.com/cerc-io/ipld-eth-statedb v0.0.5-alpha github.com/cerc-io/plugeth-statediff v0.1.1 - github.com/ethereum/go-ethereum v1.11.6 + github.com/ethereum/go-ethereum v1.12.0 // TODO: Investigate github.com/google/uuid v1.3.0 github.com/graph-gophers/graphql-go v1.3.0 github.com/ipfs/go-cid v0.4.1 @@ -291,3 +291,5 @@ replace ( // https://git.vdb.to/cerc-io/ipfs-ethdb/src/branch/v5-go-upgrade github.com/cerc-io/ipfs-ethdb/v5 => github.com/cerc-io/ipfs-ethdb/v5 v5.0.1-alpha.0.20231013070931-0b1a36562a28 ) + +replace github.com/statechannels/go-nitro v0.1.1 => github.com/cerc-io/go-nitro v0.1.1-ts-port-0.1.5 diff --git a/pkg/nitro/node.go b/pkg/nitro/node.go new file mode 100644 index 00000000..8ca98430 --- /dev/null +++ b/pkg/nitro/node.go @@ -0,0 +1,48 @@ +// VulcanizeDB +// Copyright © 2023 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package nitro + +import ( + "sync" +) + +// TODO: Implement +// Struct representing the in-process Nitro node +type NitroNode struct { + // Used to signal shutdown of the node + QuitChan chan bool +} + +func NewNitroNode() (NitroNode, error) { + // TODO: Implement + return NitroNode{}, nil +} + +func (n *NitroNode) Start(wg *sync.WaitGroup) { + // TODO: Implement + go func() { + wg.Add(1) + defer wg.Done() + <-n.QuitChan + }() +} + +func (n *NitroNode) Stop() error { + // TODO: Implement + close(n.QuitChan) + return nil +} -- 2.45.2 From 76aba989e79c5b86c8d2948befc0a68ed1fa65d0 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Tue, 10 Oct 2023 14:51:52 +0530 Subject: [PATCH 02/12] Add a PaymentsManager with Nitro node initialization --- cmd/serve.go | 13 +-- go.mod | 11 ++- go.sum | 30 ++++++ pkg/nitro/node.go | 48 ---------- pkg/payments/payments_manager.go | 153 +++++++++++++++++++++++++++++++ 5 files changed, 197 insertions(+), 58 deletions(-) delete mode 100644 pkg/nitro/node.go create mode 100644 pkg/payments/payments_manager.go diff --git a/cmd/serve.go b/cmd/serve.go index 8a4f110a..c529d6c0 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -26,7 +26,7 @@ import ( "time" "github.com/cerc-io/ipld-eth-server/v5/pkg/log" - "github.com/cerc-io/ipld-eth-server/v5/pkg/nitro" + "github.com/cerc-io/ipld-eth-server/v5/pkg/payments" "github.com/ethereum/go-ethereum/rpc" "github.com/mailgun/groupcache/v2" "github.com/spf13/cobra" @@ -98,11 +98,8 @@ func serve() { // TODO: Create required config for Nitro node - // TODO: Create a new Nitro node using the config - nitro, _ := nitro.NewNitroNode() - - // TODO: Start the Nitro node, pass wg - nitro.Start(wg) + paymentsManager, _ := payments.NewPaymentsManager(true) + paymentsManager.Start(wg) shutdown := make(chan os.Signal, 1) signal.Notify(shutdown, os.Interrupt) @@ -111,9 +108,7 @@ func serve() { graphQL.Stop() } server.Stop() - - // TODO: Stop nitro node - nitro.Stop() + paymentsManager.Stop() wg.Wait() } diff --git a/go.mod b/go.mod index feb9346a..c8d5e0f6 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.4.0 github.com/spf13/viper v1.11.0 + github.com/statechannels/go-nitro v0.1.1 gorm.io/driver/postgres v1.3.7 gorm.io/gorm v1.23.5 ) @@ -230,6 +231,14 @@ require ( github.com/subosito/gotenv v1.2.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect github.com/thoas/go-funk v0.9.3 // indirect + github.com/tidwall/btree v1.6.0 // indirect + github.com/tidwall/buntdb v1.2.10 // indirect + github.com/tidwall/gjson v1.14.4 // indirect + github.com/tidwall/grect v0.1.4 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/tidwall/rtred v0.1.2 // indirect + github.com/tidwall/tinyqueue v0.1.1 // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect @@ -292,4 +301,4 @@ replace ( github.com/cerc-io/ipfs-ethdb/v5 => github.com/cerc-io/ipfs-ethdb/v5 v5.0.1-alpha.0.20231013070931-0b1a36562a28 ) -replace github.com/statechannels/go-nitro v0.1.1 => github.com/cerc-io/go-nitro v0.1.1-ts-port-0.1.5 +replace github.com/statechannels/go-nitro v0.1.1 => github.com/cerc-io/go-nitro v0.1.1-ts-port-0.1.7 diff --git a/go.sum b/go.sum index e5ceef13..397bf025 100644 --- a/go.sum +++ b/go.sum @@ -91,12 +91,16 @@ github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2y github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= +github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 h1:KdUfX2zKommPRa+PD0sWZUyXe9w277ABlgELO7H04IM= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= +github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= @@ -110,6 +114,8 @@ github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2 github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= github.com/cerc-io/eth-ipfs-state-validator/v5 v5.1.1-alpha.0.20231013075659-56aa03028c43 h1:pkGCN+VWo5Qmu4iDjA7noGrE6wM8VOVeX1Mn6ucYhPg= github.com/cerc-io/eth-ipfs-state-validator/v5 v5.1.1-alpha.0.20231013075659-56aa03028c43/go.mod h1:snThUFpyCrpZhTuz3HibJRLL2XaS+lKNsM3XAE0gB/4= +github.com/cerc-io/go-nitro v0.1.1-ts-port-0.1.7 h1:moqgKEUH9EtnyBgEQH65JrD8Q94abj+r6zGT6BJsU90= +github.com/cerc-io/go-nitro v0.1.1-ts-port-0.1.7/go.mod h1:gkKL37JcSo54ybLTI6VJRmP75bWEu9i1kc9RYmQLp+I= github.com/cerc-io/ipfs-ethdb/v5 v5.0.1-alpha.0.20231013070931-0b1a36562a28 h1:5FXtMuZXTIXjjzzLdqgyzx9pjD22FB5os2vXayRn+BQ= github.com/cerc-io/ipfs-ethdb/v5 v5.0.1-alpha.0.20231013070931-0b1a36562a28/go.mod h1:W1C6qTXGsPcsK1HKUYPsXmBORjO2ekdm+101sJkpdNI= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= @@ -789,6 +795,8 @@ github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJys github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miguelmota/go-ethereum-hdwallet v0.1.1 h1:zdXGlHao7idpCBjEGTXThVAtMKs+IxAgivZ75xqkWK0= +github.com/miguelmota/go-ethereum-hdwallet v0.1.1/go.mod h1:f9m9uXokAHA6WNoYOPjj4AqjJS5pquQRiYYj/XSyPYc= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -1052,6 +1060,28 @@ github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJ github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw= github.com/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= +github.com/tidwall/assert v0.1.0 h1:aWcKyRBUAdLoVebxo95N7+YZVTFF/ASTr7BN4sLP6XI= +github.com/tidwall/assert v0.1.0/go.mod h1:QLYtGyeqse53vuELQheYl9dngGCJQ+mTtlxcktb+Kj8= +github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= +github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tidwall/buntdb v1.2.10 h1:U/ebfkmYPBnyiNZIirUiWFcxA/mgzjbKlyPynFsPtyM= +github.com/tidwall/buntdb v1.2.10/go.mod h1:lZZrZUWzlyDJKlLQ6DKAy53LnG7m5kHyrEHvvcDmBpU= +github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= +github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/grect v0.1.4 h1:dA3oIgNgWdSspFzn1kS4S/RDpZFLrIxAZOdJKjYapOg= +github.com/tidwall/grect v0.1.4/go.mod h1:9FBsaYRaR0Tcy4UwefBX/UDcDcDy9V5jUcxHzv2jd5Q= +github.com/tidwall/lotsa v1.0.2 h1:dNVBH5MErdaQ/xd9s769R31/n2dXavsQ0Yf4TMEHHw8= +github.com/tidwall/lotsa v1.0.2/go.mod h1:X6NiU+4yHA3fE3Puvpnn1XMDrFZrE9JO2/w+UMuqgR8= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/rtred v0.1.2 h1:exmoQtOLvDoO8ud++6LwVsAMTu0KPzLTUrMln8u1yu8= +github.com/tidwall/rtred v0.1.2/go.mod h1:hd69WNXQ5RP9vHd7dqekAz+RIdtfBogmglkZSRxCHFQ= +github.com/tidwall/tinyqueue v0.1.1 h1:SpNEvEggbpyN5DIReaJ2/1ndroY8iyEGxPYxoSaymYE= +github.com/tidwall/tinyqueue v0.1.1/go.mod h1:O/QNHwrnjqr6IHItYrzoHAKYhBkLI67Q096fQP5zMYw= github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= diff --git a/pkg/nitro/node.go b/pkg/nitro/node.go deleted file mode 100644 index 8ca98430..00000000 --- a/pkg/nitro/node.go +++ /dev/null @@ -1,48 +0,0 @@ -// VulcanizeDB -// Copyright © 2023 Vulcanize - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package nitro - -import ( - "sync" -) - -// TODO: Implement -// Struct representing the in-process Nitro node -type NitroNode struct { - // Used to signal shutdown of the node - QuitChan chan bool -} - -func NewNitroNode() (NitroNode, error) { - // TODO: Implement - return NitroNode{}, nil -} - -func (n *NitroNode) Start(wg *sync.WaitGroup) { - // TODO: Implement - go func() { - wg.Add(1) - defer wg.Done() - <-n.QuitChan - }() -} - -func (n *NitroNode) Stop() error { - // TODO: Implement - close(n.QuitChan) - return nil -} diff --git a/pkg/payments/payments_manager.go b/pkg/payments/payments_manager.go new file mode 100644 index 00000000..1b6f3697 --- /dev/null +++ b/pkg/payments/payments_manager.go @@ -0,0 +1,153 @@ +// VulcanizeDB +// Copyright © 2023 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package payments + +import ( + "sync" + + "github.com/cerc-io/ipld-eth-server/v5/pkg/log" + "github.com/ethereum/go-ethereum/common" + "github.com/statechannels/go-nitro/node/engine" + "github.com/statechannels/go-nitro/node/engine/chainservice" + "github.com/statechannels/go-nitro/node/engine/store" + + nitroNode "github.com/statechannels/go-nitro/node" + p2pms "github.com/statechannels/go-nitro/node/engine/messageservice/p2p-message-service" +) + +// TODO: Implement +// Struct representing payments manager +// Maintains either an in-process or communication with an out-of-process Nitro node +type PaymentsManager struct { + // Whether to run an in-process Nitro node + runInProcessNitroNode bool + + // In-process Nitro node; nil when runInProcessNitroNode is false + nitroNode *nitroNode.Node + + // Used to signal shutdown of the service + quitChan chan bool +} + +func NewPaymentsManager(runInProcessNitroNode bool) (PaymentsManager, error) { + // TODO: Implement + var err error + + pm := PaymentsManager{runInProcessNitroNode: runInProcessNitroNode} + + if runInProcessNitroNode { + pm.nitroNode, err = initializeNitroNode() + if err != nil { + return PaymentsManager{}, err + } + } + + return pm, nil +} + +func (pm *PaymentsManager) Start(wg *sync.WaitGroup) { + // TODO: Implement + go func() { + wg.Add(1) + defer wg.Done() + <-pm.quitChan + }() +} + +func (pm *PaymentsManager) Stop() error { + // TODO: Implement + close(pm.quitChan) + return nil +} + +func initializeNitroNode() (*nitroNode.Node, error) { + // TODO: Configure + pkString := "" + useDurableStore := true + durableStoreFolder := "./data/nitro-store" + msgPort := 3005 + wsMsgPort := 5005 + chainUrl := "ws://127.0.0.1:8546" + chainStartBlock := uint64(0) + chainPk := "" + naAddress := "" + vpaAddress := "" + caAddress := "" + + chainAuthToken := "" + publicIp := "0.0.0.0" + + chainOpts := chainservice.ChainOpts{ + ChainUrl: chainUrl, + ChainStartBlock: chainStartBlock, + ChainAuthToken: chainAuthToken, + ChainPk: chainPk, + NaAddress: common.HexToAddress(naAddress), + VpaAddress: common.HexToAddress(vpaAddress), + CaAddress: common.HexToAddress(caAddress), + } + + storeOpts := store.StoreOpts{ + PkBytes: common.Hex2Bytes(pkString), + UseDurableStore: useDurableStore, + DurableStoreFolder: durableStoreFolder, + } + + peerSlice := []string{} + + messageOpts := p2pms.MessageOpts{ + PkBytes: common.Hex2Bytes(pkString), + TcpPort: msgPort, + WsMsgPort: wsMsgPort, + BootPeers: peerSlice, + PublicIp: publicIp, + } + + ourStore, err := store.NewStore(storeOpts) + if err != nil { + return nil, err + } + + log.Info("Initializing message service", "tcp port", messageOpts.TcpPort, "web socket port", messageOpts.WsMsgPort) + messageOpts.SCAddr = *ourStore.GetAddress() + messageService := p2pms.NewMessageService(messageOpts) + + // Compare chainOpts.ChainStartBlock to lastBlockNum seen in store. The larger of the two + // gets passed as an argument when creating NewEthChainService + storeBlockNum, err := ourStore.GetLastBlockNumSeen() + if err != nil { + return nil, err + } + if storeBlockNum > chainOpts.ChainStartBlock { + chainOpts.ChainStartBlock = storeBlockNum + } + + log.Info("Initializing chain service...") + ourChain, err := chainservice.NewEthChainService(chainOpts) + if err != nil { + return nil, err + } + + node := nitroNode.New( + messageService, + ourChain, + ourStore, + &engine.PermissivePolicy{}, + ) + + return &node, nil +} -- 2.45.2 From 7bcc70f3d69019d177d4f1dd51f425ac2c603a41 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Tue, 10 Oct 2023 18:42:15 +0530 Subject: [PATCH 03/12] Implement voucher subscription loop --- go.mod | 2 +- pkg/payments/payments_manager.go | 134 +++++++++++++++++++++++++++++-- 2 files changed, 128 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index c8d5e0f6..966726bb 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/ethereum/go-ethereum v1.12.0 // TODO: Investigate github.com/google/uuid v1.3.0 github.com/graph-gophers/graphql-go v1.3.0 + github.com/hashicorp/golang-lru/v2 v2.0.5 github.com/ipfs/go-cid v0.4.1 github.com/jmoiron/sqlx v1.3.5 github.com/joho/godotenv v1.4.0 @@ -90,7 +91,6 @@ require ( github.com/hashicorp/go-bexpr v0.1.12 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect - github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.3 // indirect diff --git a/pkg/payments/payments_manager.go b/pkg/payments/payments_manager.go index 1b6f3697..1547846e 100644 --- a/pkg/payments/payments_manager.go +++ b/pkg/payments/payments_manager.go @@ -17,21 +17,44 @@ package payments import ( + "math/big" "sync" + "time" "github.com/cerc-io/ipld-eth-server/v5/pkg/log" "github.com/ethereum/go-ethereum/common" + "github.com/hashicorp/golang-lru/v2/expirable" "github.com/statechannels/go-nitro/node/engine" "github.com/statechannels/go-nitro/node/engine/chainservice" "github.com/statechannels/go-nitro/node/engine/store" + "github.com/statechannels/go-nitro/payments" nitroNode "github.com/statechannels/go-nitro/node" p2pms "github.com/statechannels/go-nitro/node/engine/messageservice/p2p-message-service" + nitroTypes "github.com/statechannels/go-nitro/types" ) -// TODO: Implement +const ( + DEFAULT_LRU_CACHE_MAX_ACCOUNTS = 1000 + DEFAULT_LRU_CACHE_ACCOUNT_TTL = 30 * 60 // 30mins + DEFAULT_LRU_CACHE_MAX_VOUCHERS_PER_ACCOUNT = 1000 + DEFAULT_LRU_CACHE_VOUCHER_TTL = 5 * 60 // 5mins + DEFAULT_LRU_CACHE_MAX_PAYMENT_CHANNELS = 10000 + DEFAULT_LRU_CACHE_PAYMENT_CHANNEL_TTL = DEFAULT_LRU_CACHE_ACCOUNT_TTL +) + +type Payment struct { + voucher payments.Voucher + amount *big.Int +} + +type paymentVoucher struct { + payer common.Address + voucherHash common.Hash +} + // Struct representing payments manager -// Maintains either an in-process or communication with an out-of-process Nitro node +// Maintains either an in-process Nitro node or communication with an out-of-process Nitro node type PaymentsManager struct { // Whether to run an in-process Nitro node runInProcessNitroNode bool @@ -39,6 +62,12 @@ type PaymentsManager struct { // In-process Nitro node; nil when runInProcessNitroNode is false nitroNode *nitroNode.Node + receivedPayments *expirable.LRU[common.Address, *expirable.LRU[common.Hash, Payment]] + + paidSoFarOnChannel *expirable.LRU[nitroTypes.Destination, *big.Int] + + paymentListeners []chan paymentVoucher + // Used to signal shutdown of the service quitChan chan bool } @@ -56,24 +85,115 @@ func NewPaymentsManager(runInProcessNitroNode bool) (PaymentsManager, error) { } } + pm.receivedPayments = expirable.NewLRU[common.Address, *expirable.LRU[common.Hash, Payment]]( + DEFAULT_LRU_CACHE_MAX_ACCOUNTS, + nil, + time.Second*DEFAULT_LRU_CACHE_ACCOUNT_TTL, + ) + + pm.paidSoFarOnChannel = expirable.NewLRU[nitroTypes.Destination, *big.Int]( + DEFAULT_LRU_CACHE_MAX_PAYMENT_CHANNELS, + nil, + time.Second*DEFAULT_LRU_CACHE_PAYMENT_CHANNEL_TTL, + ) + + // Load existing open payment channels with amount paid so far from the stored state + err = pm.loadPaymentChannels() + if err != nil { + return PaymentsManager{}, err + } + return pm, nil } func (pm *PaymentsManager) Start(wg *sync.WaitGroup) { - // TODO: Implement + log.Info("starting payments manager") + + // Channel for received vouchers + var receivedVouchers <-chan payments.Voucher + if pm.runInProcessNitroNode { + receivedVouchers = pm.nitroNode.ReceivedVouchers() + } else { + // TODO: Get vouchers from an out-of-process go-nitro node + } + + wg.Add(1) go func() { - wg.Add(1) defer wg.Done() - <-pm.quitChan + pm.run(receivedVouchers) }() } func (pm *PaymentsManager) Stop() error { - // TODO: Implement + log.Info("stopping payments manager") close(pm.quitChan) return nil } +func (pm *PaymentsManager) run(receivedVouchers <-chan payments.Voucher) { + log.Info("starting voucher subscription...") + for { + select { + case voucher := <-receivedVouchers: + payer, err := pm.getChannelCounterparty(voucher.ChannelId) + if err != nil { + // TODO: Handle + panic(err) + } + + paidSoFar, ok := pm.paidSoFarOnChannel.Get(voucher.ChannelId) + if !ok { + paidSoFar = big.NewInt(0) + } + + paymentAmount := big.NewInt(0).Sub(voucher.Amount, paidSoFar) + pm.paidSoFarOnChannel.Add(voucher.ChannelId, voucher.Amount) + log.Infof("Received a payment voucher of %s from %s", paymentAmount.String(), payer.String()) + + paymentsMap, ok := pm.receivedPayments.Get(payer) + if !ok { + paymentsMap = expirable.NewLRU[common.Hash, Payment]( + DEFAULT_LRU_CACHE_MAX_VOUCHERS_PER_ACCOUNT, + nil, + DEFAULT_LRU_CACHE_VOUCHER_TTL, + ) + + pm.receivedPayments.Add(payer, paymentsMap) + } + + voucherHash, err := voucher.Hash() + if err != nil { + // TODO: Handle + panic(err) + } + + paymentsMap.Add(voucherHash, Payment{voucher: voucher, amount: paymentAmount}) + + for _, listener := range pm.paymentListeners { + listener <- paymentVoucher{payer: payer, voucherHash: voucherHash} + } + case <-pm.quitChan: + log.Info("stopping voucher subscription loop") + // TODO: stop the nitro node if that means anything + return + } + } +} + +func (pm *PaymentsManager) getChannelCounterparty(channelId nitroTypes.Destination) (common.Address, error) { + associatedPaymentChannel, err := pm.nitroNode.GetPaymentChannel(channelId) + if err != nil { + return common.Address{}, err + } + + return associatedPaymentChannel.Balance.Payer, nil +} + +func (pm *PaymentsManager) loadPaymentChannels() error { + // TODO: Implement + return nil +} + func initializeNitroNode() (*nitroNode.Node, error) { // TODO: Configure pkString := "" @@ -122,7 +242,7 @@ func initializeNitroNode() (*nitroNode.Node, error) { return nil, err } - log.Info("Initializing message service", "tcp port", messageOpts.TcpPort, "web socket port", messageOpts.WsMsgPort) + log.Info("Initializing message service...", " tcp port=", messageOpts.TcpPort, " web socket port=", messageOpts.WsMsgPort) messageOpts.SCAddr = *ourStore.GetAddress() messageService := p2pms.NewMessageService(messageOpts) -- 2.45.2 From 88d68a93207022b5f6f3a214245c4aca6d17580e Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Wed, 11 Oct 2023 11:31:41 +0530 Subject: [PATCH 04/12] Implement payment authentication --- pkg/payments/payments_manager.go | 65 ++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/pkg/payments/payments_manager.go b/pkg/payments/payments_manager.go index 1547846e..bce32616 100644 --- a/pkg/payments/payments_manager.go +++ b/pkg/payments/payments_manager.go @@ -17,6 +17,7 @@ package payments import ( + "errors" "math/big" "sync" "time" @@ -41,6 +42,14 @@ const ( DEFAULT_LRU_CACHE_VOUCHER_TTL = 5 * 60 // 5mins DEFAULT_LRU_CACHE_MAX_PAYMENT_CHANNELS = 10000 DEFAULT_LRU_CACHE_PAYMENT_CHANNEL_TTL = DEFAULT_LRU_CACHE_ACCOUNT_TTL + + DEFAULT_VOUCHER_CHECK_INTERVAL = 2 + DEFAULT_VOUCHER_CHECK_ATTEMPTS = 5 +) + +var ( + ERR_PAYMENT_NOT_RECEIVED = errors.New("Payment not received") + ERR_AMOUNT_INSUFFICIENT = errors.New("Payment amount insufficient") ) type Payment struct { @@ -48,11 +57,6 @@ type Payment struct { amount *big.Int } -type paymentVoucher struct { - payer common.Address - voucherHash common.Hash -} - // Struct representing payments manager // Maintains either an in-process Nitro node or communication with an out-of-process Nitro node type PaymentsManager struct { @@ -66,14 +70,11 @@ type PaymentsManager struct { paidSoFarOnChannel *expirable.LRU[nitroTypes.Destination, *big.Int] - paymentListeners []chan paymentVoucher - // Used to signal shutdown of the service quitChan chan bool } func NewPaymentsManager(runInProcessNitroNode bool) (PaymentsManager, error) { - // TODO: Implement var err error pm := PaymentsManager{runInProcessNitroNode: runInProcessNitroNode} @@ -130,6 +131,50 @@ func (pm *PaymentsManager) Stop() error { return nil } +func (pm *PaymentsManager) AuthenticatePayment(voucherHash common.Hash, signerAddress common.Address, value *big.Int) error { + // Check the payments map for required voucher + var isPaymentReceived, isOfSufficientValue bool + for i := 0; i < DEFAULT_VOUCHER_CHECK_ATTEMPTS; i++ { + isPaymentReceived, isOfSufficientValue = pm.acceptReceivedPayment(voucherHash, signerAddress, value) + + if isPaymentReceived { + if !isOfSufficientValue { + return ERR_AMOUNT_INSUFFICIENT + } + + return nil + } + + // Retry after an interval if voucher not found + log.Debugf("Payment from %s not found, retrying after %d sec...", signerAddress, DEFAULT_VOUCHER_CHECK_INTERVAL) + time.Sleep(DEFAULT_VOUCHER_CHECK_INTERVAL * time.Second) + } + + return ERR_PAYMENT_NOT_RECEIVED +} + +// Check for a given payment voucher in LRU cache map +// Returns whether the voucher was found, whether it was of sufficient value +func (pm *PaymentsManager) acceptReceivedPayment(voucherHash common.Hash, signerAddress common.Address, minRequiredValue *big.Int) (bool, bool) { + paymentsMap, ok := pm.receivedPayments.Get(signerAddress) + if !ok { + return false, false + } + + receivedPayment, ok := paymentsMap.Get(voucherHash) + if !ok { + return false, false + } + + if receivedPayment.amount.Cmp(minRequiredValue) < 0 { + return true, false + } + + // Delete the voucher from map after consuming it + paymentsMap.Remove(voucherHash) + return true, true +} + func (pm *PaymentsManager) run(receivedVouchers <-chan payments.Voucher) { log.Info("starting voucher subscription...") for { @@ -168,10 +213,6 @@ func (pm *PaymentsManager) run(receivedVouchers <-chan payments.Voucher) { } paymentsMap.Add(voucherHash, Payment{voucher: voucher, amount: paymentAmount}) - - for _, listener := range pm.paymentListeners { - listener <- paymentVoucher{payer: payer, voucherHash: voucherHash} - } case <-pm.quitChan: log.Info("stopping voucher subscription loop") // TODO: stop the nitro node if that means anything -- 2.45.2 From e9e17c2be15d1fa2493263807495d8b091d5d0dd Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 12 Oct 2023 12:04:49 +0530 Subject: [PATCH 05/12] Setup in-process go-nitro node for payments --- cmd/serve.go | 118 +++++++++++- go.mod | 2 +- pkg/payments/payments_manager.go | 314 ------------------------------- pkg/rpc/http.go | 12 +- 4 files changed, 118 insertions(+), 328 deletions(-) delete mode 100644 pkg/payments/payments_manager.go diff --git a/cmd/serve.go b/cmd/serve.go index c529d6c0..a5ccea1b 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -17,6 +17,7 @@ package cmd import ( "errors" + "math/big" "net/http" "net/url" "os" @@ -26,16 +27,22 @@ import ( "time" "github.com/cerc-io/ipld-eth-server/v5/pkg/log" - "github.com/cerc-io/ipld-eth-server/v5/pkg/payments" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rpc" "github.com/mailgun/groupcache/v2" "github.com/spf13/cobra" "github.com/spf13/viper" + "github.com/statechannels/go-nitro/node/engine" + "github.com/statechannels/go-nitro/node/engine/chainservice" + "github.com/statechannels/go-nitro/node/engine/store" + "github.com/statechannels/go-nitro/paymentsmanager" "github.com/cerc-io/ipld-eth-server/v5/pkg/graphql" srpc "github.com/cerc-io/ipld-eth-server/v5/pkg/rpc" s "github.com/cerc-io/ipld-eth-server/v5/pkg/serve" v "github.com/cerc-io/ipld-eth-server/v5/version" + nitroNode "github.com/statechannels/go-nitro/node" + nitrop2pms "github.com/statechannels/go-nitro/node/engine/messageservice/p2p-message-service" ) var ErrNoRpcEndpoints = errors.New("no rpc endpoints is available") @@ -76,7 +83,24 @@ func serve() { } server.Serve(wg) - if err := startServers(server, serverConfig); err != nil { + + // TODO: Create required config for Nitro node + nitroNode, err := initializeNitroNode() + if err != nil { + panic(err) + } + + pm, err := paymentsmanager.NewPaymentsManager(nitroNode) + if err != nil { + panic(err) + } + + pm.Start(wg) + + voucherValidator := paymentsmanager.InProcessValidator{PaymentsManager: pm} + queryRates := map[string]*big.Int{"eth_getBlockByNumber": big.NewInt(50)} + + if err := startServers(server, serverConfig, voucherValidator, queryRates); err != nil { logWithCommand.Fatal(err) } graphQL, err := startEthGraphQL(server, serverConfig) @@ -96,10 +120,8 @@ func serve() { logWithCommand.Debug("state validator disabled") } - // TODO: Create required config for Nitro node - - paymentsManager, _ := payments.NewPaymentsManager(true) - paymentsManager.Start(wg) + // paymentsManager, _ := payments.NewPaymentsManager(true) + // paymentsManager.Start(wg) shutdown := make(chan os.Signal, 1) signal.Notify(shutdown, os.Interrupt) @@ -108,12 +130,12 @@ func serve() { graphQL.Stop() } server.Stop() - paymentsManager.Stop() + pm.Stop() wg.Wait() } -func startServers(server s.Server, settings *s.Config) error { +func startServers(server s.Server, settings *s.Config, voucherValidator paymentsmanager.VoucherValidator, queryRates map[string]*big.Int) error { if settings.IPCEnabled { logWithCommand.Debug("starting up IPC server") _, _, err := srpc.StartIPCEndpoint(settings.IPCEndpoint, server.APIs()) @@ -136,7 +158,7 @@ func startServers(server s.Server, settings *s.Config) error { if settings.HTTPEnabled { logWithCommand.Debug("starting up HTTP server") - _, err := srpc.StartHTTPEndpoint(settings.HTTPEndpoint, server.APIs(), []string{"vdb", "eth", "debug", "net"}, nil, []string{"*"}, rpc.HTTPTimeouts{}) + _, err := srpc.StartHTTPEndpoint(settings.HTTPEndpoint, server.APIs(), []string{"vdb", "eth", "debug", "net"}, nil, []string{"*"}, rpc.HTTPTimeouts{}, voucherValidator, queryRates) if err != nil { return err } @@ -347,3 +369,81 @@ func init() { viper.BindPFlag("validator.enabled", serveCmd.PersistentFlags().Lookup("validator-enabled")) viper.BindPFlag("validator.everyNthBlock", serveCmd.PersistentFlags().Lookup("validator-every-nth-block")) } + +func initializeNitroNode() (*nitroNode.Node, error) { + // TODO: Configure + pkString := "" + useDurableStore := true + durableStoreFolder := "./data/nitro-store" + msgPort := 3005 + wsMsgPort := 5005 + chainUrl := "ws://127.0.0.1:8545" + chainStartBlock := uint64(0) + chainPk := "" + naAddress := "" + vpaAddress := "" + caAddress := "" + + chainAuthToken := "" + publicIp := "0.0.0.0" + + chainOpts := chainservice.ChainOpts{ + ChainUrl: chainUrl, + ChainStartBlock: chainStartBlock, + ChainAuthToken: chainAuthToken, + ChainPk: chainPk, + NaAddress: common.HexToAddress(naAddress), + VpaAddress: common.HexToAddress(vpaAddress), + CaAddress: common.HexToAddress(caAddress), + } + + storeOpts := store.StoreOpts{ + PkBytes: common.Hex2Bytes(pkString), + UseDurableStore: useDurableStore, + DurableStoreFolder: durableStoreFolder, + } + + peerSlice := []string{} + + messageOpts := nitrop2pms.MessageOpts{ + PkBytes: common.Hex2Bytes(pkString), + TcpPort: msgPort, + WsMsgPort: wsMsgPort, + BootPeers: peerSlice, + PublicIp: publicIp, + } + + ourStore, err := store.NewStore(storeOpts) + if err != nil { + return nil, err + } + + log.Info("Initializing message service...", " tcp port=", messageOpts.TcpPort, " web socket port=", messageOpts.WsMsgPort) + messageOpts.SCAddr = *ourStore.GetAddress() + messageService := nitrop2pms.NewMessageService(messageOpts) + + // Compare chainOpts.ChainStartBlock to lastBlockNum seen in store. The larger of the two + // gets passed as an argument when creating NewEthChainService + storeBlockNum, err := ourStore.GetLastBlockNumSeen() + if err != nil { + return nil, err + } + if storeBlockNum > chainOpts.ChainStartBlock { + chainOpts.ChainStartBlock = storeBlockNum + } + + log.Info("Initializing chain service...") + ourChain, err := chainservice.NewEthChainService(chainOpts) + if err != nil { + return nil, err + } + + node := nitroNode.New( + messageService, + ourChain, + ourStore, + &engine.PermissivePolicy{}, + ) + + return &node, nil +} diff --git a/go.mod b/go.mod index 966726bb..c8d5e0f6 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/ethereum/go-ethereum v1.12.0 // TODO: Investigate github.com/google/uuid v1.3.0 github.com/graph-gophers/graphql-go v1.3.0 - github.com/hashicorp/golang-lru/v2 v2.0.5 github.com/ipfs/go-cid v0.4.1 github.com/jmoiron/sqlx v1.3.5 github.com/joho/godotenv v1.4.0 @@ -91,6 +90,7 @@ require ( github.com/hashicorp/go-bexpr v0.1.12 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect + github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.3 // indirect diff --git a/pkg/payments/payments_manager.go b/pkg/payments/payments_manager.go deleted file mode 100644 index bce32616..00000000 --- a/pkg/payments/payments_manager.go +++ /dev/null @@ -1,314 +0,0 @@ -// VulcanizeDB -// Copyright © 2023 Vulcanize - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package payments - -import ( - "errors" - "math/big" - "sync" - "time" - - "github.com/cerc-io/ipld-eth-server/v5/pkg/log" - "github.com/ethereum/go-ethereum/common" - "github.com/hashicorp/golang-lru/v2/expirable" - "github.com/statechannels/go-nitro/node/engine" - "github.com/statechannels/go-nitro/node/engine/chainservice" - "github.com/statechannels/go-nitro/node/engine/store" - "github.com/statechannels/go-nitro/payments" - - nitroNode "github.com/statechannels/go-nitro/node" - p2pms "github.com/statechannels/go-nitro/node/engine/messageservice/p2p-message-service" - nitroTypes "github.com/statechannels/go-nitro/types" -) - -const ( - DEFAULT_LRU_CACHE_MAX_ACCOUNTS = 1000 - DEFAULT_LRU_CACHE_ACCOUNT_TTL = 30 * 60 // 30mins - DEFAULT_LRU_CACHE_MAX_VOUCHERS_PER_ACCOUNT = 1000 - DEFAULT_LRU_CACHE_VOUCHER_TTL = 5 * 60 // 5mins - DEFAULT_LRU_CACHE_MAX_PAYMENT_CHANNELS = 10000 - DEFAULT_LRU_CACHE_PAYMENT_CHANNEL_TTL = DEFAULT_LRU_CACHE_ACCOUNT_TTL - - DEFAULT_VOUCHER_CHECK_INTERVAL = 2 - DEFAULT_VOUCHER_CHECK_ATTEMPTS = 5 -) - -var ( - ERR_PAYMENT_NOT_RECEIVED = errors.New("Payment not received") - ERR_AMOUNT_INSUFFICIENT = errors.New("Payment amount insufficient") -) - -type Payment struct { - voucher payments.Voucher - amount *big.Int -} - -// Struct representing payments manager -// Maintains either an in-process Nitro node or communication with an out-of-process Nitro node -type PaymentsManager struct { - // Whether to run an in-process Nitro node - runInProcessNitroNode bool - - // In-process Nitro node; nil when runInProcessNitroNode is false - nitroNode *nitroNode.Node - - receivedPayments *expirable.LRU[common.Address, *expirable.LRU[common.Hash, Payment]] - - paidSoFarOnChannel *expirable.LRU[nitroTypes.Destination, *big.Int] - - // Used to signal shutdown of the service - quitChan chan bool -} - -func NewPaymentsManager(runInProcessNitroNode bool) (PaymentsManager, error) { - var err error - - pm := PaymentsManager{runInProcessNitroNode: runInProcessNitroNode} - - if runInProcessNitroNode { - pm.nitroNode, err = initializeNitroNode() - if err != nil { - return PaymentsManager{}, err - } - } - - pm.receivedPayments = expirable.NewLRU[common.Address, *expirable.LRU[common.Hash, Payment]]( - DEFAULT_LRU_CACHE_MAX_ACCOUNTS, - nil, - time.Second*DEFAULT_LRU_CACHE_ACCOUNT_TTL, - ) - - pm.paidSoFarOnChannel = expirable.NewLRU[nitroTypes.Destination, *big.Int]( - DEFAULT_LRU_CACHE_MAX_PAYMENT_CHANNELS, - nil, - time.Second*DEFAULT_LRU_CACHE_PAYMENT_CHANNEL_TTL, - ) - - // Load existing open payment channels with amount paid so far from the stored state - err = pm.loadPaymentChannels() - if err != nil { - return PaymentsManager{}, err - } - - return pm, nil -} - -func (pm *PaymentsManager) Start(wg *sync.WaitGroup) { - log.Info("starting payments manager") - - // Channel for received vouchers - var receivedVouchers <-chan payments.Voucher - if pm.runInProcessNitroNode { - receivedVouchers = pm.nitroNode.ReceivedVouchers() - } else { - // TODO: Get vouchers from an out-of-process go-nitro node - } - - wg.Add(1) - go func() { - defer wg.Done() - pm.run(receivedVouchers) - }() -} - -func (pm *PaymentsManager) Stop() error { - log.Info("stopping payments manager") - close(pm.quitChan) - return nil -} - -func (pm *PaymentsManager) AuthenticatePayment(voucherHash common.Hash, signerAddress common.Address, value *big.Int) error { - // Check the payments map for required voucher - var isPaymentReceived, isOfSufficientValue bool - for i := 0; i < DEFAULT_VOUCHER_CHECK_ATTEMPTS; i++ { - isPaymentReceived, isOfSufficientValue = pm.acceptReceivedPayment(voucherHash, signerAddress, value) - - if isPaymentReceived { - if !isOfSufficientValue { - return ERR_AMOUNT_INSUFFICIENT - } - - return nil - } - - // Retry after an interval if voucher not found - log.Debugf("Payment from %s not found, retrying after %d sec...", signerAddress, DEFAULT_VOUCHER_CHECK_INTERVAL) - time.Sleep(DEFAULT_VOUCHER_CHECK_INTERVAL * time.Second) - } - - return ERR_PAYMENT_NOT_RECEIVED -} - -// Check for a given payment voucher in LRU cache map -// Returns whether the voucher was found, whether it was of sufficient value -func (pm *PaymentsManager) acceptReceivedPayment(voucherHash common.Hash, signerAddress common.Address, minRequiredValue *big.Int) (bool, bool) { - paymentsMap, ok := pm.receivedPayments.Get(signerAddress) - if !ok { - return false, false - } - - receivedPayment, ok := paymentsMap.Get(voucherHash) - if !ok { - return false, false - } - - if receivedPayment.amount.Cmp(minRequiredValue) < 0 { - return true, false - } - - // Delete the voucher from map after consuming it - paymentsMap.Remove(voucherHash) - return true, true -} - -func (pm *PaymentsManager) run(receivedVouchers <-chan payments.Voucher) { - log.Info("starting voucher subscription...") - for { - select { - case voucher := <-receivedVouchers: - payer, err := pm.getChannelCounterparty(voucher.ChannelId) - if err != nil { - // TODO: Handle - panic(err) - } - - paidSoFar, ok := pm.paidSoFarOnChannel.Get(voucher.ChannelId) - if !ok { - paidSoFar = big.NewInt(0) - } - - paymentAmount := big.NewInt(0).Sub(voucher.Amount, paidSoFar) - pm.paidSoFarOnChannel.Add(voucher.ChannelId, voucher.Amount) - log.Infof("Received a payment voucher of %s from %s", paymentAmount.String(), payer.String()) - - paymentsMap, ok := pm.receivedPayments.Get(payer) - if !ok { - paymentsMap = expirable.NewLRU[common.Hash, Payment]( - DEFAULT_LRU_CACHE_MAX_VOUCHERS_PER_ACCOUNT, - nil, - DEFAULT_LRU_CACHE_VOUCHER_TTL, - ) - - pm.receivedPayments.Add(payer, paymentsMap) - } - - voucherHash, err := voucher.Hash() - if err != nil { - // TODO: Handle - panic(err) - } - - paymentsMap.Add(voucherHash, Payment{voucher: voucher, amount: paymentAmount}) - case <-pm.quitChan: - log.Info("stopping voucher subscription loop") - // TODO: stop the nitro node if that means anything - return - } - } -} - -func (pm *PaymentsManager) getChannelCounterparty(channelId nitroTypes.Destination) (common.Address, error) { - associatedPaymentChannel, err := pm.nitroNode.GetPaymentChannel(channelId) - if err != nil { - return common.Address{}, err - } - - return associatedPaymentChannel.Balance.Payer, nil -} - -func (pm *PaymentsManager) loadPaymentChannels() error { - // TODO: Implement - return nil -} - -func initializeNitroNode() (*nitroNode.Node, error) { - // TODO: Configure - pkString := "" - useDurableStore := true - durableStoreFolder := "./data/nitro-store" - msgPort := 3005 - wsMsgPort := 5005 - chainUrl := "ws://127.0.0.1:8546" - chainStartBlock := uint64(0) - chainPk := "" - naAddress := "" - vpaAddress := "" - caAddress := "" - - chainAuthToken := "" - publicIp := "0.0.0.0" - - chainOpts := chainservice.ChainOpts{ - ChainUrl: chainUrl, - ChainStartBlock: chainStartBlock, - ChainAuthToken: chainAuthToken, - ChainPk: chainPk, - NaAddress: common.HexToAddress(naAddress), - VpaAddress: common.HexToAddress(vpaAddress), - CaAddress: common.HexToAddress(caAddress), - } - - storeOpts := store.StoreOpts{ - PkBytes: common.Hex2Bytes(pkString), - UseDurableStore: useDurableStore, - DurableStoreFolder: durableStoreFolder, - } - - peerSlice := []string{} - - messageOpts := p2pms.MessageOpts{ - PkBytes: common.Hex2Bytes(pkString), - TcpPort: msgPort, - WsMsgPort: wsMsgPort, - BootPeers: peerSlice, - PublicIp: publicIp, - } - - ourStore, err := store.NewStore(storeOpts) - if err != nil { - return nil, err - } - - log.Info("Initializing message service...", " tcp port=", messageOpts.TcpPort, " web socket port=", messageOpts.WsMsgPort) - messageOpts.SCAddr = *ourStore.GetAddress() - messageService := p2pms.NewMessageService(messageOpts) - - // Compare chainOpts.ChainStartBlock to lastBlockNum seen in store. The larger of the two - // gets passed as an argument when creating NewEthChainService - storeBlockNum, err := ourStore.GetLastBlockNumSeen() - if err != nil { - return nil, err - } - if storeBlockNum > chainOpts.ChainStartBlock { - chainOpts.ChainStartBlock = storeBlockNum - } - - log.Info("Initializing chain service...") - ourChain, err := chainservice.NewEthChainService(chainOpts) - if err != nil { - return nil, err - } - - node := nitroNode.New( - messageService, - ourChain, - ourStore, - &engine.PermissivePolicy{}, - ) - - return &node, nil -} diff --git a/pkg/rpc/http.go b/pkg/rpc/http.go index 0dc9d780..66fd4430 100644 --- a/pkg/rpc/http.go +++ b/pkg/rpc/http.go @@ -18,27 +18,31 @@ package rpc import ( "fmt" + "math/big" "github.com/cerc-io/ipld-eth-server/v5/pkg/log" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/rpc" + "github.com/statechannels/go-nitro/paymentsmanager" "github.com/cerc-io/ipld-eth-server/v5/pkg/prom" ) // StartHTTPEndpoint starts the HTTP RPC endpoint, configured with cors/vhosts/modules. -func StartHTTPEndpoint(endpoint string, apis []rpc.API, modules []string, cors []string, vhosts []string, timeouts rpc.HTTPTimeouts) (*rpc.Server, error) { - +func StartHTTPEndpoint(endpoint string, apis []rpc.API, modules []string, cors []string, vhosts []string, timeouts rpc.HTTPTimeouts, voucherValidator paymentsmanager.VoucherValidator, queryRates map[string]*big.Int) (*rpc.Server, error) { srv := rpc.NewServer() err := node.RegisterApis(apis, modules, srv) if err != nil { utils.Fatalf("Could not register HTTP API: %w", err) } - handler := prom.HTTPMiddleware(node.NewHTTPHandlerStack(srv, cors, vhosts, nil)) + + promHandler := prom.HTTPMiddleware(node.NewHTTPHandlerStack(srv, cors, vhosts, nil)) + paymentHandler := paymentsmanager.HTTPMiddleware(promHandler, voucherValidator, queryRates) // start http server - _, addr, err := node.StartHTTPEndpoint(endpoint, rpc.DefaultHTTPTimeouts, handler) + // request -> payments -> metrics -> server + _, addr, err := node.StartHTTPEndpoint(endpoint, rpc.DefaultHTTPTimeouts, paymentHandler) if err != nil { utils.Fatalf("Could not start RPC api: %v", err) } -- 2.45.2 From cb2c23da8a5e59536cc4e861dddd7db374b61476 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 12 Oct 2023 13:20:43 +0530 Subject: [PATCH 06/12] Setup essential Nitro config --- cmd/common.go | 18 ++++++++++++++++++ cmd/serve.go | 18 ++++++++++-------- pkg/serve/config.go | 24 ++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/cmd/common.go b/cmd/common.go index 3e575621..3268d0e3 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -35,3 +35,21 @@ func addDatabaseFlags(command *cobra.Command) { viper.BindPFlag("database.user", command.PersistentFlags().Lookup("database-user")) viper.BindPFlag("database.password", command.PersistentFlags().Lookup("database-password")) } + +func addNitroFlags(command *cobra.Command) { + // nitro flags + command.PersistentFlags().String("nitro-pk", "", "nitro pk") + command.PersistentFlags().String("nitro-chainPk", "", "nitro chainPk") + command.PersistentFlags().String("nitro-chainUrl", "", "nitro chainUrl") + command.PersistentFlags().String("nitro-naAddress", "", "nitro naAddress") + command.PersistentFlags().String("nitro-vpaAddress", "", "nitro vpaAddress") + command.PersistentFlags().String("nitro-caAddress", "", "nitro caAddress") + + // nitro flag bindings + viper.BindPFlag("nitro.pk", command.PersistentFlags().Lookup("nitro-pk")) + viper.BindPFlag("nitro.chainPk", command.PersistentFlags().Lookup("nitro-chainPk")) + viper.BindPFlag("nitro.chainUrl", command.PersistentFlags().Lookup("nitro-chainUrl")) + viper.BindPFlag("nitro.naAddress", command.PersistentFlags().Lookup("nitro-naAddress")) + viper.BindPFlag("nitro.vpaAddress", command.PersistentFlags().Lookup("nitro-vpaAddress")) + viper.BindPFlag("nitro.caAddress", command.PersistentFlags().Lookup("nitro-caAddress")) +} diff --git a/cmd/serve.go b/cmd/serve.go index a5ccea1b..15ac0325 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -85,7 +85,7 @@ func serve() { server.Serve(wg) // TODO: Create required config for Nitro node - nitroNode, err := initializeNitroNode() + nitroNode, err := initializeNitroNode(serverConfig.Nitro) if err != nil { panic(err) } @@ -290,6 +290,8 @@ func init() { addDatabaseFlags(serveCmd) + addNitroFlags(serveCmd) + // flags for all config variables // eth graphql and json-rpc parameters serveCmd.PersistentFlags().Bool("server-graphql", false, "turn on the eth graphql server") @@ -370,19 +372,19 @@ func init() { viper.BindPFlag("validator.everyNthBlock", serveCmd.PersistentFlags().Lookup("validator-every-nth-block")) } -func initializeNitroNode() (*nitroNode.Node, error) { +func initializeNitroNode(nitroConfig *s.NitroConfig) (*nitroNode.Node, error) { // TODO: Configure - pkString := "" + pkString := nitroConfig.Pk useDurableStore := true durableStoreFolder := "./data/nitro-store" msgPort := 3005 wsMsgPort := 5005 - chainUrl := "ws://127.0.0.1:8545" + chainUrl := nitroConfig.ChainUrl chainStartBlock := uint64(0) - chainPk := "" - naAddress := "" - vpaAddress := "" - caAddress := "" + chainPk := nitroConfig.ChainPk + naAddress := nitroConfig.NaAddress + vpaAddress := nitroConfig.VpaAddress + caAddress := nitroConfig.CaAddress chainAuthToken := "" publicIp := "0.0.0.0" diff --git a/pkg/serve/config.go b/pkg/serve/config.go index 7c12b3bb..08bc06ec 100644 --- a/pkg/serve/config.go +++ b/pkg/serve/config.go @@ -81,6 +81,15 @@ const ( DATABASE_MAX_CONN_LIFETIME = "DATABASE_MAX_CONN_LIFETIME" ) +type NitroConfig struct { + Pk string + ChainPk string + ChainUrl string + NaAddress string + VpaAddress string + CaAddress string +} + // Config struct type Config struct { DB *sqlx.DB @@ -116,6 +125,8 @@ type Config struct { StateValidationEnabled bool StateValidationEveryNthBlock uint64 + + Nitro *NitroConfig } // NewConfig is used to initialize a watcher config from a .toml file @@ -248,6 +259,8 @@ func NewConfig() (*Config, error) { c.loadValidatorConfig() + c.loadNitroConfig() + return c, err } @@ -280,6 +293,17 @@ func (c *Config) dbInit() { c.DBConfig.MaxConnLifetime = time.Duration(viper.GetInt("database.maxLifetime")) } +func (c *Config) loadNitroConfig() { + c.Nitro = &NitroConfig{} + + c.Nitro.Pk = viper.GetString("nitro.pk") + c.Nitro.ChainPk = viper.GetString("nitro.chainPk") + c.Nitro.ChainUrl = viper.GetString("nitro.chainUrl") + c.Nitro.NaAddress = viper.GetString("nitro.naAddress") + c.Nitro.VpaAddress = viper.GetString("nitro.vpaAddress") + c.Nitro.CaAddress = viper.GetString("nitro.caAddress") +} + func (c *Config) loadGroupCacheConfig() { viper.BindEnv("groupcache.pool.enabled", ethServerShared.GcachePoolEnabled) viper.BindEnv("groupcache.pool.httpEndpoint", ethServerShared.GcachePoolHttpPath) -- 2.45.2 From d26e2d542302966d64a5458609a284a35e935499 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 12 Oct 2023 13:45:45 +0530 Subject: [PATCH 07/12] Setup RPC query rates --- cmd/serve.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cmd/serve.go b/cmd/serve.go index 15ac0325..8304d1a6 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -98,7 +98,14 @@ func serve() { pm.Start(wg) voucherValidator := paymentsmanager.InProcessValidator{PaymentsManager: pm} - queryRates := map[string]*big.Int{"eth_getBlockByNumber": big.NewInt(50)} + + // TODO: Configure + queryRates := map[string]*big.Int{ + "eth_getBlockByNumber": big.NewInt(50), + "eth_getBlockByHash": big.NewInt(50), + "eth_getStorageAt": big.NewInt(50), + "eth_getLogs": big.NewInt(50), + } if err := startServers(server, serverConfig, voucherValidator, queryRates); err != nil { logWithCommand.Fatal(err) @@ -120,9 +127,6 @@ func serve() { logWithCommand.Debug("state validator disabled") } - // paymentsManager, _ := payments.NewPaymentsManager(true) - // paymentsManager.Start(wg) - shutdown := make(chan os.Signal, 1) signal.Notify(shutdown, os.Interrupt) <-shutdown -- 2.45.2 From 883f8415fdfb4f075d7449472b7d5af927c0e1c1 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 12 Oct 2023 15:16:55 +0530 Subject: [PATCH 08/12] Run in-process go-nitro RPC server --- cmd/serve.go | 60 +++++++++++++++++++++++++++++++++------------------- go.mod | 5 +++-- go.sum | 2 ++ 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/cmd/serve.go b/cmd/serve.go index 8304d1a6..5fd43c6a 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -17,6 +17,7 @@ package cmd import ( "errors" + "fmt" "math/big" "net/http" "net/url" @@ -36,6 +37,9 @@ import ( "github.com/statechannels/go-nitro/node/engine/chainservice" "github.com/statechannels/go-nitro/node/engine/store" "github.com/statechannels/go-nitro/paymentsmanager" + "github.com/statechannels/go-nitro/rpc/transport" + "github.com/tidwall/buntdb" + "golang.org/x/exp/slog" "github.com/cerc-io/ipld-eth-server/v5/pkg/graphql" srpc "github.com/cerc-io/ipld-eth-server/v5/pkg/rpc" @@ -43,6 +47,8 @@ import ( v "github.com/cerc-io/ipld-eth-server/v5/version" nitroNode "github.com/statechannels/go-nitro/node" nitrop2pms "github.com/statechannels/go-nitro/node/engine/messageservice/p2p-message-service" + nitroRpc "github.com/statechannels/go-nitro/rpc" + nitroHttpTransport "github.com/statechannels/go-nitro/rpc/transport/http" ) var ErrNoRpcEndpoints = errors.New("no rpc endpoints is available") @@ -87,12 +93,12 @@ func serve() { // TODO: Create required config for Nitro node nitroNode, err := initializeNitroNode(serverConfig.Nitro) if err != nil { - panic(err) + logWithCommand.Fatal(err) } pm, err := paymentsmanager.NewPaymentsManager(nitroNode) if err != nil { - panic(err) + logWithCommand.Fatal(err) } pm.Start(wg) @@ -107,6 +113,12 @@ func serve() { "eth_getLogs": big.NewInt(50), } + rpcPort := 4005 + nitroRpcServer, err := initializeNitroRpcServer(nitroNode, rpcPort) + if err != nil { + logWithCommand.Fatal(err) + } + if err := startServers(server, serverConfig, voucherValidator, queryRates); err != nil { logWithCommand.Fatal(err) } @@ -135,6 +147,7 @@ func serve() { } server.Stop() pm.Stop() + nitroRpcServer.Close() wg.Wait() } @@ -403,30 +416,14 @@ func initializeNitroNode(nitroConfig *s.NitroConfig) (*nitroNode.Node, error) { CaAddress: common.HexToAddress(caAddress), } - storeOpts := store.StoreOpts{ - PkBytes: common.Hex2Bytes(pkString), - UseDurableStore: useDurableStore, - DurableStoreFolder: durableStoreFolder, - } - - peerSlice := []string{} - - messageOpts := nitrop2pms.MessageOpts{ - PkBytes: common.Hex2Bytes(pkString), - TcpPort: msgPort, - WsMsgPort: wsMsgPort, - BootPeers: peerSlice, - PublicIp: publicIp, - } - - ourStore, err := store.NewStore(storeOpts) + ourStore, err := store.NewStore(common.Hex2Bytes(pkString), useDurableStore, durableStoreFolder, buntdb.Config{}) if err != nil { return nil, err } - log.Info("Initializing message service...", " tcp port=", messageOpts.TcpPort, " web socket port=", messageOpts.WsMsgPort) - messageOpts.SCAddr = *ourStore.GetAddress() - messageService := nitrop2pms.NewMessageService(messageOpts) + bootPeers := []string{} + log.Info("Initializing message service...", " tcp port=", msgPort, " web socket port=", wsMsgPort) + messageService := nitrop2pms.NewMessageService(publicIp, msgPort, wsMsgPort, *ourStore.GetAddress(), common.Hex2Bytes(pkString), bootPeers) // Compare chainOpts.ChainStartBlock to lastBlockNum seen in store. The larger of the two // gets passed as an argument when creating NewEthChainService @@ -453,3 +450,22 @@ func initializeNitroNode(nitroConfig *s.NitroConfig) (*nitroNode.Node, error) { return &node, nil } + +func initializeNitroRpcServer(node *nitroNode.Node, rpcPort int) (*nitroRpc.RpcServer, error) { + var transport transport.Responder + var err error + + slog.Info("Initializing Nitro HTTP RPC transport...") + transport, err = nitroHttpTransport.NewHttpTransportAsServer(fmt.Sprint(rpcPort)) + if err != nil { + return nil, err + } + + rpcServer, err := nitroRpc.NewRpcServer(node, transport) + if err != nil { + return nil, err + } + + slog.Info("Completed Nitro RPC server initialization") + return rpcServer, nil +} diff --git a/go.mod b/go.mod index c8d5e0f6..58f18af2 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,8 @@ require ( github.com/spf13/cobra v1.4.0 github.com/spf13/viper v1.11.0 github.com/statechannels/go-nitro v0.1.1 + github.com/tidwall/buntdb v1.2.10 + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 gorm.io/driver/postgres v1.3.7 gorm.io/gorm v1.23.5 ) @@ -78,6 +80,7 @@ require ( github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang-jwt/jwt/v5 v5.0.0 // indirect github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect @@ -232,7 +235,6 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect github.com/thoas/go-funk v0.9.3 // indirect github.com/tidwall/btree v1.6.0 // indirect - github.com/tidwall/buntdb v1.2.10 // indirect github.com/tidwall/gjson v1.14.4 // indirect github.com/tidwall/grect v0.1.4 // indirect github.com/tidwall/match v1.1.1 // indirect @@ -263,7 +265,6 @@ require ( go.uber.org/zap v1.25.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/crypto v0.12.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.14.0 // indirect golang.org/x/sync v0.3.0 // indirect diff --git a/go.sum b/go.sum index 397bf025..c512ac90 100644 --- a/go.sum +++ b/go.sum @@ -292,6 +292,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= +github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -- 2.45.2 From 578535888e589b6d8fe822a5b02e6449104b0b38 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 12 Oct 2023 15:43:25 +0530 Subject: [PATCH 09/12] Support env variables for Nitro config --- Dockerfile | 4 ++-- environments/example.toml | 8 ++++++++ pkg/serve/config.go | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 031cd0c5..f1aa8605 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ -FROM golang:1.19-alpine as debugger +FROM golang:1.21-alpine as debugger # Include dlv RUN go install github.com/go-delve/delve/cmd/dlv@latest -FROM golang:1.19-alpine as builder +FROM golang:1.21-alpine as builder RUN apk --update --no-cache add gcc musl-dev binutils-gold git diff --git a/environments/example.toml b/environments/example.toml index ab22f330..ca1624b5 100644 --- a/environments/example.toml +++ b/environments/example.toml @@ -31,3 +31,11 @@ clientName = "Geth" # $ETH_CLIENT_NAME genesisBlock = "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" # $ETH_GENESIS_BLOCK networkID = "1" # $ETH_NETWORK_ID + +[nitro] + pk = "" + chainPk = "" + chainUrl = "" + naAddress = "" + vpaAddress = "" + caAddress = "" diff --git a/pkg/serve/config.go b/pkg/serve/config.go index 08bc06ec..3a123997 100644 --- a/pkg/serve/config.go +++ b/pkg/serve/config.go @@ -79,6 +79,13 @@ const ( DATABASE_MAX_IDLE_CONNECTIONS = "DATABASE_MAX_IDLE_CONNECTIONS" DATABASE_MAX_OPEN_CONNECTIONS = "DATABASE_MAX_OPEN_CONNECTIONS" DATABASE_MAX_CONN_LIFETIME = "DATABASE_MAX_CONN_LIFETIME" + + NITRO_PK = "NITRO_PK" + NITRO_CHAIN_PK = "NITRO_CHAIN_PK" + NITRO_CHAIN_URL = "NITRO_CHAIN_URL" + NITRO_NA_ADDRESS = "NITRO_NA_ADDRESS" + NITRO_VPA_ADDRESS = "NITRO_VPA_ADDRESS" + NITRO_CA_ADDRESS = "NITRO_CA_ADDRESS" ) type NitroConfig struct { @@ -296,6 +303,13 @@ func (c *Config) dbInit() { func (c *Config) loadNitroConfig() { c.Nitro = &NitroConfig{} + viper.BindEnv("nitro.pk", NITRO_PK) + viper.BindEnv("nitro.chainPk", NITRO_CHAIN_PK) + viper.BindEnv("nitro.chainUrl", NITRO_CHAIN_URL) + viper.BindEnv("nitro.naAddress", NITRO_NA_ADDRESS) + viper.BindEnv("nitro.vpaAddress", NITRO_VPA_ADDRESS) + viper.BindEnv("nitro.caAddress", NITRO_CA_ADDRESS) + c.Nitro.Pk = viper.GetString("nitro.pk") c.Nitro.ChainPk = viper.GetString("nitro.chainPk") c.Nitro.ChainUrl = viper.GetString("nitro.chainUrl") -- 2.45.2 From 5e949cc3d6b39e6d3df6a5bdc098cdcaa23dcd61 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 12 Oct 2023 16:07:12 +0530 Subject: [PATCH 10/12] Add bash to Dockerfile --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index f1aa8605..022627fd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,6 +28,8 @@ RUN GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' - # app container FROM alpine +RUN apk --update --no-cache add bash jq curl + ARG USER="vdm" ARG CONFIG_FILE="./environments/example.toml" -- 2.45.2 From dc8b5dc8707d67a25f2dfaa68b5eb6a0cf3d6e2f Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Thu, 12 Oct 2023 16:38:16 +0530 Subject: [PATCH 11/12] Add config for durable store --- cmd/common.go | 4 ++++ cmd/serve.go | 7 ++++--- environments/example.toml | 14 ++++++++------ pkg/serve/config.go | 32 ++++++++++++++++++++------------ 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/cmd/common.go b/cmd/common.go index 3268d0e3..af4e51d5 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -44,6 +44,8 @@ func addNitroFlags(command *cobra.Command) { command.PersistentFlags().String("nitro-naAddress", "", "nitro naAddress") command.PersistentFlags().String("nitro-vpaAddress", "", "nitro vpaAddress") command.PersistentFlags().String("nitro-caAddress", "", "nitro caAddress") + command.PersistentFlags().Bool("nitro-useDurableStore", false, "nitro useDurableStore") + command.PersistentFlags().String("nitro-durableStoreFolder", "", "nitro durableStoreFolder") // nitro flag bindings viper.BindPFlag("nitro.pk", command.PersistentFlags().Lookup("nitro-pk")) @@ -52,4 +54,6 @@ func addNitroFlags(command *cobra.Command) { viper.BindPFlag("nitro.naAddress", command.PersistentFlags().Lookup("nitro-naAddress")) viper.BindPFlag("nitro.vpaAddress", command.PersistentFlags().Lookup("nitro-vpaAddress")) viper.BindPFlag("nitro.caAddress", command.PersistentFlags().Lookup("nitro-caAddress")) + viper.BindPFlag("nitro.useDurableStore", command.PersistentFlags().Lookup("nitro-useDurableStore")) + viper.BindPFlag("nitro.durableStoreFolder", command.PersistentFlags().Lookup("nitro-durableStoreFolder")) } diff --git a/cmd/serve.go b/cmd/serve.go index 5fd43c6a..edb1451b 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -103,7 +103,7 @@ func serve() { pm.Start(wg) - voucherValidator := paymentsmanager.InProcessValidator{PaymentsManager: pm} + voucherValidator := paymentsmanager.InProcessVoucherValidator{PaymentsManager: pm} // TODO: Configure queryRates := map[string]*big.Int{ @@ -389,11 +389,12 @@ func init() { viper.BindPFlag("validator.everyNthBlock", serveCmd.PersistentFlags().Lookup("validator-every-nth-block")) } +// https://github.com/cerc-io/go-nitro/releases/tag/github.com/cerc-io/go-nitro v0.1.1-ts-port-0.1.7 func initializeNitroNode(nitroConfig *s.NitroConfig) (*nitroNode.Node, error) { // TODO: Configure pkString := nitroConfig.Pk - useDurableStore := true - durableStoreFolder := "./data/nitro-store" + useDurableStore := nitroConfig.UseDurableStore + durableStoreFolder := nitroConfig.DurableStoreFolder msgPort := 3005 wsMsgPort := 5005 chainUrl := nitroConfig.ChainUrl diff --git a/environments/example.toml b/environments/example.toml index ca1624b5..9e8982f4 100644 --- a/environments/example.toml +++ b/environments/example.toml @@ -33,9 +33,11 @@ networkID = "1" # $ETH_NETWORK_ID [nitro] - pk = "" - chainPk = "" - chainUrl = "" - naAddress = "" - vpaAddress = "" - caAddress = "" + pk = "" # NITRO_PK + chainPk = "" # NITRO_CHAIN_PK + chainUrl = "" # NITRO_CHAIN_URL + naAddress = "" # NITRO_NA_ADDRESS + vpaAddress = "" # NITRO_VPA_ADDRESS + caAddress = "" # NITRO_CA_ADDRESS + useDurableStore = false # NITRO_USE_DURABLE_STORE + durableStoreFolder = "" # NITRO_DURABLE_STORE_FOLDER diff --git a/pkg/serve/config.go b/pkg/serve/config.go index 3a123997..45998b1f 100644 --- a/pkg/serve/config.go +++ b/pkg/serve/config.go @@ -80,21 +80,25 @@ const ( DATABASE_MAX_OPEN_CONNECTIONS = "DATABASE_MAX_OPEN_CONNECTIONS" DATABASE_MAX_CONN_LIFETIME = "DATABASE_MAX_CONN_LIFETIME" - NITRO_PK = "NITRO_PK" - NITRO_CHAIN_PK = "NITRO_CHAIN_PK" - NITRO_CHAIN_URL = "NITRO_CHAIN_URL" - NITRO_NA_ADDRESS = "NITRO_NA_ADDRESS" - NITRO_VPA_ADDRESS = "NITRO_VPA_ADDRESS" - NITRO_CA_ADDRESS = "NITRO_CA_ADDRESS" + NITRO_PK = "NITRO_PK" + NITRO_CHAIN_PK = "NITRO_CHAIN_PK" + NITRO_CHAIN_URL = "NITRO_CHAIN_URL" + NITRO_NA_ADDRESS = "NITRO_NA_ADDRESS" + NITRO_VPA_ADDRESS = "NITRO_VPA_ADDRESS" + NITRO_CA_ADDRESS = "NITRO_CA_ADDRESS" + NITRO_USE_DURABLE_STORE = "NITRO_USE_DURABLE_STORE" + NITRO_DURABLE_STORE_FOLDER = "NITRO_DURABLE_STORE_FOLDER" ) type NitroConfig struct { - Pk string - ChainPk string - ChainUrl string - NaAddress string - VpaAddress string - CaAddress string + Pk string + ChainPk string + ChainUrl string + NaAddress string + VpaAddress string + CaAddress string + UseDurableStore bool + DurableStoreFolder string } // Config struct @@ -309,6 +313,8 @@ func (c *Config) loadNitroConfig() { viper.BindEnv("nitro.naAddress", NITRO_NA_ADDRESS) viper.BindEnv("nitro.vpaAddress", NITRO_VPA_ADDRESS) viper.BindEnv("nitro.caAddress", NITRO_CA_ADDRESS) + viper.BindEnv("nitro.useDurableStore", NITRO_USE_DURABLE_STORE) + viper.BindEnv("nitro.durableStoreFolder", NITRO_DURABLE_STORE_FOLDER) c.Nitro.Pk = viper.GetString("nitro.pk") c.Nitro.ChainPk = viper.GetString("nitro.chainPk") @@ -316,6 +322,8 @@ func (c *Config) loadNitroConfig() { c.Nitro.NaAddress = viper.GetString("nitro.naAddress") c.Nitro.VpaAddress = viper.GetString("nitro.vpaAddress") c.Nitro.CaAddress = viper.GetString("nitro.caAddress") + c.Nitro.UseDurableStore = viper.GetBool("nitro.useDurableStore") + c.Nitro.DurableStoreFolder = viper.GetString("nitro.durableStoreFolder") } func (c *Config) loadGroupCacheConfig() { -- 2.45.2 From e6fb2d1e2987b300db1906a9f153f115a6ef4287 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Fri, 13 Oct 2023 14:29:39 +0530 Subject: [PATCH 12/12] Fix config and add todos --- cmd/common.go | 28 ++++++++++++++-------------- cmd/serve.go | 9 +++++---- pkg/rpc/http.go | 1 + 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/cmd/common.go b/cmd/common.go index af4e51d5..7cb69e80 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -39,21 +39,21 @@ func addDatabaseFlags(command *cobra.Command) { func addNitroFlags(command *cobra.Command) { // nitro flags command.PersistentFlags().String("nitro-pk", "", "nitro pk") - command.PersistentFlags().String("nitro-chainPk", "", "nitro chainPk") - command.PersistentFlags().String("nitro-chainUrl", "", "nitro chainUrl") - command.PersistentFlags().String("nitro-naAddress", "", "nitro naAddress") - command.PersistentFlags().String("nitro-vpaAddress", "", "nitro vpaAddress") - command.PersistentFlags().String("nitro-caAddress", "", "nitro caAddress") - command.PersistentFlags().Bool("nitro-useDurableStore", false, "nitro useDurableStore") - command.PersistentFlags().String("nitro-durableStoreFolder", "", "nitro durableStoreFolder") + command.PersistentFlags().String("nitro-chain-pk", "", "nitro chainPk") + command.PersistentFlags().String("nitro-chain-url", "", "nitro chainUrl") + command.PersistentFlags().String("nitro-na-address", "", "nitro naAddress") + command.PersistentFlags().String("nitro-vpa-address", "", "nitro vpaAddress") + command.PersistentFlags().String("nitro-ca-address", "", "nitro caAddress") + command.PersistentFlags().Bool("nitro-use-durable-store", false, "nitro useDurableStore") + command.PersistentFlags().String("nitro-durable-store-folder", "", "nitro durableStoreFolder") // nitro flag bindings viper.BindPFlag("nitro.pk", command.PersistentFlags().Lookup("nitro-pk")) - viper.BindPFlag("nitro.chainPk", command.PersistentFlags().Lookup("nitro-chainPk")) - viper.BindPFlag("nitro.chainUrl", command.PersistentFlags().Lookup("nitro-chainUrl")) - viper.BindPFlag("nitro.naAddress", command.PersistentFlags().Lookup("nitro-naAddress")) - viper.BindPFlag("nitro.vpaAddress", command.PersistentFlags().Lookup("nitro-vpaAddress")) - viper.BindPFlag("nitro.caAddress", command.PersistentFlags().Lookup("nitro-caAddress")) - viper.BindPFlag("nitro.useDurableStore", command.PersistentFlags().Lookup("nitro-useDurableStore")) - viper.BindPFlag("nitro.durableStoreFolder", command.PersistentFlags().Lookup("nitro-durableStoreFolder")) + viper.BindPFlag("nitro.chainPk", command.PersistentFlags().Lookup("nitro-chain-pk")) + viper.BindPFlag("nitro.chainUrl", command.PersistentFlags().Lookup("nitro-chain-url")) + viper.BindPFlag("nitro.naAddress", command.PersistentFlags().Lookup("nitro-na-address")) + viper.BindPFlag("nitro.vpaAddress", command.PersistentFlags().Lookup("nitro-vpa-address")) + viper.BindPFlag("nitro.caAddress", command.PersistentFlags().Lookup("nitro-ca-address")) + viper.BindPFlag("nitro.useDurableStore", command.PersistentFlags().Lookup("nitro-use-durable-store")) + viper.BindPFlag("nitro.durableStoreFolder", command.PersistentFlags().Lookup("nitro-durable-store")) } diff --git a/cmd/serve.go b/cmd/serve.go index edb1451b..970529b0 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -90,7 +90,6 @@ func serve() { server.Serve(wg) - // TODO: Create required config for Nitro node nitroNode, err := initializeNitroNode(serverConfig.Nitro) if err != nil { logWithCommand.Fatal(err) @@ -105,7 +104,7 @@ func serve() { voucherValidator := paymentsmanager.InProcessVoucherValidator{PaymentsManager: pm} - // TODO: Configure + // TODO: Read from config file queryRates := map[string]*big.Int{ "eth_getBlockByNumber": big.NewInt(50), "eth_getBlockByHash": big.NewInt(50), @@ -113,6 +112,7 @@ func serve() { "eth_getLogs": big.NewInt(50), } + // TODO: Read from config file rpcPort := 4005 nitroRpcServer, err := initializeNitroRpcServer(nitroNode, rpcPort) if err != nil { @@ -152,6 +152,7 @@ func serve() { wg.Wait() } +// TODO: Absorb voucherValidator and queryRates args into existing ones func startServers(server s.Server, settings *s.Config, voucherValidator paymentsmanager.VoucherValidator, queryRates map[string]*big.Int) error { if settings.IPCEnabled { logWithCommand.Debug("starting up IPC server") @@ -389,9 +390,9 @@ func init() { viper.BindPFlag("validator.everyNthBlock", serveCmd.PersistentFlags().Lookup("validator-every-nth-block")) } -// https://github.com/cerc-io/go-nitro/releases/tag/github.com/cerc-io/go-nitro v0.1.1-ts-port-0.1.7 +// https://github.com/cerc-io/go-nitro/blob/release-v0.1.1-ts-port-0.1.7/internal/node/node.go#L17 func initializeNitroNode(nitroConfig *s.NitroConfig) (*nitroNode.Node, error) { - // TODO: Configure + // TODO: Read from config file pkString := nitroConfig.Pk useDurableStore := nitroConfig.UseDurableStore durableStoreFolder := nitroConfig.DurableStoreFolder diff --git a/pkg/rpc/http.go b/pkg/rpc/http.go index 66fd4430..02c683c3 100644 --- a/pkg/rpc/http.go +++ b/pkg/rpc/http.go @@ -30,6 +30,7 @@ import ( ) // StartHTTPEndpoint starts the HTTP RPC endpoint, configured with cors/vhosts/modules. +// TODO: Absorb voucherValidator and queryRates args into existing ones func StartHTTPEndpoint(endpoint string, apis []rpc.API, modules []string, cors []string, vhosts []string, timeouts rpc.HTTPTimeouts, voucherValidator paymentsmanager.VoucherValidator, queryRates map[string]*big.Int) (*rpc.Server, error) { srv := rpc.NewServer() err := node.RegisterApis(apis, modules, srv) -- 2.45.2