forked from cerc-io/ipld-eth-server
update dependencies to work with update eth-block-extractor
This commit is contained in:
+32
@@ -0,0 +1,32 @@
|
||||
os:
|
||||
- linux
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.11.x
|
||||
|
||||
env:
|
||||
global:
|
||||
- GOTFLAGS="-race"
|
||||
matrix:
|
||||
- BUILD_DEPTYPE=gx
|
||||
- BUILD_DEPTYPE=gomod
|
||||
|
||||
|
||||
# disable travis install
|
||||
install:
|
||||
- true
|
||||
|
||||
script:
|
||||
- bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh)
|
||||
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $GOPATH/src/gx
|
||||
- $GOPATH/pkg/mod
|
||||
- $HOME/.cache/go-build
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Protocol Labs, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
export IPFS_API ?= v04x.ipfs.io
|
||||
|
||||
gx:
|
||||
go get -u github.com/whyrusleeping/gx
|
||||
go get -u github.com/whyrusleeping/gx-go
|
||||
|
||||
deps: gx
|
||||
gx --verbose install --global
|
||||
gx-go rewrite
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
# go-ipns
|
||||
|
||||
[](http://protocol.ai)
|
||||
[](http://ipfs.io/)
|
||||
[](http://webchat.freenode.net/?channels=%23ipfs)
|
||||
[](https://github.com/RichardLitt/standard-readme)
|
||||
[](https://godoc.org/github.com/ipfs/go-ipns)
|
||||
|
||||
> ipns record definitions
|
||||
|
||||
This package contains all of the components necessary to create, understand, and validate IPNS records. It does *not* publish or resolve those records. [`go-ipfs`](https://github.com/ipfs/go-ipfs) uses this package internally to manipulate records.
|
||||
|
||||
## Usage
|
||||
|
||||
To create a new IPNS record:
|
||||
|
||||
```go
|
||||
import (
|
||||
"time"
|
||||
|
||||
ipns "github.com/ipfs/go-ipns"
|
||||
crypto "github.com/libp2p/go-libp2p-crypto"
|
||||
)
|
||||
|
||||
// Generate a private key to sign the IPNS record with. Most of the time,
|
||||
// however, you'll want to retrieve an already-existing key from IPFS using the
|
||||
// go-ipfs/core/coreapi CoreAPI.KeyAPI() interface.
|
||||
privateKey, publicKey, err := crypto.GenerateKeyPair(crypto.RSA, 2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Create an IPNS record that expires in one hour and points to the IPFS address
|
||||
// /ipfs/Qme1knMqwt1hKZbc1BmQFmnm9f36nyQGwXxPGVpVJ9rMK5
|
||||
ipnsRecord, err := ipns.Create(privateKey, []byte("/ipfs/Qme1knMqwt1hKZbc1BmQFmnm9f36nyQGwXxPGVpVJ9rMK5"), 0, time.Now().Add(1*time.Hour))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
```
|
||||
|
||||
Once you have the record, you’ll need to use IPFS to *publish* it.
|
||||
|
||||
There are several other major operations you can do with `go-ipns`. Check out the [API docs](https://godoc.org/github.com/ipfs/go-ipns) or look at the tests in this repo for examples.
|
||||
|
||||
## Documentation
|
||||
|
||||
https://godoc.org/github.com/ipfs/go-ipns
|
||||
|
||||
## Contribute
|
||||
|
||||
Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-ipns/issues)!
|
||||
|
||||
This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
|
||||
|
||||
### Want to hack on IPFS?
|
||||
|
||||
[](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) Protocol Labs, Inc. under the **MIT license**. See [LICENSE file](./LICENSE) for details.
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
coverage:
|
||||
range: "50...100"
|
||||
comment: off
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package ipns
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// ErrExpiredRecord should be returned when an ipns record is
|
||||
// invalid due to being too old
|
||||
var ErrExpiredRecord = errors.New("expired record")
|
||||
|
||||
// ErrUnrecognizedValidity is returned when an IpnsRecord has an
|
||||
// unknown validity type.
|
||||
var ErrUnrecognizedValidity = errors.New("unrecognized validity type")
|
||||
|
||||
// ErrInvalidPath should be returned when an ipns record path
|
||||
// is not in a valid format
|
||||
var ErrInvalidPath = errors.New("record path invalid")
|
||||
|
||||
// ErrSignature should be returned when an ipns record fails
|
||||
// signature verification
|
||||
var ErrSignature = errors.New("record signature verification failed")
|
||||
|
||||
// ErrKeyFormat should be returned when an ipns record key is
|
||||
// incorrectly formatted (not a peer ID)
|
||||
var ErrKeyFormat = errors.New("record key could not be parsed into peer ID")
|
||||
|
||||
// ErrPublicKeyNotFound should be returned when the public key
|
||||
// corresponding to the ipns record path cannot be retrieved
|
||||
// from the peer store
|
||||
var ErrPublicKeyNotFound = errors.New("public key not found in peer store")
|
||||
|
||||
// ErrPublicKeyMismatch should be returned when the public key embedded in the
|
||||
// record doesn't match the expected public key.
|
||||
var ErrPublicKeyMismatch = errors.New("public key in record did not match expected pubkey")
|
||||
|
||||
// ErrBadRecord should be returned when an ipns record cannot be unmarshalled
|
||||
var ErrBadRecord = errors.New("record could not be unmarshalled")
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
module github.com/ipfs/go-ipns
|
||||
|
||||
require (
|
||||
github.com/gogo/protobuf v1.2.1
|
||||
github.com/ipfs/go-ipfs-util v0.0.1
|
||||
github.com/ipfs/go-log v0.0.1
|
||||
github.com/libp2p/go-libp2p-crypto v0.0.1
|
||||
github.com/libp2p/go-libp2p-peer v0.0.1
|
||||
github.com/libp2p/go-libp2p-peerstore v0.0.1
|
||||
github.com/libp2p/go-libp2p-record v0.0.1
|
||||
)
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78=
|
||||
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
||||
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
|
||||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
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/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ=
|
||||
github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
|
||||
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/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
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.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
||||
github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8=
|
||||
github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc=
|
||||
github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
|
||||
github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50=
|
||||
github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc=
|
||||
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/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ=
|
||||
github.com/libp2p/go-libp2p-crypto v0.0.1 h1:JNQd8CmoGTohO/akqrH16ewsqZpci2CbgYH/LmYl8gw=
|
||||
github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE=
|
||||
github.com/libp2p/go-libp2p-peer v0.0.1 h1:0qwAOljzYewINrU+Kndoc+1jAL7vzY/oY2Go4DCGfyY=
|
||||
github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo=
|
||||
github.com/libp2p/go-libp2p-peerstore v0.0.1 h1:twKovq8YK5trLrd3nB7PD2Zu9JcyAIdm7Bz9yBWjhq8=
|
||||
github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20=
|
||||
github.com/libp2p/go-libp2p-record v0.0.1 h1:zN7AS3X46qmwsw5JLxdDuI43cH5UYwovKxHPjKBYQxw=
|
||||
github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q=
|
||||
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.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
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/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ=
|
||||
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
|
||||
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
|
||||
github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY=
|
||||
github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44=
|
||||
github.com/multiformats/go-multiaddr-dns v0.0.1 h1:jQt9c6tDSdQLIlBo4tXYx7QUHCPjxsB1zXcag/2S7zc=
|
||||
github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
|
||||
github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g=
|
||||
github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU=
|
||||
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/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
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/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
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/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA=
|
||||
github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M=
|
||||
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
package ipns
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
pb "github.com/ipfs/go-ipns/pb"
|
||||
|
||||
u "github.com/ipfs/go-ipfs-util"
|
||||
ic "github.com/libp2p/go-libp2p-crypto"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
)
|
||||
|
||||
// Create creates a new IPNS entry and signs it with the given private key.
|
||||
//
|
||||
// This function does not embed the public key. If you want to do that, use
|
||||
// `EmbedPublicKey`.
|
||||
func Create(sk ic.PrivKey, val []byte, seq uint64, eol time.Time) (*pb.IpnsEntry, error) {
|
||||
entry := new(pb.IpnsEntry)
|
||||
|
||||
entry.Value = val
|
||||
typ := pb.IpnsEntry_EOL
|
||||
entry.ValidityType = &typ
|
||||
entry.Sequence = &seq
|
||||
entry.Validity = []byte(u.FormatRFC3339(eol))
|
||||
|
||||
sig, err := sk.Sign(ipnsEntryDataForSig(entry))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entry.Signature = sig
|
||||
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
// Validates validates the given IPNS entry against the given public key.
|
||||
func Validate(pk ic.PubKey, entry *pb.IpnsEntry) error {
|
||||
// Check the ipns record signature with the public key
|
||||
if ok, err := pk.Verify(ipnsEntryDataForSig(entry), entry.GetSignature()); err != nil || !ok {
|
||||
return ErrSignature
|
||||
}
|
||||
|
||||
eol, err := GetEOL(entry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if time.Now().After(eol) {
|
||||
return ErrExpiredRecord
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetEOL returns the EOL of this IPNS entry
|
||||
//
|
||||
// This function returns ErrUnrecognizedValidity if the validity type of the
|
||||
// record isn't EOL. Otherwise, it returns an error if it can't parse the EOL.
|
||||
func GetEOL(entry *pb.IpnsEntry) (time.Time, error) {
|
||||
if entry.GetValidityType() != pb.IpnsEntry_EOL {
|
||||
return time.Time{}, ErrUnrecognizedValidity
|
||||
}
|
||||
return u.ParseRFC3339(string(entry.GetValidity()))
|
||||
}
|
||||
|
||||
// EmbedPublicKey embeds the given public key in the given ipns entry. While not
|
||||
// strictly required, some nodes (e.g., DHT servers) may reject IPNS entries
|
||||
// that don't embed their public keys as they may not be able to validate them
|
||||
// efficiently.
|
||||
func EmbedPublicKey(pk ic.PubKey, entry *pb.IpnsEntry) error {
|
||||
// Try extracting the public key from the ID. If we can, *don't* embed
|
||||
// it.
|
||||
id, err := peer.IDFromPublicKey(pk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := id.ExtractPublicKey(); err != peer.ErrNoPublicKey {
|
||||
// Either a *real* error or nil.
|
||||
return err
|
||||
}
|
||||
|
||||
// We failed to extract the public key from the peer ID, embed it in the
|
||||
// record.
|
||||
pkBytes, err := pk.Bytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
entry.PubKey = pkBytes
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExtractPublicKey extracts a public key matching `pid` from the IPNS record,
|
||||
// if possible.
|
||||
//
|
||||
// This function returns (nil, nil) when no public key can be extracted and
|
||||
// nothing is malformed.
|
||||
func ExtractPublicKey(pid peer.ID, entry *pb.IpnsEntry) (ic.PubKey, error) {
|
||||
if entry.PubKey != nil {
|
||||
pk, err := ic.UnmarshalPublicKey(entry.PubKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unmarshaling pubkey in record: %s", err)
|
||||
}
|
||||
|
||||
expPid, err := peer.IDFromPublicKey(pk)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not regenerate peerID from pubkey: %s", err)
|
||||
}
|
||||
|
||||
if pid != expPid {
|
||||
return nil, ErrPublicKeyMismatch
|
||||
}
|
||||
return pk, nil
|
||||
}
|
||||
|
||||
return pid.ExtractPublicKey()
|
||||
}
|
||||
|
||||
// Compare compares two IPNS entries. It returns:
|
||||
//
|
||||
// * -1 if a is older than b
|
||||
// * 0 if a and b cannot be ordered (this doesn't mean that they are equal)
|
||||
// * +1 if a is newer than b
|
||||
//
|
||||
// It returns an error when either a or b are malformed.
|
||||
//
|
||||
// NOTE: It *does not* validate the records, the caller is responsible for calling
|
||||
// `Validate` first.
|
||||
//
|
||||
// NOTE: If a and b cannot be ordered by this function, you can determine their
|
||||
// order by comparing their serialized byte representations (using
|
||||
// `bytes.Compare`). You must do this if you are implementing a libp2p record
|
||||
// validator (or you can just use the one provided for you by this package).
|
||||
func Compare(a, b *pb.IpnsEntry) (int, error) {
|
||||
as := a.GetSequence()
|
||||
bs := b.GetSequence()
|
||||
|
||||
if as > bs {
|
||||
return 1, nil
|
||||
} else if as < bs {
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
at, err := u.ParseRFC3339(string(a.GetValidity()))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
bt, err := u.ParseRFC3339(string(b.GetValidity()))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if at.After(bt) {
|
||||
return 1, nil
|
||||
} else if bt.After(at) {
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func ipnsEntryDataForSig(e *pb.IpnsEntry) []byte {
|
||||
return bytes.Join([][]byte{
|
||||
e.Value,
|
||||
e.Validity,
|
||||
[]byte(fmt.Sprint(e.GetValidityType())),
|
||||
},
|
||||
[]byte{})
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"author": "stebalien",
|
||||
"bugs": {
|
||||
"url": "https://github.com/ipfs/go-ipns/issues"
|
||||
},
|
||||
"gx": {
|
||||
"dvcsimport": "github.com/ipfs/go-ipns"
|
||||
},
|
||||
"gxDependencies": [
|
||||
{
|
||||
"author": "whyrusleeping",
|
||||
"hash": "QmNohiVssaPw3KVLZik59DBVGTSm2dGvYT9eoXt5DQ36Yz",
|
||||
"name": "go-ipfs-util",
|
||||
"version": "1.2.9"
|
||||
},
|
||||
{
|
||||
"hash": "QmbkT7eMTyXfpeyB3ZMxxcxg7XH8t6uXp49jqzz4HB7BGF",
|
||||
"name": "go-log",
|
||||
"version": "1.5.9"
|
||||
},
|
||||
{
|
||||
"author": "whyrusleeping",
|
||||
"hash": "QmTW4SdgBWq9GjsBsHeUx8WuGxzhgzAf88UMH2w62PC8yK",
|
||||
"name": "go-libp2p-crypto",
|
||||
"version": "2.0.7"
|
||||
},
|
||||
{
|
||||
"author": "whyrusleeping",
|
||||
"hash": "QmYVXrKrKHDC9FobgmcmshCDyWwdrfwfanNQN4oxJ9Fk3h",
|
||||
"name": "go-libp2p-peer",
|
||||
"version": "3.1.2"
|
||||
},
|
||||
{
|
||||
"author": "whyrusleeping",
|
||||
"hash": "QmaCTz9RkrU13bm9kMB54f7atgqM4qkjDZpRwRoJiWXEqs",
|
||||
"name": "go-libp2p-peerstore",
|
||||
"version": "2.0.19"
|
||||
},
|
||||
{
|
||||
"hash": "QmbeHtaBy9nZsW4cHRcvgVY4CnDhXudE2Dr6qDxS7yg9rX",
|
||||
"name": "go-libp2p-record",
|
||||
"version": "4.1.15"
|
||||
},
|
||||
{
|
||||
"author": "whyrusleeping",
|
||||
"hash": "QmddjPSGZb3ieihSseFeCfVRpZzcqczPNsD2DvarSwnjJB",
|
||||
"name": "gogo-protobuf",
|
||||
"version": "1.2.1"
|
||||
}
|
||||
],
|
||||
"gxVersion": "0.12.1",
|
||||
"language": "go",
|
||||
"license": "MIT",
|
||||
"name": "go-ipns",
|
||||
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
|
||||
"version": "0.1.23"
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
PB = $(wildcard *.proto)
|
||||
GO = $(PB:.proto=.pb.go)
|
||||
|
||||
all: $(GO)
|
||||
|
||||
%.pb.go: %.proto
|
||||
protoc --proto_path=$(GOPATH)/src:. --gogofast_out=. $<
|
||||
|
||||
clean:
|
||||
rm -f *.pb.go
|
||||
rm -f *.go
|
||||
+678
@@ -0,0 +1,678 @@
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: ipns.proto
|
||||
|
||||
package ipns_pb
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type IpnsEntry_ValidityType int32
|
||||
|
||||
const (
|
||||
// setting an EOL says "this record is valid until..."
|
||||
IpnsEntry_EOL IpnsEntry_ValidityType = 0
|
||||
)
|
||||
|
||||
var IpnsEntry_ValidityType_name = map[int32]string{
|
||||
0: "EOL",
|
||||
}
|
||||
|
||||
var IpnsEntry_ValidityType_value = map[string]int32{
|
||||
"EOL": 0,
|
||||
}
|
||||
|
||||
func (x IpnsEntry_ValidityType) Enum() *IpnsEntry_ValidityType {
|
||||
p := new(IpnsEntry_ValidityType)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x IpnsEntry_ValidityType) String() string {
|
||||
return proto.EnumName(IpnsEntry_ValidityType_name, int32(x))
|
||||
}
|
||||
|
||||
func (x *IpnsEntry_ValidityType) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(IpnsEntry_ValidityType_value, data, "IpnsEntry_ValidityType")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = IpnsEntry_ValidityType(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (IpnsEntry_ValidityType) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_4d5b16fb32bfe8ea, []int{0, 0}
|
||||
}
|
||||
|
||||
type IpnsEntry struct {
|
||||
Value []byte `protobuf:"bytes,1,req,name=value" json:"value,omitempty"`
|
||||
Signature []byte `protobuf:"bytes,2,req,name=signature" json:"signature,omitempty"`
|
||||
ValidityType *IpnsEntry_ValidityType `protobuf:"varint,3,opt,name=validityType,enum=ipns.pb.IpnsEntry_ValidityType" json:"validityType,omitempty"`
|
||||
Validity []byte `protobuf:"bytes,4,opt,name=validity" json:"validity,omitempty"`
|
||||
Sequence *uint64 `protobuf:"varint,5,opt,name=sequence" json:"sequence,omitempty"`
|
||||
Ttl *uint64 `protobuf:"varint,6,opt,name=ttl" json:"ttl,omitempty"`
|
||||
// in order for nodes to properly validate a record upon receipt, they need the public
|
||||
// key associated with it. For old RSA keys, its easiest if we just send this as part of
|
||||
// the record itself. For newer ed25519 keys, the public key can be embedded in the
|
||||
// peerID, making this field unnecessary.
|
||||
PubKey []byte `protobuf:"bytes,7,opt,name=pubKey" json:"pubKey,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *IpnsEntry) Reset() { *m = IpnsEntry{} }
|
||||
func (m *IpnsEntry) String() string { return proto.CompactTextString(m) }
|
||||
func (*IpnsEntry) ProtoMessage() {}
|
||||
func (*IpnsEntry) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_4d5b16fb32bfe8ea, []int{0}
|
||||
}
|
||||
func (m *IpnsEntry) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *IpnsEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_IpnsEntry.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalTo(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *IpnsEntry) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_IpnsEntry.Merge(m, src)
|
||||
}
|
||||
func (m *IpnsEntry) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *IpnsEntry) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_IpnsEntry.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_IpnsEntry proto.InternalMessageInfo
|
||||
|
||||
func (m *IpnsEntry) GetValue() []byte {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IpnsEntry) GetSignature() []byte {
|
||||
if m != nil {
|
||||
return m.Signature
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IpnsEntry) GetValidityType() IpnsEntry_ValidityType {
|
||||
if m != nil && m.ValidityType != nil {
|
||||
return *m.ValidityType
|
||||
}
|
||||
return IpnsEntry_EOL
|
||||
}
|
||||
|
||||
func (m *IpnsEntry) GetValidity() []byte {
|
||||
if m != nil {
|
||||
return m.Validity
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IpnsEntry) GetSequence() uint64 {
|
||||
if m != nil && m.Sequence != nil {
|
||||
return *m.Sequence
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *IpnsEntry) GetTtl() uint64 {
|
||||
if m != nil && m.Ttl != nil {
|
||||
return *m.Ttl
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *IpnsEntry) GetPubKey() []byte {
|
||||
if m != nil {
|
||||
return m.PubKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("ipns.pb.IpnsEntry_ValidityType", IpnsEntry_ValidityType_name, IpnsEntry_ValidityType_value)
|
||||
proto.RegisterType((*IpnsEntry)(nil), "ipns.pb.IpnsEntry")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("ipns.proto", fileDescriptor_4d5b16fb32bfe8ea) }
|
||||
|
||||
var fileDescriptor_4d5b16fb32bfe8ea = []byte{
|
||||
// 221 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xca, 0x2c, 0xc8, 0x2b,
|
||||
0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x87, 0xb0, 0x93, 0x94, 0xfe, 0x33, 0x72, 0x71,
|
||||
0x7a, 0x16, 0xe4, 0x15, 0xbb, 0xe6, 0x95, 0x14, 0x55, 0x0a, 0x89, 0x70, 0xb1, 0x96, 0x25, 0xe6,
|
||||
0x94, 0xa6, 0x4a, 0x30, 0x2a, 0x30, 0x69, 0xf0, 0x04, 0x41, 0x38, 0x42, 0x32, 0x5c, 0x9c, 0xc5,
|
||||
0x99, 0xe9, 0x79, 0x89, 0x25, 0xa5, 0x45, 0xa9, 0x12, 0x4c, 0x60, 0x19, 0x84, 0x80, 0x90, 0x33,
|
||||
0x17, 0x4f, 0x59, 0x62, 0x4e, 0x66, 0x4a, 0x66, 0x49, 0x65, 0x48, 0x65, 0x41, 0xaa, 0x04, 0xb3,
|
||||
0x02, 0xa3, 0x06, 0x9f, 0x91, 0xbc, 0x1e, 0xd4, 0x06, 0x3d, 0xb8, 0xe9, 0x7a, 0x61, 0x48, 0xca,
|
||||
0x82, 0x50, 0x34, 0x09, 0x49, 0x71, 0x71, 0xc0, 0xf8, 0x12, 0x2c, 0x0a, 0x8c, 0x1a, 0x3c, 0x41,
|
||||
0x70, 0x3e, 0x48, 0xae, 0x38, 0xb5, 0xb0, 0x34, 0x35, 0x2f, 0x39, 0x55, 0x82, 0x55, 0x81, 0x51,
|
||||
0x83, 0x25, 0x08, 0xce, 0x17, 0x12, 0xe0, 0x62, 0x2e, 0x29, 0xc9, 0x91, 0x60, 0x03, 0x0b, 0x83,
|
||||
0x98, 0x42, 0x62, 0x5c, 0x6c, 0x05, 0xa5, 0x49, 0xde, 0xa9, 0x95, 0x12, 0xec, 0x60, 0x73, 0xa0,
|
||||
0x3c, 0x25, 0x71, 0x2e, 0x1e, 0x64, 0xfb, 0x85, 0xd8, 0xb9, 0x98, 0x5d, 0xfd, 0x7d, 0x04, 0x18,
|
||||
0x9c, 0x78, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0x46, 0x40,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x32, 0x35, 0xc7, 0xf2, 0x25, 0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *IpnsEntry) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *IpnsEntry) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.Value == nil {
|
||||
return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value")
|
||||
} else {
|
||||
dAtA[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintIpns(dAtA, i, uint64(len(m.Value)))
|
||||
i += copy(dAtA[i:], m.Value)
|
||||
}
|
||||
if m.Signature == nil {
|
||||
return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("signature")
|
||||
} else {
|
||||
dAtA[i] = 0x12
|
||||
i++
|
||||
i = encodeVarintIpns(dAtA, i, uint64(len(m.Signature)))
|
||||
i += copy(dAtA[i:], m.Signature)
|
||||
}
|
||||
if m.ValidityType != nil {
|
||||
dAtA[i] = 0x18
|
||||
i++
|
||||
i = encodeVarintIpns(dAtA, i, uint64(*m.ValidityType))
|
||||
}
|
||||
if m.Validity != nil {
|
||||
dAtA[i] = 0x22
|
||||
i++
|
||||
i = encodeVarintIpns(dAtA, i, uint64(len(m.Validity)))
|
||||
i += copy(dAtA[i:], m.Validity)
|
||||
}
|
||||
if m.Sequence != nil {
|
||||
dAtA[i] = 0x28
|
||||
i++
|
||||
i = encodeVarintIpns(dAtA, i, uint64(*m.Sequence))
|
||||
}
|
||||
if m.Ttl != nil {
|
||||
dAtA[i] = 0x30
|
||||
i++
|
||||
i = encodeVarintIpns(dAtA, i, uint64(*m.Ttl))
|
||||
}
|
||||
if m.PubKey != nil {
|
||||
dAtA[i] = 0x3a
|
||||
i++
|
||||
i = encodeVarintIpns(dAtA, i, uint64(len(m.PubKey)))
|
||||
i += copy(dAtA[i:], m.PubKey)
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
i += copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func encodeVarintIpns(dAtA []byte, offset int, v uint64) int {
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return offset + 1
|
||||
}
|
||||
func (m *IpnsEntry) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.Value != nil {
|
||||
l = len(m.Value)
|
||||
n += 1 + l + sovIpns(uint64(l))
|
||||
}
|
||||
if m.Signature != nil {
|
||||
l = len(m.Signature)
|
||||
n += 1 + l + sovIpns(uint64(l))
|
||||
}
|
||||
if m.ValidityType != nil {
|
||||
n += 1 + sovIpns(uint64(*m.ValidityType))
|
||||
}
|
||||
if m.Validity != nil {
|
||||
l = len(m.Validity)
|
||||
n += 1 + l + sovIpns(uint64(l))
|
||||
}
|
||||
if m.Sequence != nil {
|
||||
n += 1 + sovIpns(uint64(*m.Sequence))
|
||||
}
|
||||
if m.Ttl != nil {
|
||||
n += 1 + sovIpns(uint64(*m.Ttl))
|
||||
}
|
||||
if m.PubKey != nil {
|
||||
l = len(m.PubKey)
|
||||
n += 1 + l + sovIpns(uint64(l))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovIpns(x uint64) (n int) {
|
||||
for {
|
||||
n++
|
||||
x >>= 7
|
||||
if x == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
func sozIpns(x uint64) (n int) {
|
||||
return sovIpns(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *IpnsEntry) Unmarshal(dAtA []byte) error {
|
||||
var hasFields [1]uint64
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowIpns
|
||||
}
|
||||
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: IpnsEntry: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: IpnsEntry: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowIpns
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthIpns
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthIpns
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.Value == nil {
|
||||
m.Value = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
hasFields[0] |= uint64(0x00000001)
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowIpns
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthIpns
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthIpns
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.Signature == nil {
|
||||
m.Signature = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
hasFields[0] |= uint64(0x00000002)
|
||||
case 3:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ValidityType", wireType)
|
||||
}
|
||||
var v IpnsEntry_ValidityType
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowIpns
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= IpnsEntry_ValidityType(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.ValidityType = &v
|
||||
case 4:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Validity", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowIpns
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthIpns
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthIpns
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Validity = append(m.Validity[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.Validity == nil {
|
||||
m.Validity = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 5:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType)
|
||||
}
|
||||
var v uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowIpns
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.Sequence = &v
|
||||
case 6:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType)
|
||||
}
|
||||
var v uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowIpns
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.Ttl = &v
|
||||
case 7:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field PubKey", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowIpns
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthIpns
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthIpns
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.PubKey = append(m.PubKey[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.PubKey == nil {
|
||||
m.PubKey = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipIpns(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthIpns
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
return ErrInvalidLengthIpns
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
if hasFields[0]&uint64(0x00000001) == 0 {
|
||||
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value")
|
||||
}
|
||||
if hasFields[0]&uint64(0x00000002) == 0 {
|
||||
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("signature")
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipIpns(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowIpns
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowIpns
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
return iNdEx, nil
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowIpns
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthIpns
|
||||
}
|
||||
iNdEx += length
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthIpns
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 3:
|
||||
for {
|
||||
var innerWire uint64
|
||||
var start int = iNdEx
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowIpns
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
innerWire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
innerWireType := int(innerWire & 0x7)
|
||||
if innerWireType == 4 {
|
||||
break
|
||||
}
|
||||
next, err := skipIpns(dAtA[start:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
iNdEx = start + next
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthIpns
|
||||
}
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 4:
|
||||
return iNdEx, nil
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
return iNdEx, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthIpns = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowIpns = fmt.Errorf("proto: integer overflow")
|
||||
)
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
syntax = "proto2";
|
||||
|
||||
package ipns.pb;
|
||||
|
||||
message IpnsEntry {
|
||||
enum ValidityType {
|
||||
// setting an EOL says "this record is valid until..."
|
||||
EOL = 0;
|
||||
}
|
||||
required bytes value = 1;
|
||||
required bytes signature = 2;
|
||||
|
||||
optional ValidityType validityType = 3;
|
||||
optional bytes validity = 4;
|
||||
|
||||
optional uint64 sequence = 5;
|
||||
|
||||
optional uint64 ttl = 6;
|
||||
|
||||
// in order for nodes to properly validate a record upon receipt, they need the public
|
||||
// key associated with it. For old RSA keys, its easiest if we just send this as part of
|
||||
// the record itself. For newer ed25519 keys, the public key can be embedded in the
|
||||
// peerID, making this field unnecessary.
|
||||
optional bytes pubKey = 7;
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package ipns
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
|
||||
pb "github.com/ipfs/go-ipns/pb"
|
||||
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
logging "github.com/ipfs/go-log"
|
||||
ic "github.com/libp2p/go-libp2p-crypto"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
pstore "github.com/libp2p/go-libp2p-peerstore"
|
||||
record "github.com/libp2p/go-libp2p-record"
|
||||
)
|
||||
|
||||
var log = logging.Logger("ipns")
|
||||
|
||||
var _ record.Validator = Validator{}
|
||||
|
||||
// RecordKey returns the libp2p record key for a given peer ID.
|
||||
func RecordKey(pid peer.ID) string {
|
||||
return "/ipns/" + string(pid)
|
||||
}
|
||||
|
||||
// Validator is an IPNS record validator that satisfies the libp2p record
|
||||
// validator interface.
|
||||
type Validator struct {
|
||||
// KeyBook, if non-nil, will be used to lookup keys for validating IPNS
|
||||
// records.
|
||||
KeyBook pstore.KeyBook
|
||||
}
|
||||
|
||||
// Validate validates an IPNS record.
|
||||
func (v Validator) Validate(key string, value []byte) error {
|
||||
ns, pidString, err := record.SplitKey(key)
|
||||
if err != nil || ns != "ipns" {
|
||||
return ErrInvalidPath
|
||||
}
|
||||
|
||||
// Parse the value into an IpnsEntry
|
||||
entry := new(pb.IpnsEntry)
|
||||
err = proto.Unmarshal(value, entry)
|
||||
if err != nil {
|
||||
return ErrBadRecord
|
||||
}
|
||||
|
||||
// Get the public key defined by the ipns path
|
||||
pid, err := peer.IDFromString(pidString)
|
||||
if err != nil {
|
||||
log.Debugf("failed to parse ipns record key %s into peer ID", pidString)
|
||||
return ErrKeyFormat
|
||||
}
|
||||
|
||||
pubk, err := v.getPublicKey(pid, entry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return Validate(pubk, entry)
|
||||
}
|
||||
|
||||
func (v Validator) getPublicKey(pid peer.ID, entry *pb.IpnsEntry) (ic.PubKey, error) {
|
||||
switch pk, err := ExtractPublicKey(pid, entry); err {
|
||||
case peer.ErrNoPublicKey:
|
||||
case nil:
|
||||
return pk, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if v.KeyBook == nil {
|
||||
log.Debugf("public key with hash %s not found in IPNS record and no peer store provided", pid)
|
||||
return nil, ErrPublicKeyNotFound
|
||||
}
|
||||
|
||||
pubk := v.KeyBook.PubKey(pid)
|
||||
if pubk == nil {
|
||||
log.Debugf("public key with hash %s not found in peer store", pid)
|
||||
return nil, ErrPublicKeyNotFound
|
||||
}
|
||||
return pubk, nil
|
||||
}
|
||||
|
||||
// Select selects the best record by checking which has the highest sequence
|
||||
// number and latest EOL.
|
||||
//
|
||||
// This function returns an error if any of the records fail to parse. Validate
|
||||
// your records first!
|
||||
func (v Validator) Select(k string, vals [][]byte) (int, error) {
|
||||
var recs []*pb.IpnsEntry
|
||||
for _, v := range vals {
|
||||
e := new(pb.IpnsEntry)
|
||||
if err := proto.Unmarshal(v, e); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
recs = append(recs, e)
|
||||
}
|
||||
|
||||
return selectRecord(recs, vals)
|
||||
}
|
||||
|
||||
func selectRecord(recs []*pb.IpnsEntry, vals [][]byte) (int, error) {
|
||||
switch len(recs) {
|
||||
case 0:
|
||||
return -1, errors.New("no usable records in given set")
|
||||
case 1:
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var i int
|
||||
for j := 1; j < len(recs); j++ {
|
||||
cmp, err := Compare(recs[i], recs[j])
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
if cmp == 0 {
|
||||
cmp = bytes.Compare(vals[i], vals[j])
|
||||
}
|
||||
if cmp < 0 {
|
||||
i = j
|
||||
}
|
||||
}
|
||||
|
||||
return i, nil
|
||||
}
|
||||
Reference in New Issue
Block a user