Certified addresses (#98)

This commit is contained in:
Yusef Napora 2020-03-06 07:07:36 -05:00 committed by GitHub
parent f65b2b42ac
commit 59abcf549d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1023 additions and 180 deletions

5
go.mod
View File

@ -8,14 +8,15 @@ require (
github.com/ipfs/go-ds-leveldb v0.4.1
github.com/ipfs/go-log v1.0.2
github.com/libp2p/go-buffer-pool v0.0.2
github.com/libp2p/go-libp2p-core v0.3.0
github.com/libp2p/go-libp2p-core v0.4.0
github.com/multiformats/go-base32 v0.0.3
github.com/multiformats/go-multiaddr v0.2.0
github.com/multiformats/go-multiaddr v0.2.1
github.com/multiformats/go-multiaddr-fmt v0.1.0
github.com/multiformats/go-multiaddr-net v0.1.2
github.com/multiformats/go-multihash v0.0.13
github.com/pkg/errors v0.9.1
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 // indirect
)
go 1.13

57
go.sum
View File

@ -20,7 +20,6 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -32,7 +31,6 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
@ -47,23 +45,16 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
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=
github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU=
github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU=
github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc=
github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/ipfs/go-cid v0.0.3 h1:UIAh32wymBpStoe83YCzwVQQ5Oy/H0FdxvUS6DJDzms=
github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
github.com/ipfs/go-cid v0.0.5 h1:o0Ix8e/ql7Zb5UVUJEUfjsWCIY8t48++9lR8qi6oiJU=
github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog=
github.com/ipfs/go-datastore v0.4.0/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
github.com/ipfs/go-datastore v0.4.1 h1:W4ZfzyhNi3xmuU5dQhjfuRn/wFuqEE1KnOmmQiOevEY=
github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
github.com/ipfs/go-datastore v0.4.2 h1:h8/n7WPzhp239kkLws+epN3Ic7YtcBPgcaXfEfdVDWM=
github.com/ipfs/go-datastore v0.4.2/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
github.com/ipfs/go-datastore v0.4.4 h1:rjvQ9+muFaJ+QZ7dN5B1MSDNQ0JVZKkkES/rMZmA8X8=
github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
github.com/ipfs/go-ds-badger v0.2.1 h1:RsC9DDlwFhFdfT+s2PeC8joxbSp2YMufK8w/RBOxKtk=
@ -71,14 +62,12 @@ github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9Dr
github.com/ipfs/go-ds-leveldb v0.4.1 h1:zaoLcP8zs4Aj9k8fA4cowyOyNBIvy9Dnt6hf7mHRY7s=
github.com/ipfs/go-ds-leveldb v0.4.1/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s=
github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc=
github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM=
github.com/ipfs/go-log v1.0.2 h1:s19ZwJxH8rPWzypjcDpqPLIyV7BnbLqvpli3iZoqYK0=
github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk=
github.com/ipfs/go-log/v2 v2.0.2 h1:xguurydRdfKMJjKyxNXNU8lYP0VZH1NUwJRwUorjuEw=
github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0=
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw=
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10=
github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
@ -99,56 +88,45 @@ 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.3.0 h1:F7PqduvrztDtFsAa/bcheQ3azmNo+Nq7m8hQY5GiUW8=
github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw=
github.com/libp2p/go-libp2p-core v0.4.0 h1:LjZJP/Yy4q8kc724izkYQ9v6YkAmkKCOaE5jLv/NZRo=
github.com/libp2p/go-libp2p-core v0.4.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0=
github.com/libp2p/go-openssl v0.0.4 h1:d27YZvLoTyMhIN4njrkr8zMDOM4lfpHIp6A+TK9fovg=
github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ=
github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78=
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
github.com/multiformats/go-multiaddr v0.1.1 h1:rVAztJYMhCQ7vEFr8FvxW3mS+HF2eY/oPbOMeS0ZDnE=
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
github.com/multiformats/go-multiaddr v0.2.0 h1:lR52sFwcTCuQb6bTfnXF6zA2XfyYvyd+5a9qECv/J90=
github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4=
github.com/multiformats/go-multiaddr v0.2.1 h1:SgG/cw5vqyB5QQe5FPe2TqggU9WtrA9X4nZw7LlVqOI=
github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE=
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
github.com/multiformats/go-multiaddr-net v0.1.2 h1:P7zcBH9FRETdPkDrylcXVjQLQ2t1JQtNItZULWNWgeg=
github.com/multiformats/go-multiaddr-net v0.1.2/go.mod h1:QsWt3XK/3hwvNxZJp92iMQKME1qHfpYmyIjFVsSOY6Y=
github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA=
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ=
github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U=
github.com/multiformats/go-multihash v0.0.8 h1:wrYcW5yxSi3dU07n5jnuS5PrNwyHy0zRHGVoUugWvXg=
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
github.com/multiformats/go-multihash v0.0.10 h1:lMoNbh2Ssd9PUF74Nz008KGzGPlfeV6wH3rit5IIGCM=
github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc=
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
github.com/multiformats/go-varint v0.0.1 h1:TR/0rdQtnNxuN2IhiB639xC3tWM4IUi7DkTBVTdGW/M=
github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg=
github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -156,12 +134,10 @@ github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -169,7 +145,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/smola/gocompat v0.2.0 h1:6b1oIMlUXIpz//VKEDzPVBK8KG7beVwmHIUEBIs/Pns=
github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
@ -185,7 +160,6 @@ github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@ -194,11 +168,10 @@ github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpP
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc=
github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo=
github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM=
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
@ -208,7 +181,6 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -220,15 +192,12 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r
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-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo=
golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/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 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
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=
@ -237,15 +206,12 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h
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-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
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 h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@ -255,7 +221,6 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/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 h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
@ -265,7 +230,6 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn
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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
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=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -275,7 +239,6 @@ gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVY
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -29,6 +29,8 @@ type AddrBookRecord struct {
Id *ProtoPeerID `protobuf:"bytes,1,opt,name=id,proto3,customtype=ProtoPeerID" json:"id,omitempty"`
// The multiaddresses. This is a sorted list where element 0 expires the soonest.
Addrs []*AddrBookRecord_AddrEntry `protobuf:"bytes,2,rep,name=addrs,proto3" json:"addrs,omitempty"`
// The most recently received signed PeerRecord.
CertifiedRecord *AddrBookRecord_CertifiedRecord `protobuf:"bytes,3,opt,name=certified_record,json=certifiedRecord,proto3" json:"certified_record,omitempty"`
}
func (m *AddrBookRecord) Reset() { *m = AddrBookRecord{} }
@ -71,6 +73,13 @@ func (m *AddrBookRecord) GetAddrs() []*AddrBookRecord_AddrEntry {
return nil
}
func (m *AddrBookRecord) GetCertifiedRecord() *AddrBookRecord_CertifiedRecord {
if m != nil {
return m.CertifiedRecord
}
return nil
}
// AddrEntry represents a single multiaddress.
type AddrBookRecord_AddrEntry struct {
Addr *ProtoAddr `protobuf:"bytes,1,opt,name=addr,proto3,customtype=ProtoAddr" json:"addr,omitempty"`
@ -127,31 +136,93 @@ func (m *AddrBookRecord_AddrEntry) GetTtl() int64 {
return 0
}
// CertifiedRecord contains a serialized signed PeerRecord used to
// populate the signedAddrs list.
type AddrBookRecord_CertifiedRecord struct {
// The Seq counter from the signed PeerRecord envelope
Seq uint64 `protobuf:"varint,1,opt,name=seq,proto3" json:"seq,omitempty"`
// The serialized bytes of the SignedEnvelope containing the PeerRecord.
Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3" json:"raw,omitempty"`
}
func (m *AddrBookRecord_CertifiedRecord) Reset() { *m = AddrBookRecord_CertifiedRecord{} }
func (m *AddrBookRecord_CertifiedRecord) String() string { return proto.CompactTextString(m) }
func (*AddrBookRecord_CertifiedRecord) ProtoMessage() {}
func (*AddrBookRecord_CertifiedRecord) Descriptor() ([]byte, []int) {
return fileDescriptor_f96873690e08a98f, []int{0, 1}
}
func (m *AddrBookRecord_CertifiedRecord) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *AddrBookRecord_CertifiedRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_AddrBookRecord_CertifiedRecord.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *AddrBookRecord_CertifiedRecord) XXX_Merge(src proto.Message) {
xxx_messageInfo_AddrBookRecord_CertifiedRecord.Merge(m, src)
}
func (m *AddrBookRecord_CertifiedRecord) XXX_Size() int {
return m.Size()
}
func (m *AddrBookRecord_CertifiedRecord) XXX_DiscardUnknown() {
xxx_messageInfo_AddrBookRecord_CertifiedRecord.DiscardUnknown(m)
}
var xxx_messageInfo_AddrBookRecord_CertifiedRecord proto.InternalMessageInfo
func (m *AddrBookRecord_CertifiedRecord) GetSeq() uint64 {
if m != nil {
return m.Seq
}
return 0
}
func (m *AddrBookRecord_CertifiedRecord) GetRaw() []byte {
if m != nil {
return m.Raw
}
return nil
}
func init() {
proto.RegisterType((*AddrBookRecord)(nil), "pstore.pb.AddrBookRecord")
proto.RegisterType((*AddrBookRecord_AddrEntry)(nil), "pstore.pb.AddrBookRecord.AddrEntry")
proto.RegisterType((*AddrBookRecord_CertifiedRecord)(nil), "pstore.pb.AddrBookRecord.CertifiedRecord")
}
func init() { proto.RegisterFile("pstore.proto", fileDescriptor_f96873690e08a98f) }
var fileDescriptor_f96873690e08a98f = []byte{
// 255 bytes of a gzipped FileDescriptorProto
// 322 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x28, 0x2e, 0xc9,
0x2f, 0x4a, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x84, 0xf1, 0x92, 0xa4, 0x74, 0xd3,
0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0xd3, 0xf3, 0xf5, 0xc1,
0x2a, 0x92, 0x4a, 0xd3, 0xc0, 0x3c, 0x30, 0x07, 0xcc, 0x82, 0xe8, 0x54, 0x3a, 0xc6, 0xc8, 0xc5,
0x2a, 0x92, 0x4a, 0xd3, 0xc0, 0x3c, 0x30, 0x07, 0xcc, 0x82, 0xe8, 0x54, 0xba, 0xcc, 0xc4, 0xc5,
0xe7, 0x98, 0x92, 0x52, 0xe4, 0x94, 0x9f, 0x9f, 0x1d, 0x94, 0x9a, 0x9c, 0x5f, 0x94, 0x22, 0x24,
0xcf, 0xc5, 0x94, 0x99, 0x22, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0xe3, 0xc4, 0x7f, 0xeb, 0x9e, 0x3c,
0x77, 0x00, 0x48, 0x65, 0x40, 0x6a, 0x6a, 0x91, 0xa7, 0x4b, 0x10, 0x53, 0x66, 0x8a, 0x90, 0x25,
0x17, 0x6b, 0x62, 0x4a, 0x4a, 0x51, 0xb1, 0x04, 0x93, 0x02, 0xb3, 0x06, 0xb7, 0x91, 0xb2, 0x1e,
0xdc, 0x76, 0x3d, 0x54, 0xa3, 0xc0, 0x5c, 0xd7, 0xbc, 0x92, 0xa2, 0xca, 0x20, 0x88, 0x0e, 0xa9,
0x08, 0x2e, 0x4e, 0xb8, 0x98, 0x90, 0x22, 0x17, 0x0b, 0x48, 0x14, 0x6a, 0x15, 0xef, 0xad, 0x7b,
0xf2, 0x9c, 0x60, 0xab, 0x40, 0x2a, 0x82, 0xc0, 0x52, 0x42, 0x62, 0x5c, 0x6c, 0xa9, 0x15, 0x05,
0x99, 0x45, 0x95, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xcc, 0x41, 0x50, 0x9e, 0x90, 0x00, 0x17, 0x73,
0x49, 0x49, 0x8e, 0x04, 0x33, 0x58, 0x10, 0xc4, 0x74, 0x52, 0xf8, 0xf1, 0x50, 0x8e, 0xf1, 0xc0,
0x23, 0x39, 0xc6, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71,
0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x48, 0x62, 0x03, 0xfb,
0xd8, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xb1, 0x1a, 0x16, 0x43, 0x3b, 0x01, 0x00, 0x00,
0xdc, 0x76, 0x3d, 0x54, 0xa3, 0xc0, 0x5c, 0xd7, 0xbc, 0x92, 0xa2, 0xca, 0x20, 0x88, 0x0e, 0xa1,
0x10, 0x2e, 0x81, 0xe4, 0xd4, 0xa2, 0x92, 0xcc, 0xb4, 0xcc, 0xd4, 0x94, 0xf8, 0x22, 0xb0, 0x22,
0x09, 0x66, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x4d, 0xdc, 0xa6, 0x38, 0xc3, 0x74, 0x40, 0xf8, 0x41,
0xfc, 0xc9, 0xa8, 0x02, 0x52, 0x11, 0x5c, 0x9c, 0x70, 0x9b, 0x84, 0x14, 0xb9, 0x58, 0x40, 0x76,
0x41, 0x3d, 0xc0, 0x7b, 0xeb, 0x9e, 0x3c, 0x27, 0xd8, 0x03, 0x20, 0x15, 0x41, 0x60, 0x29, 0x21,
0x31, 0x2e, 0xb6, 0xd4, 0x8a, 0x82, 0xcc, 0xa2, 0x4a, 0x09, 0x26, 0x05, 0x46, 0x0d, 0xe6, 0x20,
0x28, 0x4f, 0x48, 0x80, 0x8b, 0xb9, 0xa4, 0x24, 0x07, 0xec, 0x20, 0xe6, 0x20, 0x10, 0x53, 0xca,
0x94, 0x8b, 0x1f, 0xcd, 0x76, 0x90, 0xa2, 0xe2, 0xd4, 0x42, 0xb0, 0xf1, 0x2c, 0x41, 0x20, 0x26,
0x48, 0xa4, 0x28, 0xb1, 0x1c, 0x6c, 0x16, 0x4f, 0x10, 0x88, 0xe9, 0xa4, 0xf0, 0xe3, 0xa1, 0x1c,
0xe3, 0x81, 0x47, 0x72, 0x8c, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91,
0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x90, 0xc4,
0x06, 0x0e, 0x7e, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x29, 0xcd, 0xe8, 0xd4, 0xc8, 0x01,
0x00, 0x00,
}
func (m *AddrBookRecord) Marshal() (dAtA []byte, err error) {
@ -174,6 +245,18 @@ func (m *AddrBookRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.CertifiedRecord != nil {
{
size, err := m.CertifiedRecord.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintPstore(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
if len(m.Addrs) > 0 {
for iNdEx := len(m.Addrs) - 1; iNdEx >= 0; iNdEx-- {
{
@ -248,6 +331,41 @@ func (m *AddrBookRecord_AddrEntry) MarshalToSizedBuffer(dAtA []byte) (int, error
return len(dAtA) - i, nil
}
func (m *AddrBookRecord_CertifiedRecord) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *AddrBookRecord_CertifiedRecord) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *AddrBookRecord_CertifiedRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Raw) > 0 {
i -= len(m.Raw)
copy(dAtA[i:], m.Raw)
i = encodeVarintPstore(dAtA, i, uint64(len(m.Raw)))
i--
dAtA[i] = 0x12
}
if m.Seq != 0 {
i = encodeVarintPstore(dAtA, i, uint64(m.Seq))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarintPstore(dAtA []byte, offset int, v uint64) int {
offset -= sovPstore(v)
base := offset
@ -269,6 +387,9 @@ func NewPopulatedAddrBookRecord(r randyPstore, easy bool) *AddrBookRecord {
this.Addrs[i] = NewPopulatedAddrBookRecord_AddrEntry(r, easy)
}
}
if r.Intn(5) != 0 {
this.CertifiedRecord = NewPopulatedAddrBookRecord_CertifiedRecord(r, easy)
}
if !easy && r.Intn(10) != 0 {
}
return this
@ -290,6 +411,19 @@ func NewPopulatedAddrBookRecord_AddrEntry(r randyPstore, easy bool) *AddrBookRec
return this
}
func NewPopulatedAddrBookRecord_CertifiedRecord(r randyPstore, easy bool) *AddrBookRecord_CertifiedRecord {
this := &AddrBookRecord_CertifiedRecord{}
this.Seq = uint64(uint64(r.Uint32()))
v2 := r.Intn(100)
this.Raw = make([]byte, v2)
for i := 0; i < v2; i++ {
this.Raw[i] = byte(r.Intn(256))
}
if !easy && r.Intn(10) != 0 {
}
return this
}
type randyPstore interface {
Float32() float32
Float64() float64
@ -309,9 +443,9 @@ func randUTF8RunePstore(r randyPstore) rune {
return rune(ru + 61)
}
func randStringPstore(r randyPstore) string {
v2 := r.Intn(100)
tmps := make([]rune, v2)
for i := 0; i < v2; i++ {
v3 := r.Intn(100)
tmps := make([]rune, v3)
for i := 0; i < v3; i++ {
tmps[i] = randUTF8RunePstore(r)
}
return string(tmps)
@ -333,11 +467,11 @@ func randFieldPstore(dAtA []byte, r randyPstore, fieldNumber int, wire int) []by
switch wire {
case 0:
dAtA = encodeVarintPopulatePstore(dAtA, uint64(key))
v3 := r.Int63()
v4 := r.Int63()
if r.Intn(2) == 0 {
v3 *= -1
v4 *= -1
}
dAtA = encodeVarintPopulatePstore(dAtA, uint64(v3))
dAtA = encodeVarintPopulatePstore(dAtA, uint64(v4))
case 1:
dAtA = encodeVarintPopulatePstore(dAtA, uint64(key))
dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
@ -378,6 +512,10 @@ func (m *AddrBookRecord) Size() (n int) {
n += 1 + l + sovPstore(uint64(l))
}
}
if m.CertifiedRecord != nil {
l = m.CertifiedRecord.Size()
n += 1 + l + sovPstore(uint64(l))
}
return n
}
@ -400,6 +538,22 @@ func (m *AddrBookRecord_AddrEntry) Size() (n int) {
return n
}
func (m *AddrBookRecord_CertifiedRecord) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Seq != 0 {
n += 1 + sovPstore(uint64(m.Seq))
}
l = len(m.Raw)
if l > 0 {
n += 1 + l + sovPstore(uint64(l))
}
return n
}
func sovPstore(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@ -504,6 +658,42 @@ func (m *AddrBookRecord) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field CertifiedRecord", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPstore
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthPstore
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthPstore
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.CertifiedRecord == nil {
m.CertifiedRecord = &AddrBookRecord_CertifiedRecord{}
}
if err := m.CertifiedRecord.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPstore(dAtA[iNdEx:])
@ -654,6 +844,112 @@ func (m *AddrBookRecord_AddrEntry) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *AddrBookRecord_CertifiedRecord) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPstore
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: CertifiedRecord: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: CertifiedRecord: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Seq", wireType)
}
m.Seq = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPstore
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Seq |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Raw", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPstore
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthPstore
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthPstore
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Raw = append(m.Raw[:0], dAtA[iNdEx:postIndex]...)
if m.Raw == nil {
m.Raw = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPstore(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthPstore
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthPstore
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipPstore(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0

View File

@ -14,6 +14,9 @@ message AddrBookRecord {
// The multiaddresses. This is a sorted list where element 0 expires the soonest.
repeated AddrEntry addrs = 2;
// The most recently received signed PeerRecord.
CertifiedRecord certified_record = 3;
// AddrEntry represents a single multiaddress.
message AddrEntry {
bytes addr = 1 [(gogoproto.customtype) = "ProtoAddr"];
@ -24,4 +27,14 @@ message AddrBookRecord {
// The original TTL of this address.
int64 ttl = 3;
}
// CertifiedRecord contains a serialized signed PeerRecord used to
// populate the signedAddrs list.
message CertifiedRecord {
// The Seq counter from the signed PeerRecord envelope
uint64 seq = 1;
// The serialized bytes of the SignedEnvelope containing the PeerRecord.
bytes raw = 2;
}
}

View File

@ -98,6 +98,46 @@ func BenchmarkAddrBookRecord_AddrEntryProtoUnmarshal(b *testing.B) {
b.SetBytes(int64(total / b.N))
}
func BenchmarkAddrBookRecord_CertifiedRecordProtoMarshal(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
pops := make([]*AddrBookRecord_CertifiedRecord, 10000)
for i := 0; i < 10000; i++ {
pops[i] = NewPopulatedAddrBookRecord_CertifiedRecord(popr, false)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
dAtA, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000])
if err != nil {
panic(err)
}
total += len(dAtA)
}
b.SetBytes(int64(total / b.N))
}
func BenchmarkAddrBookRecord_CertifiedRecordProtoUnmarshal(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
datas := make([][]byte, 10000)
for i := 0; i < 10000; i++ {
dAtA, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedAddrBookRecord_CertifiedRecord(popr, false))
if err != nil {
panic(err)
}
datas[i] = dAtA
}
msg := &AddrBookRecord_CertifiedRecord{}
b.ResetTimer()
for i := 0; i < b.N; i++ {
total += len(datas[i%10000])
if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil {
panic(err)
}
}
b.SetBytes(int64(total / b.N))
}
func BenchmarkAddrBookRecordSize(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
@ -126,4 +166,18 @@ func BenchmarkAddrBookRecord_AddrEntrySize(b *testing.B) {
b.SetBytes(int64(total / b.N))
}
func BenchmarkAddrBookRecord_CertifiedRecordSize(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
pops := make([]*AddrBookRecord_CertifiedRecord, 1000)
for i := 0; i < 1000; i++ {
pops[i] = NewPopulatedAddrBookRecord_CertifiedRecord(popr, false)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
total += pops[i%1000].Size()
}
b.SetBytes(int64(total / b.N))
}
//These tests are generated by github.com/gogo/protobuf/plugin/testgen

View File

@ -21,6 +21,7 @@ type peerstore struct {
// NewPeerstore creates a data structure that stores peer data, backed by the
// supplied implementations of KeyBook, AddrBook and PeerMetadata.
// Deprecated: use pstoreds.NewPeerstore or peerstoremem.NewPeerstore instead.
func NewPeerstore(kb pstore.KeyBook, ab pstore.AddrBook, pb pstore.ProtoBook, md pstore.PeerMetadata) pstore.Peerstore {
return &peerstore{
KeyBook: kb,

View File

@ -3,20 +3,21 @@ package pstoreds
import (
"context"
"fmt"
"github.com/libp2p/go-libp2p-core/record"
"sort"
"sync"
"time"
ds "github.com/ipfs/go-datastore"
query "github.com/ipfs/go-datastore/query"
"github.com/ipfs/go-datastore/query"
logging "github.com/ipfs/go-log"
peer "github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/peer"
pstore "github.com/libp2p/go-libp2p-core/peerstore"
pb "github.com/libp2p/go-libp2p-peerstore/pb"
pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem"
"github.com/libp2p/go-libp2p-peerstore/pstoremem"
lru "github.com/hashicorp/golang-lru"
"github.com/hashicorp/golang-lru"
b32 "github.com/multiformats/go-base32"
ma "github.com/multiformats/go-multiaddr"
)
@ -47,6 +48,7 @@ type addrsRecord struct {
// marked for deletion, in which case we call ds.Delete. To be called within a lock.
func (r *addrsRecord) flush(write ds.Write) (err error) {
key := addrBookBase.ChildString(b32.RawStdEncoding.EncodeToString([]byte(r.Id.ID)))
if len(r.Addrs) == 0 {
if err = write.Delete(key); err == nil {
r.dirty = false
@ -83,37 +85,49 @@ func (r *addrsRecord) flush(write ds.Write) (err error) {
// If the return value is true, the caller should perform a flush immediately to sync the record with the store.
func (r *addrsRecord) clean() (chgd bool) {
now := time.Now().Unix()
if !r.dirty && len(r.Addrs) > 0 && r.Addrs[0].Expiry > now {
addrsLen := len(r.Addrs)
if !r.dirty && !r.hasExpiredAddrs(now) {
// record is not dirty, and we have no expired entries to purge.
return false
}
if len(r.Addrs) == 0 {
if addrsLen == 0 {
// this is a ghost record; let's signal it has to be written.
// flush() will take care of doing the deletion.
return true
}
if r.dirty && len(r.Addrs) > 1 {
// the record has been modified, so it may need resorting.
// we keep addresses sorted by expiration, where 0 is the soonest expiring.
if r.dirty && addrsLen > 1 {
sort.Slice(r.Addrs, func(i, j int) bool {
return r.Addrs[i].Expiry < r.Addrs[j].Expiry
})
}
r.Addrs = removeExpired(r.Addrs, now)
return r.dirty || len(r.Addrs) != addrsLen
}
func (r *addrsRecord) hasExpiredAddrs(now int64) bool {
if len(r.Addrs) > 0 && r.Addrs[0].Expiry <= now {
return true
}
return false
}
func removeExpired(entries []*pb.AddrBookRecord_AddrEntry, now int64) []*pb.AddrBookRecord_AddrEntry {
// since addresses are sorted by expiration, we find the first
// survivor and split the slice on its index.
pivot := -1
for i, addr := range r.Addrs {
for i, addr := range entries {
if addr.Expiry > now {
break
}
pivot = i
}
r.Addrs = r.Addrs[pivot+1:]
return r.dirty || pivot >= 0
return entries[pivot+1:]
}
// dsAddrBook is an address book backed by a Datastore with a GC procedure to purge expired entries. It uses an
@ -133,6 +147,7 @@ type dsAddrBook struct {
}
var _ pstore.AddrBook = (*dsAddrBook)(nil)
var _ pstore.CertifiedAddrBook = (*dsAddrBook)(nil)
// NewAddrBook initializes a new datastore-backed address book. It serves as a drop-in replacement for pstoremem
// (memory-backed peerstore), and works with any datastore implementing the ds.Batching interface.
@ -240,7 +255,91 @@ func (ab *dsAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duratio
return
}
addrs = cleanAddrs(addrs)
ab.setAddrs(p, addrs, ttl, ttlExtend)
ab.setAddrs(p, addrs, ttl, ttlExtend, false)
}
// ConsumePeerRecord adds addresses from a signed peer.PeerRecord (contained in
// a record.Envelope), which will expire after the given TTL.
// See https://godoc.org/github.com/libp2p/go-libp2p-core/peerstore#CertifiedAddrBook for more details.
func (ab *dsAddrBook) ConsumePeerRecord(recordEnvelope *record.Envelope, ttl time.Duration) (bool, error) {
r, err := recordEnvelope.Record()
if err != nil {
return false, err
}
rec, ok := r.(*peer.PeerRecord)
if !ok {
return false, fmt.Errorf("envelope did not contain PeerRecord")
}
if !rec.PeerID.MatchesPublicKey(recordEnvelope.PublicKey) {
return false, fmt.Errorf("signing key does not match PeerID in PeerRecord")
}
// ensure that the seq number from envelope is > any previously received seq no
if ab.latestPeerRecordSeq(rec.PeerID) >= rec.Seq {
return false, nil
}
addrs := cleanAddrs(rec.Addrs)
err = ab.setAddrs(rec.PeerID, addrs, ttl, ttlExtend, true)
if err != nil {
return false, err
}
err = ab.storeSignedPeerRecord(rec.PeerID, recordEnvelope, rec)
if err != nil {
return false, err
}
return true, nil
}
func (ab *dsAddrBook) latestPeerRecordSeq(p peer.ID) uint64 {
pr, err := ab.loadRecord(p, true, false)
if err != nil || len(pr.Addrs) == 0 || pr.CertifiedRecord == nil || len(pr.CertifiedRecord.Raw) == 0 {
return 0
}
return pr.CertifiedRecord.Seq
}
func (ab *dsAddrBook) storeSignedPeerRecord(p peer.ID, envelope *record.Envelope, rec *peer.PeerRecord) error {
envelopeBytes, err := envelope.Marshal()
if err != nil {
return err
}
// reload record and add routing state
// this has to be done after we add the addresses, since if
// we try to flush a datastore record with no addresses,
// it will just get deleted
pr, err := ab.loadRecord(p, true, false)
if err != nil {
return err
}
pr.CertifiedRecord = &pb.AddrBookRecord_CertifiedRecord{
Seq: rec.Seq,
Raw: envelopeBytes,
}
pr.dirty = true
err = pr.flush(ab.ds)
return err
}
// GetPeerRecord returns a record.Envelope containing a peer.PeerRecord for the
// given peer id, if one exists.
// Returns nil if no signed PeerRecord exists for the peer.
func (ab *dsAddrBook) GetPeerRecord(p peer.ID) *record.Envelope {
pr, err := ab.loadRecord(p, true, false)
if err != nil {
log.Errorf("unable to load record for peer %s: %v", p.Pretty(), err)
return nil
}
if pr.CertifiedRecord == nil || len(pr.CertifiedRecord.Raw) == 0 || len(pr.Addrs) == 0 {
return nil
}
state, _, err := record.ConsumeEnvelope(pr.CertifiedRecord.Raw, peer.PeerRecordEnvelopeDomain)
if err != nil {
log.Errorf("error unmarshaling stored signed peer record for peer %s: %v", p.Pretty(), err)
return nil
}
return state
}
// SetAddr will add or update the TTL of an address in the AddrBook.
@ -255,7 +354,7 @@ func (ab *dsAddrBook) SetAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duratio
ab.deleteAddrs(p, addrs)
return
}
ab.setAddrs(p, addrs, ttl, ttlOverride)
ab.setAddrs(p, addrs, ttl, ttlOverride, false)
}
// UpdateAddrs will update any addresses for a given peer and TTL combination to
@ -295,9 +394,9 @@ func (ab *dsAddrBook) Addrs(p peer.ID) []ma.Multiaddr {
pr.RLock()
defer pr.RUnlock()
addrs := make([]ma.Multiaddr, 0, len(pr.Addrs))
for _, a := range pr.Addrs {
addrs = append(addrs, a.Addr)
addrs := make([]ma.Multiaddr, len(pr.Addrs))
for i, a := range pr.Addrs {
addrs[i] = a.Addr
}
return addrs
}
@ -330,7 +429,7 @@ func (ab *dsAddrBook) ClearAddrs(p peer.ID) {
}
}
func (ab *dsAddrBook) setAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration, mode ttlWriteMode) (err error) {
func (ab *dsAddrBook) setAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration, mode ttlWriteMode, signed bool) (err error) {
pr, err := ab.loadRecord(p, true, false)
if err != nil {
return fmt.Errorf("failed to load peerstore entry for peer %v while setting addrs, err: %v", p, err)
@ -339,14 +438,19 @@ func (ab *dsAddrBook) setAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duratio
pr.Lock()
defer pr.Unlock()
newExp := time.Now().Add(ttl).Unix()
existed := make([]bool, len(addrs)) // keeps track of which addrs we found.
// // if we have a signed PeerRecord, ignore attempts to add unsigned addrs
// if !signed && pr.CertifiedRecord != nil {
// return nil
// }
Outer:
for i, incoming := range addrs {
for _, have := range pr.Addrs {
newExp := time.Now().Add(ttl).Unix()
// TODO this is very inefficient O(m*n); we could build a map to use as an
// index, and test against it. That would turn it into O(m+n). This code
// will be refactored entirely anyway, and it's not being used by users
// (that we know of); so OK to keep it for now.
updateExisting := func(entryList []*pb.AddrBookRecord_AddrEntry, incoming ma.Multiaddr) *pb.AddrBookRecord_AddrEntry {
for _, have := range entryList {
if incoming.Equal(have.Addr) {
existed[i] = true
switch mode {
case ttlOverride:
have.Ttl = int64(ttl)
@ -361,38 +465,73 @@ Outer:
default:
panic("BUG: unimplemented ttl mode")
}
// we found the address, and addresses cannot be duplicate,
// so let's move on to the next.
continue Outer
return have
}
}
return nil
}
// add addresses we didn't hold.
var added []*pb.AddrBookRecord_AddrEntry
for i, e := range existed {
if e {
continue
var entries []*pb.AddrBookRecord_AddrEntry
for _, incoming := range addrs {
existingEntry := updateExisting(pr.Addrs, incoming)
if existingEntry == nil {
// if signed {
// entries = append(entries, existingEntry)
// }
// } else {
// new addr, add & broadcast
entry := &pb.AddrBookRecord_AddrEntry{
Addr: &pb.ProtoAddr{Multiaddr: incoming},
Ttl: int64(ttl),
Expiry: newExp,
}
entries = append(entries, entry)
// note: there's a minor chance that writing the record will fail, in which case we would've broadcast
// the addresses without persisting them. This is very unlikely and not much of an issue.
ab.subsManager.BroadcastAddr(p, incoming)
}
addr := addrs[i]
entry := &pb.AddrBookRecord_AddrEntry{
Addr: &pb.ProtoAddr{Multiaddr: addr},
Ttl: int64(ttl),
Expiry: newExp,
}
added = append(added, entry)
// note: there's a minor chance that writing the record will fail, in which case we would've broadcast
// the addresses without persisting them. This is very unlikely and not much of an issue.
ab.subsManager.BroadcastAddr(p, addr)
}
pr.Addrs = append(pr.Addrs, added...)
// if signed {
// // when adding signed addrs, we want to keep _only_ the incoming addrs
// pr.Addrs = entries
// } else {
pr.Addrs = append(pr.Addrs, entries...)
// }
pr.dirty = true
pr.clean()
return pr.flush(ab.ds)
}
// deletes addresses in place, avoiding copies until we encounter the first deletion.
// does not preserve order, but entries are re-sorted before flushing to disk anyway.
func deleteInPlace(s []*pb.AddrBookRecord_AddrEntry, addrs []ma.Multiaddr) []*pb.AddrBookRecord_AddrEntry {
if s == nil || len(addrs) == 0 {
return s
}
survived := len(s)
Outer:
for i, addr := range s {
for _, del := range addrs {
if !addr.Addr.Equal(del) {
continue
}
survived--
// if there are no survivors, bail out
if survived == 0 {
break Outer
}
s[i] = s[survived]
// we've already dealt with s[i], move to the next
continue Outer
}
}
return s[:survived]
}
func (ab *dsAddrBook) deleteAddrs(p peer.ID, addrs []ma.Multiaddr) (err error) {
pr, err := ab.loadRecord(p, false, false)
if err != nil {
@ -406,20 +545,7 @@ func (ab *dsAddrBook) deleteAddrs(p peer.ID, addrs []ma.Multiaddr) (err error) {
pr.Lock()
defer pr.Unlock()
// deletes addresses in place, and avoiding copies until we encounter the first deletion.
survived := 0
for i, addr := range pr.Addrs {
for _, del := range addrs {
if addr.Addr.Equal(del) {
continue
}
if i != survived {
pr.Addrs[survived] = pr.Addrs[i]
}
survived++
}
}
pr.Addrs = pr.Addrs[:survived]
pr.Addrs = deleteInPlace(pr.Addrs, addrs)
pr.dirty = true
pr.clean()

View File

@ -28,7 +28,7 @@ type dsKeyBook struct {
var _ pstore.KeyBook = (*dsKeyBook)(nil)
func NewKeyBook(_ context.Context, store ds.Datastore, _ Options) (pstore.KeyBook, error) {
func NewKeyBook(_ context.Context, store ds.Datastore, _ Options) (*dsKeyBook, error) {
return &dsKeyBook{store}, nil
}

View File

@ -36,7 +36,7 @@ func init() {
// See `init()` to learn which types are registered by default. Modules wishing to store
// values of other types will need to `gob.Register()` them explicitly, or else callers
// will receive runtime errors.
func NewPeerMetadata(_ context.Context, store ds.Datastore, _ Options) (pstore.PeerMetadata, error) {
func NewPeerMetadata(_ context.Context, store ds.Datastore, _ Options) (*dsPeerMetadata, error) {
return &dsPeerMetadata{store}, nil
}

View File

@ -2,6 +2,8 @@ package pstoreds
import (
"context"
"fmt"
"io"
"time"
base32 "github.com/multiformats/go-base32"
@ -47,8 +49,17 @@ func DefaultOpts() Options {
}
}
type pstoreds struct {
peerstore.Metrics
dsKeyBook
dsAddrBook
dsProtoBook
dsPeerMetadata
}
// NewPeerstore creates a peerstore backed by the provided persistent datastore.
func NewPeerstore(ctx context.Context, store ds.Batching, opts Options) (peerstore.Peerstore, error) {
func NewPeerstore(ctx context.Context, store ds.Batching, opts Options) (*pstoreds, error) {
addrBook, err := NewAddrBook(ctx, store, opts)
if err != nil {
return nil, err
@ -66,7 +77,13 @@ func NewPeerstore(ctx context.Context, store ds.Batching, opts Options) (peersto
protoBook := NewProtoBook(peerMetadata)
ps := pstore.NewPeerstore(keyBook, addrBook, protoBook, peerMetadata)
ps := &pstoreds{
Metrics: pstore.NewMetrics(),
dsKeyBook: *keyBook,
dsAddrBook: *addrBook,
dsPeerMetadata: *peerMetadata,
dsProtoBook: *protoBook,
}
return ps, nil
}
@ -103,3 +120,47 @@ func uniquePeerIds(ds ds.Datastore, prefix ds.Key, extractor func(result query.R
}
return ids, nil
}
func (ps *pstoreds) Close() (err error) {
var errs []error
weakClose := func(name string, c interface{}) {
if cl, ok := c.(io.Closer); ok {
if err = cl.Close(); err != nil {
errs = append(errs, fmt.Errorf("%s error: %s", name, err))
}
}
}
weakClose("keybook", ps.dsKeyBook)
weakClose("addressbook", ps.dsAddrBook)
weakClose("protobook", ps.dsProtoBook)
weakClose("peermetadata", ps.dsPeerMetadata)
if len(errs) > 0 {
return fmt.Errorf("failed while closing peerstore; err(s): %q", errs)
}
return nil
}
func (ps *pstoreds) Peers() peer.IDSlice {
set := map[peer.ID]struct{}{}
for _, p := range ps.PeersWithKeys() {
set[p] = struct{}{}
}
for _, p := range ps.PeersWithAddrs() {
set[p] = struct{}{}
}
pps := make(peer.IDSlice, 0, len(set))
for p := range set {
pps = append(pps, p)
}
return pps
}
func (ps *pstoreds) PeerInfo(p peer.ID) peer.AddrInfo {
return peer.AddrInfo{
ID: p,
Addrs: ps.dsAddrBook.Addrs(p),
}
}

View File

@ -26,7 +26,7 @@ type dsProtoBook struct {
var _ pstore.ProtoBook = (*dsProtoBook)(nil)
func NewProtoBook(meta pstore.PeerMetadata) pstore.ProtoBook {
func NewProtoBook(meta pstore.PeerMetadata) *dsProtoBook {
return &dsProtoBook{
meta: meta,
segments: func() (ret protoSegments) {

View File

@ -2,16 +2,18 @@ package pstoremem
import (
"context"
"fmt"
"sort"
"sync"
"time"
logging "github.com/ipfs/go-log"
peer "github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/peer"
pstore "github.com/libp2p/go-libp2p-core/peerstore"
"github.com/libp2p/go-libp2p-core/record"
ma "github.com/multiformats/go-multiaddr"
pstore "github.com/libp2p/go-libp2p-core/peerstore"
addr "github.com/libp2p/go-libp2p-peerstore/addr"
"github.com/libp2p/go-libp2p-peerstore/addr"
)
var log = logging.Logger("peerstore")
@ -26,6 +28,11 @@ func (e *expiringAddr) ExpiredBy(t time.Time) bool {
return t.After(e.Expires)
}
type peerRecordState struct {
Envelope *record.Envelope
Seq uint64
}
type addrSegments [256]*addrSegment
type addrSegment struct {
@ -35,10 +42,12 @@ type addrSegment struct {
// space unused. storing the *values* directly in the map will
// drastically increase the space waste. In our case, by 6x.
addrs map[peer.ID]map[string]*expiringAddr
signedPeerRecords map[peer.ID]*peerRecordState
}
func (s *addrSegments) get(p peer.ID) *addrSegment {
return s[byte(p[len(p)-1])]
func (segments *addrSegments) get(p peer.ID) *addrSegment {
return segments[byte(p[len(p)-1])]
}
// memoryAddrBook manages addresses.
@ -52,14 +61,17 @@ type memoryAddrBook struct {
}
var _ pstore.AddrBook = (*memoryAddrBook)(nil)
var _ pstore.CertifiedAddrBook = (*memoryAddrBook)(nil)
func NewAddrBook() pstore.AddrBook {
func NewAddrBook() *memoryAddrBook {
ctx, cancel := context.WithCancel(context.Background())
ab := &memoryAddrBook{
segments: func() (ret addrSegments) {
for i, _ := range ret {
ret[i] = &addrSegment{addrs: make(map[peer.ID]map[string]*expiringAddr)}
ret[i] = &addrSegment{
addrs: make(map[peer.ID]map[string]*expiringAddr),
signedPeerRecords: make(map[peer.ID]*peerRecordState)}
}
return ret
}(),
@ -98,6 +110,7 @@ func (mab *memoryAddrBook) gc() {
now := time.Now()
for _, s := range mab.segments {
s.Lock()
var collectedPeers []peer.ID
for p, amap := range s.addrs {
for k, addr := range amap {
if addr.ExpiredBy(now) {
@ -106,23 +119,30 @@ func (mab *memoryAddrBook) gc() {
}
if len(amap) == 0 {
delete(s.addrs, p)
collectedPeers = append(collectedPeers, p)
}
}
// remove signed records for peers whose signed addrs have all been removed
for _, p := range collectedPeers {
delete(s.signedPeerRecords, p)
}
s.Unlock()
}
}
func (mab *memoryAddrBook) PeersWithAddrs() peer.IDSlice {
var pids peer.IDSlice
// deduplicate, since the same peer could have both signed & unsigned addrs
pidSet := peer.NewSet()
for _, s := range mab.segments {
s.RLock()
for pid, _ := range s.addrs {
pids = append(pids, pid)
for pid, amap := range s.addrs {
if amap != nil && len(amap) > 0 {
pidSet.Add(pid)
}
}
s.RUnlock()
}
return pids
return pidSet.Peers()
}
// AddAddr calls AddAddrs(p, []ma.Multiaddr{addr}, ttl)
@ -134,6 +154,48 @@ func (mab *memoryAddrBook) AddAddr(p peer.ID, addr ma.Multiaddr, ttl time.Durati
// (time-to-live), after which the address is no longer valid.
// This function never reduces the TTL or expiration of an address.
func (mab *memoryAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration) {
// if we have a valid peer record, ignore unsigned addrs
// peerRec := mab.GetPeerRecord(p)
// if peerRec != nil {
// return
// }
mab.addAddrs(p, addrs, ttl, false)
}
// ConsumePeerRecord adds addresses from a signed peer.PeerRecord (contained in
// a record.Envelope), which will expire after the given TTL.
// See https://godoc.org/github.com/libp2p/go-libp2p-core/peerstore#CertifiedAddrBook for more details.
func (mab *memoryAddrBook) ConsumePeerRecord(recordEnvelope *record.Envelope, ttl time.Duration) (bool, error) {
r, err := recordEnvelope.Record()
if err != nil {
return false, err
}
rec, ok := r.(*peer.PeerRecord)
if !ok {
return false, fmt.Errorf("unable to process envelope: not a PeerRecord")
}
if !rec.PeerID.MatchesPublicKey(recordEnvelope.PublicKey) {
return false, fmt.Errorf("signing key does not match PeerID in PeerRecord")
}
// ensure seq is greater than last received
s := mab.segments.get(rec.PeerID)
s.Lock()
lastState, found := s.signedPeerRecords[rec.PeerID]
if found && lastState.Seq >= rec.Seq {
s.Unlock()
return false, nil
}
s.signedPeerRecords[rec.PeerID] = &peerRecordState{
Envelope: recordEnvelope,
Seq: rec.Seq,
}
s.Unlock() // need to release the lock, since addAddrs will try to take it
mab.addAddrs(rec.PeerID, rec.Addrs, ttl, true)
return true, nil
}
func (mab *memoryAddrBook) addAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration, signed bool) {
// if ttl is zero, exit. nothing to do.
if ttl <= 0 {
return
@ -143,26 +205,33 @@ func (mab *memoryAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Du
s.Lock()
defer s.Unlock()
amap := s.addrs[p]
if amap == nil {
amap = make(map[string]*expiringAddr, len(addrs))
amap, ok := s.addrs[p]
if !ok {
amap = make(map[string]*expiringAddr)
s.addrs[p] = amap
}
exp := time.Now().Add(ttl)
addrSet := make(map[string]struct{}, len(addrs))
for _, addr := range addrs {
if addr == nil {
log.Warnf("was passed nil multiaddr for %s", p)
continue
}
asBytes := addr.Bytes()
a, found := amap[string(asBytes)] // won't allocate.
k := string(addr.Bytes())
addrSet[k] = struct{}{}
// find the highest TTL and Expiry time between
// existing records and function args
a, found := amap[k] // won't allocate.
if !found {
// not found, save and announce it.
amap[string(asBytes)] = &expiringAddr{Addr: addr, Expires: exp, TTL: ttl}
// not found, announce it.
entry := &expiringAddr{Addr: addr, Expires: exp, TTL: ttl}
amap[k] = entry
mab.subManager.BroadcastAddr(p, addr)
} else {
// Update expiration/TTL independently.
// We never want to reduce either.
// update ttl & exp to whichever is greater between new and existing entry
if ttl > a.TTL {
a.TTL = ttl
}
@ -171,6 +240,21 @@ func (mab *memoryAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Du
}
}
}
// // when adding signed addrs, make sure only the addrs from the input list remain.
// if signed {
// for k := range amap {
// _, ok := addrSet[k]
// if !ok {
// delete(amap, k)
// }
// }
// }
// if we've expired all the signed addresses for a peer, remove their signed routing state record
if len(addrs) == 0 {
delete(s.signedPeerRecords, p)
}
}
// SetAddr calls mgr.SetAddrs(p, addr, ttl)
@ -185,9 +269,9 @@ func (mab *memoryAddrBook) SetAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Du
s.Lock()
defer s.Unlock()
amap := s.addrs[p]
if amap == nil {
amap = make(map[string]*expiringAddr, len(addrs))
amap, ok := s.addrs[p]
if !ok {
amap = make(map[string]*expiringAddr)
s.addrs[p] = amap
}
@ -197,16 +281,22 @@ func (mab *memoryAddrBook) SetAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Du
log.Warnf("was passed nil multiaddr for %s", p)
continue
}
aBytes := addr.Bytes()
key := string(aBytes)
// re-set all of them for new ttl.
aBytes := addr.Bytes()
if ttl > 0 {
amap[string(aBytes)] = &expiringAddr{Addr: addr, Expires: exp, TTL: ttl}
amap[key] = &expiringAddr{Addr: addr, Expires: exp, TTL: ttl}
mab.subManager.BroadcastAddr(p, addr)
} else {
delete(amap, string(aBytes))
delete(amap, key)
}
}
// if we've expired all the signed addresses for a peer, remove their signed routing state record
if len(amap) == 0 {
delete(s.signedPeerRecords, p)
}
}
// UpdateAddrs updates the addresses associated with the given peer that have
@ -215,35 +305,39 @@ func (mab *memoryAddrBook) UpdateAddrs(p peer.ID, oldTTL time.Duration, newTTL t
s := mab.segments.get(p)
s.Lock()
defer s.Unlock()
exp := time.Now().Add(newTTL)
amap, found := s.addrs[p]
if !found {
return
if found {
for k, a := range amap {
if oldTTL == a.TTL {
a.TTL = newTTL
a.Expires = exp
amap[k] = a
}
}
}
exp := time.Now().Add(newTTL)
for k, addr := range amap {
if oldTTL == addr.TTL {
addr.TTL = newTTL
addr.Expires = exp
amap[k] = addr
}
// if we've expired all the signed addresses for a peer, remove their signed routing state record
if len(amap) == 0 {
delete(s.signedPeerRecords, p)
}
}
// Addresses returns all known (and valid) addresses for a given
// Addrs returns all known (and valid) addresses for a given peer
func (mab *memoryAddrBook) Addrs(p peer.ID) []ma.Multiaddr {
s := mab.segments.get(p)
s.RLock()
defer s.RUnlock()
amap, found := s.addrs[p]
if !found {
return nil
}
return validAddrs(s.addrs[p])
}
func validAddrs(amap map[string]*expiringAddr) []ma.Multiaddr {
now := time.Now()
good := make([]ma.Multiaddr, 0, len(amap))
if amap == nil {
return good
}
for _, m := range amap {
if !m.ExpiredBy(now) {
good = append(good, m.Addr)
@ -253,6 +347,28 @@ func (mab *memoryAddrBook) Addrs(p peer.ID) []ma.Multiaddr {
return good
}
// GetPeerRecord returns a Envelope containing a PeerRecord for the
// given peer id, if one exists.
// Returns nil if no signed PeerRecord exists for the peer.
func (mab *memoryAddrBook) GetPeerRecord(p peer.ID) *record.Envelope {
s := mab.segments.get(p)
s.RLock()
defer s.RUnlock()
// although the signed record gets garbage collected when all addrs inside it are expired,
// we may be in between the expiration time and the GC interval
// so, we check to see if we have any valid signed addrs before returning the record
if len(validAddrs(s.addrs[p])) == 0 {
return nil
}
state := s.signedPeerRecords[p]
if state == nil {
return nil
}
return state.Envelope
}
// ClearAddrs removes all previously stored addresses
func (mab *memoryAddrBook) ClearAddrs(p peer.ID) {
s := mab.segments.get(p)
@ -260,6 +376,7 @@ func (mab *memoryAddrBook) ClearAddrs(p peer.ID) {
defer s.Unlock()
delete(s.addrs, p)
delete(s.signedPeerRecords, p)
}
// AddrStream returns a channel on which all new addresses discovered for a

View File

@ -19,7 +19,7 @@ type memoryKeyBook struct {
var _ pstore.KeyBook = (*memoryKeyBook)(nil)
// noop new, but in the future we may want to do some init work.
func NewKeyBook() pstore.KeyBook {
func NewKeyBook() *memoryKeyBook {
return &memoryKeyBook{
pks: map[peer.ID]ic.PubKey{},
sks: map[peer.ID]ic.PrivKey{},

View File

@ -27,7 +27,7 @@ type memoryPeerMetadata struct {
var _ pstore.PeerMetadata = (*memoryPeerMetadata)(nil)
func NewPeerMetadata() pstore.PeerMetadata {
func NewPeerMetadata() *memoryPeerMetadata {
return &memoryPeerMetadata{
ds: make(map[metakey]interface{}),
interned: make(map[string]interface{}),

View File

@ -1,12 +1,73 @@
package pstoremem
import pstore "github.com/libp2p/go-libp2p-peerstore"
import (
"fmt"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/peerstore"
pstore "github.com/libp2p/go-libp2p-peerstore"
"io"
)
type pstoremem struct {
peerstore.Metrics
memoryKeyBook
memoryAddrBook
memoryProtoBook
memoryPeerMetadata
}
// NewPeerstore creates an in-memory threadsafe collection of peers.
func NewPeerstore() pstore.Peerstore {
return pstore.NewPeerstore(
NewKeyBook(),
NewAddrBook(),
NewProtoBook(),
NewPeerMetadata())
func NewPeerstore() *pstoremem {
return &pstoremem{
Metrics: pstore.NewMetrics(),
memoryKeyBook: *NewKeyBook(),
memoryAddrBook: *NewAddrBook(),
memoryProtoBook: *NewProtoBook(),
memoryPeerMetadata: *NewPeerMetadata(),
}
}
func (ps *pstoremem) Close() (err error) {
var errs []error
weakClose := func(name string, c interface{}) {
if cl, ok := c.(io.Closer); ok {
if err = cl.Close(); err != nil {
errs = append(errs, fmt.Errorf("%s error: %s", name, err))
}
}
}
weakClose("keybook", ps.memoryKeyBook)
weakClose("addressbook", ps.memoryAddrBook)
weakClose("protobook", ps.memoryProtoBook)
weakClose("peermetadata", ps.memoryPeerMetadata)
if len(errs) > 0 {
return fmt.Errorf("failed while closing peerstore; err(s): %q", errs)
}
return nil
}
func (ps *pstoremem) Peers() peer.IDSlice {
set := map[peer.ID]struct{}{}
for _, p := range ps.PeersWithKeys() {
set[p] = struct{}{}
}
for _, p := range ps.PeersWithAddrs() {
set[p] = struct{}{}
}
pps := make(peer.IDSlice, 0, len(set))
for p := range set {
pps = append(pps, p)
}
return pps
}
func (ps *pstoremem) PeerInfo(p peer.ID) peer.AddrInfo {
return peer.AddrInfo{
ID: p,
Addrs: ps.memoryAddrBook.Addrs(p),
}
}

View File

@ -28,7 +28,7 @@ type memoryProtoBook struct {
var _ pstore.ProtoBook = (*memoryProtoBook)(nil)
func NewProtoBook() pstore.ProtoBook {
func NewProtoBook() *memoryProtoBook {
return &memoryProtoBook{
interned: make(map[string]string, 256),
segments: func() (ret protoSegments) {

View File

@ -1,6 +1,11 @@
package test
import (
"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/record"
"github.com/libp2p/go-libp2p-core/test"
"github.com/multiformats/go-multiaddr"
"testing"
"time"
@ -16,6 +21,7 @@ var addressBookSuite = map[string]func(book pstore.AddrBook) func(*testing.T){
"AddressesExpire": testAddressesExpire,
"ClearWithIter": testClearWithIterator,
"PeersWithAddresses": testPeersWithAddrs,
"CertifiedAddresses": testCertifiedAddresses,
}
type AddrBookFactory func() (pstore.AddrBook, func())
@ -168,6 +174,30 @@ func testSetNegativeTTLClears(m pstore.AddrBook) func(t *testing.T) {
survivors = append(survivors[0:74], survivors[75:]...)
AssertAddressesEqual(t, survivors, m.Addrs(id))
// remove _all_ the addresses
m.SetAddrs(id, survivors, -1)
if len(m.Addrs(id)) != 0 {
t.Error("expected empty address list after clearing all addresses")
}
// add half, but try to remove more than we added
m.SetAddrs(id, addrs[:50], time.Hour)
m.SetAddrs(id, addrs, -1)
if len(m.Addrs(id)) != 0 {
t.Error("expected empty address list after clearing all addresses")
}
// try to remove the same addr multiple times
m.SetAddrs(id, addrs[:5], time.Hour)
repeated := make([]multiaddr.Multiaddr, 10)
for i := 0; i < len(repeated); i++ {
repeated[i] = addrs[0]
}
m.SetAddrs(id, repeated, -1)
if len(m.Addrs(id)) != 4 {
t.Errorf("expected 4 addrs after removing one, got %d", len(m.Addrs(id)))
}
}
}
@ -331,3 +361,113 @@ func testPeersWithAddrs(m pstore.AddrBook) func(t *testing.T) {
})
}
}
func testCertifiedAddresses(m pstore.AddrBook) func(*testing.T) {
return func(t *testing.T) {
cab := m.(pstore.CertifiedAddrBook)
priv, _, err := test.RandTestKeyPair(crypto.Ed25519, 256)
if err != nil {
t.Errorf("error generating testing keys: %v", err)
}
id, _ := peer.IDFromPrivateKey(priv)
allAddrs := GenerateAddrs(10)
certifiedAddrs := allAddrs[:5]
uncertifiedAddrs := allAddrs[5:]
rec := peer.NewPeerRecord()
rec.PeerID = id
rec.Addrs = certifiedAddrs
signedRec, err := record.Seal(rec, priv)
if err != nil {
t.Errorf("error creating signed routing record: %v", err)
}
// add a few non-certified addrs
m.AddAddrs(id, uncertifiedAddrs, time.Hour)
// make sure they're present
AssertAddressesEqual(t, uncertifiedAddrs, m.Addrs(id))
// add the signed record to addr book
_, err = cab.ConsumePeerRecord(signedRec, time.Hour)
if err != nil {
t.Errorf("error adding signed routing record to addrbook: %v", err)
}
// the non-certified addrs should be gone & we should get only certified addrs back from Addrs
// AssertAddressesEqual(t, certifiedAddrs, m.Addrs(id))
AssertAddressesEqual(t, allAddrs, m.Addrs(id))
// PeersWithAddrs should return a single peer
if len(m.PeersWithAddrs()) != 1 {
t.Errorf("expected PeersWithAddrs to return 1, got %d", len(m.PeersWithAddrs()))
}
// adding the same peer record again should result in the record being ignored
accepted, err := cab.ConsumePeerRecord(signedRec, time.Hour)
if accepted {
t.Error("Expected record with duplicate sequence number to be ignored")
}
if err != nil {
t.Errorf("Expected record with duplicate sequence number to be ignored without error, got err: %s", err)
}
// once certified addrs exist, trying to add non-certified addrs should have no effect
// m.AddAddrs(id, uncertifiedAddrs, time.Hour)
// AssertAddressesEqual(t, certifiedAddrs, m.Addrs(id))
m.AddAddrs(id, uncertifiedAddrs, time.Hour)
AssertAddressesEqual(t, allAddrs, m.Addrs(id))
// we should be able to retrieve the signed peer record
rec2 := cab.GetPeerRecord(id)
if rec2 == nil || !signedRec.Equal(rec2) {
t.Error("unable to retrieve signed routing record from addrbook")
}
// Adding a new envelope should clear existing certified addresses.
// Only the newly-added ones should remain
certifiedAddrs = certifiedAddrs[:3]
rec = peer.NewPeerRecord()
rec.PeerID = id
rec.Addrs = certifiedAddrs
signedRec, err = record.Seal(rec, priv)
test.AssertNilError(t, err)
_, err = cab.ConsumePeerRecord(signedRec, time.Hour)
test.AssertNilError(t, err)
// AssertAddressesEqual(t, certifiedAddrs, m.Addrs(id))
AssertAddressesEqual(t, allAddrs, m.Addrs(id))
// update TTL on signed addrs to -1 to remove them.
// the signed routing record should be deleted
// m.SetAddrs(id, certifiedAddrs, -1)
m.SetAddrs(id, allAddrs, -1)
if len(m.Addrs(id)) != 0 {
t.Error("expected zero certified addrs after setting TTL to -1")
}
if cab.GetPeerRecord(id) != nil {
t.Error("expected signed peer record to be removed when addresses expire")
}
// Test that natural TTL expiration clears signed peer records
_, err = cab.ConsumePeerRecord(signedRec, time.Second)
test.AssertNilError(t, err)
AssertAddressesEqual(t, certifiedAddrs, m.Addrs(id))
time.Sleep(2 * time.Second)
if cab.GetPeerRecord(id) != nil {
t.Error("expected signed peer record to be removed when addresses expire")
}
// adding a peer record that's signed with the wrong key should fail
priv2, _, err := test.RandTestKeyPair(crypto.Ed25519, 256)
test.AssertNilError(t, err)
env, err := record.Seal(rec, priv2)
test.AssertNilError(t, err)
accepted, err = cab.ConsumePeerRecord(env, time.Second)
if accepted || err == nil {
t.Error("expected adding a PeerRecord that's signed with the wrong key to fail")
}
}
}

View File

@ -23,6 +23,7 @@ var peerstoreSuite = map[string]func(pstore.Peerstore) func(*testing.T){
"PeerstoreProtoStore": testPeerstoreProtoStore,
"BasicPeerstore": testBasicPeerstore,
"Metadata": testMetadata,
"CertifiedAddrBook": testCertifiedAddrBook,
}
type PeerstoreFactory func() (pstore.Peerstore, func())
@ -357,6 +358,15 @@ func testMetadata(ps pstore.Peerstore) func(t *testing.T) {
}
}
func testCertifiedAddrBook(ps pstore.Peerstore) func(*testing.T) {
return func(t *testing.T) {
_, ok := ps.(pstore.CertifiedAddrBook)
if !ok {
t.Error("expected peerstore to implement CertifiedAddrBook interface")
}
}
}
func getAddrs(t *testing.T, n int) []ma.Multiaddr {
var addrs []ma.Multiaddr
for i := 0; i < n; i++ {