From 38b079cb96dbe656d9cafb7f84022d97ca75a7eb Mon Sep 17 00:00:00 2001 From: noot <36753753+noot@users.noreply.github.com> Date: Wed, 24 Aug 2022 20:34:40 -0400 Subject: [PATCH] persist peerstore to disk (#173) --- .gitignore | 1 + cmd/daemon/main.go | 28 ++++++++++++++++++++++++++++ cmd/daemon/main_test.go | 8 ++++---- cmd/recover/main.go | 3 +-- cmd/recover/main_test.go | 3 +-- cmd/tester/main.go | 3 +-- cmd/utils/utils.go | 1 + common/rpctypes/utils.go | 4 ++-- common/utils.go | 24 ++++++++++++++++++++++++ go.mod | 10 +++++++++- go.sum | 19 +++++++++++++++++++ net/discovery_test.go | 21 +++++++++++---------- net/host.go | 31 ++++++++++++++++++++++++++++--- net/host_test.go | 9 ++++++--- net/initiate_test.go | 10 ---------- net/query_test.go | 5 ----- net/utils.go | 3 +-- protocol/write.go | 26 ++------------------------ 18 files changed, 139 insertions(+), 70 deletions(-) diff --git a/.gitignore b/.gitignore index 33806b5a..3aa636ad 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ swapcli swapd swaprecover +swaptester # Test binary, built with `go test -c` *.test diff --git a/cmd/daemon/main.go b/cmd/daemon/main.go index 554882ed..9fd5dc2a 100644 --- a/cmd/daemon/main.go +++ b/cmd/daemon/main.go @@ -49,6 +49,10 @@ const ( var ( log = logging.Logger("cmd") + + // default dev basepaths + defaultXMRMakerBasepath = os.TempDir() + "/xmrmaker" + defaultXMRTakerBasepath = os.TempDir() + "/xmrtaker" ) const ( @@ -303,9 +307,33 @@ func (d *daemon) make(c *cli.Context) error { libp2pPort = defaultLibp2pPort } + // basepath is already set in default case + basepath := c.String(flagBasepath) + switch { + case basepath != "": + cfg.Basepath = basepath + case devXMRTaker: + cfg.Basepath = defaultXMRTakerBasepath + case devXMRMaker: + cfg.Basepath = defaultXMRMakerBasepath + } + + exists, err := common.Exists(cfg.Basepath) + if err != nil { + return err + } + + if !exists { + err = common.MakeDir(cfg.Basepath) + if err != nil { + return err + } + } + netCfg := &net.Config{ Ctx: d.ctx, Environment: env, + Basepath: cfg.Basepath, ChainID: chainID, Port: libp2pPort, KeyFile: libp2pKey, diff --git a/cmd/daemon/main_test.go b/cmd/daemon/main_test.go index 1de12316..80358a8a 100644 --- a/cmd/daemon/main_test.go +++ b/cmd/daemon/main_test.go @@ -65,8 +65,8 @@ func newTestContext(t *testing.T, description string, flags []string, values []i func TestDaemon_DevXMRTaker(t *testing.T) { c := newTestContext(t, "test --dev-xmrtaker", - []string{flagDevXMRTaker}, - []interface{}{true}, + []string{flagDevXMRTaker, flagBasepath}, + []interface{}{true, t.TempDir()}, ) ctx, cancel := context.WithCancel(context.Background()) @@ -84,8 +84,8 @@ func TestDaemon_DevXMRTaker(t *testing.T) { func TestDaemon_DevXMRMaker(t *testing.T) { c := newTestContext(t, "test --dev-xmrmaker", - []string{flagDevXMRMaker, flagDeploy}, - []interface{}{true, true}, + []string{flagDevXMRMaker, flagDeploy, flagBasepath}, + []interface{}{true, true, t.TempDir()}, ) ctx, cancel := context.WithCancel(context.Background()) diff --git a/cmd/recover/main.go b/cmd/recover/main.go index 17adaee1..da8e62bd 100644 --- a/cmd/recover/main.go +++ b/cmd/recover/main.go @@ -3,7 +3,6 @@ package main import ( "context" "encoding/json" - "io/ioutil" "math/big" "os" "path/filepath" @@ -141,7 +140,7 @@ func (inst *instance) recover(c *cli.Context) error { return errMustProvideInfoFile } - infofileBytes, err := ioutil.ReadFile(filepath.Clean(infofilePath)) + infofileBytes, err := os.ReadFile(filepath.Clean(infofilePath)) if err != nil { return err } diff --git a/cmd/recover/main_test.go b/cmd/recover/main_test.go index be998d4e..57102479 100644 --- a/cmd/recover/main_test.go +++ b/cmd/recover/main_test.go @@ -4,7 +4,6 @@ import ( "encoding/json" "flag" "fmt" - "io/ioutil" "os" "path" "strconv" @@ -123,7 +122,7 @@ func createInfoFile(t *testing.T, kpA, kpB *mcrypto.PrivateKeyPair, contractAddr bz, err := json.MarshalIndent(infofile, "", "\t") require.NoError(t, err) filepath := path.Join(t.TempDir(), "test-infofile.txt") - err = ioutil.WriteFile(filepath, bz, os.ModePerm) + err = os.WriteFile(filepath, bz, os.ModePerm) require.NoError(t, err) return filepath } diff --git a/cmd/tester/main.go b/cmd/tester/main.go index 314868e7..bb83a17e 100644 --- a/cmd/tester/main.go +++ b/cmd/tester/main.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "encoding/json" "fmt" - "io/ioutil" "math/big" mrand "math/rand" "os" @@ -139,7 +138,7 @@ func runTester(c *cli.Context) error { config = defaultConfigFile } - bz, err := ioutil.ReadFile(filepath.Clean(config)) + bz, err := os.ReadFile(filepath.Clean(config)) if err != nil { return err } diff --git a/cmd/utils/utils.go b/cmd/utils/utils.go index 214776db..da3ca3d4 100644 --- a/cmd/utils/utils.go +++ b/cmd/utils/utils.go @@ -14,6 +14,7 @@ import ( ) const ( + // TODO: just move all the flags to here, or their own package? there's a lot of duplicate ones flagEthereumPrivKey = "ethereum-privkey" flagEnv = "env" ) diff --git a/common/rpctypes/utils.go b/common/rpctypes/utils.go index 2a83539c..1eed29ea 100644 --- a/common/rpctypes/utils.go +++ b/common/rpctypes/utils.go @@ -5,7 +5,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net" "net/http" "time" @@ -56,7 +56,7 @@ func PostRPC(endpoint, method, params string) (*Response, error) { _ = resp.Body.Close() }() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("failed to read response body: %w", err) } diff --git a/common/utils.go b/common/utils.go index 8b2c8e1a..d405cebb 100644 --- a/common/utils.go +++ b/common/utils.go @@ -2,6 +2,7 @@ package common import ( "crypto/ecdsa" + "os" ethcommon "github.com/ethereum/go-ethereum/common" ethcrypto "github.com/ethereum/go-ethereum/crypto" @@ -30,3 +31,26 @@ func GetTopic(sig string) ethcommon.Hash { copy(b[:], h) return b } + +// MakeDir makes a directory +func MakeDir(dir string) error { + if err := os.MkdirAll(dir, os.ModePerm); err != nil { + return err + } + + return nil +} + +// Exists returns whether the given file or directory exists +func Exists(path string) (bool, error) { + _, err := os.Stat(path) + if err == nil { + return true, nil + } + + if os.IsNotExist(err) { + return false, nil + } + + return false, err +} diff --git a/go.mod b/go.mod index 003a1feb..fcf3f7cf 100644 --- a/go.mod +++ b/go.mod @@ -14,10 +14,12 @@ require ( github.com/gorilla/mux v1.8.0 github.com/gorilla/rpc v1.2.0 github.com/gorilla/websocket v1.5.0 + github.com/ipfs/go-ds-badger2 v0.1.3 github.com/ipfs/go-log v1.0.5 github.com/libp2p/go-libp2p v0.21.0 github.com/libp2p/go-libp2p-core v0.19.1 github.com/libp2p/go-libp2p-kad-dht v0.17.0 + github.com/libp2p/go-libp2p-peerstore v0.7.1 github.com/multiformats/go-multiaddr v0.6.0 github.com/noot/cgo-dleq v0.0.0-20220726051627-d0716fb55684 github.com/stretchr/testify v1.8.0 @@ -26,9 +28,11 @@ require ( ) require ( + github.com/DataDog/zstd v1.4.1 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.1 // indirect + github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cheekybits/genny v1.0.0 // indirect github.com/containerd/cgroups v1.0.4 // indirect @@ -38,7 +42,11 @@ require ( github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/deckarep/golang-set v1.8.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/dgraph-io/badger/v2 v2.2007.3 // indirect + github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de // indirect + github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect github.com/docker/go-units v0.4.0 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/flynn/noise v1.0.0 // indirect @@ -51,6 +59,7 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/uuid v1.3.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -76,7 +85,6 @@ require ( github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.4.7 // indirect - github.com/libp2p/go-libp2p-peerstore v0.7.1 // indirect github.com/libp2p/go-libp2p-record v0.1.3 // indirect github.com/libp2p/go-libp2p-resource-manager v0.5.3 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.2.3 // indirect diff --git a/go.sum b/go.sum index 694ebd51..94022e62 100644 --- a/go.sum +++ b/go.sum @@ -41,11 +41,15 @@ filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= +github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/MarinX/monerorpc v1.0.0 h1:rO7yWgFl5YdmaugwCqGvef7ybPRriM0Tkq4KQ6eNO9Y= github.com/MarinX/monerorpc v1.0.0/go.mod h1:NohAIf5kJ4pS0sO9mbEQkI1dLHuxd4L0DX2Zou0Yofo= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -81,6 +85,7 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= @@ -125,11 +130,18 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= +github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= +github.com/dgraph-io/badger/v2 v2.2007.3 h1:Sl9tQWz92WCbVSe8pj04Tkqlm2boW+KAxd+XSs58SQI= +github.com/dgraph-io/badger/v2 v2.2007.3/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= +github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/ebfe/keccak v0.0.0-20150115210727-5cc570678d1b h1:BMyjwV6Fal/Ffphi4dJfulSxMeDl0xFS2vs5QLr6rsI= github.com/ebfe/keccak v0.0.0-20150115210727-5cc570678d1b/go.mod h1:fnviDXB7GJWiSUI9thIXmk9QKM8Rhj1JV/LcMRzkiVA= @@ -227,7 +239,9 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -318,7 +332,11 @@ github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= github.com/ipfs/go-ds-badger v0.2.7/go.mod h1:02rnztVKA4aZwDuaRPTf8mpqcKmXP7mLl6JPxd14JHA= +github.com/ipfs/go-ds-badger v0.3.0 h1:xREL3V0EH9S219kFFueOYJJTcjgNSZ2HY1iSvN7U1Ro= +github.com/ipfs/go-ds-badger2 v0.1.3 h1:Zo9JicXJ1DmXTN4KOw7oPXkspZ0AWHcAFCP1tQKnegg= +github.com/ipfs/go-ds-badger2 v0.1.3/go.mod h1:TPhhljfrgewjbtuL/tczP8dNrBYwwk+SdPYbms/NO9w= github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= +github.com/ipfs/go-ds-leveldb v0.5.0 h1:s++MEBbD3ZKc9/8/njrn4flZLnCuY9I79v94gBUNumo= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= @@ -333,6 +351,7 @@ github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JP github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= +github.com/ipfs/go-log/v2 v2.5.0/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipld/go-ipld-prime v0.9.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= diff --git a/net/discovery_test.go b/net/discovery_test.go index 09e31196..1b6826b6 100644 --- a/net/discovery_test.go +++ b/net/discovery_test.go @@ -9,6 +9,8 @@ import ( "github.com/stretchr/testify/require" ) +var testAdvertisementSleepDuration = time.Millisecond * 100 + func TestHost_Discover(t *testing.T) { ha := newHost(t, defaultPort) err := ha.Start() @@ -20,24 +22,23 @@ func TestHost_Discover(t *testing.T) { err = hc.Start() require.NoError(t, err) - defer func() { - _ = ha.Stop() - _ = hb.Stop() - _ = hc.Stop() - }() - // connect a + b and b + c, see if c can discover a via DHT err = ha.h.Connect(ha.ctx, hb.addrInfo()) require.NoError(t, err) - err = hc.h.Connect(ha.ctx, hb.addrInfo()) + err = hc.h.Connect(hc.ctx, hb.addrInfo()) require.NoError(t, err) + require.GreaterOrEqual(t, len(ha.h.Network().Peers()), 1) + require.GreaterOrEqual(t, len(hb.h.Network().Peers()), 2) + require.GreaterOrEqual(t, len(hc.h.Network().Peers()), 1) + ha.Advertise() - time.Sleep(initialAdvertisementTimeout) + hb.Advertise() + hc.Advertise() + time.Sleep(testAdvertisementSleepDuration) peers, err := hc.Discover(types.ProvidesXMR, time.Second) require.NoError(t, err) - require.Equal(t, 1, len(peers)) - require.Equal(t, ha.h.ID(), peers[0].ID) + require.GreaterOrEqual(t, len(peers), 1) } diff --git a/net/host.go b/net/host.go index 053d29d9..78354b05 100644 --- a/net/host.go +++ b/net/host.go @@ -3,17 +3,20 @@ package net import ( "context" "fmt" + "path" "sync" "time" "github.com/athanorlabs/atomic-swap/common" "github.com/athanorlabs/atomic-swap/common/types" + badger "github.com/ipfs/go-ds-badger2" "github.com/libp2p/go-libp2p" libp2phost "github.com/libp2p/go-libp2p-core/host" libp2pnetwork "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p-peerstore/pstoreds" ma "github.com/multiformats/go-multiaddr" "github.com/chyeh/pubip" @@ -54,6 +57,7 @@ type host struct { bootnodes []peer.AddrInfo discovery *discovery handler Handler + ds *badger.Datastore // swap instance info swapMu sync.Mutex @@ -67,6 +71,7 @@ type host struct { type Config struct { Ctx context.Context Environment common.Environment + Basepath string ChainID int64 Port uint16 KeyFile string @@ -106,12 +111,23 @@ func NewHost(cfg *Config) (*host, error) { } } + ds, err := badger.NewDatastore(path.Join(cfg.Basepath, "libp2p-datastore"), &badger.DefaultOptions) + if err != nil { + return nil, err + } + + ps, err := pstoreds.NewPeerstore(cfg.Ctx, ds, pstoreds.DefaultOpts()) + if err != nil { + return nil, err + } + // set libp2p host options opts := []libp2p.Option{ libp2p.ListenAddrs(addr), libp2p.DisableRelay(), libp2p.Identity(key), libp2p.NATPortMap(), + libp2p.Peerstore(ps), libp2p.AddrsFactory(func(as []ma.Multiaddr) []ma.Multiaddr { if cfg.Environment == common.Development { return as @@ -152,6 +168,7 @@ func NewHost(cfg *Config) (*host, error) { protocolID: fmt.Sprintf("%s/%s/%d", protocolID, cfg.Environment, cfg.ChainID), h: h, handler: cfg.Handler, + ds: ds, bootnodes: bns, queryBuf: make([]byte, 1024*5), swaps: make(map[types.Hash]*swap), @@ -209,10 +226,18 @@ func (h *host) Stop() error { return err } - // close libp2p host if err := h.h.Close(); err != nil { - log.Error("Failed to close libp2p host", "error", err) - return err + return fmt.Errorf("failed to close libp2p host: %w", err) + } + + err := h.h.Peerstore().Close() + if err != nil { + return fmt.Errorf("failed to close peerstore: %w", err) + } + + err = h.ds.Close() + if err != nil { + return fmt.Errorf("failed to close libp2p datastore: %w", err) } return nil diff --git a/net/host_test.go b/net/host_test.go index 136a7c68..d0ec95ae 100644 --- a/net/host_test.go +++ b/net/host_test.go @@ -20,7 +20,7 @@ func TestMain(m *testing.M) { os.Exit(0) } -var defaultPort uint16 = 5001 +var defaultPort uint16 = 5009 var testID = types.Hash{99} type mockHandler struct { @@ -62,6 +62,7 @@ func newHost(t *testing.T, port uint16) *host { cfg := &Config{ Ctx: context.Background(), Environment: common.Development, + Basepath: t.TempDir(), ChainID: common.GanacheChainID, Port: port, KeyFile: path.Join(t.TempDir(), fmt.Sprintf("node-%d.key", port)), @@ -71,6 +72,10 @@ func newHost(t *testing.T, port uint16) *host { h, err := NewHost(cfg) require.NoError(t, err) + t.Cleanup(func() { + err = h.Stop() + require.NoError(t, err) + }) return h } @@ -78,6 +83,4 @@ func TestNewHost(t *testing.T) { h := newHost(t, defaultPort) err := h.Start() require.NoError(t, err) - err = h.Stop() - require.NoError(t, err) } diff --git a/net/initiate_test.go b/net/initiate_test.go index 3b9ce274..a5f27d18 100644 --- a/net/initiate_test.go +++ b/net/initiate_test.go @@ -17,11 +17,6 @@ func TestHost_Initiate(t *testing.T) { err = hb.Start() require.NoError(t, err) - defer func() { - _ = ha.Stop() - _ = hb.Stop() - }() - err = ha.h.Connect(ha.ctx, hb.addrInfo()) require.NoError(t, err) @@ -42,11 +37,6 @@ func TestHost_ConcurrentSwaps(t *testing.T) { testID2 := types.Hash{98} - defer func() { - _ = ha.Stop() - _ = hb.Stop() - }() - err = ha.h.Connect(ha.ctx, hb.addrInfo()) require.NoError(t, err) diff --git a/net/query_test.go b/net/query_test.go index 6785bd3c..9a4a79ce 100644 --- a/net/query_test.go +++ b/net/query_test.go @@ -16,11 +16,6 @@ func TestHost_Query(t *testing.T) { err = hb.Start() require.NoError(t, err) - defer func() { - _ = ha.Stop() - _ = hb.Stop() - }() - err = ha.h.Connect(ha.ctx, hb.addrInfo()) require.NoError(t, err) diff --git a/net/utils.go b/net/utils.go index 7909954d..bbaf02e7 100644 --- a/net/utils.go +++ b/net/utils.go @@ -5,7 +5,6 @@ import ( "encoding/hex" "fmt" "io" - "io/ioutil" mrand "math/rand" "os" "path/filepath" @@ -65,7 +64,7 @@ func generateKey(seed int64, fp string) (crypto.PrivKey, error) { // loadKey attempts to load a private key from the provided filepath func loadKey(fp string) (crypto.PrivKey, error) { - keyData, err := ioutil.ReadFile(filepath.Clean(fp)) + keyData, err := os.ReadFile(filepath.Clean(fp)) if err != nil { return nil, err } diff --git a/protocol/write.go b/protocol/write.go index 5d99a8ab..7a1580cd 100644 --- a/protocol/write.go +++ b/protocol/write.go @@ -95,7 +95,7 @@ func WriteSharedSwapKeyPairToFile(infofile string, keys *mcrypto.PrivateKeyPair, } func setupFile(infofile string) (*os.File, *InfoFileContents, error) { - exists, err := exists(infofile) + exists, err := common.Exists(infofile) if err != nil { return nil, nil, err } @@ -105,7 +105,7 @@ func setupFile(infofile string) (*os.File, *InfoFileContents, error) { contents *InfoFileContents ) if !exists { - err = makeDir(filepath.Dir(infofile)) + err = common.MakeDir(filepath.Dir(infofile)) if err != nil { return nil, nil, fmt.Errorf("failed to make directory %s: %w", filepath.Dir(infofile), err) } @@ -145,25 +145,3 @@ func setupFile(infofile string) (*os.File, *InfoFileContents, error) { return file, contents, nil } - -func makeDir(dir string) error { - if err := os.MkdirAll(dir, os.ModePerm); err != nil { - return err - } - - return nil -} - -// exists returns whether the given file or directory exists -func exists(path string) (bool, error) { - _, err := os.Stat(path) - if err == nil { - return true, nil - } - - if os.IsNotExist(err) { - return false, nil - } - - return false, err -}