diff --git a/go.mod b/go.mod index b0c30da..c904d96 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-log/v2 v2.3.0 github.com/libp2p/go-buffer-pool v0.0.2 - github.com/libp2p/go-libp2p-core v0.8.6 + github.com/libp2p/go-libp2p-core v0.12.0 github.com/multiformats/go-base32 v0.0.3 github.com/multiformats/go-multiaddr v0.3.3 github.com/multiformats/go-multiaddr-fmt v0.1.0 diff --git a/go.sum b/go.sum index 957a39f..3d52b17 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 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 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= @@ -18,7 +17,6 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -40,15 +38,11 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -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= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -90,8 +84,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= -github.com/libp2p/go-libp2p-core v0.8.6 h1:3S8g006qG6Tjpj1JdRK2S+TWc2DJQKX/RG9fdLeiLSU= -github.com/libp2p/go-libp2p-core v0.8.6/go.mod h1:dgHr0l0hIKfWpGpqAMbpo19pen9wJfdCGv51mTmdpmM= +github.com/libp2p/go-libp2p-core v0.12.0 h1:S9bO2lhSJtOvAKo8QAdW9Zp1FEo0XkfXymqvrW6l/I8= +github.com/libp2p/go-libp2p-core v0.12.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw= @@ -165,7 +159,6 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -186,51 +179,36 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -245,12 +223,6 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= @@ -265,6 +237,5 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/metrics.go b/metrics.go index 3f916fb..87a9410 100644 --- a/metrics.go +++ b/metrics.go @@ -7,14 +7,14 @@ import ( "github.com/libp2p/go-libp2p-core/peer" ) -// LatencyEWMASmooting governs the decay of the EWMA (the speed +// LatencyEWMASmoothing governs the decay of the EWMA (the speed // at which it changes). This must be a normalized (0-1) value. // 1 is 100% change, 0 is no change. var LatencyEWMASmoothing = 0.1 type metrics struct { + mutex sync.RWMutex latmap map[peer.ID]time.Duration - latmu sync.RWMutex } func NewMetrics() *metrics { @@ -31,7 +31,7 @@ func (m *metrics) RecordLatency(p peer.ID, next time.Duration) { s = 0.1 // ignore the knob. it's broken. look, it jiggles. } - m.latmu.Lock() + m.mutex.Lock() ewma, found := m.latmap[p] ewmaf := float64(ewma) if !found { @@ -40,14 +40,19 @@ func (m *metrics) RecordLatency(p peer.ID, next time.Duration) { nextf = ((1.0 - s) * ewmaf) + (s * nextf) m.latmap[p] = time.Duration(nextf) } - m.latmu.Unlock() + m.mutex.Unlock() } // LatencyEWMA returns an exponentially-weighted moving avg. // of all measurements of a peer's latency. func (m *metrics) LatencyEWMA(p peer.ID) time.Duration { - m.latmu.RLock() - lat := m.latmap[p] - m.latmu.RUnlock() - return time.Duration(lat) + m.mutex.RLock() + defer m.mutex.RUnlock() + return m.latmap[p] +} + +func (m *metrics) RemovePeer(p peer.ID) { + m.mutex.Lock() + delete(m.latmap, p) + m.mutex.Unlock() } diff --git a/pstoreds/keybook.go b/pstoreds/keybook.go index 892302c..7ee06c8 100644 --- a/pstoreds/keybook.go +++ b/pstoreds/keybook.go @@ -4,13 +4,13 @@ import ( "context" "errors" - base32 "github.com/multiformats/go-base32" + "github.com/multiformats/go-base32" ds "github.com/ipfs/go-datastore" - query "github.com/ipfs/go-datastore/query" + "github.com/ipfs/go-datastore/query" ic "github.com/libp2p/go-libp2p-core/crypto" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peer" pstore "github.com/libp2p/go-libp2p-core/peerstore" ) @@ -33,7 +33,7 @@ func NewKeyBook(_ context.Context, store ds.Datastore, _ Options) (*dsKeyBook, e } func (kb *dsKeyBook) PubKey(p peer.ID) ic.PubKey { - key := kbBase.ChildString(base32.RawStdEncoding.EncodeToString([]byte(p))).Child(pubSuffix) + key := peerToKey(p, pubSuffix) var pk ic.PubKey if value, err := kb.ds.Get(context.TODO(), key); err == nil { @@ -56,8 +56,7 @@ func (kb *dsKeyBook) PubKey(p peer.ID) ic.PubKey { log.Errorf("error when turning extracted pubkey into bytes for peer %s: %s\n", p.Pretty(), err) return nil } - err = kb.ds.Put(context.TODO(), key, pkb) - if err != nil { + if err := kb.ds.Put(context.TODO(), key, pkb); err != nil { log.Errorf("error when adding extracted pubkey to peerstore for peer %s: %s\n", p.Pretty(), err) return nil } @@ -74,24 +73,21 @@ func (kb *dsKeyBook) AddPubKey(p peer.ID, pk ic.PubKey) error { return errors.New("peer ID does not match public key") } - key := kbBase.ChildString(base32.RawStdEncoding.EncodeToString([]byte(p))).Child(pubSuffix) val, err := ic.MarshalPublicKey(pk) if err != nil { log.Errorf("error while converting pubkey byte string for peer %s: %s\n", p.Pretty(), err) return err } - err = kb.ds.Put(context.TODO(), key, val) - if err != nil { + if err := kb.ds.Put(context.TODO(), peerToKey(p, pubSuffix), val); err != nil { log.Errorf("error while updating pubkey in datastore for peer %s: %s\n", p.Pretty(), err) + return err } - return err + return nil } func (kb *dsKeyBook) PrivKey(p peer.ID) ic.PrivKey { - key := kbBase.ChildString(base32.RawStdEncoding.EncodeToString([]byte(p))).Child(privSuffix) - value, err := kb.ds.Get(context.TODO(), key) + value, err := kb.ds.Get(context.TODO(), peerToKey(p, privSuffix)) if err != nil { - log.Errorf("error while fetching privkey from datastore for peer %s: %s\n", p.Pretty(), err) return nil } sk, err := ic.UnmarshalPrivateKey(value) @@ -110,14 +106,12 @@ func (kb *dsKeyBook) AddPrivKey(p peer.ID, sk ic.PrivKey) error { return errors.New("peer ID does not match private key") } - key := kbBase.ChildString(base32.RawStdEncoding.EncodeToString([]byte(p))).Child(privSuffix) val, err := ic.MarshalPrivateKey(sk) if err != nil { log.Errorf("error while converting privkey byte string for peer %s: %s\n", p.Pretty(), err) return err } - err = kb.ds.Put(context.TODO(), key, val) - if err != nil { + if err := kb.ds.Put(context.TODO(), peerToKey(p, privSuffix), val); err != nil { log.Errorf("error while updating privkey in datastore for peer %s: %s\n", p.Pretty(), err) } return err @@ -132,3 +126,12 @@ func (kb *dsKeyBook) PeersWithKeys() peer.IDSlice { } return ids } + +func (kb *dsKeyBook) RemovePeer(p peer.ID) { + kb.ds.Delete(context.TODO(), peerToKey(p, privSuffix)) + kb.ds.Delete(context.TODO(), peerToKey(p, pubSuffix)) +} + +func peerToKey(p peer.ID, suffix ds.Key) ds.Key { + return kbBase.ChildString(base32.RawStdEncoding.EncodeToString([]byte(p))).Child(suffix) +} diff --git a/pstoreds/metadata.go b/pstoreds/metadata.go index 73646fd..0350fa0 100644 --- a/pstoreds/metadata.go +++ b/pstoreds/metadata.go @@ -5,13 +5,13 @@ import ( "context" "encoding/gob" - base32 "github.com/multiformats/go-base32" - - ds "github.com/ipfs/go-datastore" - pool "github.com/libp2p/go-buffer-pool" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peer" pstore "github.com/libp2p/go-libp2p-core/peerstore" + + ds "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/query" + "github.com/multiformats/go-base32" ) // Metadata is stored under the following db key pattern: @@ -71,3 +71,17 @@ func (pm *dsPeerMetadata) Put(p peer.ID, key string, val interface{}) error { } return pm.ds.Put(context.TODO(), k, buf.Bytes()) } + +func (pm *dsPeerMetadata) RemovePeer(p peer.ID) { + result, err := pm.ds.Query(context.TODO(), query.Query{ + Prefix: pmBase.ChildString(base32.RawStdEncoding.EncodeToString([]byte(p))).String(), + KeysOnly: true, + }) + if err != nil { + log.Warnw("querying datastore when removing peer failed", "peer", p, "error", err) + return + } + for entry := range result.Next() { + pm.ds.Delete(context.TODO(), ds.NewKey(entry.Key)) + } +} diff --git a/pstoreds/peerstore.go b/pstoreds/peerstore.go index bbafe62..3cfd20a 100644 --- a/pstoreds/peerstore.go +++ b/pstoreds/peerstore.go @@ -6,14 +6,13 @@ import ( "io" "time" - "github.com/multiformats/go-base32" - - ds "github.com/ipfs/go-datastore" - "github.com/ipfs/go-datastore/query" - "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peerstore" pstore "github.com/libp2p/go-libp2p-peerstore" + + ds "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/query" + "github.com/multiformats/go-base32" ) // Configuration object for the peerstore. @@ -172,3 +171,16 @@ func (ps *pstoreds) PeerInfo(p peer.ID) peer.AddrInfo { Addrs: ps.dsAddrBook.Addrs(p), } } + +// RemovePeer removes entries associated with a peer from: +// * the KeyBook +// * the ProtoBook +// * the PeerMetadata +// * the Metrics +// It DOES NOT remove the peer from the AddrBook. +func (ps *pstoreds) RemovePeer(p peer.ID) { + ps.dsKeyBook.RemovePeer(p) + ps.dsProtoBook.RemovePeer(p) + ps.dsPeerMetadata.RemovePeer(p) + ps.Metrics.RemovePeer(p) +} diff --git a/pstoreds/protobook.go b/pstoreds/protobook.go index d4c0bce..596f575 100644 --- a/pstoreds/protobook.go +++ b/pstoreds/protobook.go @@ -213,3 +213,7 @@ func (pb *dsProtoBook) getProtocolMap(p peer.ID) (map[string]struct{}, error) { return cast, nil } } + +func (pb *dsProtoBook) RemovePeer(p peer.ID) { + pb.meta.RemovePeer(p) +} diff --git a/pstoremem/keybook.go b/pstoremem/keybook.go index 79f2550..387a573 100644 --- a/pstoremem/keybook.go +++ b/pstoremem/keybook.go @@ -5,7 +5,7 @@ import ( "sync" ic "github.com/libp2p/go-libp2p-core/crypto" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peer" pstore "github.com/libp2p/go-libp2p-core/peerstore" ) @@ -18,7 +18,6 @@ type memoryKeyBook struct { var _ pstore.KeyBook = (*memoryKeyBook)(nil) -// noop new, but in the future we may want to do some init work. func NewKeyBook() *memoryKeyBook { return &memoryKeyBook{ pks: map[peer.ID]ic.PubKey{}, @@ -71,9 +70,8 @@ func (mkb *memoryKeyBook) AddPubKey(p peer.ID, pk ic.PubKey) error { func (mkb *memoryKeyBook) PrivKey(p peer.ID) ic.PrivKey { mkb.RLock() - sk := mkb.sks[p] - mkb.RUnlock() - return sk + defer mkb.RUnlock() + return mkb.sks[p] } func (mkb *memoryKeyBook) AddPrivKey(p peer.ID, sk ic.PrivKey) error { @@ -91,3 +89,10 @@ func (mkb *memoryKeyBook) AddPrivKey(p peer.ID, sk ic.PrivKey) error { mkb.Unlock() return nil } + +func (mkb *memoryKeyBook) RemovePeer(p peer.ID) { + mkb.Lock() + delete(mkb.sks, p) + delete(mkb.pks, p) + mkb.Unlock() +} diff --git a/pstoremem/metadata.go b/pstoremem/metadata.go index a8c7d3c..1f9693f 100644 --- a/pstoremem/metadata.go +++ b/pstoremem/metadata.go @@ -62,3 +62,9 @@ func (ps *memoryPeerMetadata) Get(p peer.ID, key string) (interface{}, error) { } return val, nil } + +func (ps *memoryPeerMetadata) RemovePeer(p peer.ID) { + ps.dslock.Lock() + delete(ps.ds, p) + ps.dslock.Unlock() +} diff --git a/pstoremem/peerstore.go b/pstoremem/peerstore.go index dc29149..30b1aa0 100644 --- a/pstoremem/peerstore.go +++ b/pstoremem/peerstore.go @@ -83,3 +83,16 @@ func (ps *pstoremem) PeerInfo(p peer.ID) peer.AddrInfo { Addrs: ps.memoryAddrBook.Addrs(p), } } + +// RemovePeer removes entries associated with a peer from: +// * the KeyBook +// * the ProtoBook +// * the PeerMetadata +// * the Metrics +// It DOES NOT remove the peer from the AddrBook. +func (ps *pstoremem) RemovePeer(p peer.ID) { + ps.memoryKeyBook.RemovePeer(p) + ps.memoryProtoBook.RemovePeer(p) + ps.memoryPeerMetadata.RemovePeer(p) + ps.Metrics.RemovePeer(p) +} diff --git a/pstoremem/protobook.go b/pstoremem/protobook.go index f2fbe50..a95915f 100644 --- a/pstoremem/protobook.go +++ b/pstoremem/protobook.go @@ -199,3 +199,10 @@ func (pb *memoryProtoBook) FirstSupportedProtocol(p peer.ID, protos ...string) ( } return "", nil } + +func (pb *memoryProtoBook) RemovePeer(p peer.ID) { + s := pb.segments.get(p) + s.Lock() + delete(s.protocols, p) + s.Unlock() +} diff --git a/test/keybook_suite.go b/test/keybook_suite.go index 4ecedf5..2774b3d 100644 --- a/test/keybook_suite.go +++ b/test/keybook_suite.go @@ -4,8 +4,10 @@ import ( "sort" "testing" + "github.com/stretchr/testify/require" + ic "github.com/libp2p/go-libp2p-core/crypto" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peer" pt "github.com/libp2p/go-libp2p-core/test" pstore "github.com/libp2p/go-libp2p-core/peerstore" @@ -16,6 +18,7 @@ var keyBookSuite = map[string]func(kb pstore.KeyBook) func(*testing.T){ "AddGetPubKey": testKeyBookPubKey, "PeersWithKeys": testKeyBookPeers, "PubKeyAddedOnRetrieve": testInlinedPubKeyAddedOnRetrieve, + "Delete": testKeyBookDelete, } type KeyBookFactory func() (pstore.KeyBook, func()) @@ -176,6 +179,23 @@ func testInlinedPubKeyAddedOnRetrieve(kb pstore.KeyBook) func(t *testing.T) { } } +func testKeyBookDelete(kb pstore.KeyBook) func(t *testing.T) { + return func(t *testing.T) { + // don't use an ed25519 key here, otherwise the key book might try to derive the pubkey from the peer ID + priv, pub, err := ic.GenerateKeyPair(ic.RSA, 2048) + require.NoError(t, err) + p, err := peer.IDFromPublicKey(pub) + require.NoError(t, err) + require.NoError(t, kb.AddPubKey(p, pub)) + require.NoError(t, kb.AddPrivKey(p, priv)) + require.NotNil(t, kb.PrivKey(p)) + require.NotNil(t, kb.PubKey(p)) + kb.RemovePeer(p) + require.Nil(t, kb.PrivKey(p)) + require.Nil(t, kb.PubKey(p)) + } +} + var keybookBenchmarkSuite = map[string]func(kb pstore.KeyBook) func(*testing.B){ "PubKey": benchmarkPubKey, "AddPubKey": benchmarkAddPubKey, diff --git a/test/peerstore_suite.go b/test/peerstore_suite.go index bdfd9ab..37dc0c7 100644 --- a/test/peerstore_suite.go +++ b/test/peerstore_suite.go @@ -207,114 +207,97 @@ func testAddrStreamDuplicates(ps pstore.Peerstore) func(t *testing.T) { func testPeerstoreProtoStore(ps pstore.Peerstore) func(t *testing.T) { return func(t *testing.T) { - p1, protos := peer.ID("TESTPEER"), []string{"a", "b", "c", "d"} - - err := ps.AddProtocols(p1, protos...) - if err != nil { - t.Fatal(err) - } - - out, err := ps.GetProtocols(p1) - if err != nil { - t.Fatal(err) - } - - if len(out) != len(protos) { - t.Fatal("got wrong number of protocols back") - } - - sort.Strings(out) - for i, p := range protos { - if out[i] != p { - t.Fatal("got wrong protocol") + t.Run("adding and removing protocols", func(t *testing.T) { + p1 := peer.ID("TESTPEER") + protos := []string{"a", "b", "c", "d"} + + require.NoError(t, ps.AddProtocols(p1, protos...)) + out, err := ps.GetProtocols(p1) + require.NoError(t, err) + require.Len(t, out, len(protos), "got wrong number of protocols back") + + sort.Strings(out) + for i, p := range protos { + if out[i] != p { + t.Fatal("got wrong protocol") + } } - } - - supported, err := ps.SupportsProtocols(p1, "q", "w", "a", "y", "b") - if err != nil { - t.Fatal(err) - } - if len(supported) != 2 { - t.Fatal("only expected 2 supported") - } - - if supported[0] != "a" || supported[1] != "b" { - t.Fatal("got wrong supported array: ", supported) - } + supported, err := ps.SupportsProtocols(p1, "q", "w", "a", "y", "b") + require.NoError(t, err) + require.Len(t, supported, 2, "only expected 2 supported") - b, err := ps.FirstSupportedProtocol(p1, "q", "w", "a", "y", "b") - require.NoError(t, err) - require.Equal(t, "a", b) + if supported[0] != "a" || supported[1] != "b" { + t.Fatal("got wrong supported array: ", supported) + } - b, err = ps.FirstSupportedProtocol(p1, "q", "x", "z") - require.NoError(t, err) - require.Empty(t, b) + b, err := ps.FirstSupportedProtocol(p1, "q", "w", "a", "y", "b") + require.NoError(t, err) + require.Equal(t, "a", b) - b, err = ps.FirstSupportedProtocol(p1, "a") - require.NoError(t, err) - require.Equal(t, "a", b) + b, err = ps.FirstSupportedProtocol(p1, "q", "x", "z") + require.NoError(t, err) + require.Empty(t, b) - protos = []string{"other", "yet another", "one more"} - err = ps.SetProtocols(p1, protos...) - if err != nil { - t.Fatal(err) - } + b, err = ps.FirstSupportedProtocol(p1, "a") + require.NoError(t, err) + require.Equal(t, "a", b) - supported, err = ps.SupportsProtocols(p1, "q", "w", "a", "y", "b") - if err != nil { - t.Fatal(err) - } + protos = []string{"other", "yet another", "one more"} + require.NoError(t, ps.SetProtocols(p1, protos...)) - if len(supported) != 0 { - t.Fatal("none of those protocols should have been supported") - } + supported, err = ps.SupportsProtocols(p1, "q", "w", "a", "y", "b") + require.NoError(t, err) + require.Empty(t, supported, "none of those protocols should have been supported") - supported, err = ps.GetProtocols(p1) - if err != nil { - t.Fatal(err) - } - sort.Strings(supported) - sort.Strings(protos) - if !reflect.DeepEqual(supported, protos) { - t.Fatalf("expected previously set protos; expected: %v, have: %v", protos, supported) - } + supported, err = ps.GetProtocols(p1) + require.NoError(t, err) - err = ps.RemoveProtocols(p1, protos[:2]...) - if err != nil { - t.Fatal(err) - } + sort.Strings(supported) + sort.Strings(protos) + if !reflect.DeepEqual(supported, protos) { + t.Fatalf("expected previously set protos; expected: %v, have: %v", protos, supported) + } - supported, err = ps.GetProtocols(p1) - if err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(supported, protos[2:]) { - t.Fatal("expected only one protocol to remain") - } + require.NoError(t, ps.RemoveProtocols(p1, protos[:2]...)) - // test bad peer IDs - badp := peer.ID("") + supported, err = ps.GetProtocols(p1) + require.NoError(t, err) + if !reflect.DeepEqual(supported, protos[2:]) { + t.Fatal("expected only one protocol to remain") + } + }) - err = ps.AddProtocols(badp, protos...) - if err == nil { - t.Fatal("expected error when using a bad peer ID") - } + t.Run("bad peer ID", func(t *testing.T) { + badp := peer.ID("") + require.Error(t, ps.AddProtocols(badp, "proto"), "expected error when using a bad peer ID") - _, err = ps.GetProtocols(badp) - if err == nil || err == pstore.ErrNotFound { - t.Fatal("expected error when using a bad peer ID") - } + if _, err := ps.GetProtocols(badp); err == nil || err == pstore.ErrNotFound { + t.Fatal("expected error when using a bad peer ID") + } - _, err = ps.SupportsProtocols(badp, "q", "w", "a", "y", "b") - if err == nil || err == pstore.ErrNotFound { - t.Fatal("expected error when using a bad peer ID") - } + if _, err := ps.SupportsProtocols(badp, "q", "w", "a", "y", "b"); err == nil || err == pstore.ErrNotFound { + t.Fatal("expected error when using a bad peer ID") + } - err = ps.RemoveProtocols(badp) - if err == nil || err == pstore.ErrNotFound { - t.Fatal("expected error when using a bad peer ID") - } + if err := ps.RemoveProtocols(badp); err == nil || err == pstore.ErrNotFound { + t.Fatal("expected error when using a bad peer ID") + } + }) + + t.Run("removing peer", func(t *testing.T) { + p := peer.ID("foobar") + protos := []string{"a", "b"} + + require.NoError(t, ps.SetProtocols(p, protos...)) + out, err := ps.GetProtocols(p) + require.NoError(t, err) + require.Len(t, out, 2) + ps.RemovePeer(p) + out, err = ps.GetProtocols(p) + require.NoError(t, err) + require.Empty(t, out) + }) } } @@ -354,53 +337,53 @@ func testBasicPeerstore(ps pstore.Peerstore) func(t *testing.T) { func testMetadata(ps pstore.Peerstore) func(t *testing.T) { return func(t *testing.T) { - pids := make([]peer.ID, 10) - for i := range pids { - priv, _, err := crypto.GenerateKeyPair(crypto.RSA, 2048) - if err != nil { - t.Fatal(err) - } - p, err := peer.IDFromPrivateKey(priv) - if err != nil { - t.Fatal(err) - } - pids[i] = p - } - for _, p := range pids { - if err := ps.Put(p, "AgentVersion", "string"); err != nil { - t.Errorf("failed to put %q: %s", "AgentVersion", err) + t.Run("putting and getting", func(t *testing.T) { + pids := make([]peer.ID, 3) + for i := range pids { + priv, _, err := crypto.GenerateKeyPair(crypto.RSA, 2048) + require.NoError(t, err) + p, err := peer.IDFromPrivateKey(priv) + require.NoError(t, err) + pids[i] = p } - if err := ps.Put(p, "bar", 1); err != nil { - t.Errorf("failed to put %q: %s", "bar", err) + for _, p := range pids { + require.NoError(t, ps.Put(p, "AgentVersion", "string"), "failed to put AgentVersion") + require.NoError(t, ps.Put(p, "bar", 1), "failed to put bar") } - } - for _, p := range pids { - v, err := ps.Get(p, "AgentVersion") - if err != nil { - t.Errorf("failed to find %q: %s", "AgentVersion", err) - continue - } - if v != "string" { - t.Errorf("expected %q, got %q", "string", p) - continue + for _, p := range pids { + v, err := ps.Get(p, "AgentVersion") + require.NoError(t, err) + require.Equal(t, v, "string") + + v, err = ps.Get(p, "bar") + require.NoError(t, err) + require.Equal(t, v, 1) } + }) - v, err = ps.Get(p, "bar") - if err != nil { - t.Errorf("failed to find %q: %s", "bar", err) - continue + t.Run("bad peer ID", func(t *testing.T) { + require.Error(t, ps.Put("", "foobar", "thing"), "expected error for bad peer ID") + if _, err := ps.Get("", "foobar"); err == nil || err == pstore.ErrNotFound { + t.Fatalf("expected error for bad peer ID") } - if v != 1 { - t.Errorf("expected %q, got %v", 1, v) - continue - } - } - if err := ps.Put("", "foobar", "thing"); err == nil { - t.Errorf("expected error for bad peer ID") - } - if _, err := ps.Get("", "foobar"); err == nil || err == pstore.ErrNotFound { - t.Errorf("expected error for bad peer ID") - } + }) + + t.Run("removing a peer", func(t *testing.T) { + p := peer.ID("foo") + otherP := peer.ID("foobar") + require.NoError(t, ps.Put(otherP, "AgentVersion", "v1")) + require.NoError(t, ps.Put(p, "AgentVersion", "v1")) + require.NoError(t, ps.Put(p, "bar", 1)) + ps.RemovePeer(p) + _, err := ps.Get(p, "AgentVersion") + require.ErrorIs(t, err, pstore.ErrNotFound) + _, err = ps.Get(p, "bar") + require.ErrorIs(t, err, pstore.ErrNotFound) + // make sure that entries for otherP were not deleted + val, err := ps.Get(otherP, "AgentVersion") + require.NoError(t, err) + require.Equal(t, val, "v1") + }) } }