From 5da064fdc400e3fa572f6e446fa6084d6686b607 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sun, 17 Jan 2021 01:57:07 +0530 Subject: [PATCH 01/71] all: switch from merkle tree to serial hash --- Makefile | 52 +- blob/blob.go | 29 +- blob/blob_test.go | 7 +- blob/consts.go | 4 +- blob/hash.go | 89 ++ blob/io.go | 5 +- blob/io_test.go | 7 +- blob/merkle.go | 16 +- blob/merkle_test.go | 20 +- blob/pathify.go | 2 +- blob/seal.go | 20 +- blob/seal_test.go | 18 +- blob/store.go | 9 + blob/store_test.go | 2 +- blob/transaction.go | 18 +- blob/util_test.go | 2 +- cli/homedir.go | 2 +- cli/signer.go | 4 +- cmd/{fnd-cli => ddrpcli}/cmd/blob/blob.go | 2 +- cmd/{fnd-cli => ddrpcli}/cmd/blob/info.go | 23 +- cmd/{fnd-cli => ddrpcli}/cmd/blob/list.go | 10 +- cmd/{fnd-cli => ddrpcli}/cmd/blob/read.go | 8 +- cmd/{fnd-cli => ddrpcli}/cmd/blob/write.go | 38 +- cmd/{fnd-cli => ddrpcli}/cmd/identity.go | 9 +- cmd/{fnd-cli => ddrpcli}/cmd/init.go | 4 +- cmd/{fnd-cli => ddrpcli}/cmd/net/add_peer.go | 8 +- cmd/{fnd-cli => ddrpcli}/cmd/net/ban_peer.go | 8 +- cmd/{fnd-cli => ddrpcli}/cmd/net/net.go | 2 +- cmd/{fnd-cli => ddrpcli}/cmd/net/peer_info.go | 10 +- cmd/{fnd-cli => ddrpcli}/cmd/net/status.go | 8 +- .../cmd/net/unban_peer.go | 10 +- cmd/{fnd-cli => ddrpcli}/cmd/root.go | 14 +- .../cmd/unsafe/reset_blobs.go | 10 +- .../cmd/unsafe/reset_name_store.go | 10 +- .../cmd/unsafe/reset_peer_store.go | 10 +- cmd/{fnd-cli => ddrpcli}/cmd/unsafe/unsafe.go | 2 +- cmd/{fnd-cli => ddrpcli}/cmd/version.go | 4 +- cmd/ddrpcli/main.go | 7 + cmd/{fnd => ddrpd}/cmd/init.go | 6 +- cmd/{fnd => ddrpd}/cmd/root.go | 10 +- cmd/{fnd => ddrpd}/cmd/start.go | 36 +- cmd/{fnd => ddrpd}/cmd/version.go | 4 +- cmd/{fnd => ddrpd}/main.go | 2 +- cmd/fnd-cli/main.go | 7 - config/config.go | 12 +- config/default.go | 87 +- config/home.go | 2 +- dwire/.gitignore | 18 + dwire/Makefile | 8 + dwire/README.md | 167 +++ dwire/decode.go | 228 ++++ dwire/decode_test.go | 166 +++ dwire/doc.go | 54 + dwire/encode.go | 135 +++ dwire/encode_test.go | 105 ++ dwire/encoder.go | 42 + dwire/encoding_bench_test.go | 107 ++ dwire/well_known.go | 62 + dwire/well_known_test.go | 37 + go.mod | 17 +- go.sum | 34 +- p2p/counting_reader_test.go | 2 +- p2p/envelope_io.go | 4 +- p2p/incoming_handshake.go | 4 +- p2p/incoming_handshake_test.go | 37 +- p2p/listener.go | 4 +- p2p/outgoing_handshake.go | 6 +- p2p/outgoing_handshake_test.go | 8 +- p2p/peer.go | 4 +- p2p/peer_manager.go | 10 +- p2p/peer_muxer.go | 8 +- p2p/peer_test.go | 4 +- p2p/seed_test.go | 10 +- p2p/seeds.go | 2 +- packaging/scripts/after_install.sh | 12 +- packaging/scripts/after_remove.sh | 4 +- protocol/ban_list.go | 6 +- protocol/ban_list_test.go | 36 +- protocol/epoch.go | 34 + protocol/epoch_test.go | 279 +++++ protocol/heartbeater.go | 8 +- protocol/heartbeater_test.go | 6 +- protocol/moderation.go | 6 +- protocol/moderation_test.go | 10 +- protocol/name_importer.go | 46 +- protocol/name_importer_test.go | 22 +- protocol/name_syncer.go | 28 +- protocol/peer_exchanger.go | 14 +- protocol/peer_set.go | 2 +- protocol/peer_set_test.go | 2 +- protocol/pinger.go | 8 +- protocol/pinger_test.go | 10 +- protocol/sector_server.go | 121 +- protocol/syncer.go | 296 ++--- protocol/syncer_test.go | 12 +- protocol/testdata/blob | Bin 16777217 -> 16777216 bytes protocol/testdata/block8506.json | 2 +- protocol/transaction_mock_test.go | 2 +- protocol/update_queue.go | 124 +- protocol/update_queue_test.go | 134 +-- protocol/update_server.go | 25 +- protocol/update_server_test.go | 86 +- protocol/updater.go | 214 ++-- protocol/updater_test.go | 221 ++-- protocol/util_test.go | 2 +- rpc/blob.go | 23 +- rpc/blob_reader.go | 8 +- rpc/blob_writer.go | 148 +-- rpc/net.go | 22 +- rpc/server.go | 153 +-- rpc/v1/api.pb.go | 1040 ++++++----------- rpc/v1/api.proto | 49 +- scripts/gen-node-bindings.sh | 2 +- scripts/release-public.sh | 36 +- store/headers.go | 116 +- store/headers_test.go | 28 +- store/naming_test.go | 2 +- store/peers.go | 2 +- store/peers_test.go | 2 +- store/store.go | 2 +- testutil/mockapp/null.go | 32 + testutil/mockapp/peer.go | 8 +- testutil/mockapp/storage.go | 52 +- testutil/net.go | 4 +- testutil/testcrypto/crypto.go | 2 +- testutil/testflags/flags.go | 4 +- testutil/testfs/fs.go | 4 +- version/version.go | 2 +- wire/blob_req.go | 55 + wire/blob_req_test.go | 15 + wire/blob_res.go | 67 ++ wire/blob_res_test.go | 18 + wire/envelope.go | 17 +- wire/hash_cacher.go | 5 +- wire/hash_cacher_test.go | 7 +- wire/hello.go | 7 +- wire/hello_ack.go | 5 +- wire/hello_test.go | 2 +- wire/message.go | 23 +- wire/nil_update.go | 5 +- wire/peer_req.go | 2 +- wire/peer_res.go | 5 +- wire/ping.go | 2 +- wire/sector_req.go | 50 - wire/sector_req_test.go | 14 - wire/sector_res.go | 55 - wire/sector_res_test.go | 16 - wire/testdata/blob_req | Bin 0 -> 14 bytes wire/testdata/blob_res | Bin 0 -> 79 bytes wire/testdata/hello | Bin 109 -> 108 bytes wire/testdata/hello_ack | Bin 33 -> 32 bytes wire/testdata/nil_update | 2 +- wire/testdata/peer_res | Bin 98 -> 97 bytes wire/testdata/update | Bin 143 -> 142 bytes wire/testdata/update_req | Bin 14 -> 13 bytes wire/tree_base_req.go | 46 - wire/tree_base_req_test.go | 13 - wire/tree_base_res.go | 49 - wire/tree_base_res_test.go | 15 - wire/update.go | 32 +- wire/update_req.go | 20 +- wire/update_req_test.go | 6 +- wire/update_test.go | 11 +- wire/util_test.go | 11 +- 164 files changed, 3529 insertions(+), 2511 deletions(-) create mode 100644 blob/hash.go rename cmd/{fnd-cli => ddrpcli}/cmd/blob/blob.go (76%) rename cmd/{fnd-cli => ddrpcli}/cmd/blob/info.go (79%) rename cmd/{fnd-cli => ddrpcli}/cmd/blob/list.go (84%) rename cmd/{fnd-cli => ddrpcli}/cmd/blob/read.go (73%) rename cmd/{fnd-cli => ddrpcli}/cmd/blob/write.go (73%) rename cmd/{fnd-cli => ddrpcli}/cmd/identity.go (78%) rename cmd/{fnd-cli => ddrpcli}/cmd/init.go (78%) rename cmd/{fnd-cli => ddrpcli}/cmd/net/add_peer.go (86%) rename cmd/{fnd-cli => ddrpcli}/cmd/net/ban_peer.go (81%) rename cmd/{fnd-cli => ddrpcli}/cmd/net/net.go (71%) rename cmd/{fnd-cli => ddrpcli}/cmd/net/peer_info.go (90%) rename cmd/{fnd-cli => ddrpcli}/cmd/net/status.go (85%) rename cmd/{fnd-cli => ddrpcli}/cmd/net/unban_peer.go (69%) rename cmd/{fnd-cli => ddrpcli}/cmd/root.go (64%) rename cmd/{fnd-cli => ddrpcli}/cmd/unsafe/reset_blobs.go (76%) rename cmd/{fnd-cli => ddrpcli}/cmd/unsafe/reset_name_store.go (69%) rename cmd/{fnd-cli => ddrpcli}/cmd/unsafe/reset_peer_store.go (69%) rename cmd/{fnd-cli => ddrpcli}/cmd/unsafe/unsafe.go (92%) rename cmd/{fnd-cli => ddrpcli}/cmd/version.go (70%) create mode 100644 cmd/ddrpcli/main.go rename cmd/{fnd => ddrpd}/cmd/init.go (66%) rename cmd/{fnd => ddrpd}/cmd/root.go (71%) rename cmd/{fnd => ddrpd}/cmd/start.go (93%) rename cmd/{fnd => ddrpd}/cmd/version.go (69%) rename cmd/{fnd => ddrpd}/main.go (57%) delete mode 100644 cmd/fnd-cli/main.go create mode 100644 dwire/.gitignore create mode 100644 dwire/Makefile create mode 100644 dwire/README.md create mode 100644 dwire/decode.go create mode 100644 dwire/decode_test.go create mode 100644 dwire/doc.go create mode 100644 dwire/encode.go create mode 100644 dwire/encode_test.go create mode 100644 dwire/encoder.go create mode 100644 dwire/encoding_bench_test.go create mode 100644 dwire/well_known.go create mode 100644 dwire/well_known_test.go create mode 100644 protocol/epoch.go create mode 100644 protocol/epoch_test.go create mode 100644 testutil/mockapp/null.go create mode 100644 wire/blob_req.go create mode 100644 wire/blob_req_test.go create mode 100644 wire/blob_res.go create mode 100644 wire/blob_res_test.go delete mode 100644 wire/sector_req.go delete mode 100644 wire/sector_req_test.go delete mode 100644 wire/sector_res.go delete mode 100644 wire/sector_res_test.go create mode 100644 wire/testdata/blob_req create mode 100644 wire/testdata/blob_res delete mode 100644 wire/tree_base_req.go delete mode 100644 wire/tree_base_req_test.go delete mode 100644 wire/tree_base_res.go delete mode 100644 wire/tree_base_res_test.go diff --git a/Makefile b/Makefile index ba653d0..3ab6814 100644 --- a/Makefile +++ b/Makefile @@ -1,35 +1,33 @@ fpm = @docker run --rm -i -v "$(CURDIR):$(CURDIR)" -w "$(CURDIR)" -u $(shell id -u) digitalocean/fpm:latest git_commit := $(shell git log -1 --format='%H') git_tag := $(shell git describe --tags --abbrev=0) -ldflags = -X fnd/version.GitCommit=$(git_commit) -X fnd/version.GitTag=$(git_tag) +ldflags = -X github.com/ddrp-org/ddrp/version.GitCommit=$(git_commit) -X github.com/ddrp-org/ddrp/version.GitTag=$(git_tag) build_flags := -ldflags '$(ldflags)' -all: fnd fnd-cli +all: ddrpd ddrpcli .PHONY: all all-cross: - GOOS=darwin GOARCH=amd64 go build $(build_flags) -o ./build/fnd-darwin-amd64 ./cmd/fnd/main.go - GOOS=darwin GOARCH=amd64 go build $(build_flags) -o ./build/fnd-cli-darwin-amd64 ./cmd/fnd-cli/main.go - GOOS=linux GOARCH=amd64 go build $(build_flags) -o ./build/fnd-linux-amd64 ./cmd/fnd/main.go - GOOS=windows GOARCH=amd64 go build $(build_flags) -o ./build/fnd-win-amd64.exe ./cmd/fnd/main.go - GOOS=windows GOARCH=amd64 go build $(build_flags) -o ./build/fnd-cli-win-amd64.exe ./cmd/fnd/main.go - GOOS=linux GOARCH=amd64 go build $(build_flags) -o ./build/fnd-cli-linux-amd64 ./cmd/fnd-cli/main.go + GOOS=darwin GOARCH=amd64 go build $(build_flags) -o ./build/ddrpd-darwin-amd64 ./cmd/ddrpd/main.go + GOOS=darwin GOARCH=amd64 go build $(build_flags) -o ./build/ddrpcli-darwin-amd64 ./cmd/ddrpcli/main.go + GOOS=linux GOARCH=amd64 go build $(build_flags) -o ./build/ddrpd-linux-amd64 ./cmd/ddrpd/main.go + GOOS=linux GOARCH=amd64 go build $(build_flags) -o ./build/ddrpcli-linux-amd64 ./cmd/ddrpcli/main.go .PHONY: all-cross -fnd-cli: proto - go build $(build_flags) -o ./build/fnd-cli ./cmd/fnd-cli/main.go -.PHONY: fnd-cli +ddrpcli: proto + go build $(build_flags) -o ./build/ddrpcli ./cmd/ddrpcli/main.go +.PHONY: ddrpcli -fnd: proto - go build $(build_flags) -o ./build/fnd ./cmd/fnd/main.go -.PHONY: fnd +ddrpd: proto + go build $(build_flags) -o ./build/ddrpd ./cmd/ddrpd/main.go +.PHONY: ddrpd proto: protoc -I rpc/v1/ rpc/v1/api.proto --go_out=plugins=grpc:rpc/v1 .PHONY: proto test: proto - go test ./... -v + go test ./... -v -timeout 1m .PHONY: test install: all @@ -53,23 +51,23 @@ package-deb: all-cross --input-type dir \ --force \ --architecture amd64 \ - --package ./build/fnd-$(version)-amd64.deb \ + --package ./build/ddrp-$(version)-amd64.deb \ --no-depends \ - --name fnd \ - --maintainer "The Footnote Maintainers" \ + --name ddrp \ + --maintainer "The DDRP Maintainers" \ --version $(version) \ - --description "Footnote Network Daemon" \ + --description "DDRP Network Daemon" \ --license MIT \ - --vendor "The Footnote Maintainers" \ - --url "https://fnd.network" \ + --vendor "The DDRP Maintainers" \ + --url "https://ddrp.network" \ --log info \ - --deb-user fnd \ + --deb-user ddrp \ --deb-group nobody \ --after-install packaging/scripts/after_install.sh \ --after-remove packaging/scripts/after_remove.sh \ - --config-files /lib/systemd/system/fnd.service \ - build/fnd-linux-amd64=/usr/bin/fnd \ - build/fnd-cli-linux-amd64=/usr/bin/fnd-cli \ - packaging/lib/systemd/system/fnd.service=/lib/systemd/system/fnd.service - @docker run --rm -i -v "$(CURDIR):$(CURDIR)" -w "$(CURDIR)" ubuntu:xenial /bin/bash -c 'dpkg --info ./build/fnd-$(version)-amd64.deb && dpkg -c ./build/fnd-$(version)-amd64.deb' + --config-files /lib/systemd/system/ddrpd.service \ + build/ddrpd-linux-amd64=/usr/bin/ddrpd \ + build/ddrpcli-linux-amd64=/usr/bin/ddrpcli \ + packaging/lib/systemd/system/ddrpd.service=/lib/systemd/system/ddrpd.service + @docker run --rm -i -v "$(CURDIR):$(CURDIR)" -w "$(CURDIR)" ubuntu:xenial /bin/bash -c 'dpkg --info ./build/ddrp-$(version)-amd64.deb && dpkg -c ./build/ddrp-$(version)-amd64.deb' .PHONY: package-deb diff --git a/blob/blob.go b/blob/blob.go index e7433e3..58c848b 100644 --- a/blob/blob.go +++ b/blob/blob.go @@ -1,11 +1,12 @@ package blob import ( - "github.com/pkg/errors" "io" "io/ioutil" "os" "sync" + + "github.com/pkg/errors" ) type SectorReader interface { @@ -22,12 +23,15 @@ type Blob interface { io.Closer Readable Transaction() (Transaction, error) + Seek(uint16) + At() uint16 } type blobImpl struct { - f *os.File - name string - mu sync.Mutex + f *os.File + sectorSize uint16 + name string + mu sync.Mutex } func newFromFile(name string, f *os.File) Blob { @@ -41,6 +45,14 @@ func (b *blobImpl) Name() string { return b.name } +func (b *blobImpl) Seek(sectorSize uint16) { + b.sectorSize = sectorSize +} + +func (b *blobImpl) At() uint16 { + return b.sectorSize +} + func (b *blobImpl) ReadSector(id uint8) (Sector, error) { b.mu.Lock() defer b.mu.Unlock() @@ -55,10 +67,11 @@ func (b *blobImpl) ReadAt(p []byte, off int64) (int, error) { func (b *blobImpl) Transaction() (Transaction, error) { return &txImpl{ - name: b.name, - cloner: b.txCloner, - committer: b.txCommitter, - remover: b.txRemover, + name: b.name, + sectorSize: b.sectorSize, + cloner: b.txCloner, + committer: b.txCommitter, + remover: b.txRemover, }, nil } diff --git a/blob/blob_test.go b/blob/blob_test.go index e5e430e..af709b8 100644 --- a/blob/blob_test.go +++ b/blob/blob_test.go @@ -2,9 +2,10 @@ package blob import ( "crypto/rand" - "github.com/stretchr/testify/require" "io" "testing" + + "github.com/stretchr/testify/require" ) // note: transaction functionality is tested in transaction_test.go @@ -18,13 +19,13 @@ func TestBlob_Reading(t *testing.T) { require.Equal(t, "foobar", bl.Name()) var expSector Sector - _, err = f.ReadAt(expSector[:], 65536) + _, err = f.ReadAt(expSector[:], 256) require.NoError(t, err) actSector, err := bl.ReadSector(1) require.NoError(t, err) require.Equal(t, expSector, actSector) actData := make([]byte, 10, 10) - _, err = bl.ReadAt(actData, 65536) + _, err = bl.ReadAt(actData, 256) require.NoError(t, err) require.EqualValues(t, expSector[:10], actData) } diff --git a/blob/consts.go b/blob/consts.go index 43e0668..e406d6a 100644 --- a/blob/consts.go +++ b/blob/consts.go @@ -2,8 +2,8 @@ package blob const ( HeaderLen = 1 + 1 + 63 + 8 + 32 + 65 - SectorLen = 4096 - SectorCount = 256 + SectorLen = 256 + SectorCount = 4096 Size = SectorLen * SectorCount CurrentVersion = 1 ) diff --git a/blob/hash.go b/blob/hash.go new file mode 100644 index 0000000..06559f6 --- /dev/null +++ b/blob/hash.go @@ -0,0 +1,89 @@ +package blob + +import ( + "io" + + "github.com/ddrp-org/ddrp/crypto" + "golang.org/x/crypto/blake2b" +) + +var ( + ZeroHash crypto.Hash + ZeroSectorHashes SectorHashes +) + +type SectorHashes [SectorCount]crypto.Hash + +func (s SectorHashes) Encode(w io.Writer) error { + for _, h := range s { + if _, err := w.Write(h[:]); err != nil { + return err + } + } + return nil +} + +func (s *SectorHashes) Decode(r io.Reader) error { + var res SectorHashes + var hash crypto.Hash + for i := 0; i < len(res); i++ { + if _, err := r.Read(hash[:]); err != nil { + return err + } + res[i] = hash + } + + *s = res + return nil +} + +func (s SectorHashes) DiffWith(other SectorHashes) int { + if s == other { + return -1 + } + + var i int + for i = 0; i < len(s); i++ { + if s[i] != other[i] { + break + } + } + return i +} + +func (s SectorHashes) Tip() crypto.Hash { + var i int + for i = 0; i < SectorCount; i++ { + if s[i] == ZeroHash { + break + } + } + if i == 0 { + return crypto.ZeroHash + } + return s[i-1] +} + +func SerialHashSector(sector Sector, prevHash crypto.Hash) crypto.Hash { + var res crypto.Hash + hasher, _ := blake2b.New256(nil) + hasher.Write(prevHash[:]) + hasher.Write(sector[:]) + h := hasher.Sum(nil) + copy(res[:], h) + return res +} + +// SerialHash returns serial hash of the contents of the reader br +func SerialHash(br io.Reader, prevHash crypto.Hash, sectorSize uint16) (SectorHashes, error) { + var res SectorHashes + var sector Sector + for i := 0; i < int(sectorSize); i++ { + if _, err := br.Read(sector[:]); err != nil { + return ZeroSectorHashes, err + } + res[i] = SerialHashSector(sector, prevHash) + prevHash = res[i] + } + return res, nil +} diff --git a/blob/io.go b/blob/io.go index bdd57be..0b3cb7e 100644 --- a/blob/io.go +++ b/blob/io.go @@ -1,8 +1,9 @@ package blob import ( - "github.com/pkg/errors" "io" + + "github.com/pkg/errors" ) var ( @@ -47,7 +48,7 @@ func WriteBlobAt(w io.WriterAt, b []byte, off int64) (int, error) { return w.WriteAt(b, off) } -func WriteSector(w io.WriterAt, id uint8, sector Sector) error { +func WriteSector(w io.WriterAt, id uint16, sector Sector) error { _, err := w.WriteAt(sector[:], int64(id)*int64(SectorLen)) return err } diff --git a/blob/io_test.go b/blob/io_test.go index ab2d454..2dd6995 100644 --- a/blob/io_test.go +++ b/blob/io_test.go @@ -1,9 +1,10 @@ package blob import ( - "github.com/stretchr/testify/require" "io" "testing" + + "github.com/stretchr/testify/require" ) type zeroReader struct{} @@ -110,7 +111,7 @@ func TestReadSector(t *testing.T) { }, { 255, - 16711680, + 65280, }, } r := &readerWrapper{ @@ -189,7 +190,7 @@ func TestWriteSector(t *testing.T) { }, { 255, - 16711680, + 65280, }, } w := &writerWrapper{ diff --git a/blob/merkle.go b/blob/merkle.go index 006bce2..e5112e6 100644 --- a/blob/merkle.go +++ b/blob/merkle.go @@ -2,19 +2,20 @@ package blob import ( "bytes" - "fnd/crypto" - "github.com/pkg/errors" "io" "math" "math/bits" "strings" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/pkg/errors" ) const ( MerkleTreeHeight = 8 MerkleProofLen = 8 * 32 - SubsectorSize = 4096 + SubsectorSize = 256 SubsectorCountBlob = Size / SubsectorSize SubsectorCountSector = SectorLen / SubsectorSize SubsectorProofLevel = 8 @@ -38,11 +39,10 @@ var ( {0xaa, 0xbd, 0xcb, 0xb2, 0x3b, 0xfc, 0xea, 0xfe, 0x71, 0xf3, 0x83, 0x4a, 0x17, 0xec, 0x1d, 0x24, 0xbd, 0x4e, 0xf2, 0xda, 0xed, 0x68, 0xd2, 0xcc, 0xc3, 0xc2, 0x98, 0x9f, 0xd0, 0x92, 0xe3, 0x53}: {0x7d, 0x1e, 0x84, 0xe6, 0x2d, 0x7e, 0xc9, 0xf6, 0xbc, 0x3f, 0x88, 0x66, 0x75, 0x73, 0x3d, 0xa0, 0x6d, 0xaf, 0x02, 0x77, 0xad, 0x8f, 0xfc, 0xf7, 0xc5, 0x39, 0x93, 0x8c, 0xa5, 0xee, 0x9c, 0xf2}, } - zero4kSector = make([]byte, 4096) - zero4kSectorHash = crypto.Hash{0x68, 0x6e, 0xde, 0x92, 0x88, 0xc3, 0x91, 0xe7, 0xe0, 0x50, 0x26, 0xe5, 0x6f, 0x2f, 0x91, 0xbf, 0xd8, 0x79, 0x98, 0x7a, 0x04, 0x0e, 0xa9, 0x84, 0x45, 0xda, 0xbc, 0x76, 0xf5, 0x5b, 0x8e, 0x5f} - - EmptyBlobMerkleRoot = crypto.Hash{0x7d, 0x1e, 0x84, 0xe6, 0x2d, 0x7e, 0xc9, 0xf6, 0xbc, 0x3f, 0x88, 0x66, 0x75, 0x73, 0x3d, 0xa0, 0x6d, 0xaf, 0x02, 0x77, 0xad, 0x8f, 0xfc, 0xf7, 0xc5, 0x39, 0x93, 0x8c, 0xa5, 0xee, 0x9c, 0xf2} - EmptyBlobBaseHash = crypto.Hash{0x53, 0x2a, 0x12, 0xf0, 0x9f, 0xeb, 0xf8, 0x52, 0x14, 0x19, 0x95, 0x99, 0x73, 0xad, 0x53, 0x46, 0x94, 0x4c, 0x2b, 0x22, 0xbf, 0x76, 0x4d, 0x0e, 0x1a, 0x34, 0x25, 0x5b, 0x65, 0x64, 0xfe, 0x4b} + zero4kSector = make([]byte, 4096) + zero4kSectorHash = crypto.Hash{0x68, 0x6e, 0xde, 0x92, 0x88, 0xc3, 0x91, 0xe7, 0xe0, 0x50, 0x26, 0xe5, 0x6f, 0x2f, 0x91, 0xbf, 0xd8, 0x79, 0x98, 0x7a, 0x04, 0x0e, 0xa9, 0x84, 0x45, 0xda, 0xbc, 0x76, 0xf5, 0x5b, 0x8e, 0x5f} + EmptyBlobMerkleRoot = crypto.Hash{0x0c, 0x63, 0x8a, 0xfe, 0x73, 0x32, 0x49, 0x76, 0x16, 0x59, 0x07, 0xbc, 0x33, 0x86, 0x2e, 0xbf, 0x74, 0xe9, 0x71, 0x32, 0x66, 0x6e, 0x6a, 0x68, 0x15, 0x4f, 0xe9, 0xf7, 0x42, 0xf4, 0x45, 0x7f} + EmptyBlobBaseHash = crypto.Hash{0xe, 0x57, 0x51, 0xc0, 0x26, 0xe5, 0x43, 0xb2, 0xe8, 0xab, 0x2e, 0xb0, 0x60, 0x99, 0xda, 0xa1, 0xd1, 0xe5, 0xdf, 0x47, 0x77, 0x8f, 0x77, 0x87, 0xfa, 0xab, 0x45, 0xcd, 0xf1, 0x2f, 0xe3, 0xa8} ZeroMerkleBase MerkleBase ) diff --git a/blob/merkle_test.go b/blob/merkle_test.go index f41db34..5fba05a 100644 --- a/blob/merkle_test.go +++ b/blob/merkle_test.go @@ -4,20 +4,14 @@ import ( "bytes" "crypto/rand" "encoding/hex" - "fnd/testutil/testfs" - "github.com/stretchr/testify/require" "io" "testing" + + "github.com/ddrp-org/ddrp/testutil/testfs" + "github.com/stretchr/testify/require" ) -const expProof = "532a12f09febf8521419959973ad5346944c2b22bf764d0e1a34255b6564fe4b" + - "ffe2cf7ecd1b993235746be21e91c8e61a1e22dace9850912585416501e98447" + - "60522e01341fe96254668ba1bc2c79dd6fc66b3784c2eb39d4f07319c6232657" + - "ae0182ab7803fc44d085c1c734a552fffdb0f744179f0d95bd60dd6f8f1818af" + - "f34c7d70b652eba48e02b4717e1f0a2be9337b0751ccf7bf3644674cbe6423d5" + - "3200b99bfcd82c64c818b1a2b26e14bf784fe9188a559b6b38a6dda4fb553147" + - "b86be3a8b288b0ef0b7ee5a9852d118167a50c8471bfb9fb8f0c7992f452c79c" + - "aabdcbb23bfceafe71f3834a17ec1d24bd4ef2daed68d2ccc3c2989fd092e353" +const expProof = "d87e2783f806556be18f0d7d71324c9efa47d76dcb6ab20ebfb1bd11fcdd8e16159fb570f424dd23426b626a4274af3fb0673a3d94df9ec9ea5b32a23fb4888cd394b989e56276a3b452ffc4c693c292fd3939b3b88dbb5f07caf89434e4c598ccc660bb61bf612c077f45f098cbe1c2fc417349705b9dffb4b4357dce2839bdc587910d908005e8d451b4305190ceabff410d145a569f8d2de57c89dfac823b16b0b07f28b35127b90ee00b4cc5612ae2d2d9e2a3343ac9c0261ef96d812d43a63c26e267529de752e0f066a3a882364f28da1f02e2a1dcd852580ee804d6c4fe623c1fbe4bdad753ab5a0c281c90bcc87c59fd3c65c6723a87b72b501ae0ea" func TestEncodeDecode(t *testing.T) { f, done := testfs.NewTempFile(t) @@ -47,14 +41,14 @@ func TestMerkleize(t *testing.T) { blob := newFromFile("foobar", f) mt, err := Merkleize(NewReader(blob)) require.NoError(t, err) - require.Equal(t, "7d1e84e62d7ec9f6bc3f886675733da06daf0277ad8ffcf7c539938ca5ee9cf2", hex.EncodeToString(mt.Root().Bytes())) + require.Equal(t, "f60de559740b01fe11dd241dee2729782caabd36613c469806a5449aaeef0a27", hex.EncodeToString(mt.Root().Bytes())) _, err = f.WriteAt([]byte{0x01, 0x99, 0x99, 0x99, 0xff, 0xad, 0xfc, 0x11, 0x99}, int64(SectorLen*2)) require.NoError(t, err) mt, err = Merkleize(NewReader(blob)) require.NoError(t, err) - require.Equal(t, "e9aa8bdf96bd79398d64a31865d2dd4d95eee2ba54b06a4e30b85e9e838497dd", hex.EncodeToString(mt.Root().Bytes())) + require.Equal(t, "75a87ea080e57925f81c6bf732bf72fb1f6465ee2ecbfaf7580b444fd3990cc7", hex.EncodeToString(mt.Root().Bytes())) } func TestGenProof(t *testing.T) { @@ -95,6 +89,6 @@ func TestProtocolBase(t *testing.T) { base := mt.ProtocolBase() for i := 0; i < len(base); i++ { - require.Equal(t, "532a12f09febf8521419959973ad5346944c2b22bf764d0e1a34255b6564fe4b", hex.EncodeToString(base[i][:])) + require.Equal(t, "d87e2783f806556be18f0d7d71324c9efa47d76dcb6ab20ebfb1bd11fcdd8e16", hex.EncodeToString(base[i][:])) } } diff --git a/blob/pathify.go b/blob/pathify.go index ca05aaf..2f449f4 100644 --- a/blob/pathify.go +++ b/blob/pathify.go @@ -3,7 +3,7 @@ package blob import ( "bytes" "encoding/hex" - "fnd.localhost/handshake/primitives" + "github.com/mslipper/handshake/primitives" "path" ) diff --git a/blob/seal.go b/blob/seal.go index da8755b..d4eb2eb 100644 --- a/blob/seal.go +++ b/blob/seal.go @@ -1,24 +1,26 @@ package blob import ( - "fnd/crypto" - "fnd.localhost/dwire" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" "golang.org/x/crypto/blake2b" - "time" ) -func SealHash(name string, ts time.Time, merkleRoot crypto.Hash, reservedRoot crypto.Hash) crypto.Hash { +func SealHash(name string, epochHeight, sectorSize uint16, sectorTipHash crypto.Hash, reservedRoot crypto.Hash) crypto.Hash { h, _ := blake2b.New256(nil) - if _, err := h.Write([]byte("FNBLOB")); err != nil { + if _, err := h.Write([]byte("DDRPBLOB")); err != nil { panic(err) } if err := dwire.EncodeField(h, name); err != nil { panic(err) } - if err := dwire.EncodeField(h, ts); err != nil { + if err := dwire.EncodeField(h, epochHeight); err != nil { panic(err) } - if _, err := h.Write(merkleRoot[:]); err != nil { + if err := dwire.EncodeField(h, sectorSize); err != nil { + panic(err) + } + if _, err := h.Write(sectorTipHash[:]); err != nil { panic(err) } if _, err := h.Write(reservedRoot[:]); err != nil { @@ -30,7 +32,7 @@ func SealHash(name string, ts time.Time, merkleRoot crypto.Hash, reservedRoot cr return out } -func SignSeal(signer crypto.Signer, name string, ts time.Time, merkleRoot crypto.Hash, reservedRoot crypto.Hash) (crypto.Signature, error) { - h := SealHash(name, ts, merkleRoot, reservedRoot) +func SignSeal(signer crypto.Signer, name string, epochHeight, sectorSize uint16, sectorTipHash crypto.Hash, reservedRoot crypto.Hash) (crypto.Signature, error) { + h := SealHash(name, epochHeight, sectorSize, sectorTipHash, reservedRoot) return signer.Sign(h) } diff --git a/blob/seal_test.go b/blob/seal_test.go index 3978503..54be6e8 100644 --- a/blob/seal_test.go +++ b/blob/seal_test.go @@ -2,24 +2,26 @@ package blob import ( "encoding/hex" - "fnd/crypto" - "fnd/testutil/testcrypto" + "testing" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/testutil/testcrypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "testing" - "time" ) func TestSealHash(t *testing.T) { - zeroTime := time.Unix(0, 0) - h := SealHash("testname", zeroTime, crypto.ZeroHash, crypto.ZeroHash) + epochZero := uint16(0) + sectorSize := uint16(0) + h := SealHash("testname", epochZero, sectorSize, crypto.ZeroHash, crypto.ZeroHash) assert.Equal(t, "694802db0f9b9b72725cf9c108b7a496bf20e1bdcc4d7feb9c42b8df1a08823b", hex.EncodeToString(h[:])) } func TestSignSeal(t *testing.T) { - zeroTime := time.Unix(0, 0) + epochZero := uint16(0) + sectorSize := uint16(0) priv, _ := testcrypto.FixedKey(t) - sig, err := SignSeal(crypto.NewSECP256k1Signer(priv), "testname", zeroTime, crypto.ZeroHash, crypto.ZeroHash) + sig, err := SignSeal(crypto.NewSECP256k1Signer(priv), "testname", epochZero, sectorSize, crypto.ZeroHash, crypto.ZeroHash) require.NoError(t, err) assert.Equal(t, "1cdb0e3aa14a5489cc1bfcf25843d6747cb9412d6200c35b69dd5fb9cb133ebc7c339ea9d5bb0cce8a9b20e84642757d9a2bc82e9e0a777a9641dd05fb9e5e4836", sig.String()) } diff --git a/blob/store.go b/blob/store.go index 205dad4..7195c2c 100644 --- a/blob/store.go +++ b/blob/store.go @@ -50,6 +50,7 @@ func NewInStorePath(blobsPath string, name string) (Blob, error) { if err != nil { return nil, err } + // TODO: Open in append-only mode (O_APPEND) if exists { f, err = os.OpenFile(blobFile, os.O_RDWR, 0666) } else { @@ -91,6 +92,14 @@ func (w *wrappedBlob) Name() string { return w.blob.Name() } +func (w *wrappedBlob) Seek(sectorSize uint16) { + w.blob.Seek(sectorSize) +} + +func (w *wrappedBlob) At() uint16 { + return w.blob.At() +} + func (w *wrappedBlob) ReadAt(p []byte, off int64) (n int, err error) { return w.blob.ReadAt(p, off) } diff --git a/blob/store_test.go b/blob/store_test.go index 202834a..290bf86 100644 --- a/blob/store_test.go +++ b/blob/store_test.go @@ -2,7 +2,7 @@ package blob import ( "crypto/rand" - "fnd/testutil/testfs" + "github.com/ddrp-org/ddrp/testutil/testfs" "github.com/stretchr/testify/require" "golang.org/x/crypto/blake2b" "io" diff --git a/blob/transaction.go b/blob/transaction.go index 82a4e5d..47e52c6 100644 --- a/blob/transaction.go +++ b/blob/transaction.go @@ -1,11 +1,12 @@ package blob import ( - "github.com/pkg/errors" "io" "io/ioutil" "os" "sync" + + "github.com/pkg/errors" ) var ( @@ -16,7 +17,7 @@ var ( type Transaction interface { Readable io.WriterAt - WriteSector(id uint8, sector Sector) error + WriteSector(sector Sector) error Truncate() error Commit() error Rollback() error @@ -26,6 +27,7 @@ type Transaction interface { type txImpl struct { name string f *os.File + sectorSize uint16 mu sync.Mutex cloner func() (*os.File, error) committer func(clone *os.File) error @@ -39,6 +41,10 @@ func (t *txImpl) Name() string { return t.name } +func (t *txImpl) SectorSize() uint16 { + return t.sectorSize +} + func (t *txImpl) ReadSector(id uint8) (Sector, error) { t.mu.Lock() defer t.mu.Unlock() @@ -69,7 +75,7 @@ func (t *txImpl) ReadAt(p []byte, off int64) (int, error) { return ReadBlobAt(t.f, p, off) } -func (t *txImpl) WriteSector(id uint8, sector Sector) error { +func (t *txImpl) WriteSector(sector Sector) error { t.mu.Lock() defer t.mu.Unlock() if t.closed { @@ -81,7 +87,11 @@ func (t *txImpl) WriteSector(id uint8, sector Sector) error { if err := t.lazyInitialize(); err != nil { return errors.Wrap(err, "error initializing transaction") } - return WriteSector(t.f, id, sector) + if err := WriteSector(t.f, t.sectorSize, sector); err != nil { + return errors.Wrap(err, "error writing sector") + } + t.sectorSize++ + return nil } func (t *txImpl) WriteAt(p []byte, off int64) (int, error) { diff --git a/blob/util_test.go b/blob/util_test.go index 43e29fe..cb09d01 100644 --- a/blob/util_test.go +++ b/blob/util_test.go @@ -1,7 +1,7 @@ package blob import ( - "fnd/testutil/testfs" + "github.com/ddrp-org/ddrp/testutil/testfs" "github.com/stretchr/testify/require" "os" "testing" diff --git a/cli/homedir.go b/cli/homedir.go index 2f0eef2..efaaf5d 100644 --- a/cli/homedir.go +++ b/cli/homedir.go @@ -2,7 +2,7 @@ package cli import ( "errors" - "fnd/config" + "github.com/ddrp-org/ddrp/config" "github.com/spf13/cobra" ) diff --git a/cli/signer.go b/cli/signer.go index 22db766..0115ba8 100644 --- a/cli/signer.go +++ b/cli/signer.go @@ -1,8 +1,8 @@ package cli import ( - "fnd/config" - "fnd/crypto" + "github.com/ddrp-org/ddrp/config" + "github.com/ddrp-org/ddrp/crypto" ) func GetSigner(homeDir string) (crypto.Signer, error) { diff --git a/cmd/fnd-cli/cmd/blob/blob.go b/cmd/ddrpcli/cmd/blob/blob.go similarity index 76% rename from cmd/fnd-cli/cmd/blob/blob.go rename to cmd/ddrpcli/cmd/blob/blob.go index 7905f73..3b4ba0b 100644 --- a/cmd/fnd-cli/cmd/blob/blob.go +++ b/cmd/ddrpcli/cmd/blob/blob.go @@ -4,7 +4,7 @@ import "github.com/spf13/cobra" var cmd = &cobra.Command{ Use: "blob", - Short: "Commands related to Footnote blobs.", + Short: "Commands related to DDRP blobs.", } func AddCmd(parent *cobra.Command) { diff --git a/cmd/fnd-cli/cmd/blob/info.go b/cmd/ddrpcli/cmd/blob/info.go similarity index 79% rename from cmd/fnd-cli/cmd/blob/info.go rename to cmd/ddrpcli/cmd/blob/info.go index c75ab0a..3133a87 100644 --- a/cmd/fnd-cli/cmd/blob/info.go +++ b/cmd/ddrpcli/cmd/blob/info.go @@ -3,21 +3,22 @@ package blob import ( "encoding/hex" "fmt" - "fnd/cli" - "fnd/rpc" - apiv1 "fnd/rpc/v1" - "fnd.localhost/handshake/primitives" - "github.com/olekukonko/tablewriter" - "github.com/pkg/errors" - "github.com/spf13/cobra" "os" "strconv" "strings" + + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/rpc" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + "github.com/mslipper/handshake/primitives" + "github.com/olekukonko/tablewriter" + "github.com/pkg/errors" + "github.com/spf13/cobra" ) var infoCmd = &cobra.Command{ Use: "info ", - Short: "Returns metadata about Footnote blobs.", + Short: "Returns metadata about DDRP blobs.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { names := strings.Split(args[0], ",") @@ -31,7 +32,7 @@ var infoCmd = &cobra.Command{ if err != nil { return err } - grpcClient := apiv1.NewFootnotev1Client(conn) + grpcClient := apiv1.NewDDRPv1Client(conn) table := tablewriter.NewWriter(os.Stdout) table.SetHeader([]string{ "Name", @@ -53,12 +54,12 @@ var infoCmd = &cobra.Command{ table.Append([]string{ res.Name, hex.EncodeToString(res.PublicKey.SerializeCompressed()), - res.Timestamp.String(), + strconv.Itoa(int(res.EpochHeight)), + strconv.Itoa(int(res.SectorSize)), res.MerkleRoot.String(), res.ReservedRoot.String(), res.ReceivedAt.String(), res.Signature.String(), - strconv.Itoa(res.Timebank), }) } diff --git a/cmd/fnd-cli/cmd/blob/list.go b/cmd/ddrpcli/cmd/blob/list.go similarity index 84% rename from cmd/fnd-cli/cmd/blob/list.go rename to cmd/ddrpcli/cmd/blob/list.go index 6aa3833..13e00a9 100644 --- a/cmd/fnd-cli/cmd/blob/list.go +++ b/cmd/ddrpcli/cmd/blob/list.go @@ -2,10 +2,10 @@ package blob import ( "encoding/json" - "fnd/cli" - "fnd/rpc" - apiv1 "fnd/rpc/v1" - "fnd/store" + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/rpc" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + "github.com/ddrp-org/ddrp/store" "github.com/spf13/cobra" "math" "os" @@ -34,7 +34,7 @@ var listCmd = &cobra.Command{ if err != nil { return err } - grpcClient := apiv1.NewFootnotev1Client(conn) + grpcClient := apiv1.NewDDRPv1Client(conn) var count int encoder := json.NewEncoder(os.Stdout) var innerErr error diff --git a/cmd/fnd-cli/cmd/blob/read.go b/cmd/ddrpcli/cmd/blob/read.go similarity index 73% rename from cmd/fnd-cli/cmd/blob/read.go rename to cmd/ddrpcli/cmd/blob/read.go index dfcd9f0..7f1d42b 100644 --- a/cmd/fnd-cli/cmd/blob/read.go +++ b/cmd/ddrpcli/cmd/blob/read.go @@ -1,9 +1,9 @@ package blob import ( - "fnd/cli" - "fnd/rpc" - apiv1 "fnd/rpc/v1" + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/rpc" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" "github.com/spf13/cobra" "io" "os" @@ -20,7 +20,7 @@ var readCmd = &cobra.Command{ return err } - br := rpc.NewBlobReader(apiv1.NewFootnotev1Client(conn), name) + br := rpc.NewBlobReader(apiv1.NewDDRPv1Client(conn), name) if _, err := io.Copy(os.Stdout, br); err != nil { return err } diff --git a/cmd/fnd-cli/cmd/blob/write.go b/cmd/ddrpcli/cmd/blob/write.go similarity index 73% rename from cmd/fnd-cli/cmd/blob/write.go rename to cmd/ddrpcli/cmd/blob/write.go index ea54136..05e7df9 100644 --- a/cmd/fnd-cli/cmd/blob/write.go +++ b/cmd/ddrpcli/cmd/blob/write.go @@ -4,22 +4,22 @@ import ( "bufio" "bytes" "fmt" - "fnd/cli" - "fnd/rpc" - apiv1 "fnd/rpc/v1" - "github.com/mattn/go-isatty" - "github.com/spf13/cobra" "io" "os" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/rpc" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + "github.com/mattn/go-isatty" + "github.com/spf13/cobra" ) const ( - TruncateFlag = "truncate" BroadcastFlag = "broadcast" ) var ( - truncate bool broadcast bool ) @@ -39,16 +39,11 @@ var writeCmd = &cobra.Command{ } name := args[0] - wr := rpc.NewBlobWriter(apiv1.NewFootnotev1Client(conn), signer, name) + wr := rpc.NewBlobWriter(apiv1.NewDDRPv1Client(conn), signer, name) if err := wr.Open(); err != nil { return err } - if truncate { - if err := wr.Truncate(); err != nil { - return err - } - } var rd io.Reader if len(args) < 2 { if isatty.IsTerminal(os.Stdin.Fd()) { @@ -59,14 +54,22 @@ var writeCmd = &cobra.Command{ } else { rd = bufio.NewReader(bytes.NewReader([]byte(args[1]))) } - if _, err := io.Copy(wr, rd); err != nil { - return err + var sector blob.Sector + for i := 0; i < blob.SectorCount; i++ { + if _, err := rd.Read(sector[:]); err != nil { + if err == io.EOF { + break + } + return err + } + wr.WriteSector(sector[:]) } - if err := wr.Commit(broadcast); err != nil { + sectorTipHash, err := wr.Commit(broadcast) + if err != nil { return err } - fmt.Println("Success.") + fmt.Printf("Success. Hash: %v\n", sectorTipHash) return nil }, } @@ -87,7 +90,6 @@ func readDataTTY() []byte { } func init() { - writeCmd.Flags().BoolVar(&truncate, TruncateFlag, false, "Truncate the blob before writing") writeCmd.Flags().BoolVar(&broadcast, BroadcastFlag, true, "Broadcast data to the network upon completion") cmd.AddCommand(writeCmd) } diff --git a/cmd/fnd-cli/cmd/identity.go b/cmd/ddrpcli/cmd/identity.go similarity index 78% rename from cmd/fnd-cli/cmd/identity.go rename to cmd/ddrpcli/cmd/identity.go index 3d58f76..a77675d 100644 --- a/cmd/fnd-cli/cmd/identity.go +++ b/cmd/ddrpcli/cmd/identity.go @@ -1,10 +1,10 @@ package cmd import ( - "encoding/base64" + "encoding/hex" "fmt" - "fnd/cli" - "fnd/config" + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/config" "github.com/spf13/cobra" ) @@ -22,7 +22,8 @@ var identityCmd = &cobra.Command{ return err } pub := signer.Pub() - fmt.Println(base64.StdEncoding.EncodeToString(pub.SerializeCompressed())) + + fmt.Println(hex.EncodeToString(pub.SerializeCompressed())) return nil }, } diff --git a/cmd/fnd-cli/cmd/init.go b/cmd/ddrpcli/cmd/init.go similarity index 78% rename from cmd/fnd-cli/cmd/init.go rename to cmd/ddrpcli/cmd/init.go index 04b4a51..244069d 100644 --- a/cmd/fnd-cli/cmd/init.go +++ b/cmd/ddrpcli/cmd/init.go @@ -2,7 +2,7 @@ package cmd import ( "fmt" - "fnd/cli" + "github.com/ddrp-org/ddrp/cli" "github.com/spf13/cobra" ) @@ -15,7 +15,7 @@ var initCmd = &cobra.Command{ return err } - fmt.Printf("Successfully initialized fnd-cli in %s.\n", dir) + fmt.Printf("Successfully initialized ddrpcli in %s.\n", dir) return nil }, } diff --git a/cmd/fnd-cli/cmd/net/add_peer.go b/cmd/ddrpcli/cmd/net/add_peer.go similarity index 86% rename from cmd/fnd-cli/cmd/net/add_peer.go rename to cmd/ddrpcli/cmd/net/add_peer.go index d1df809..41d1833 100644 --- a/cmd/fnd-cli/cmd/net/add_peer.go +++ b/cmd/ddrpcli/cmd/net/add_peer.go @@ -2,9 +2,9 @@ package net import ( "errors" - "fnd/cli" - "fnd/rpc" - apiv1 "fnd/rpc/v1" + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/rpc" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" "github.com/spf13/cobra" "strings" ) @@ -23,7 +23,7 @@ var addPeerCmd = &cobra.Command{ if err != nil { return err } - grpcClient := apiv1.NewFootnotev1Client(conn) + grpcClient := apiv1.NewDDRPv1Client(conn) splits := strings.Split(args[0], "@") if verifyPeerID && len(splits) == 1 { return errors.New("must define a peer ID if the peer ID is to be verified") diff --git a/cmd/fnd-cli/cmd/net/ban_peer.go b/cmd/ddrpcli/cmd/net/ban_peer.go similarity index 81% rename from cmd/fnd-cli/cmd/net/ban_peer.go rename to cmd/ddrpcli/cmd/net/ban_peer.go index b5a01ed..99237a7 100644 --- a/cmd/fnd-cli/cmd/net/ban_peer.go +++ b/cmd/ddrpcli/cmd/net/ban_peer.go @@ -1,9 +1,9 @@ package net import ( - "fnd/cli" - "fnd/rpc" - apiv1 "fnd/rpc/v1" + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/rpc" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" "github.com/spf13/cobra" "strconv" ) @@ -19,7 +19,7 @@ to this peer will be closed.`, if err != nil { return err } - grpcClient := apiv1.NewFootnotev1Client(conn) + grpcClient := apiv1.NewDDRPv1Client(conn) peerID := args[0] duration, err := strconv.Atoi(args[1]) if err != nil { diff --git a/cmd/fnd-cli/cmd/net/net.go b/cmd/ddrpcli/cmd/net/net.go similarity index 71% rename from cmd/fnd-cli/cmd/net/net.go rename to cmd/ddrpcli/cmd/net/net.go index 9ef486f..7baeef1 100644 --- a/cmd/fnd-cli/cmd/net/net.go +++ b/cmd/ddrpcli/cmd/net/net.go @@ -6,7 +6,7 @@ import ( var cmd = &cobra.Command{ Use: "net", - Short: "Commands related to Footnote's network connection.", + Short: "Commands related to DDRP's network connection.", } func AddCmd(parent *cobra.Command) { diff --git a/cmd/fnd-cli/cmd/net/peer_info.go b/cmd/ddrpcli/cmd/net/peer_info.go similarity index 90% rename from cmd/fnd-cli/cmd/net/peer_info.go rename to cmd/ddrpcli/cmd/net/peer_info.go index ba76542..27976c5 100644 --- a/cmd/fnd-cli/cmd/net/peer_info.go +++ b/cmd/ddrpcli/cmd/net/peer_info.go @@ -3,9 +3,9 @@ package net import ( "encoding/json" "fmt" - "fnd/cli" - "fnd/rpc" - apiv1 "fnd/rpc/v1" + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/rpc" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" "os" @@ -23,13 +23,13 @@ type peerJSON struct { var peerInfoCmd = &cobra.Command{ Use: "peer-info", - Short: "Returns information about all peers Footnote has heard of.", + Short: "Returns information about all peers DDRP has heard of.", RunE: func(cmd *cobra.Command, args []string) error { conn, err := cli.DialRPC(cmd) if err != nil { return err } - grpcClient := apiv1.NewFootnotev1Client(conn) + grpcClient := apiv1.NewDDRPv1Client(conn) peers, err := rpc.ListPeers(grpcClient) if err != nil { return err diff --git a/cmd/fnd-cli/cmd/net/status.go b/cmd/ddrpcli/cmd/net/status.go similarity index 85% rename from cmd/fnd-cli/cmd/net/status.go rename to cmd/ddrpcli/cmd/net/status.go index a5b21ab..add8f20 100644 --- a/cmd/fnd-cli/cmd/net/status.go +++ b/cmd/ddrpcli/cmd/net/status.go @@ -1,9 +1,9 @@ package net import ( - "fnd/cli" - "fnd/rpc" - apiv1 "fnd/rpc/v1" + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/rpc" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" "os" @@ -18,7 +18,7 @@ var statusCmd = &cobra.Command{ if err != nil { return err } - grpcClient := apiv1.NewFootnotev1Client(conn) + grpcClient := apiv1.NewDDRPv1Client(conn) res, err := rpc.GetStatus(grpcClient) if err != nil { diff --git a/cmd/fnd-cli/cmd/net/unban_peer.go b/cmd/ddrpcli/cmd/net/unban_peer.go similarity index 69% rename from cmd/fnd-cli/cmd/net/unban_peer.go rename to cmd/ddrpcli/cmd/net/unban_peer.go index 0355b22..379d9b9 100644 --- a/cmd/fnd-cli/cmd/net/unban_peer.go +++ b/cmd/ddrpcli/cmd/net/unban_peer.go @@ -1,9 +1,9 @@ package net import ( - "fnd/cli" - "fnd/rpc" - apiv1 "fnd/rpc/v1" + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/rpc" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" "github.com/spf13/cobra" ) @@ -11,7 +11,7 @@ var unbanPeerCmd = &cobra.Command{ Use: "unban-peer ", Short: "Unbans a peer.", Long: `Unbans a peer. A connection with the peer will not be automatically reestablished; -fnd will either reconnect to the unbanned peer the next time it refills its +ddrpd will either reconnect to the unbanned peer the next time it refills its peer list or following the add-peer CLI command.`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -19,7 +19,7 @@ peer list or following the add-peer CLI command.`, if err != nil { return err } - grpcClient := apiv1.NewFootnotev1Client(conn) + grpcClient := apiv1.NewDDRPv1Client(conn) return rpc.UnbanPeer(grpcClient, args[0]) }, } diff --git a/cmd/fnd-cli/cmd/root.go b/cmd/ddrpcli/cmd/root.go similarity index 64% rename from cmd/fnd-cli/cmd/root.go rename to cmd/ddrpcli/cmd/root.go index 78429dd..80bcb12 100644 --- a/cmd/fnd-cli/cmd/root.go +++ b/cmd/ddrpcli/cmd/root.go @@ -2,17 +2,17 @@ package cmd import ( "fmt" - "fnd/cli" - "fnd/cmd/fnd-cli/cmd/blob" - "fnd/cmd/fnd-cli/cmd/net" - "fnd/cmd/fnd-cli/cmd/unsafe" + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/cmd/ddrpcli/cmd/blob" + "github.com/ddrp-org/ddrp/cmd/ddrpcli/cmd/net" + "github.com/ddrp-org/ddrp/cmd/ddrpcli/cmd/unsafe" "github.com/spf13/cobra" "os" ) var rootCmd = &cobra.Command{ - Use: "fnd-cli", - Short: "Command-line RPC interface for Footnote.", + Use: "ddrpcli", + Short: "Command-line RPC interface for DDRP.", } func Execute() { @@ -25,7 +25,7 @@ func Execute() { func init() { rootCmd.PersistentFlags().Int(cli.FlagRPCPort, 9098, "RPC port to connect to.") rootCmd.PersistentFlags().String(cli.FlagRPCHost, "127.0.0.1", "RPC host to connect to.") - rootCmd.PersistentFlags().String(cli.FlagHome, "~/.fnd-cli", "Home directory for the CLI's configuration.") + rootCmd.PersistentFlags().String(cli.FlagHome, "~/.ddrpcli", "Home directory for the CLI's configuration.") rootCmd.PersistentFlags().String(cli.FlagFormat, "text", "Output format") net.AddCmd(rootCmd) blob.AddCmd(rootCmd) diff --git a/cmd/fnd-cli/cmd/unsafe/reset_blobs.go b/cmd/ddrpcli/cmd/unsafe/reset_blobs.go similarity index 76% rename from cmd/fnd-cli/cmd/unsafe/reset_blobs.go rename to cmd/ddrpcli/cmd/unsafe/reset_blobs.go index 7e58d68..60161b8 100644 --- a/cmd/fnd-cli/cmd/unsafe/reset_blobs.go +++ b/cmd/ddrpcli/cmd/unsafe/reset_blobs.go @@ -2,8 +2,8 @@ package unsafe import ( "fmt" - "fnd/config" - "fnd/store" + "github.com/ddrp-org/ddrp/config" + "github.com/ddrp-org/ddrp/store" "github.com/pkg/errors" "github.com/spf13/cobra" "os" @@ -11,9 +11,9 @@ import ( var resetBlobsCmd = &cobra.Command{ Use: "reset-blobs", - Short: "Wipes fnd's blob data directly on disk", + Short: "Wipes ddrpd's blob data directly on disk", RunE: func(cmd *cobra.Command, args []string) error { - homePath := config.ExpandHomePath(fndHome) + homePath := config.ExpandHomePath(ddrpdHome) db, err := store.Open(config.ExpandDBPath(homePath)) if err != nil { return errors.Wrap(err, "error opening store") @@ -37,6 +37,6 @@ var resetBlobsCmd = &cobra.Command{ } func init() { - resetBlobsCmd.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to FootnoteD's home directory.") + resetBlobsCmd.Flags().StringVar(&ddrpdHome, "ddrpd-home", "~/.ddrpd", "Path to DDRPD's home directory.") cmd.AddCommand(resetBlobsCmd) } diff --git a/cmd/fnd-cli/cmd/unsafe/reset_name_store.go b/cmd/ddrpcli/cmd/unsafe/reset_name_store.go similarity index 69% rename from cmd/fnd-cli/cmd/unsafe/reset_name_store.go rename to cmd/ddrpcli/cmd/unsafe/reset_name_store.go index e76e3be..b274aa4 100644 --- a/cmd/fnd-cli/cmd/unsafe/reset_name_store.go +++ b/cmd/ddrpcli/cmd/unsafe/reset_name_store.go @@ -2,17 +2,17 @@ package unsafe import ( "fmt" - "fnd/config" - "fnd/store" + "github.com/ddrp-org/ddrp/config" + "github.com/ddrp-org/ddrp/store" "github.com/pkg/errors" "github.com/spf13/cobra" ) var resetNameStore = &cobra.Command{ Use: "reset-name-store", - Short: "Wipes fnd's naming data directly on disk", + Short: "Wipes ddrpd's naming data directly on disk", RunE: func(cmd *cobra.Command, args []string) error { - homePath := config.ExpandHomePath(fndHome) + homePath := config.ExpandHomePath(ddrpdHome) db, err := store.Open(config.ExpandDBPath(homePath)) if err != nil { return errors.Wrap(err, "failed to open store") @@ -29,6 +29,6 @@ var resetNameStore = &cobra.Command{ } func init() { - resetNameStore.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to FootnoteD's home directory.") + resetNameStore.Flags().StringVar(&ddrpdHome, "ddrpd-home", "~/.ddrpd", "Path to DDRPD's home directory.") cmd.AddCommand(resetNameStore) } diff --git a/cmd/fnd-cli/cmd/unsafe/reset_peer_store.go b/cmd/ddrpcli/cmd/unsafe/reset_peer_store.go similarity index 69% rename from cmd/fnd-cli/cmd/unsafe/reset_peer_store.go rename to cmd/ddrpcli/cmd/unsafe/reset_peer_store.go index 68e4bb6..5e0e1b1 100644 --- a/cmd/fnd-cli/cmd/unsafe/reset_peer_store.go +++ b/cmd/ddrpcli/cmd/unsafe/reset_peer_store.go @@ -2,17 +2,17 @@ package unsafe import ( "fmt" - "fnd/config" - "fnd/store" + "github.com/ddrp-org/ddrp/config" + "github.com/ddrp-org/ddrp/store" "github.com/pkg/errors" "github.com/spf13/cobra" ) var resetPeerStoreCmd = &cobra.Command{ Use: "reset-peer-store", - Short: "Wipes fnd's peer store directly on disk", + Short: "Wipes ddrpd's peer store directly on disk", RunE: func(cmd *cobra.Command, args []string) error { - homePath := config.ExpandHomePath(fndHome) + homePath := config.ExpandHomePath(ddrpdHome) db, err := store.Open(config.ExpandDBPath(homePath)) if err != nil { return errors.Wrap(err, "error opening store") @@ -29,6 +29,6 @@ var resetPeerStoreCmd = &cobra.Command{ } func init() { - resetPeerStoreCmd.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to FootnoteD's home directory.") + resetPeerStoreCmd.Flags().StringVar(&ddrpdHome, "ddrpd-home", "~/.ddrpd", "Path to DDRPD's home directory.") cmd.AddCommand(resetPeerStoreCmd) } diff --git a/cmd/fnd-cli/cmd/unsafe/unsafe.go b/cmd/ddrpcli/cmd/unsafe/unsafe.go similarity index 92% rename from cmd/fnd-cli/cmd/unsafe/unsafe.go rename to cmd/ddrpcli/cmd/unsafe/unsafe.go index 116c5a8..db061e8 100644 --- a/cmd/fnd-cli/cmd/unsafe/unsafe.go +++ b/cmd/ddrpcli/cmd/unsafe/unsafe.go @@ -2,7 +2,7 @@ package unsafe import "github.com/spf13/cobra" -var fndHome string +var ddrpdHome string var cmd = &cobra.Command{ Use: "unsafe", diff --git a/cmd/fnd-cli/cmd/version.go b/cmd/ddrpcli/cmd/version.go similarity index 70% rename from cmd/fnd-cli/cmd/version.go rename to cmd/ddrpcli/cmd/version.go index 0b88689..b473e11 100644 --- a/cmd/fnd-cli/cmd/version.go +++ b/cmd/ddrpcli/cmd/version.go @@ -2,14 +2,14 @@ package cmd import ( "fmt" - "fnd/version" + "github.com/ddrp-org/ddrp/version" "github.com/spf13/cobra" ) var versionCmd = &cobra.Command{ Use: "version", RunE: func(cmd *cobra.Command, args []string) error { - fmt.Printf("fnd-cli %s (%s)\n", version.GitTag, version.GitCommit) + fmt.Printf("ddrpcli %s (%s)\n", version.GitTag, version.GitCommit) return nil }, } diff --git a/cmd/ddrpcli/main.go b/cmd/ddrpcli/main.go new file mode 100644 index 0000000..9b2c1c2 --- /dev/null +++ b/cmd/ddrpcli/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/ddrp-org/ddrp/cmd/ddrpcli/cmd" + +func main() { + cmd.Execute() +} diff --git a/cmd/fnd/cmd/init.go b/cmd/ddrpd/cmd/init.go similarity index 66% rename from cmd/fnd/cmd/init.go rename to cmd/ddrpd/cmd/init.go index 98a1300..cfa4882 100644 --- a/cmd/fnd/cmd/init.go +++ b/cmd/ddrpd/cmd/init.go @@ -2,19 +2,19 @@ package cmd import ( "fmt" - "fnd/cli" + "github.com/ddrp-org/ddrp/cli" "github.com/spf13/cobra" ) var initCmd = &cobra.Command{ Use: "init", - Short: "Initializes the fnd daemon's home directory.", + Short: "Initializes the ddrpd daemon's home directory.", RunE: func(cmd *cobra.Command, args []string) error { dir, err := cli.InitHomeDir(cmd) if err != nil { return err } - fmt.Printf("Successfully initialized fnd in %s.\n", dir) + fmt.Printf("Successfully initialized ddrpd in %s.\n", dir) return nil }, } diff --git a/cmd/fnd/cmd/root.go b/cmd/ddrpd/cmd/root.go similarity index 71% rename from cmd/fnd/cmd/root.go rename to cmd/ddrpd/cmd/root.go index 725b921..3f59b60 100644 --- a/cmd/fnd/cmd/root.go +++ b/cmd/ddrpd/cmd/root.go @@ -2,8 +2,8 @@ package cmd import ( "fmt" - "fnd/cli" - "fnd/config" + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/config" "github.com/pkg/errors" "github.com/spf13/cobra" "os" @@ -12,8 +12,8 @@ import ( var configuredHomeDir string var rootCmd = &cobra.Command{ - Use: "fnd", - Short: "Footnote Daemon", + Use: "ddrpd", + Short: "DDRP Daemon", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { if cmd.CalledAs() == "init" { return nil @@ -27,7 +27,7 @@ var rootCmd = &cobra.Command{ } func init() { - rootCmd.PersistentFlags().String(cli.FlagHome, "~/.fnd", "Home directory for the daemon's config and database.") + rootCmd.PersistentFlags().String(cli.FlagHome, "~/.ddrpd", "Home directory for the daemon's config and database.") } func Execute() { diff --git a/cmd/fnd/cmd/start.go b/cmd/ddrpd/cmd/start.go similarity index 93% rename from cmd/fnd/cmd/start.go rename to cmd/ddrpd/cmd/start.go index e480944..b81681e 100644 --- a/cmd/fnd/cmd/start.go +++ b/cmd/ddrpd/cmd/start.go @@ -2,22 +2,6 @@ package cmd import ( "fmt" - "fnd/blob" - "fnd/cli" - "fnd/config" - "fnd/crypto" - "fnd/log" - "fnd/p2p" - "fnd/protocol" - "fnd/rpc" - "fnd/service" - "fnd/store" - "fnd/util" - "fnd/version" - "fnd.localhost/handshake/client" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "github.com/syndtr/goleveldb/leveldb" "net/http" _ "net/http/pprof" "os" @@ -25,6 +9,23 @@ import ( "runtime" "syscall" "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/cli" + "github.com/ddrp-org/ddrp/config" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/protocol" + "github.com/ddrp-org/ddrp/rpc" + "github.com/ddrp-org/ddrp/service" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/util" + "github.com/ddrp-org/ddrp/version" + "github.com/mslipper/handshake/client" + "github.com/pkg/errors" + "github.com/spf13/cobra" + "github.com/syndtr/goleveldb/leveldb" ) var startCmd = &cobra.Command{ @@ -45,7 +46,7 @@ var startCmd = &cobra.Command{ log.SetLevel(logLevel) lgr := log.WithModule("main") - lgr.Info("starting fnd", "git_commit", version.GitCommit, "git_tag", version.GitTag) + lgr.Info("starting ddrp", "git_commit", version.GitCommit, "git_tag", version.GitTag) lgr.Info("opening home directory", "path", configuredHomeDir) signer, err := cli.GetSigner(configuredHomeDir) if err != nil { @@ -145,7 +146,6 @@ var startCmd = &cobra.Command{ updateQueue := protocol.NewUpdateQueue(mux, db) updateQueue.MaxLen = int32(cfg.Tuning.UpdateQueue.MaxLen) - updateQueue.MinUpdateInterval = config.ConvertDuration(cfg.Tuning.Timebank.MinUpdateIntervalMS, time.Millisecond) updater := protocol.NewUpdater(mux, db, updateQueue, nameLocker, bs) updater.PollInterval = config.ConvertDuration(cfg.Tuning.Updater.PollIntervalMS, time.Millisecond) diff --git a/cmd/fnd/cmd/version.go b/cmd/ddrpd/cmd/version.go similarity index 69% rename from cmd/fnd/cmd/version.go rename to cmd/ddrpd/cmd/version.go index 5e4f242..ff36a7a 100644 --- a/cmd/fnd/cmd/version.go +++ b/cmd/ddrpd/cmd/version.go @@ -2,14 +2,14 @@ package cmd import ( "fmt" - "fnd/version" + "github.com/ddrp-org/ddrp/version" "github.com/spf13/cobra" ) var versionCmd = &cobra.Command{ Use: "version", RunE: func(cmd *cobra.Command, args []string) error { - fmt.Printf("fnd %s (%s)\n", version.GitTag, version.GitCommit) + fmt.Printf("ddrpd %s (%s)\n", version.GitTag, version.GitCommit) return nil }, } diff --git a/cmd/fnd/main.go b/cmd/ddrpd/main.go similarity index 57% rename from cmd/fnd/main.go rename to cmd/ddrpd/main.go index e060065..6222198 100644 --- a/cmd/fnd/main.go +++ b/cmd/ddrpd/main.go @@ -1,7 +1,7 @@ package main import ( - "fnd/cmd/fnd/cmd" + "github.com/ddrp-org/ddrp/cmd/ddrpd/cmd" ) func main() { diff --git a/cmd/fnd-cli/main.go b/cmd/fnd-cli/main.go deleted file mode 100644 index 4bd892e..0000000 --- a/cmd/fnd-cli/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "fnd/cmd/fnd-cli/cmd" - -func main() { - cmd.Execute() -} diff --git a/config/config.go b/config/config.go index 1ccbdbe..b1e25eb 100644 --- a/config/config.go +++ b/config/config.go @@ -1,10 +1,11 @@ package config import ( - "github.com/pelletier/go-toml" - "github.com/pkg/errors" "io" "time" + + "github.com/pelletier/go-toml" + "github.com/pkg/errors" ) type Config struct { @@ -45,7 +46,6 @@ type HNSResolverConfig struct { } type TuningConfig struct { - Timebank TimebankConfig `mapstructure:"timebank"` UpdateQueue UpdateQueueConfig `mapstructure:"update_queue"` Updater UpdaterConfig `mapstructure:"updater"` Syncer SyncerConfig `mapstructure:"syncer"` @@ -56,12 +56,6 @@ type TuningConfig struct { NameSyncer NameSyncerConfig `mapstructure:"name_syncer"` } -type TimebankConfig struct { - PeriodMS int `mapstructure:"period_ms"` - MinUpdateIntervalMS int `mapstructure:"min_update_interval_ms"` - FullUpdatesPerPeriod int `mapstructure:"full_updates_per_period"` -} - type UpdateQueueConfig struct { MaxLen int `mapstructure:"max_len"` ReapIntervalMS int `mapstructure:"reap_interval_ms"` diff --git a/config/default.go b/config/default.go index bf1c761..4c8061d 100644 --- a/config/default.go +++ b/config/default.go @@ -2,12 +2,13 @@ package config import ( "bytes" - "fnd/log" - "github.com/pkg/errors" "io" "os" "path" "text/template" + + "github.com/ddrp-org/ddrp/log" + "github.com/pkg/errors" ) var DefaultConfig = Config{ @@ -16,15 +17,14 @@ var DefaultConfig = Config{ EnableProfiler: false, Heartbeat: HeartbeatConfig{ Moniker: "", - URL: "", + URL: "https://www.ddrpscan.com/heartbeat", }, P2P: P2PConfig{ Host: "0.0.0.0", - DNSSeeds: []string{}, - FixedSeeds: []string{ - "3b755ceafc5811f0a50e102c96169b062ad1295edea0adf675e8647963acf89e@64.225.89.142", - "e3c8cfea75ff146db0b93c51cf8967242c43170dac702aec268ed566f4aa6f4b@45.55.99.2", + DNSSeeds: []string{ + "seeds.ddrp.network", }, + FixedSeeds: []string{}, MaxInboundPeers: 117, MaxOutboundPeers: 8, ConnectionTimeoutMS: 5000, @@ -40,11 +40,6 @@ var DefaultConfig = Config{ APIKey: "", }, Tuning: TuningConfig{ - Timebank: TimebankConfig{ - PeriodMS: 86400 * 2, - MinUpdateIntervalMS: 120, - FullUpdatesPerPeriod: 2, - }, UpdateQueue: UpdateQueueConfig{ MaxLen: 1000, ReapIntervalMS: 5000, @@ -87,7 +82,7 @@ var DefaultConfig = Config{ }, } -const defaultConfigTemplateText = `# FootnoteD Config File +const defaultConfigTemplateText = `# DDRPD Config File # List of ban list URLs. ban_lists = [] @@ -111,7 +106,7 @@ log_level = "{{.LogLevel}}" # Sets the URL the node will heartbeat to. url = "{{.Heartbeat.URL}}" -# Configures the connection to the Handshake network. Footnote assumes +# Configures the connection to the Handshake network. DDRP assumes # that HSD is hosted at a url with the following format: # :/. [hns_resolver] @@ -133,7 +128,7 @@ log_level = "{{.LogLevel}}" # Sets the set of domain names to query for seed nodes. # A records belonging to nodes in this list will be # connected to during node startup. - dns_seeds = [] + dns_seeds = ["{{index .P2P.DNSSeeds 0}}"] # Sets the IP this node should listen on. Should be set to 0.0.0.0 # for all Internet-accessible nodes. host = "{{.P2P.Host}}" @@ -146,13 +141,13 @@ log_level = "{{.LogLevel}}" # default of 8 was chosen to match Bitcoin. max_outbound_peers = {{.P2P.MaxOutboundPeers}} # Sets a list of fixed seed peers. Items should be formatted as @. - seed_peers = ["{{index .P2P.FixedSeeds 0}}", "{{index .P2P.FixedSeeds 1}}"] + seed_peers = [] # Configures the behavior of this node's RPC server. [rpc] # Sets the IP this node should listen for RPC requests on. # For the most part, this should be set to 127.0.0.1. Exposing - # fnd's RPC port to the public internet is not safe. + # ddrpd's RPC port to the public internet is not safe. host = "{{.RPC.Host}}" # Sets the port this node should listen for RPC requests on. port = {{.RPC.Port}} @@ -162,29 +157,29 @@ log_level = "{{.LogLevel}}" # defaults. [tuning] - # Configures how often fnd will perform heartbeats and + # Configures how often ddrpd will perform heartbeats and # when to time out heartbeat requests. [tuning.heartbeat] interval_ms = {{.Tuning.Heartbeat.IntervalMS}} timeout_ms = {{.Tuning.Heartbeat.TimeoutMS}} - # Configures how fnd scans the Handshake blockchain for - # new TXT records. + # Configures how ddrpd scans the Handshake blockchain for + # new DDRPKEY records. [tuning.name_importer] - # Sets how often fnd scans for new names. + # Sets how often ddrpd scans for new names. check_interval_ms = {{.Tuning.NameImporter.CheckIntervalMS}} - # Sets how many blocks fnd will wait before considering + # Sets how many blocks ddrpd will wait before considering # a Handshake name record to be finalized. Changing this # value to something lower than the default will lead to # the network rejecting updates originating from this node. confirmation_depth = {{.Tuning.NameImporter.ConfirmationDepth}} # Sets how many blocks should be fetched from HSD concurrently. workers = {{.Tuning.NameImporter.Workers}} - # Sets the minimum sync percentage fnd will accept from HSD before + # Sets the minimum sync percentage ddrpd will accept from HSD before # importing names. verification_threshold = {{.Tuning.NameImporter.VerificationThreshold}} - # Configures how fnd scans for updates in the background. + # Configures how ddrpd scans for updates in the background. [tuning.name_syncer] # Sets how often updates will be scanned for. interval_ms = {{.Tuning.NameSyncer.IntervalMS}} @@ -199,61 +194,49 @@ log_level = "{{.LogLevel}}" # Sets how many names will be synchronized concurrently. workers = {{.Tuning.NameSyncer.Workers}} - # Configures how fnd exchanges peers with the rest of the network. + # Configures how ddrpd exchanges peers with the rest of the network. [tuning.peer_exchanger] - # Sets how many concurrent dials fnd will make when it + # Sets how many concurrent dials ddrpd will make when it # receives exchanged peers. max_concurrent_dials = {{.Tuning.PeerExchanger.MaxConcurrentDials}} - # Sets the maximum number of peers fnd will process after + # Sets the maximum number of peers ddrpd will process after # receiving exchanged peers. max_received_peers = {{.Tuning.PeerExchanger.MaxReceivedPeers}} - # Sets the maximum number of peers fnd will send after receiving a + # Sets the maximum number of peers ddrpd will send after receiving a # request for peers. max_sent_peers = {{.Tuning.PeerExchanger.MaxSentPeers}} - # Sets how often fnd will request new peers. + # Sets how often ddrpd will request new peers. request_interval_ms = {{.Tuning.PeerExchanger.RequestIntervalMS}} - # Sets how many peers fnd will request new peers from during each + # Sets how many peers ddrpd will request new peers from during each # peer exchange operation. sample_size = {{.Tuning.PeerExchanger.SampleSize}} - # Configures how fnd serves sector data to peers that request it. + # Configures how ddrpd serves sector data to peers that request it. [tuning.sector_server] - # Sets how often fnd will reap in-memory cached sectors. + # Sets how often ddrpd will reap in-memory cached sectors. cache_expiry_ms = {{.Tuning.SectorServer.CacheExpiryMS}} - # Configures how fnd synchronizes sectors with remote peers. + # Configures how ddrpd synchronizes sectors with remote peers. [tuning.syncer] - # Sets how long fnd will wait for remote peers to return + # Sets how long ddrpd will wait for remote peers to return # sector data before retrying. sector_response_timeout_ms = {{.Tuning.Syncer.SectorResponseTimeoutMS}} - # Sets how long fnd will wait for a remote peers to return + # Sets how long ddrpd will wait for a remote peers to return # tree base data before trying another peer. tree_base_response_timeout_ms = {{.Tuning.Syncer.TreeBaseResponseTimeoutMS}} - # Configures how fnd manages each name's timebank. The timebank is used - # to throttle blob updates. Changing these values after fnd has fully - # synced is undefined behavior. - [tuning.timebank] - # Sets how many complete blob updates (i.e., updates that change all 256 - # sectors) fnd will allow per time period. - full_updates_per_period = {{.Tuning.Timebank.FullUpdatesPerPeriod}} - # Sets the minimum amount of time between updates fnd will accept. - min_update_interval_ms = {{.Tuning.Timebank.MinUpdateIntervalMS}} - # Sets the time period over which the timebank will be calculated. - period_ms = {{.Tuning.Timebank.PeriodMS}} - - # Configures how fnd enqueues blob updates. + # Configures how ddrpd enqueues blob updates. [tuning.update_queue] # Sets the maximum length of the update queue. max_len = {{.Tuning.UpdateQueue.MaxLen}} - # Sets how often fnd will reap disposed of queue entries. + # Sets how often ddrpd will reap disposed of queue entries. reap_interval_ms = {{.Tuning.UpdateQueue.ReapIntervalMS}} - # Configures how fnd updates blobs. + # Configures how ddrpd updates blobs. [tuning.updater] - # Sets how often fnd will check the update queue for new updates. + # Sets how often ddrpd will check the update queue for new updates. poll_interval_ms = {{.Tuning.Updater.PollIntervalMS}} - # Sets how many updates fnd will process concurrently. + # Sets how many updates ddrpd will process concurrently. workers = {{.Tuning.Updater.Workers}} ` diff --git a/config/home.go b/config/home.go index c35de8a..7de7347 100644 --- a/config/home.go +++ b/config/home.go @@ -26,7 +26,7 @@ func EnsureHomeDir(path string) error { return err } if !exists { - return errors.New("home directory does not exist - try running fnd init") + return errors.New("home directory does not exist - try running ddrpd init") } return nil } diff --git a/dwire/.gitignore b/dwire/.gitignore new file mode 100644 index 0000000..ea34f98 --- /dev/null +++ b/dwire/.gitignore @@ -0,0 +1,18 @@ +# Created by .ignore support plugin (hsz.mobi) +### Go template +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + diff --git a/dwire/Makefile b/dwire/Makefile new file mode 100644 index 0000000..98eb341 --- /dev/null +++ b/dwire/Makefile @@ -0,0 +1,8 @@ +test: + go test ./... --race + +fmt: + goimports -w . + gofmt -s -w . + +.PHONY: test fmt diff --git a/dwire/README.md b/dwire/README.md new file mode 100644 index 0000000..698706f --- /dev/null +++ b/dwire/README.md @@ -0,0 +1,167 @@ + +# dwire + +A library for encoding and decoding things using Footnote's wire format. + +## Usage + +To encode a single value: + +```go +import ( + "fnd.localhost/dwire" + "fnd" +) + +value := "a string value" +var w bytes.Buffer +if err := dwire.EncodeField(&w, value); err != nil { + log.Fatal(err) +} +``` + +To encode a struct: + +```go +import ( + "fnd.localhost/dwire" + "bytes" +) + +type Foo struct { + StrField string + Uint8Field uint8 +} + +foo := &Foo{ + StrField: "some string", + Uint8Field: 1 +} + +var w bytes.Buffer +if err := dwire.EncodeFields(&w, foo.StrField, foo.Uint8Field); err != nil { + log.Fatal(err) +} +``` + +Decoding works on pointer values. For example, to decode a single value: + +```go +import ( + "fnd.localhost/dwire" + "bytes" +) + +var uint8Value uint8 +r := bytes.NewReader([]byte{ 0x01 }) +if err := dwire.DecodeField(r, &uint8Value); err != nil { + log.Fatal(err) +} +``` + +To decode a struct: + +```go +import ( + "fnd.localhost/dwire" + "bytes" +) + +type Foo struct { + Uint8Field uint8 +} + +var foo Foo +r := bytes.NewReader([]byte{0x01}) + +if err := dwire.DecodeFields(r, &foo.Uint8Field); err != nil { + log.Fatal(err) +} +``` + +For convenience, objects that implement the `Encoder` and `Decoder` interfaces can be passed directly to `dwire`'s encoding/decodig methods. For example, the first struct example above could be implemented as follows: + +```go +import ( + "fnd.localhost/dwire" + "bytes" +) + +type Foo struct { + StrField string + Uint8Field uint8 +} + +func (f *Foo) Encode(w io.Writer) error { + return dwire.EncodeFields( + w, + f.StrField, + f.Uint8Field, + ) +} + +func (f *Foo) Decode(r io.Reader) error { + return dwire.DecodeFields( + r, + &f.StrField, + &f.Uint8Field, + ) +} + +foo := &Foo{ + StrField: "some string", + Uint8Field: 1 +} + +var w bytes.Buffer +if err := dwire.EncodeField(&w, foo); err != nil { + log.Fatal(err) +} +``` + +## Wire Format Definition + +This definition is lifted from the canonical specification described in [PIP-1](https://fnd.network/docs/spec/pip-1.html). For clarity, we will use the function `Encode(t) = b`, where `t` is the inputted field and `b` represents the outputted bytes, to provide example encodings where necessary. + +`dwire` defines encodings for the following types: + +1. `bool`: Encoded as `0x01` or `0x00` if the value is `true` or `false`, respectively. +2. `uint8`, `uint16`, `uint32`, `uint64`: Encoded as big-endian unsigned integers. +3. `byte`: Encoded as `uint8`. +4. `[N]` (i.e., fixed-length arrays of element `T`): Encoded as the concatenation of `Encode()` for each array element. +5. `[]` (i.e., variable-length arrays of element `T`): Encoded as the concatenation of a `Uvarint` length prefix and `Encode()` for each array element. +6. `string`: Encoded as `[]byte`. + +### Well-Known Types + +Certain complex types are considered "well known," and are encoded/decoded directly in this package without implementing the `Encoder`/`Decoder` interfaces. These types are: + +1. `time.Time`: Encoded as a `uint64` Unix timestamp. + +## Benchmarks + +Benchmarks recorded on a mid-2018 MacBook Pro with the following specifications: + +1. 2.2GHz 6-Core Intel i7 +2. 32GB 2400MHz DDR4 + +``` +goos: darwin +goarch: amd64 +pkg: fnd.localhost/dwire +BenchmarkUint8Encoding-12 711883 1469 ns/op +BenchmarkUint16Encoding-12 867793 1472 ns/op +BenchmarkUint32Encoding-12 841219 1446 ns/op +BenchmarkUint64Encoding-12 845859 1544 ns/op +BenchmarkByteSliceEncoding1024-12 744835 1623 ns/op +BenchmarkStringEncoding1024-12 710882 1845 ns/op +BenchmarkByteArrayEncoding32-12 748132 1551 ns/op +BenchmarkByteArrayEncodingReflect-12 577855 2178 ns/op +BenchmarkUint16ArrayEncodingReflect-12 30091 41010 ns/op +BenchmarkStringArrayEncodingReflect-12 10000 121458 ns/op +BenchmarkWellKnownTimeEncoding-12 701935 1845 ns/op +``` + +## Acknowledgements + +Much of this library was directly inspired by `lnwire`, the wire encoding library used by the Lightning Network. As such, we would like to extend our deepest thanks to the Lightning team for their trailblazing work. diff --git a/dwire/decode.go b/dwire/decode.go new file mode 100644 index 0000000..18c622c --- /dev/null +++ b/dwire/decode.go @@ -0,0 +1,228 @@ +package dwire + +import ( + "encoding/binary" + "fmt" + "io" + "reflect" + + "github.com/pkg/errors" +) + +type byteReader struct { + r io.Reader + buf []byte +} + +func newByteReader(r io.Reader) *byteReader { + return &byteReader{ + r: r, + buf: make([]byte, 1, 1), + } +} + +func (r *byteReader) Read(p []byte) (int, error) { + return r.r.Read(p) +} + +func (r *byteReader) ReadByte() (byte, error) { + _, err := io.ReadFull(r.r, r.buf) + if err != nil { + return 0, err + } + return r.buf[0], nil +} + +// DecodeFields decodes each field in the variadic items argument from the +// Reader using the default Encoder. Items provided to DecodeFields +// must be pointer types. +func DecodeFields(r io.Reader, items ...interface{}) error { + return defaultEncoder.DecodeFields(r, items...) +} + +// DecodeFields decodes the field in the item argument from the Reader using +// the default Encoder. The item provided to DecodeField must be a pointer type. +func DecodeField(r io.Reader, item interface{}) error { + return defaultEncoder.DecodeField(r, item) +} + +// DecodeFields decodes each field in the variadic items argument +// from the Reader. Items provided to DecodeFields must be pointer types. +func (c *ConfiguredEncoder) DecodeFields(r io.Reader, items ...interface{}) error { + for _, item := range items { + if err := c.DecodeField(r, item); err != nil { + return err + } + } + + return nil +} + +// DecodeField decodes the field in the item argument from the Reader. The item +// provided to DecodeField must be a pointer type. +func (c *ConfiguredEncoder) DecodeField(r io.Reader, item interface{}) error { + var err error + switch it := item.(type) { + case Decoder: + err = it.Decode(r) + case *bool: + b := make([]byte, 1, 1) + if _, err := io.ReadFull(r, b); err != nil { + return err + } + if b[0] == 0x00 { + *it = false + } else if b[0] == 0x01 { + *it = true + } else { + return errors.Errorf("invalid boolean value: %x", b[0]) + } + case *uint8: + b := make([]byte, 1, 1) + if _, err := io.ReadFull(r, b); err != nil { + return err + } + *it = b[0] + case *uint16: + b := make([]byte, 2, 2) + if _, err := io.ReadFull(r, b); err != nil { + return err + } + *it = binary.BigEndian.Uint16(b) + case *uint32: + b := make([]byte, 4, 4) + if _, err := io.ReadFull(r, b); err != nil { + return err + } + *it = binary.BigEndian.Uint32(b) + case *uint64: + b := make([]byte, 8, 8) + if _, err := io.ReadFull(r, b); err != nil { + return err + } + *it = binary.BigEndian.Uint64(b) + case *[]byte: + br := newByteReader(r) + l, err := binary.ReadUvarint(br) + if err != nil { + return err + } + if l > c.MaxByteFieldLen { + return errors.New("byte-assignable field length too large to decode") + } + buf := make([]byte, l, l) + if _, err := io.ReadFull(r, buf); err != nil { + return err + } + *it = buf + case *string: + var buf []byte + if err := c.DecodeField(r, &buf); err != nil { + return err + } + *it = string(buf) + case *[32]byte: + var buf [32]byte + if _, err := io.ReadFull(r, buf[:]); err != nil { + return err + } + *it = buf + default: + err = c.decodeReflect(r, item) + } + + return err +} + +func (c *ConfiguredEncoder) decodeReflect(r io.Reader, item interface{}) error { + itemT := reflect.TypeOf(item) + if itemT.Kind() != reflect.Ptr { + return errors.New("can only decode into pointer types") + } + + canonicalized := canonicalizeWellKnown(itemT.Elem()) + if wellKnownDecoders[canonicalized] != nil { + return wellKnownDecoders[canonicalized](r, item) + } + + elemKind := itemT.Elem().Kind() + if itemT.Elem().Kind() == reflect.Array { + return c.decodeArray(r, item) + } + + if elemKind == reflect.Slice { + return c.decodeSlice(r, item) + } + + return errors.New(fmt.Sprintf("type %s cannot be decoded", itemT.String())) +} + +func (c *ConfiguredEncoder) decodeArray(r io.Reader, item interface{}) error { + itemVal := reflect.ValueOf(item) + indirectVal := reflect.Indirect(itemVal) + indirectT := indirectVal.Type() + + l := indirectT.Len() + tmp := reflect.Zero(reflect.ArrayOf(l, indirectT.Elem())) + tmpPtr := reflect.New(indirectT) + tmpPtr.Elem().Set(tmp) + if indirectT.Elem().Kind() == reflect.Uint8 { + buf := make([]byte, l, l) + if _, err := io.ReadFull(r, buf); err != nil { + return err + } + reflect.Copy(tmpPtr.Elem().Slice(0, l), reflect.ValueOf(buf)) + } else { + for i := 0; i < indirectVal.Len(); i++ { + if err := c.DecodeField(r, tmpPtr.Elem().Index(i).Addr().Interface()); err != nil { + return err + } + } + } + itemVal.Elem().Set(tmpPtr.Elem()) + return nil +} + +func (c *ConfiguredEncoder) decodeSlice(r io.Reader, item interface{}) error { + itemVal := reflect.ValueOf(item) + indirectVal := reflect.Indirect(itemVal) + indirectT := indirectVal.Type() + + tmp := reflect.Zero(reflect.SliceOf(indirectT.Elem())) + tmpPtr := reflect.New(indirectT) + tmpPtr.Elem().Set(tmp) + + br := newByteReader(r) + l, err := binary.ReadUvarint(br) + if err != nil { + return err + } + if l > uint64(c.MaxVariableArrayLen) { + return errors.New("variable array field length too large to decode") + } + + if indirectT.Elem().Kind() == reflect.Ptr { + for i := 0; i < int(l); i++ { + sliceItem := reflect.Zero(indirectT.Elem().Elem()) + sliceItemPtr := reflect.New(sliceItem.Type()) + sliceItemPtr.Elem().Set(sliceItem) + if err := c.DecodeField(r, sliceItemPtr.Interface()); err != nil { + return err + } + tmpPtr.Elem().Set(reflect.Append(tmpPtr.Elem(), sliceItemPtr)) + } + } else { + for i := 0; i < int(l); i++ { + sliceItem := reflect.Zero(indirectT.Elem()) + sliceItemPtr := reflect.New(indirectT.Elem()) + sliceItemPtr.Elem().Set(sliceItem) + if err := c.DecodeField(r, sliceItemPtr.Interface()); err != nil { + return err + } + tmpPtr.Elem().Set(reflect.Append(tmpPtr.Elem(), sliceItemPtr.Elem())) + } + } + + itemVal.Elem().Set(tmpPtr.Elem()) + return nil +} diff --git a/dwire/decode_test.go b/dwire/decode_test.go new file mode 100644 index 0000000..2e6ac42 --- /dev/null +++ b/dwire/decode_test.go @@ -0,0 +1,166 @@ +package dwire + +import ( + "bytes" + "encoding/hex" + "errors" + "io" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +type cafeEncodeDecoder struct { + data []byte +} + +func (c *cafeEncodeDecoder) Decode(r io.Reader) error { + buf := make([]byte, 2, 2) + if _, err := io.ReadFull(r, buf); err != nil { + return err + } + if !bytes.Equal(buf, []byte{0xca, 0xfe}) { + return errors.New("invalid cafe decode") + } + c.data = buf + return nil +} + +func (c *cafeEncodeDecoder) Encode(w io.Writer) error { + _, err := w.Write([]byte{0xca, 0xfe}) + return err +} + +func TestDecodeFields(t *testing.T) { + var cafe cafeEncodeDecoder + + type testStruct struct { + f0 cafeEncodeDecoder + f1 uint8 + f2 uint16 + f3 uint32 + f4 uint64 + f5 []byte + f6 string + f7 [32]byte + f8 [2]uint8 + f9 []uint8 + f10 []string + f11 time.Time + f12 [2]string + f13 []*cafeEncodeDecoder + } + exp := &testStruct{ + f0: cafe, + f1: 1, + f2: 2, + f3: 3, + f4: 4, + f5: []byte{0xff, 0x00}, + f6: "testing", + f7: [32]byte{}, + f8: [2]uint8{ + 1, + 2, + }, + f9: []uint8{ + 3, + 4, + }, + f10: []string{ + "testing", + "testing", + }, + f11: time.Unix(1, 0), + f12: [2]string{ + "testing", + "testing", + }, + f13: []*cafeEncodeDecoder{ + &cafe, + &cafe, + }, + } + exp.f7[0] = 0x11 + + var actual testStruct + inputBytes, err := hex.DecodeString( + "cafe" + + "01" + + "0002" + + "00000003" + + "0000000000000004" + + "02ff00" + + "0774657374696e67" + + "1100000000000000000000000000000000000000000000000000000000000000" + + "0102" + + "020304" + + "020774657374696e670774657374696e67" + + "00000001" + + "0774657374696e670774657374696e67" + + "02cafecafe", + ) + require.NoError(t, err) + require.NoError(t, DecodeFields( + bytes.NewReader(inputBytes), + &actual.f0, + &actual.f1, + &actual.f2, + &actual.f3, + &actual.f4, + &actual.f5, + &actual.f6, + &actual.f7, + &actual.f8, + &actual.f9, + &actual.f10, + &actual.f11, + &actual.f12, + &actual.f13, + )) + require.EqualValues(t, exp.f0.data, exp.f0.data) + require.EqualValues(t, exp.f1, actual.f1) + require.EqualValues(t, exp.f2, actual.f2) + require.EqualValues(t, exp.f3, actual.f3) + require.EqualValues(t, exp.f4, actual.f4) + require.EqualValues(t, exp.f5, actual.f5) + require.EqualValues(t, exp.f6, actual.f6) + require.EqualValues(t, exp.f7, actual.f7) + require.EqualValues(t, exp.f8, actual.f8) + require.EqualValues(t, exp.f9, actual.f9) + require.EqualValues(t, exp.f10, actual.f10) + require.EqualValues(t, exp.f11, actual.f11) + require.EqualValues(t, exp.f12, actual.f12) + require.Equal(t, len(exp.f13), len(actual.f13)) +} + +func TestDecode_Errors(t *testing.T) { + var boolVal bool + err := DecodeField(bytes.NewReader([]byte{0x02}), &boolVal) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid boolean value") + + err = DecodeField(bytes.NewReader([]byte{}), uint64(0)) + require.Error(t, err) + require.Contains(t, err.Error(), "can only decode into pointer types") + + var buf bytes.Buffer + require.NoError(t, writeUvarint(&buf, DefaultMaxByteFieldLen+DefaultMaxVariableArrayLen+1)) + var byteArrVal []byte + err = DecodeField(bytes.NewReader(buf.Bytes()), &byteArrVal) + require.Error(t, err) + require.Contains(t, err.Error(), "byte-assignable field length too large to decode") + + var strVal string + // zero out err since the err message is the same + err = nil + err = DecodeField(bytes.NewReader(buf.Bytes()), &strVal) + require.Error(t, err) + require.Contains(t, err.Error(), "byte-assignable field length too large to decode") + + var strArrVal []string + err = DecodeField(bytes.NewReader(buf.Bytes()), &strArrVal) + require.Error(t, err) + require.Contains(t, err.Error(), "variable array field length too large to decode") +} diff --git a/dwire/doc.go b/dwire/doc.go new file mode 100644 index 0000000..7235644 --- /dev/null +++ b/dwire/doc.go @@ -0,0 +1,54 @@ +/* +Package dwire implements the Footnote message encoding scheme as defined in +PIP-1. + +Fundamental types: + + - bool: Encoded as 0x00 or 0x01 if the value is true or false, + respectively. + - uint8: Encoded as a single byte in the range 0x00-0xff. + - uint16: Encoded as two big-endian bytes in the range 0x0000-0xffff. + - uint32: Encoded as four big-endian bytes in the range + 0x00000000-0xffffffff + - uint64: Encoded as eight big-endian bytes in the range + 0x0000000000000000-0xffffffffffffffff. + - string: Encoded as a UTF-8 []byte. + - [N]T: Encoded as the concatenation of the encoding of T. + - []T: Encoded as a binary.Uvarint length prefix followed by the + concatenation of the encoding of T. + +Well-known types: + + - time.Time: Encoded as uint32(time.Unix()). + +The easiest way to use this library is to call the EncodeField/DecodeField family +of methods. To encode a value into a Writer: + + value1 := "this is my value" + value2 := 2 + err := dwire.EncodeFields(w, value1, value2) + +To decode a value from a reader: + + var value1 string + var value2 string + err := dwire.DecodeFields(r, &value1, &value2) + +Note that values passed to DecodeField/DecodeFields MUST be pointers. + +dwire exposes Encoder and Decoder interfaces, which allow arbitrary types to be +encoded and decoded by EncodeField/DecodeField. For example: + + type Foo struct { + Value string + } + + func (f *Foo) Encode(w io.Writer) error { + return dwire.EncodeFields(w, f.Value) + } + + func (f *Foo) Decode(r io.Reader) error { + return dwire.DecodeFields(r, &f.Value) + } + */ +package dwire diff --git a/dwire/encode.go b/dwire/encode.go new file mode 100644 index 0000000..d7abde1 --- /dev/null +++ b/dwire/encode.go @@ -0,0 +1,135 @@ +package dwire + +import ( + "encoding/binary" + "errors" + "fmt" + "io" + "reflect" +) + +var ( + trueWire = []byte{0x01} + falseWire = []byte{0x00} +) + +// EncodeFields encodes each field in the variadic items argument +// into the Writer using the default Encoder. +func EncodeFields(w io.Writer, items ...interface{}) error { + return defaultEncoder.EncodeFields(w, items...) +} + +// EncodeField encodes a single field into the Writer using the +// default Encoder. +func EncodeField(w io.Writer, item interface{}) error { + return defaultEncoder.EncodeField(w, item) +} + +// EncodeFields encodes each field in the variadic items argument +// into the Writer. +func (c *ConfiguredEncoder) EncodeFields(w io.Writer, items ...interface{}) error { + for _, item := range items { + if err := c.EncodeField(w, item); err != nil { + return err + } + } + + return nil +} + +// EncodeFields encodes a single field into the Writer. +func (c *ConfiguredEncoder) EncodeField(w io.Writer, item interface{}) error { + var err error + switch it := item.(type) { + case Encoder: + err = it.Encode(w) + case bool: + val := falseWire + if it { + val = trueWire + } + _, err = w.Write(val) + case uint8: + _, err = w.Write([]byte{it}) + case uint16: + b := make([]byte, 2, 2) + binary.BigEndian.PutUint16(b, it) + _, err = w.Write(b) + case uint32: + b := make([]byte, 4, 4) + binary.BigEndian.PutUint32(b, it) + _, err = w.Write(b) + case uint64: + b := make([]byte, 8, 8) + binary.BigEndian.PutUint64(b, it) + _, err = w.Write(b) + case []byte: + if uint64(len(it)) > c.MaxByteFieldLen { + return errors.New("byte-assignable field length too large to encode") + } + if err := writeUvarint(w, len(it)); err != nil { + return err + } + _, err = w.Write(it) + case string: + err = c.EncodeField(w, []byte(item.(string))) + case [32]byte: + _, err = w.Write(it[:]) + default: + err = c.encodeReflect(w, item) + } + + return err +} + +func (c *ConfiguredEncoder) encodeReflect(w io.Writer, item interface{}) error { + t := reflect.TypeOf(item) + + canonicalized := canonicalizeWellKnown(t) + if wellKnownEncoders[canonicalized] != nil { + return wellKnownEncoders[canonicalized](w, item) + } + + if t.Kind() == reflect.Array { + itemVal := reflect.ValueOf(item) + if t.Elem().Kind() == reflect.Uint8 { + itemPtr := reflect.New(t) + itemPtr.Elem().Set(itemVal) + _, err := w.Write(itemPtr.Elem().Slice(0, itemVal.Len()).Bytes()) + return err + } + + for i := 0; i < itemVal.Len(); i++ { + if err := c.EncodeField(w, itemVal.Index(i).Interface()); err != nil { + return err + } + } + return nil + } + + if t.Kind() == reflect.Slice { + val := reflect.ValueOf(item) + if val.Len() > c.MaxVariableArrayLen { + return errors.New("variable array field length too large to encode") + } + + if err := writeUvarint(w, val.Len()); err != nil { + return err + } + for i := 0; i < val.Len(); i++ { + if err := c.EncodeField(w, val.Index(i).Interface()); err != nil { + return err + } + } + return nil + } + + return errors.New(fmt.Sprintf("type %s cannot be encoded", t.String())) +} + +func writeUvarint(w io.Writer, n int) error { + lenBuf := make([]byte, binary.MaxVarintLen64, binary.MaxVarintLen64) + bytesWritten := binary.PutUvarint(lenBuf, uint64(n)) + _, err := w.Write(lenBuf[:bytesWritten]) + return err +} diff --git a/dwire/encode_test.go b/dwire/encode_test.go new file mode 100644 index 0000000..7061395 --- /dev/null +++ b/dwire/encode_test.go @@ -0,0 +1,105 @@ +package dwire + +import ( + "bytes" + "encoding/hex" + "math" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestEncodeFields(t *testing.T) { + cafe := new(cafeEncodeDecoder) + + var threeTwoByte [32]byte + threeTwoByte[1] = 0xff + + var buf bytes.Buffer + require.NoError(t, EncodeFields( + &buf, + cafe, + []*cafeEncodeDecoder{ + cafe, + cafe, + }, + true, + false, + uint8(0), + uint16(0), + uint32(0), + uint64(0), + uint8(math.MaxUint8), + uint16(math.MaxUint16), + uint32(math.MaxUint32), + uint64(math.MaxUint64), + threeTwoByte, + [2]string{ + "testing", + "testing", + }, + []byte{ + 0x01, 0x02, + }, + []string{ + "testing", + "testing", + }, + "hello there", + time.Unix(1, 0), + )) + require.Equal( + t, + "cafe"+ + "02cafecafe"+ + "01"+ + "00"+ + "00"+ + "0000"+ + "00000000"+ + "0000000000000000"+ + "ff"+ + "ffff"+ + "ffffffff"+ + "ffffffffffffffff"+ + "00ff000000000000000000000000000000000000000000000000000000000000"+ + "0774657374696e670774657374696e67"+ + "020102"+ + "020774657374696e670774657374696e67"+ + "0b68656c6c6f207468657265"+ + "00000001", + hex.EncodeToString(buf.Bytes()), + ) + + buf.Reset() + err := EncodeFields(&buf, uint8(1), struct{}{}) + require.Error(t, err) + require.Contains(t, err.Error(), "cannot be encoded") +} + +func TestEncode_Errors(t *testing.T) { + rw := new(NopReadWriter) + err := EncodeField(rw, &struct{}{}) + require.Error(t, err) + require.Contains(t, err.Error(), "cannot be encoded") + + customEncoder := &ConfiguredEncoder{ + MaxVariableArrayLen: 5, + MaxByteFieldLen: 5, + } + + err = customEncoder.EncodeField(rw, make([]byte, customEncoder.MaxByteFieldLen+1)) + require.Error(t, err) + require.Contains(t, err.Error(), "byte-assignable field length too large to encode") + + // zero out err since the message is the same + err = nil + err = customEncoder.EncodeField(rw, "123456") + require.Error(t, err) + require.Contains(t, err.Error(), "byte-assignable field length too large to encode") + + err = customEncoder.EncodeField(rw, make([]string, customEncoder.MaxVariableArrayLen+1)) + require.Error(t, err) + require.Contains(t, err.Error(), "variable array field length too large to encode") +} diff --git a/dwire/encoder.go b/dwire/encoder.go new file mode 100644 index 0000000..2800098 --- /dev/null +++ b/dwire/encoder.go @@ -0,0 +1,42 @@ +package dwire + +import "io" + +const ( + DefaultMaxVariableArrayLen = 4096 + DefaultMaxByteFieldLen = 8 * 256 * 4096 +) + +// Encoder is an interface that allows arbitrary types to be +// encoded. Types implementing the Encoder interface can be +// encoded using EncodeField or EncodeFields. +type Encoder interface { + Encode(w io.Writer) error +} + +// Decoder is an interface that allows arbitrary types to be +// decoded. Types implementing the Decoder interface can be +// decoded using DecodeField or DecodeFields. +type Decoder interface { + Decode(r io.Reader) error +} + +type EncodeDecoder interface { + Encoder + Decoder +} + +type ConfiguredEncoder struct { + // MaxVariableArrayLen is the maximum length of a variable-length array dwire + // will decode before stopping early. + MaxVariableArrayLen int + + // MaxByteFieldLen is the maximum length of a variable-length byte array field + // dwire will decode before stopping early. + MaxByteFieldLen uint64 +} + +var defaultEncoder = &ConfiguredEncoder{ + MaxVariableArrayLen: DefaultMaxVariableArrayLen, + MaxByteFieldLen: DefaultMaxByteFieldLen, +} diff --git a/dwire/encoding_bench_test.go b/dwire/encoding_bench_test.go new file mode 100644 index 0000000..948457e --- /dev/null +++ b/dwire/encoding_bench_test.go @@ -0,0 +1,107 @@ +package dwire + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +type NopReadWriter struct{} + +func (n *NopReadWriter) Read(p []byte) (int, error) { + return len(p), nil +} + +func (n *NopReadWriter) Write(p []byte) (int, error) { + return len(p), nil +} + +func BenchmarkUint8Encoding(b *testing.B) { + var i uint8 + rw := new(NopReadWriter) + for n := 0; n < b.N; n++ { + require.NoError(b, EncodeField(rw, i)) + } +} + +func BenchmarkUint16Encoding(b *testing.B) { + var i uint16 + rw := new(NopReadWriter) + for n := 0; n < b.N; n++ { + require.NoError(b, EncodeField(rw, i)) + } +} + +func BenchmarkUint32Encoding(b *testing.B) { + var i uint32 + rw := new(NopReadWriter) + for n := 0; n < b.N; n++ { + require.NoError(b, EncodeField(rw, i)) + } +} + +func BenchmarkUint64Encoding(b *testing.B) { + var i uint64 + rw := new(NopReadWriter) + for n := 0; n < b.N; n++ { + require.NoError(b, EncodeField(rw, i)) + } +} + +func BenchmarkByteSliceEncoding1024(b *testing.B) { + bytes := make([]byte, 1024, 1024) + rw := new(NopReadWriter) + for n := 0; n < b.N; n++ { + require.NoError(b, EncodeField(rw, bytes)) + } +} + +func BenchmarkStringEncoding1024(b *testing.B) { + bytes := make([]byte, 1024, 1024) + str := string(bytes) + rw := new(NopReadWriter) + for n := 0; n < b.N; n++ { + require.NoError(b, EncodeField(rw, str)) + } +} + +func BenchmarkByteArrayEncoding32(b *testing.B) { + bytes := make([]byte, 32, 32) + rw := new(NopReadWriter) + for n := 0; n < b.N; n++ { + require.NoError(b, EncodeField(rw, bytes)) + } +} + +func BenchmarkByteArrayEncodingReflect(b *testing.B) { + var bytes [1024]byte + rw := new(NopReadWriter) + for n := 0; n < b.N; n++ { + require.NoError(b, EncodeField(rw, bytes)) + } +} + +func BenchmarkUint16ArrayEncodingReflect(b *testing.B) { + var uints [1024]uint16 + rw := new(NopReadWriter) + for n := 0; n < b.N; n++ { + require.NoError(b, EncodeField(rw, uints)) + } +} + +func BenchmarkStringArrayEncodingReflect(b *testing.B) { + var strings [1024]string + rw := new(NopReadWriter) + for n := 0; n < b.N; n++ { + require.NoError(b, EncodeField(rw, strings)) + } +} + +func BenchmarkWellKnownTimeEncoding(b *testing.B) { + ts := time.Now() + rw := new(NopReadWriter) + for n := 0; n < b.N; n++ { + require.NoError(b, EncodeField(rw, ts)) + } +} diff --git a/dwire/well_known.go b/dwire/well_known.go new file mode 100644 index 0000000..24ee9ea --- /dev/null +++ b/dwire/well_known.go @@ -0,0 +1,62 @@ +package dwire + +import ( + "fmt" + "io" + "reflect" + "time" + + "github.com/pkg/errors" +) + +type encoderFunc func(w io.Writer, val interface{}) error +type decoderFunc func(r io.Reader, val interface{}) error + +var ( + wellKnownEncoders = make(map[string]encoderFunc) + wellKnownDecoders = make(map[string]decoderFunc) +) + +// Encodes a time.Time value into the Writer. Since time.Time is a +// well-known type, you likely do not need to call this method directly. +// Instead, provide the time value to EncodeField or EncodeFields. +func EncodeTime(w io.Writer, val interface{}) error { + cast, ok := val.(time.Time) + if !ok { + return errors.New("value is not a time.Time") + } + + unix := cast.Unix() + if unix < 0 { + return errors.New("negative UNIX time") + } + return EncodeField(w, uint32(unix)) +} + +// Decodes a time.Time value from the Reader. Since time.Time is a +// well-known type, you likely do not need to call this method directly. +// Instead, call EncodeField or EncodeFields with a &time.Time item. +func DecodeTime(r io.Reader, val interface{}) error { + cast, ok := val.(*time.Time) + if !ok { + return errors.New("value is not a *time.Time") + } + + var unixTs uint32 + if err := DecodeField(r, &unixTs); err != nil { + return errors.Wrap(err, "failed to decode timestamp") + } + + *cast = time.Unix(int64(unixTs), 0) + return nil +} + +func canonicalizeWellKnown(t reflect.Type) string { + return fmt.Sprintf("%s/%s", t.PkgPath(), t.Name()) +} + +func init() { + timeTypeKey := canonicalizeWellKnown(reflect.TypeOf(time.Time{})) + wellKnownEncoders[timeTypeKey] = EncodeTime + wellKnownDecoders[timeTypeKey] = DecodeTime +} diff --git a/dwire/well_known_test.go b/dwire/well_known_test.go new file mode 100644 index 0000000..181d285 --- /dev/null +++ b/dwire/well_known_test.go @@ -0,0 +1,37 @@ +package dwire + +import ( + "bytes" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestEncodeTime(t *testing.T) { + var buf bytes.Buffer + require.NoError(t, EncodeTime(&buf, time.Unix(12345, 0))) + require.EqualValues(t, []byte{0x00, 0x00, 0x30, 0x39}, buf.Bytes()) + + rw := new(NopReadWriter) + err := EncodeTime(rw, 9001) + require.Error(t, err) + require.Contains(t, err.Error(), "value is not a time.Time") + + err = EncodeTime(rw, time.Time{}) + require.Error(t, err) + require.Contains(t, err.Error(), "negative UNIX time") +} + +func TestDecodeTime(t *testing.T) { + input := []byte{0x00, 0x00, 0x30, 0x39} + rd := bytes.NewReader(input) + var output time.Time + require.NoError(t, DecodeTime(rd, &output)) + require.True(t, output.Equal(time.Unix(12345, 0))) + + rd = bytes.NewReader(input) + err := DecodeTime(rd, output) + require.Error(t, err) + require.Contains(t, err.Error(), "value is not a *time.Time") +} diff --git a/go.mod b/go.mod index 73b1a69..240849d 100644 --- a/go.mod +++ b/go.mod @@ -1,24 +1,18 @@ -module fnd +module github.com/ddrp-org/ddrp go 1.12 -replace fnd.localhost/dwire => ./vendor/fnd.localhost/dwire - -replace fnd.localhost/mstream => ./vendor/fnd.localhost/mstream - -replace fnd.localhost/handshake => ./vendor/fnd.localhost/handshake - require ( - fnd.localhost/dwire v1.0.1 - fnd.localhost/handshake v0.0.0-20200428084808-2c986090302e github.com/btcsuite/btcd v0.20.1-beta - github.com/golang/protobuf v1.4.2 + github.com/golang/protobuf v1.4.0-rc.3 github.com/golang/snappy v0.0.1 // indirect + github.com/google/go-cmp v0.5.0 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/kr/pretty v0.1.0 // indirect github.com/mattn/go-isatty v0.0.11 github.com/mattn/go-runewidth v0.0.4 // indirect github.com/mitchellh/go-homedir v1.1.0 + github.com/mslipper/handshake v0.0.0-20200428084808-2c986090302e github.com/olekukonko/tablewriter v0.0.1 github.com/onsi/ginkgo v1.8.0 // indirect github.com/onsi/gomega v1.5.0 // indirect @@ -30,13 +24,12 @@ require ( github.com/stretchr/testify v1.5.1 github.com/syndtr/goleveldb v1.0.0 golang.org/x/crypto v0.0.0-20200422194213-44a606286825 - golang.org/x/net v0.0.0-20190923162816-aa69164e4478 golang.org/x/sync v0.0.0-20190423024810-112230192c58 golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 // indirect golang.org/x/text v0.3.2 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 google.golang.org/grpc v1.27.0 - google.golang.org/protobuf v1.25.0 + google.golang.org/protobuf v1.20.0 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.2.8 // indirect ) diff --git a/go.sum b/go.sum index 77e6f54..097834c 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,4 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -fnd.localhost/dwire v1.0.1 h1:OD5D5aRahOuy0QGCHxXrZf5ZJlX0IBcT/3P0k97elpQ= -fnd.localhost/dwire v1.0.1/go.mod h1:BkHitp5E9PSDVLq5nPLXWzQFEwFSR5aNhTL7M9xeC7I= -fnd.localhost/handshake v0.0.0-20200428084808-2c986090302e h1:MgJUOlZMg4aEHfxoH7DrrOZxuP7XkHQUTZ6WHfMhaXM= -fnd.localhost/handshake v0.0.0-20200428084808-2c986090302e/go.mod h1:YVUlfqY28yFbCM7y59cmL92/VfM0EDBXKrhjgmo2OAg= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -41,12 +37,8 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.0-rc.3 h1:OzhhLcnXjTNb98owNUFibnt+cUqC2RSAGyFqxU4x3ok= +github.com/golang/protobuf v1.4.0-rc.3/go.mod h1:57iy8tErfL8eYKb9AjvkwLdYn7fzOM4yLPLUGc/0Cew= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -54,6 +46,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= @@ -83,6 +76,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mslipper/handshake v0.0.0-20200428084808-2c986090302e h1:MgJUOlZMg4aEHfxoH7DrrOZxuP7XkHQUTZ6WHfMhaXM= +github.com/mslipper/handshake v0.0.0-20200428084808-2c986090302e/go.mod h1:YVUlfqY28yFbCM7y59cmL92/VfM0EDBXKrhjgmo2OAg= github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -119,8 +114,6 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH 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= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= @@ -175,31 +168,22 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610 h1:Ygq9/SRJX9+dU0WCIICM8RkWvDw03lvB77hrhJnpxfU= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw= -google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.20.0 h1:SsQNHvKpk2VTiWoQ5Pqkt3Go/c2ly77C+v2Lggu5Qek= +google.golang.org/protobuf v1.20.0/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= diff --git a/p2p/counting_reader_test.go b/p2p/counting_reader_test.go index b80bad8..0e45a1f 100644 --- a/p2p/counting_reader_test.go +++ b/p2p/counting_reader_test.go @@ -2,7 +2,7 @@ package p2p import ( "bytes" - "fnd/crypto" + "github.com/ddrp-org/ddrp/crypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "testing" diff --git a/p2p/envelope_io.go b/p2p/envelope_io.go index 25b20cd..48428ae 100644 --- a/p2p/envelope_io.go +++ b/p2p/envelope_io.go @@ -3,8 +3,8 @@ package p2p import ( "context" "errors" - "fnd/crypto" - "fnd/wire" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/wire" "time" ) diff --git a/p2p/incoming_handshake.go b/p2p/incoming_handshake.go index 90de2ca..7b329d6 100644 --- a/p2p/incoming_handshake.go +++ b/p2p/incoming_handshake.go @@ -2,8 +2,8 @@ package p2p import ( "context" - "fnd/crypto" - "fnd/wire" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/wire" "github.com/pkg/errors" ) diff --git a/p2p/incoming_handshake_test.go b/p2p/incoming_handshake_test.go index 7031320..a12570a 100644 --- a/p2p/incoming_handshake_test.go +++ b/p2p/incoming_handshake_test.go @@ -3,12 +3,12 @@ package p2p import ( "context" "errors" - "fnd/crypto" - "fnd/testutil/testcrypto" - "fnd/wire" - "github.com/stretchr/testify/require" "testing" "time" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/wire" + "github.com/stretchr/testify/require" ) func TestHandleIncomingHandshake(t *testing.T) { @@ -40,35 +40,6 @@ func TestHandleIncomingHandshake(t *testing.T) { setup.Close(t) } -func TestHandleIncomingHandshake_InvalidHelloSig(t *testing.T) { - ctx := context.Background() - setup := initializeHandshakes(t) - doneCh := make(chan struct{}, 2) - go func() { - _, err := HandleIncomingHandshake(ctx, &HandshakeConfig{ - Magic: 12345, - ProtocolVersion: 1, - Peer: setup.inPeer, - Signer: setup.inSigner, - }) - require.True(t, errors.Is(err, ErrInvalidEnvelopeSignature)) - doneCh <- struct{}{} - }() - go func() { - _, err := HandleOutgoingHandshake(ctx, &HandshakeConfig{ - Magic: 12345, - ProtocolVersion: 1, - Peer: setup.outPeer, - Signer: testcrypto.NewRandomSigner(), - }) - require.True(t, errors.Is(err, ErrPeerClosed)) - doneCh <- struct{}{} - }() - <-doneCh - setup.Close(t) - <-doneCh -} - func TestHandleIncomingHandshake_InvalidHelloAckNonce(t *testing.T) { ctx := context.Background() setup := initializeHandshakes(t) diff --git a/p2p/listener.go b/p2p/listener.go index b56a2ea..b4233a4 100644 --- a/p2p/listener.go +++ b/p2p/listener.go @@ -2,8 +2,8 @@ package p2p import ( "fmt" - "fnd/log" - "fnd/service" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/service" "github.com/pkg/errors" "net" "sync" diff --git a/p2p/outgoing_handshake.go b/p2p/outgoing_handshake.go index 789eeb4..eebf325 100644 --- a/p2p/outgoing_handshake.go +++ b/p2p/outgoing_handshake.go @@ -2,9 +2,9 @@ package p2p import ( "context" - "fnd/crypto" - "fnd/version" - "fnd/wire" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/version" + "github.com/ddrp-org/ddrp/wire" "github.com/pkg/errors" "time" ) diff --git a/p2p/outgoing_handshake_test.go b/p2p/outgoing_handshake_test.go index bca4a4a..29910e0 100644 --- a/p2p/outgoing_handshake_test.go +++ b/p2p/outgoing_handshake_test.go @@ -4,10 +4,10 @@ import ( "context" "errors" "fmt" - "fnd/crypto" - "fnd/testutil" - "fnd/testutil/testcrypto" - "fnd/wire" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/testutil" + "github.com/ddrp-org/ddrp/testutil/testcrypto" + "github.com/ddrp-org/ddrp/wire" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "net" diff --git a/p2p/peer.go b/p2p/peer.go index 4c4cabb..4cb027b 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -4,8 +4,8 @@ import ( "bufio" "context" "errors" - "fnd/log" - "fnd/wire" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/wire" "golang.org/x/time/rate" "io" "math" diff --git a/p2p/peer_manager.go b/p2p/peer_manager.go index 2782340..44cdec0 100644 --- a/p2p/peer_manager.go +++ b/p2p/peer_manager.go @@ -3,11 +3,11 @@ package p2p import ( "context" "fmt" - "fnd/crypto" - "fnd/log" - "fnd/service" - "fnd/store" - "fnd/util" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/service" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/util" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" "golang.org/x/sync/semaphore" diff --git a/p2p/peer_muxer.go b/p2p/peer_muxer.go index 77d33a4..1afa96b 100644 --- a/p2p/peer_muxer.go +++ b/p2p/peer_muxer.go @@ -2,10 +2,10 @@ package p2p import ( "fmt" - "fnd/crypto" - "fnd/log" - "fnd/util" - "fnd/wire" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/util" + "github.com/ddrp-org/ddrp/wire" "github.com/pkg/errors" "sync" "sync/atomic" diff --git a/p2p/peer_test.go b/p2p/peer_test.go index fe944ad..a321327 100644 --- a/p2p/peer_test.go +++ b/p2p/peer_test.go @@ -4,8 +4,8 @@ import ( "bytes" "context" "errors" - "fnd/testutil/testcrypto" - "fnd/wire" + "github.com/ddrp-org/ddrp/testutil/testcrypto" + "github.com/ddrp-org/ddrp/wire" "github.com/stretchr/testify/require" "io" "sync" diff --git a/p2p/seed_test.go b/p2p/seed_test.go index 945f743..cbcc430 100644 --- a/p2p/seed_test.go +++ b/p2p/seed_test.go @@ -1,15 +1,15 @@ package p2p import ( - "github.com/stretchr/testify/require" "testing" + + "github.com/stretchr/testify/require" ) func TestLookupDNSSeeds(t *testing.T) { - seeds, err := ResolveDNSSeeds("seeds-test.fnd.network") + seeds, err := ResolveDNSSeeds("seeds-test.merkleblock.com") require.NoError(t, err) - require.Equal(t, 2, len(seeds)) - require.Contains(t, seeds, "10.1.0.1") - require.Contains(t, seeds, "10.1.0.2") + require.Equal(t, 1, len(seeds)) + require.Contains(t, seeds, "78.46.17.17") } diff --git a/p2p/seeds.go b/p2p/seeds.go index 1b97e5c..6d7eea0 100644 --- a/p2p/seeds.go +++ b/p2p/seeds.go @@ -1,7 +1,7 @@ package p2p import ( - "fnd/crypto" + "github.com/ddrp-org/ddrp/crypto" "github.com/pkg/errors" "net" "strings" diff --git a/packaging/scripts/after_install.sh b/packaging/scripts/after_install.sh index 4b7d27b..3e94175 100644 --- a/packaging/scripts/after_install.sh +++ b/packaging/scripts/after_install.sh @@ -6,16 +6,16 @@ set -ue -USERNAME="fnd" -SERVICE="fnd" +USERNAME="ddrp" +SERVICE="ddrpd" UNIT_FILE="/etc/systemd/system/${SERVICE}.service" main() { echo "Adding ${USERNAME} user..." useradd -s /bin/false -M --system $USERNAME - echo "Initializing fnd config in /etc/fnd.." - /usr/bin/fnd init --home /etc/fnd || true - chown -R $USERNAME:$USERNAME /etc/fnd + echo "Initializing ddrpd config in /etc/ddrpd.." + /usr/bin/ddrpd init --home /etc/ddrpd || true + chown -R $USERNAME:$USERNAME /etc/ddrpd if command -v systemctl >/dev/null 2>&1; then rm -f "${UNIT_FILE}" @@ -31,4 +31,4 @@ main() { echo "Done." } -main +main \ No newline at end of file diff --git a/packaging/scripts/after_remove.sh b/packaging/scripts/after_remove.sh index d2e018c..9d9eee1 100644 --- a/packaging/scripts/after_remove.sh +++ b/packaging/scripts/after_remove.sh @@ -6,7 +6,7 @@ set -ue -SERVICE="fnd" +SERVICE="ddrpd" # fix an issue where this script runs on upgrades for rpm # see https://github.com/jordansissel/fpm/issues/1175#issuecomment-240086016 @@ -33,4 +33,4 @@ clean_systemd() { systemctl daemon-reload || true } -main +main \ No newline at end of file diff --git a/protocol/ban_list.go b/protocol/ban_list.go index d18cf87..63fe2a9 100644 --- a/protocol/ban_list.go +++ b/protocol/ban_list.go @@ -2,7 +2,7 @@ package protocol import ( "bufio" - "fnd.localhost/handshake/primitives" + "github.com/mslipper/handshake/primitives" "github.com/pkg/errors" "io" "net/http" @@ -22,8 +22,8 @@ func ParseBanListVersion(line string) (int, error) { if len(splits) != 2 { return 0, errors.New("ban list version must consist of two colon-separated components") } - if splits[0] != "FNBAN" { - return 0, errors.New("ban list version must start with FNBAN") + if splits[0] != "DDRPBAN" { + return 0, errors.New("ban list version must start with DDRPBAN") } if !verRegex.MatchString(splits[1]) { return 0, errors.New("ban list version must end with v followed by a digit") diff --git a/protocol/ban_list_test.go b/protocol/ban_list_test.go index fe4a865..b074118 100644 --- a/protocol/ban_list_test.go +++ b/protocol/ban_list_test.go @@ -13,11 +13,11 @@ func TestParseBanListVersion(t *testing.T) { }{ {"", "colon-separated components"}, {"whatever", "colon-separated components"}, - {":", "start with FNBAN"}, - {"FNBAN", "colon-separated components"}, - {"FNBAN:", "end with v followed by a digit"}, - {"FNBAN:beep", "end with v followed by a digit"}, - {"FNBAN:1", "end with v followed by a digit"}, + {":", "start with DDRPBAN"}, + {"DDRPBAN", "colon-separated components"}, + {"DDRPBAN:", "end with v followed by a digit"}, + {"DDRPBAN:beep", "end with v followed by a digit"}, + {"DDRPBAN:1", "end with v followed by a digit"}, } for _, test := range invalidTests { @@ -31,9 +31,9 @@ func TestParseBanListVersion(t *testing.T) { in string ver int }{ - {"FNBAN:v0", 0}, - {"FNBAN:v1", 1}, - {"FNBAN:v10", 10}, + {"DDRPBAN:v0", 0}, + {"DDRPBAN:v1", 1}, + {"DDRPBAN:v10", 10}, } for _, test := range validTests { @@ -53,15 +53,15 @@ func TestReadBanList(t *testing.T) { "must start with version line", }, { - "FNBAN:", + "DDRPBAN:", "v followed by a digit", }, { - "FNBAN:v1\n-------.", + "DDRPBAN:v1\n-------.", "start with a hyphen", }, { - "FNBAN:v0\nhonk", + "DDRPBAN:v0\nhonk", "unsupported ban list version", }, } @@ -78,7 +78,7 @@ func TestReadBanList(t *testing.T) { out []string }{ { - "FNBAN:v1\nwar\nis\npeace", + "DDRPBAN:v1\nwar\nis\npeace", []string{ "war", "is", @@ -86,27 +86,27 @@ func TestReadBanList(t *testing.T) { }, }, { - "FNBAN:v1", + "DDRPBAN:v1", []string{}, }, { - "FNBAN:v1\n", + "DDRPBAN:v1\n", []string{}, }, { - "FNBAN:v1\n test2 \n", + "DDRPBAN:v1\n test2 \n", []string{ "test2", }, }, { - "FNBAN:v1\ntest2 \n", + "DDRPBAN:v1\ntest2 \n", []string{ "test2", }, }, { - "FNBAN:v1\n\ttest2 \nhello", + "DDRPBAN:v1\n\ttest2 \nhello", []string{ "test2", "hello", @@ -125,7 +125,7 @@ func TestReadBanList(t *testing.T) { } func TestFetchListFile(t *testing.T) { - names, err := FetchListFile("") + names, err := FetchListFile("https://gist.githubusercontent.com/mslipper/fd68d2eea1fbb0c435924d71c3152f19/raw/ccfa9fff79ce805c149ebdfff0dfa938f408fa52/banlist") require.NoError(t, err) require.Equal(t, 3, len(names)) require.Equal(t, names[0], "testname") diff --git a/protocol/epoch.go b/protocol/epoch.go new file mode 100644 index 0000000..b5e5b8b --- /dev/null +++ b/protocol/epoch.go @@ -0,0 +1,34 @@ +package protocol + +import ( + "time" + + "github.com/mslipper/handshake/primitives" +) + +// 2020 Jan 1 00:00 UTC +var epochDate = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC) + +const ( + secondsPerHour = 60 * 60 + hoursPerWeek = 7 * 24 + weekDuration = time.Duration(hoursPerWeek * time.Hour) +) + +func modBuffer(b []byte, n int) int { + p := 256 % n + acc := 0 + + for i := 0; i < len(b); i++ { + acc = (p*acc + int(b[i])) % n + } + return acc +} + +func CurrentEpoch(name string) uint16 { + hash := primitives.HashName(name) + mod := modBuffer(hash, hoursPerWeek) + offset := mod * secondsPerHour + startDate := epochDate.Add(time.Duration(offset) * time.Second) + return uint16(int(time.Now().Sub(startDate).Seconds()) / int(weekDuration.Seconds())) +} diff --git a/protocol/epoch_test.go b/protocol/epoch_test.go new file mode 100644 index 0000000..61aacb4 --- /dev/null +++ b/protocol/epoch_test.go @@ -0,0 +1,279 @@ +package protocol + +import ( + "errors" + "testing" + "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/testutil/mockapp" + "github.com/ddrp-org/ddrp/util" + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" +) + +type epochTestSetup struct { + tp *mockapp.TestPeers + ls *mockapp.TestStorage + rs *mockapp.TestStorage +} + +func TestEpoch(t *testing.T) { + name := "foobar" + tests := []struct { + name string + run func(t *testing.T, setup *epochTestSetup) + }{ + { + "syncs sectors when the local node has never seen the name before", + func(t *testing.T, setup *epochTestSetup) { + ts := time.Now() + update := mockapp.FillBlobRandom( + t, + setup.rs.DB, + setup.rs.BlobStore, + setup.tp.RemoteSigner, + name, + 0, + blob.SectorCount, + ts, + ) + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + NameLocker: util.NewMultiLocker(), + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: setup.tp.RemoteSigner.Pub(), + }, + } + require.NoError(t, UpdateBlob(cfg)) + mockapp.RequireBlobsEqual(t, setup.ls.BlobStore, setup.rs.BlobStore, name) + }, + }, + { + "aborts sync if the name is banned", + func(t *testing.T, setup *epochTestSetup) { + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: CurrentEpoch(name) + 1, + }, + } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: 0, + SectorSize: 10, + Banned: true, + BannedAt: time.Now().Add(-1 * 24 * time.Duration(time.Hour)), + }, blob.ZeroSectorHashes) + })) + err := UpdateBlob(cfg) + require.NotNil(t, err) + require.True(t, errors.Is(err, ErrNameBanned)) + }, + }, + { + "syncs sectors when the name ban has passed", + func(t *testing.T, setup *epochTestSetup) { + ts := time.Now() + update := mockapp.FillBlobRandom( + t, + setup.rs.DB, + setup.rs.BlobStore, + setup.tp.RemoteSigner, + name, + 0, + blob.SectorCount, + ts, + ) + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + NameLocker: util.NewMultiLocker(), + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: setup.tp.RemoteSigner.Pub(), + }, + } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: 0, + SectorSize: 0, + Banned: true, + BannedAt: time.Now().Add(-8 * 24 * time.Duration(time.Hour)), + }, blob.ZeroSectorHashes) + })) + require.NoError(t, UpdateBlob(cfg)) + mockapp.RequireBlobsEqual(t, setup.ls.BlobStore, setup.rs.BlobStore, name) + }, + }, + { + "aborts sync if the epoch is throttled", + func(t *testing.T, setup *epochTestSetup) { + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: CurrentEpoch(name) + 1, + }, + } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: 0, + SectorSize: 10, + EpochStartAt: time.Now(), + }, blob.ZeroSectorHashes) + })) + err := UpdateBlob(cfg) + require.NotNil(t, err) + require.True(t, errors.Is(err, ErrInvalidEpochThrottled)) + }, + }, + { + "aborts sync if the epoch is backdated", + func(t *testing.T, setup *epochTestSetup) { + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: 0, + }, + } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: CurrentEpoch(name), + SectorSize: 10, + Banned: true, + BannedAt: time.Now().Add(-1 * 24 * time.Duration(time.Hour)), + }, blob.ZeroSectorHashes) + })) + err := UpdateBlob(cfg) + require.NotNil(t, err) + require.True(t, errors.Is(err, ErrInvalidEpochBackdated)) + }, + }, + { + "aborts sync if the epoch is futuredated", + func(t *testing.T, setup *epochTestSetup) { + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: CurrentEpoch(name) + 1, + }, + } + err := UpdateBlob(cfg) + require.NotNil(t, err) + require.True(t, errors.Is(err, ErrInvalidEpochFuturedated)) + }, + }, + { + "rewrites partial blob with new blob on epoch rollover", + func(t *testing.T, setup *epochTestSetup) { + ts := time.Now() + update := mockapp.FillBlobRandom( + t, + setup.rs.DB, + setup.rs.BlobStore, + setup.tp.RemoteSigner, + name, + CurrentEpoch(name), + blob.SectorCount, + ts, + ) + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + NameLocker: util.NewMultiLocker(), + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: setup.tp.RemoteSigner.Pub(), + }, + } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: CurrentEpoch(name) - 1, + SectorSize: 10, + }, blob.ZeroSectorHashes) + })) + require.NoError(t, UpdateBlob(cfg)) + mockapp.RequireBlobsEqual(t, setup.ls.BlobStore, setup.rs.BlobStore, name) + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + testPeers, peersDone := mockapp.ConnectTestPeers(t) + defer peersDone() + remoteStorage, remoteStorageDone := mockapp.CreateStorage(t) + defer remoteStorageDone() + localStorage, localStorageDone := mockapp.CreateStorage(t) + defer localStorageDone() + remoteSS := NewSectorServer(testPeers.RemoteMux, remoteStorage.DB, remoteStorage.BlobStore, util.NewMultiLocker()) + require.NoError(t, remoteSS.Start()) + defer require.NoError(t, remoteSS.Stop()) + + tt.run(t, &epochTestSetup{ + tp: testPeers, + ls: localStorage, + rs: remoteStorage, + }) + }) + } +} diff --git a/protocol/heartbeater.go b/protocol/heartbeater.go index 1b86d65..046613f 100644 --- a/protocol/heartbeater.go +++ b/protocol/heartbeater.go @@ -3,10 +3,10 @@ package protocol import ( "bytes" "encoding/json" - "fnd/crypto" - "fnd/log" - "fnd/service" - "fnd/version" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/service" + "github.com/ddrp-org/ddrp/version" "github.com/pkg/errors" "net/http" "sync" diff --git a/protocol/heartbeater_test.go b/protocol/heartbeater_test.go index 8fc3c1e..f44ceb1 100644 --- a/protocol/heartbeater_test.go +++ b/protocol/heartbeater_test.go @@ -2,8 +2,8 @@ package protocol import ( "encoding/json" - "fnd/crypto" - "fnd/testutil/testcrypto" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/testutil/testcrypto" "github.com/stretchr/testify/require" "io/ioutil" "net/http" @@ -37,7 +37,7 @@ func TestHeartbeater_SendHeartbeats(t *testing.T) { beat := <-resCh require.Equal(t, "test moniker", beat.Moniker) require.Equal(t, peerID, beat.PeerID) - require.Equal(t, "fnd/+", beat.UserAgent) + require.Equal(t, "ddrpd/+", beat.UserAgent) require.NoError(t, heartbeater.Stop()) server.Close() diff --git a/protocol/moderation.go b/protocol/moderation.go index 2bb9c42..3d14ac0 100644 --- a/protocol/moderation.go +++ b/protocol/moderation.go @@ -1,9 +1,9 @@ package protocol import ( - "fnd/blob" - "fnd/log" - "fnd/store" + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/store" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" "time" diff --git a/protocol/moderation_test.go b/protocol/moderation_test.go index 21e875a..293143e 100644 --- a/protocol/moderation_test.go +++ b/protocol/moderation_test.go @@ -1,9 +1,9 @@ package protocol import ( - "fnd/blob" - "fnd/store" - "fnd/testutil/testfs" + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/testutil/testfs" "github.com/stretchr/testify/require" "testing" ) @@ -22,8 +22,8 @@ func TestIngestBanLists(t *testing.T) { require.NoError(t, bl.Close()) err = IngestBanLists(db, bs, []string{ - "", - "", + "https://gist.githubusercontent.com/mslipper/b5d28fe54850be8b879b4064abcacddf/raw/6c412b8bc02a3765b49acf455b6ce32c7a5a4ddd/banlist-test-1", + "https://gist.githubusercontent.com/mslipper/cc32c19da426622e156cf771aafa58da/raw/07210f958c01737a139d916c5082dd1bc7724955/banlist-test-2", }) require.NoError(t, err) diff --git a/protocol/name_importer.go b/protocol/name_importer.go index 4b45227..75e63a7 100644 --- a/protocol/name_importer.go +++ b/protocol/name_importer.go @@ -3,17 +3,17 @@ package protocol import ( "bytes" "encoding/hex" - "encoding/base64" "fmt" "github.com/btcsuite/btcd/btcec" - "fnd/config" - "fnd/log" - "fnd/store" - "fnd.localhost/handshake/client" - "fnd.localhost/handshake/dns" - "fnd.localhost/handshake/primitives" + "github.com/ddrp-org/ddrp/config" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/store" + "github.com/mslipper/handshake/client" + "github.com/mslipper/handshake/dns" + "github.com/mslipper/handshake/primitives" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" + "strings" "sync" "sync/atomic" "time" @@ -196,13 +196,13 @@ func (n *NameImporter) fetchBlocks(start int, count int) ([]*primitives.Block, e return partition, nil } -type FNRecord struct { +type DDRPKeyRecord struct { NameHash string PublicKey *btcec.PublicKey } -func ExtractTXTRecordsBlock(block *primitives.Block) []*FNRecord { - uniqRecords := make(map[string]*FNRecord) +func ExtractTXTRecordsBlock(block *primitives.Block) []*DDRPKeyRecord { + uniqRecords := make(map[string]*DDRPKeyRecord) var order []string for _, tx := range block.Transactions { records := ExtractTXTRecordsTx(tx) @@ -213,15 +213,15 @@ func ExtractTXTRecordsBlock(block *primitives.Block) []*FNRecord { uniqRecords[rec.NameHash] = rec } } - out := make([]*FNRecord, len(uniqRecords)) + out := make([]*DDRPKeyRecord, len(uniqRecords)) for i := 0; i < len(order); i++ { out[i] = uniqRecords[order[i]] } return out } -func ExtractTXTRecordsTx(tx *primitives.Transaction) []*FNRecord { - var out []*FNRecord +func ExtractTXTRecordsTx(tx *primitives.Transaction) []*DDRPKeyRecord { + var out []*DDRPKeyRecord for _, vOut := range tx.Outputs { covenant := vOut.Covenant var resource *dns.Resource @@ -246,16 +246,13 @@ func ExtractTXTRecordsTx(tx *primitives.Transaction) []*FNRecord { } var pub *btcec.PublicKey - if resource == nil { - continue - } for _, record := range resource.Records { txt, ok := record.(*dns.TXTRecord) if !ok { continue } for _, entry := range txt.Entries { - p, err := ParseFNRecord(entry) + p, err := ParseDDRPKeyRecord(entry) if err != nil { continue } @@ -267,7 +264,7 @@ func ExtractTXTRecordsTx(tx *primitives.Transaction) []*FNRecord { continue } - out = append(out, &FNRecord{ + out = append(out, &DDRPKeyRecord{ NameHash: hex.EncodeToString(nh), PublicKey: pub, }) @@ -275,19 +272,18 @@ func ExtractTXTRecordsTx(tx *primitives.Transaction) []*FNRecord { return out } -func ParseFNRecord(record string) (*btcec.PublicKey, error) { - if len(record) != 45 { +func ParseDDRPKeyRecord(record string) (*btcec.PublicKey, error) { + splits := strings.Split(record, ":") + if len(splits) != 2 { return nil, errors.New("mal-formed txt record") } - prefix := record[0:1] - pubkeyb64 := record[1:] - if prefix != "f" { + if splits[0] != "DDRPKEY" { return nil, errors.New("mal-formed record sigil") } - if len(pubkeyb64) != 44 { + if len(splits[1]) != 66 { return nil, errors.New("invalid public key length") } - keyBytes, err := base64.StdEncoding.DecodeString(pubkeyb64) + keyBytes, err := hex.DecodeString(splits[1]) if err != nil { return nil, errors.New("mal-formed public key") } diff --git a/protocol/name_importer_test.go b/protocol/name_importer_test.go index 9d4b3e0..e0174e5 100644 --- a/protocol/name_importer_test.go +++ b/protocol/name_importer_test.go @@ -2,30 +2,30 @@ package protocol import ( "fmt" - "fnd/testutil/testcrypto" + "github.com/ddrp-org/ddrp/testutil/testcrypto" "github.com/stretchr/testify/require" "testing" ) -func TestParseFNRecord(t *testing.T) { +func TestParseDDRPKeyRecord(t *testing.T) { invalid := []string{ - "f000000000000000000000000000000000000000000000000000000000000000000", - "fwhateverwhateverwhateverwhateverwhateverwhateverwhateverwhateverwh", - "f", - "f", - "fwhatever", - "f", + "DDRPKEY:000000000000000000000000000000000000000000000000000000000000000000", + "DDRPKEY:whateverwhateverwhateverwhateverwhateverwhateverwhateverwhateverwh", + "DDRPKEY", + "DDRPKEY:", + "DDRPKEY:whatever", + "DDRPKEY", "", "wibble", } for _, rec := range invalid { - _, err := ParseFNRecord(rec) + _, err := ParseDDRPKeyRecord(rec) require.Error(t, err) } _, expPub := testcrypto.RandKey() - rec := fmt.Sprintf("f%x", expPub.SerializeCompressed()) - actPub, err := ParseFNRecord(rec) + rec := fmt.Sprintf("DDRPKEY:%x", expPub.SerializeCompressed()) + actPub, err := ParseDDRPKeyRecord(rec) require.NoError(t, err) require.True(t, expPub.IsEqual(actPub)) } diff --git a/protocol/name_syncer.go b/protocol/name_syncer.go index 70c3339..8891ab2 100644 --- a/protocol/name_syncer.go +++ b/protocol/name_syncer.go @@ -1,18 +1,19 @@ package protocol import ( - "fnd/config" - "fnd/crypto" - "fnd/log" - "fnd/p2p" - "fnd/store" - "fnd/util" - "fnd/wire" - "github.com/pkg/errors" - "github.com/syndtr/goleveldb/leveldb" "sync" "sync/atomic" "time" + + "github.com/ddrp-org/ddrp/config" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/util" + "github.com/ddrp-org/ddrp/wire" + "github.com/pkg/errors" + "github.com/syndtr/goleveldb/leveldb" ) var ( @@ -172,7 +173,7 @@ func (ns *NameSyncer) OnSyncError(cb func(name string, err error)) util.Unsubscr func (ns *NameSyncer) syncName(info *store.NameInfo) { name := info.Name - ownTS := time.Unix(0, 0) + ownEpoch := uint16(0) header, err := store.GetHeader(ns.db, info.Name) if err != nil && !errors.Is(err, leveldb.ErrNotFound) { ns.lgr.Error( @@ -182,7 +183,7 @@ func (ns *NameSyncer) syncName(info *store.NameInfo) { return } if err == nil { - ownTS = header.Timestamp + ownEpoch = header.EpochHeight } isEnvelopeCh := make(chan bool) @@ -196,8 +197,9 @@ func (ns *NameSyncer) syncName(info *store.NameInfo) { }) recips, _ := p2p.BroadcastRandom(ns.mux, ns.SampleSize, &wire.UpdateReq{ - Name: name, - Timestamp: ownTS, + Name: name, + EpochHeight: ownEpoch, + SectorSize: uint16(0), // FIXME }) sampleSize := len(recips) diff --git a/protocol/peer_exchanger.go b/protocol/peer_exchanger.go index 7696b14..b1638e4 100644 --- a/protocol/peer_exchanger.go +++ b/protocol/peer_exchanger.go @@ -1,13 +1,13 @@ package protocol import ( - "fnd/config" - "fnd/crypto" - "fnd/log" - "fnd/p2p" - "fnd/store" - "fnd/util" - "fnd/wire" + "github.com/ddrp-org/ddrp/config" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/util" + "github.com/ddrp-org/ddrp/wire" "github.com/syndtr/goleveldb/leveldb" "math" "math/rand" diff --git a/protocol/peer_set.go b/protocol/peer_set.go index 6fe15af..60a942b 100644 --- a/protocol/peer_set.go +++ b/protocol/peer_set.go @@ -1,7 +1,7 @@ package protocol import ( - "fnd/crypto" + "github.com/ddrp-org/ddrp/crypto" "sync" ) diff --git a/protocol/peer_set_test.go b/protocol/peer_set_test.go index b5cdabe..3f1d583 100644 --- a/protocol/peer_set_test.go +++ b/protocol/peer_set_test.go @@ -1,7 +1,7 @@ package protocol import ( - "fnd/crypto" + "github.com/ddrp-org/ddrp/crypto" "github.com/stretchr/testify/require" "testing" ) diff --git a/protocol/pinger.go b/protocol/pinger.go index 62dab89..1465d35 100644 --- a/protocol/pinger.go +++ b/protocol/pinger.go @@ -3,10 +3,10 @@ package protocol import ( "context" "errors" - "fnd/crypto" - "fnd/log" - "fnd/p2p" - "fnd/wire" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/wire" "sync" "sync/atomic" "time" diff --git a/protocol/pinger_test.go b/protocol/pinger_test.go index 3bbc3d7..cec8e43 100644 --- a/protocol/pinger_test.go +++ b/protocol/pinger_test.go @@ -2,11 +2,11 @@ package protocol import ( "context" - "fnd/crypto" - "fnd/p2p" - "fnd/testutil" - "fnd/testutil/testcrypto" - "fnd/wire" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/testutil" + "github.com/ddrp-org/ddrp/testutil/testcrypto" + "github.com/ddrp-org/ddrp/wire" "github.com/stretchr/testify/require" "io" "io/ioutil" diff --git a/protocol/sector_server.go b/protocol/sector_server.go index 9010a18..d78bd90 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -1,18 +1,18 @@ package protocol import ( - "errors" "fmt" - "fnd/blob" - "fnd/config" - "fnd/crypto" - "fnd/log" - "fnd/p2p" - "fnd/store" - "fnd/util" - "fnd/wire" - "github.com/syndtr/goleveldb/leveldb" "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/config" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/util" + "github.com/ddrp-org/ddrp/wire" + "github.com/syndtr/goleveldb/leveldb" ) type SectorServer struct { @@ -38,8 +38,7 @@ func NewSectorServer(mux *p2p.PeerMuxer, db *leveldb.DB, bs blob.Store, nameLock } func (s *SectorServer) Start() error { - s.mux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeTreeBaseReq, s.onTreeBaseReq)) - s.mux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeSectorReq, s.onSectorReq)) + s.mux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeBlobReq, s.onBlobReq)) return nil } @@ -47,62 +46,43 @@ func (s *SectorServer) Stop() error { return nil } -func (s *SectorServer) onTreeBaseReq(peerID crypto.Hash, envelope *wire.Envelope) { - reqMsg := envelope.Message.(*wire.TreeBaseReq) +func (s *SectorServer) onBlobReq(peerID crypto.Hash, envelope *wire.Envelope) { + reqMsg := envelope.Message.(*wire.BlobReq) lgr := s.lgr.Sub( "name", reqMsg.Name, "peer_id", peerID, ) if !s.nameLocker.TryRLock(reqMsg.Name) { - lgr.Info("dropping diff req for busy name") + lgr.Info("dropping sector req for busy name") return } - merkleBase, err := store.GetMerkleBase(s.db, reqMsg.Name) + + header, err := store.GetHeader(s.db, reqMsg.Name) if err != nil { - s.nameLocker.RUnlock(reqMsg.Name) - lgr.Error("error getting merkle base", "err", err) + lgr.Error( + "failed to fetch header", + "err", err) return } - s.nameLocker.RUnlock(reqMsg.Name) - resMsg := &wire.TreeBaseRes{ - Name: reqMsg.Name, - MerkleBase: merkleBase, - } - if err := s.mux.Send(peerID, resMsg); err != nil { - lgr.Error("error serving tree base response", "err", err) - return + var prevHash crypto.Hash = blob.ZeroHash + if reqMsg.SectorSize != 0 { + hash, err := store.GetSectorHash(s.db, reqMsg.Name, reqMsg.SectorSize-1) + if err != nil { + lgr.Error( + "failed to fetch sector hash", + "err", err) + return + } + prevHash = hash } - lgr.Debug("served tree base response") -} - -func (s *SectorServer) onSectorReq(peerID crypto.Hash, envelope *wire.Envelope) { - reqMsg := envelope.Message.(*wire.SectorReq) - lgr := s.lgr.Sub( - "name", reqMsg.Name, - "peer_id", peerID, - ) - if !s.nameLocker.TryRLock(reqMsg.Name) { - lgr.Info("dropping sector req for busy name") - return - } - header, err := store.GetHeader(s.db, reqMsg.Name) - if errors.Is(err, leveldb.ErrNotFound) { - s.nameLocker.RUnlock(reqMsg.Name) - return - } - if err != nil { - lgr.Error("error getting blob header", "err", err) - s.nameLocker.RUnlock(reqMsg.Name) - return - } - cacheKey := fmt.Sprintf("%s:%d:%d", reqMsg.Name, header.Timestamp.Unix(), reqMsg.SectorID) + cacheKey := fmt.Sprintf("%s:%d:%d", reqMsg.Name, reqMsg.EpochHeight, reqMsg.SectorSize) cached := s.cache.Get(cacheKey) if cached != nil { s.nameLocker.RUnlock(reqMsg.Name) - s.sendResponse(peerID, reqMsg.Name, reqMsg.SectorID, cached.(blob.Sector)) + s.sendResponse(peerID, reqMsg.Name, prevHash, cached.([]blob.Sector), reqMsg.EpochHeight, reqMsg.SectorSize) return } @@ -120,25 +100,32 @@ func (s *SectorServer) onSectorReq(peerID crypto.Hash, envelope *wire.Envelope) s.lgr.Error("failed to close blob", "err", err) } }() - sector, err := bl.ReadSector(reqMsg.SectorID) - if err != nil { - s.nameLocker.RUnlock(reqMsg.Name) - lgr.Error( - "failed to read sector", - "err", err, - ) - return + var sectors []blob.Sector + for i := reqMsg.SectorSize; i < header.SectorSize; i++ { + sector := &blob.Sector{} + _, err = bl.ReadAt(sector[:], int64(i)*blob.SectorLen) + if err != nil { + s.nameLocker.RUnlock(reqMsg.Name) + lgr.Error( + "failed to read sector", + "err", err, + ) + return + } + sectors = append(sectors, *sector) } - s.cache.Set(cacheKey, sector, int64(s.CacheExpiry/time.Millisecond)) + s.cache.Set(cacheKey, sectors, int64(s.CacheExpiry/time.Millisecond)) s.nameLocker.RUnlock(reqMsg.Name) - s.sendResponse(peerID, reqMsg.Name, reqMsg.SectorID, sector) + s.sendResponse(peerID, reqMsg.Name, prevHash, sectors, reqMsg.EpochHeight, reqMsg.SectorSize) } -func (s *SectorServer) sendResponse(peerID crypto.Hash, name string, sectorID uint8, sector blob.Sector) { - resMsg := &wire.SectorRes{ - Name: name, - SectorID: sectorID, - Sector: sector, +func (s *SectorServer) sendResponse(peerID crypto.Hash, name string, prevHash crypto.Hash, sectors []blob.Sector, epochHeight, sectorSize uint16) { + resMsg := &wire.BlobRes{ + Name: name, + EpochHeight: epochHeight, + PayloadPosition: sectorSize, + PrevHash: prevHash, + Payload: sectors, } if err := s.mux.Send(peerID, resMsg); err != nil { s.lgr.Error("error serving sector response", "err", err) @@ -147,6 +134,6 @@ func (s *SectorServer) sendResponse(peerID crypto.Hash, name string, sectorID ui s.lgr.Debug( "served sector response", "peer_id", peerID, - "sector_id", sectorID, + "sector_size", sectorSize, ) } diff --git a/protocol/syncer.go b/protocol/syncer.go index bf1c635..b4b51da 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -1,267 +1,145 @@ package protocol import ( - "fnd/blob" - "fnd/crypto" - "fnd/log" - "fnd/p2p" - "fnd/wire" - "github.com/pkg/errors" - "sync" "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/wire" + "github.com/pkg/errors" ) const ( - DefaultSyncerTreeBaseResTimeout = 10 * time.Second - DefaultSyncerSectorResTimeout = 15 * time.Second + DefaultSyncerBlobResTimeout = 15 * time.Second ) var ( - ErrNoTreeBaseCandidates = errors.New("no tree base candidates") - ErrSyncerNoProgress = errors.New("sync not progressing") - ErrSyncerMaxAttempts = errors.New("reached max sync attempts") + ErrSyncerNoProgress = errors.New("sync not progressing") + ErrSyncerMaxAttempts = errors.New("reached max sync attempts") ) -type SyncTreeBasesOpts struct { - Timeout time.Duration - Mux *p2p.PeerMuxer - Peers *PeerSet - MerkleRoot crypto.Hash - Name string -} - -func SyncTreeBases(opts *SyncTreeBasesOpts) (blob.MerkleBase, error) { - lgr := log.WithModule("tree-base-syncer") - treeBaseResCh := make(chan *wire.TreeBaseRes, 1) - iter := opts.Peers.Iterator() - var newMerkleBase blob.MerkleBase - for { - peerID, ok := iter() - if !ok { - return newMerkleBase, ErrNoTreeBaseCandidates - } - - var once sync.Once - unsubTreeBaseRes := opts.Mux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeTreeBaseRes, func(recvPeerID crypto.Hash, res *wire.Envelope) { - msg := res.Message.(*wire.TreeBaseRes) - if msg.Name != opts.Name { - return - } - if peerID != recvPeerID { - return - } - once.Do(func() { - treeBaseResCh <- msg - }) - })) - err := opts.Mux.Send(peerID, &wire.TreeBaseReq{ - Name: opts.Name, - }) - if err != nil { - lgr.Warn("error fetching tree base from peer, trying another", "peer_id", peerID, "err", err) - unsubTreeBaseRes() - continue - } - - timeout := 10 * time.Second - if opts.Timeout != 0 { - timeout = opts.Timeout - } - timer := time.NewTimer(timeout) - - select { - case <-timer.C: - lgr.Warn("timed out fetching tree base from peer, trying another", "peer_id", peerID) - unsubTreeBaseRes() - continue - case msg := <-treeBaseResCh: - unsubTreeBaseRes() - candMerkleTree := blob.MakeTreeFromBase(msg.MerkleBase) - if candMerkleTree.Root() != opts.MerkleRoot { - lgr.Warn("received invalid merkle base from peer, trying another", "peer_id", peerID) - continue - } - newMerkleBase = candMerkleTree.ProtocolBase() - return newMerkleBase, nil - } - } -} - type SyncSectorsOpts struct { Timeout time.Duration Mux *p2p.PeerMuxer Tx blob.Transaction Peers *PeerSet - MerkleBase blob.MerkleBase - SectorsNeeded []uint8 + EpochHeight uint16 + SectorSize uint16 + PrevHash crypto.Hash + SectorTipHash crypto.Hash Name string } -type sectorRes struct { +type payloadRes struct { peerID crypto.Hash - msg *wire.SectorRes + msg *wire.BlobRes } -type reqdSectorsMap map[uint8][33]byte - func SyncSectors(opts *SyncSectorsOpts) error { - l := log.WithModule("sector-syncer").Sub("name", opts.Name) - tx := opts.Tx - reqdSectors := make(reqdSectorsMap) - for _, id := range opts.SectorsNeeded { - hash := opts.MerkleBase[id] - if hash == blob.EmptyBlobBaseHash { - if err := tx.WriteSector(id, blob.ZeroSector); err != nil { - return errors.Wrap(err, "error writing zero sector") - } - continue - } - reqdSectors[id] = awaitingSectorHash(id, hash) - } - - neededLen := len(reqdSectors) - var attempts int - for { - if attempts == 3 { - return ErrSyncerMaxAttempts - } - - l.Trace("performing sync attempt", "attempts", attempts+1) - reqdSectors = syncLoop(opts, reqdSectors) - remainingLen := len(reqdSectors) - l.Info( - "synced sectors", - "received", neededLen-remainingLen, - "remaining", remainingLen, - ) - if remainingLen == 0 { - return nil - } - if neededLen == remainingLen { - return ErrSyncerNoProgress - } - neededLen = remainingLen - attempts++ - } -} - -func syncLoop(opts *SyncSectorsOpts, reqdSectors reqdSectorsMap) reqdSectorsMap { - lgr := log.WithModule("sync-loop").Sub("name", opts.Name) - - outReqdSectors := make(map[uint8][33]byte) - for k, v := range reqdSectors { - outReqdSectors[k] = v - } - sectorReqCh := make(chan uint8) - sectorResCh := make(chan *sectorRes) - sectorProcessedCh := make(chan struct{}, 1) + lgr := log.WithModule("payload-syncer").Sub("name", opts.Name) + // Implement payload hash based sync + payloadResCh := make(chan *payloadRes) + payloadProcessedCh := make(chan struct{}, 1) doneCh := make(chan struct{}) - unsubRes := opts.Mux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeSectorRes, func(peerID crypto.Hash, envelope *wire.Envelope) { - sectorResCh <- §orRes{ + unsubRes := opts.Mux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeBlobRes, func(peerID crypto.Hash, envelope *wire.Envelope) { + payloadResCh <- &payloadRes{ peerID: peerID, - msg: envelope.Message.(*wire.SectorRes), + msg: envelope.Message.(*wire.BlobRes), } })) go func() { - receivedSectors := make(map[uint8]bool) - awaitingSectorID := -1 + receivedPayloads := make(map[uint16]bool) for { - select { - case id := <-sectorReqCh: - awaitingSectorID = int(id) - iter := opts.Peers.Iterator() - var sendCount int - for { - peerID, ok := iter() - if !ok { - break - } - if sendCount == 7 { - break - } - err := opts.Mux.Send(peerID, &wire.SectorReq{ - Name: opts.Name, - SectorID: id, - }) - if err != nil { - lgr.Warn("error fetching sector from peer, trying another", "peer_id", peerID, "err", err) - continue - } - lgr.Debug( - "requested sector from peer", - "id", id, - "peer_id", peerID, - ) - sendCount++ + iter := opts.Peers.Iterator() + var sendCount int + for { + peerID, ok := iter() + if !ok { + break + } + if sendCount == 7 { + break + } + err := opts.Mux.Send(peerID, &wire.BlobReq{ + Name: opts.Name, + EpochHeight: opts.EpochHeight, + SectorSize: opts.SectorSize, + }) + if err != nil { + lgr.Warn("error fetching payload from peer, trying another", "peer_id", peerID, "err", err) + continue } - case res := <-sectorResCh: + lgr.Debug( + "requested payload from peer", + "peer_id", peerID, + ) + sendCount++ + } + select { + case res := <-payloadResCh: msg := res.msg peerID := res.peerID - expHash, ok := reqdSectors[msg.SectorID] if msg.Name != opts.Name { - lgr.Trace("received sector for extraneous name", "other_name", msg.Name, "sector_id", msg.SectorID) + lgr.Trace("received payload for extraneous name", "other_name", msg.Name) continue } - if !ok { - lgr.Trace("received unnecessary sector", "sector_id", msg.SectorID, "peer_id", peerID) + if receivedPayloads[msg.PayloadPosition] { + lgr.Trace("already processed this payload", "payload_position", msg.PayloadPosition, "peer_id", peerID) continue } - if receivedSectors[msg.SectorID] { - lgr.Trace("already processed this sector", "sector_id", msg.SectorID, "peer_id", peerID) + // TODO: if payloadposition = 0xff, handle equivocation proof + if opts.SectorSize != msg.PayloadPosition { + lgr.Trace("received unexpected payload position", "payload_size", opts.SectorSize, "payload_position", msg.PayloadPosition) continue } - if awaitingSectorID != int(msg.SectorID) { - lgr.Trace("received unsolicited sector", "sector_id", msg.SectorID, "peer_id", peerID) - continue + var sectorTipHash crypto.Hash = opts.PrevHash + for i := 0; int(i) < len(msg.Payload); i++ { + sectorTipHash = blob.SerialHashSector(msg.Payload[i], sectorTipHash) } - hash := awaitingSectorHash(msg.SectorID, blob.HashSector(msg.Sector)) - if expHash != hash { - lgr.Warn("invalid sector received", "sector_id", msg.SectorID, "peer_id", peerID) + if sectorTipHash != opts.SectorTipHash { + lgr.Trace("payload tip hash mismatch", "payload_tip_hash", sectorTipHash, "expected_payload_tip_hash", opts.SectorTipHash) + peer, err := opts.Mux.PeerByID(peerID) + if err != nil { + lgr.Trace("error fetching peer", "peer_id", peerID) + } + // TODO: set header.bannedat = time.now for this name + if err := peer.Close(); err != nil { + lgr.Trace("error banning peer", "peer_id", peerID) + } + // TODO: generate equivocation proof continue } - if err := opts.Tx.WriteSector(msg.SectorID, msg.Sector); err != nil { - lgr.Error("failed to write sector", "sector_id", msg.SectorID, "err", err) - continue + for i := 0; int(i) < len(msg.Payload); i++ { + if err := opts.Tx.WriteSector(msg.Payload[i]); err != nil { + lgr.Error("failed to write payload", "payload_id", i, "err", err) + continue + } } - receivedSectors[msg.SectorID] = true - lgr.Debug( - "synced sector", - "name", opts.Name, - "sector_id", msg.SectorID, - "peer_id", peerID, - ) - awaitingSectorID = -1 - sectorProcessedCh <- struct{}{} + receivedPayloads[msg.PayloadPosition] = true + payloadProcessedCh <- struct{}{} case <-doneCh: return } } }() -sectorLoop: - for id := range reqdSectors { - timeout := time.NewTimer(opts.Timeout) - lgr.Debug("requesting sector", "id", id) - sectorReqCh <- id +payloadLoop: + for { + lgr.Debug("requesting payload") select { - case <-sectorProcessedCh: - lgr.Debug("sector processed", "id", id) - delete(outReqdSectors, id) - case <-timeout.C: - lgr.Warn("sector request timed out", "id", id) - break sectorLoop + case <-payloadProcessedCh: + lgr.Debug("payload processed") + break payloadLoop + case <-time.NewTimer(opts.Timeout).C: + lgr.Warn("payload request timed out") + break payloadLoop } } unsubRes() close(doneCh) - return outReqdSectors -} - -func awaitingSectorHash(id uint8, hash crypto.Hash) [33]byte { - var buf [33]byte - buf[0] = id - copy(buf[1:], hash[:]) - return buf + return nil } diff --git a/protocol/syncer_test.go b/protocol/syncer_test.go index 1aa1eb2..2a8e3bd 100644 --- a/protocol/syncer_test.go +++ b/protocol/syncer_test.go @@ -4,13 +4,15 @@ import ( "bytes" "crypto/rand" "errors" - "fnd/blob" - "fnd/crypto" - "fnd/testutil/mockapp" - "fnd/util" - "github.com/stretchr/testify/require" "testing" "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/testutil/mockapp" + "github.com/ddrp-org/ddrp/util" + + "github.com/stretchr/testify/require" ) type syncTreeBasesSetup struct { diff --git a/protocol/testdata/blob b/protocol/testdata/blob index d7776fec633737d6f8542c54d7cbda2eae8a2ca9..f8f241094699f689470613d9f00dca2107b0876f 100644 GIT binary patch delta 519 zcmWl|1JD)*007X-wr$(Cv5d8B+y4G~*;`(=v0Aom+qPZTyL&-_K-j?Vf(b5!kU|M9 zjIhE9FM^07i7bk!qKPhsm|}@7j=189FM)&-Ni2z^l1VOwlu}78jkMB9FN2IS$t;Vk zvdJ!ooN~!6kG%59uYiIIDXfU1iYcyyl1eG9jIzopuY!vHP)TJ~R8>uNHPlo~ZGWoc zFLl*ZUjq#_(pVEsHPc)REw$2G8*R1IUI!g@(peW>b<Mn?|&O?w8>^$Y_-jHJM6T}ZhP#t&wd9SbjV>x9CgfbC!BQ3X=j{u&UqJH zbjf8`Ty@QLH{5i~ZFk&t&wUR(^vGjRJoU_TFTC{1Yj3>u&U+tx^vP#meD%$DKm7a! Djz0#S delta 521 zcmWN=1Jo7<006+3Z7Ro%AxuD3i>x z_)}Kd{N-=i<&aY@x#f{pKKT_;P$7jCQB*O-l~7VCrIk@uIptMQQ6-gCQB^h7)lgF{ zwbfBqJ@qxv&_5daS7S{y)l75$X`!W7T5F@NcG~NpqfR>OqN{GY>!GJ!dh4UFfFS+! z#{dHjGT0D94Kv&bBaJfJ7-Nky-UJg(GT9VUO*7pLGtDyF9COVx-vSFQve*(!EwkJT zE3LBH8f&ey-Ub_Ove_0}ZL{4DJMFUD9((<7pZyLv=#ayXIO>?=PB`h5)6O{SobxWY z=#tB>xaykgZn)`|+wQpQp8Fnn=#j^sc update.SectorSize { return ErrUpdateQueueStaleTimestamp } - if storedTimestamp.Equal(update.Timestamp) { + if storedSectorSize == update.SectorSize { return ErrUpdateQueueIdenticalTimestamp } - if time.Now().Sub(headerReceivedAt) < u.MinUpdateInterval { - return ErrUpdateQueueThrottled - } - u.mu.Lock() defer u.mu.Unlock() entry := u.entries[update.Name] - if entry == nil || entry.Timestamp.Before(update.Timestamp) { + if entry == nil || entry.SectorSize < update.SectorSize { u.entries[update.Name] = &UpdateQueueItem{ - PeerIDs: NewPeerSet([]crypto.Hash{peerID}), - Name: update.Name, - Timestamp: update.Timestamp, - MerkleRoot: update.MerkleRoot, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: nameInfo.PublicKey, - Height: nameInfo.ImportHeight, + PeerIDs: NewPeerSet([]crypto.Hash{peerID}), + Name: update.Name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: nameInfo.PublicKey, + Height: nameInfo.ImportHeight, } if entry == nil { u.queue = append(u.queue, update.Name) atomic.AddInt32(&u.queueLen, 1) } - u.lgr.Info("enqueued update", "name", update.Name, "timestamp", update.Timestamp) + u.lgr.Info("enqueued update", "name", update.Name, "epoch", update.EpochHeight, "sector", update.SectorSize) return nil } - if entry.Timestamp.After(update.Timestamp) { + if entry.SectorSize > update.SectorSize { return ErrUpdateQueueStaleTimestamp } if entry.Signature != update.Signature { return ErrUpdateQueueSpltBrain } - u.lgr.Info("enqueued update", "name", update.Name, "timestamp", update.Timestamp) + u.lgr.Info("enqueued update", "name", update.Name, "epoch", update.EpochHeight, "sector", update.SectorSize) entry.PeerIDs.Add(peerID) return nil } @@ -179,7 +171,7 @@ func (u *UpdateQueue) Dequeue() *UpdateQueueItem { return ret } -func (u *UpdateQueue) validateUpdate(name string, ts time.Time, mr crypto.Hash, rr crypto.Hash, sig crypto.Signature) (*store.NameInfo, error) { +func (u *UpdateQueue) validateUpdate(name string, epochHeight, sectorSize uint16, mr crypto.Hash, rr crypto.Hash, sig crypto.Signature) (*store.NameInfo, error) { if err := primitives.ValidateName(name); err != nil { return nil, errors.Wrap(err, "update name is invalid") } @@ -194,7 +186,7 @@ func (u *UpdateQueue) validateUpdate(name string, ts time.Time, mr crypto.Hash, if err != nil { return nil, errors.Wrap(err, "error reading name info") } - h := blob.SealHash(name, ts, mr, rr) + h := blob.SealHash(name, epochHeight, sectorSize, mr, rr) if !crypto.VerifySigPub(info.PublicKey, sig, h) { return nil, errors.New("update signature is invalid") } diff --git a/protocol/update_queue_test.go b/protocol/update_queue_test.go index c5df409..31d0906 100644 --- a/protocol/update_queue_test.go +++ b/protocol/update_queue_test.go @@ -1,17 +1,18 @@ package protocol import ( - "fnd/blob" - "fnd/crypto" - "fnd/p2p" - "fnd/store" - "fnd/testutil" - "fnd/testutil/testcrypto" - "fnd/wire" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" "testing" "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/testutil" + "github.com/ddrp-org/ddrp/testutil/testcrypto" + "github.com/ddrp-org/ddrp/wire" + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" ) func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { @@ -19,19 +20,22 @@ func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { defer done() identicalHeader := signHeader(t, &store.Header{ - Name: "identical", - Timestamp: time.Unix(1, 0), - ReceivedAt: time.Unix(1, 0), + Name: "identical", + EpochHeight: uint16(0), + SectorSize: uint16(1), + EpochStartAt: time.Unix(1, 0), }) throttledHeader := signHeader(t, &store.Header{ - Name: "throttled", - Timestamp: time.Unix(1, 0), - ReceivedAt: time.Now(), + Name: "throttled", + EpochHeight: uint16(0), + SectorSize: uint16(1), + EpochStartAt: time.Now(), }) staleHeader := signHeader(t, &store.Header{ - Name: "stale", - Timestamp: time.Unix(100, 0), - ReceivedAt: time.Unix(1, 0), + Name: "stale", + EpochHeight: uint16(0), + SectorSize: uint16(100), + EpochStartAt: time.Unix(1, 0), }) headers := []*store.Header{ @@ -55,7 +59,7 @@ func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { if err := store.SetNameInfoTx(tx, header.Name, pub, 10); err != nil { return err } - if err := store.SetHeaderTx(tx, header, blob.ZeroMerkleBase); err != nil { + if err := store.SetHeaderTx(tx, header, blob.ZeroSectorHashes); err != nil { return err } } @@ -88,11 +92,12 @@ func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { { "bad signature", &wire.Update{ - Name: identicalHeader.Name, - Timestamp: identicalHeader.Timestamp.Add(10 * time.Second), - MerkleRoot: identicalHeader.MerkleRoot, - ReservedRoot: identicalHeader.ReservedRoot, - Signature: identicalHeader.Signature, + Name: identicalHeader.Name, + EpochHeight: identicalHeader.EpochHeight, + SectorSize: identicalHeader.SectorSize + 10, + SectorTipHash: identicalHeader.SectorTipHash, + ReservedRoot: identicalHeader.ReservedRoot, + Signature: identicalHeader.Signature, }, func(t *testing.T, err error) { require.Contains(t, err.Error(), "signature is invalid") @@ -101,35 +106,25 @@ func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { { "identical", &wire.Update{ - Name: identicalHeader.Name, - Timestamp: identicalHeader.Timestamp, - MerkleRoot: identicalHeader.MerkleRoot, - ReservedRoot: identicalHeader.ReservedRoot, - Signature: identicalHeader.Signature, + Name: identicalHeader.Name, + EpochHeight: identicalHeader.EpochHeight, + SectorSize: identicalHeader.SectorSize, + SectorTipHash: identicalHeader.SectorTipHash, + ReservedRoot: identicalHeader.ReservedRoot, + Signature: identicalHeader.Signature, }, func(t *testing.T, err error) { require.Equal(t, ErrUpdateQueueIdenticalTimestamp, err) }, }, - { - "throttled", - signUpdate(t, &wire.Update{ - Name: throttledHeader.Name, - Timestamp: throttledHeader.Timestamp.Add(10 * time.Second), - MerkleRoot: throttledHeader.MerkleRoot, - ReservedRoot: identicalHeader.ReservedRoot, - }), - func(t *testing.T, err error) { - require.Equal(t, ErrUpdateQueueThrottled, err) - }, - }, { "stale", signUpdate(t, &wire.Update{ - Name: staleHeader.Name, - Timestamp: staleHeader.Timestamp.Add(-10 * time.Second), - MerkleRoot: throttledHeader.MerkleRoot, - ReservedRoot: identicalHeader.ReservedRoot, + Name: staleHeader.Name, + EpochHeight: staleHeader.EpochHeight, + SectorSize: staleHeader.SectorSize - 10, + SectorTipHash: throttledHeader.SectorTipHash, + ReservedRoot: identicalHeader.ReservedRoot, }), func(t *testing.T, err error) { require.Equal(t, ErrUpdateQueueStaleTimestamp, err) @@ -149,9 +144,10 @@ func TestUpdateQueue_Enqueue_InvalidAfterEnqueue(t *testing.T) { defer done() header := signHeader(t, &store.Header{ - Name: "somename", - Timestamp: time.Unix(100, 0), - ReceivedAt: time.Unix(1, 0), + Name: "somename", + EpochHeight: uint16(0), + SectorSize: uint16(100), + EpochStartAt: time.Unix(1, 0), }) _, pub := testcrypto.FixedKey(t) @@ -162,7 +158,7 @@ func TestUpdateQueue_Enqueue_InvalidAfterEnqueue(t *testing.T) { if err := store.SetNameInfoTx(tx, header.Name, pub, 10); err != nil { return err } - if err := store.SetHeaderTx(tx, header, blob.ZeroMerkleBase); err != nil { + if err := store.SetHeaderTx(tx, header, blob.ZeroSectorHashes); err != nil { return err } return nil @@ -170,17 +166,20 @@ func TestUpdateQueue_Enqueue_InvalidAfterEnqueue(t *testing.T) { queue := NewUpdateQueue(p2p.NewPeerMuxer(testutil.TestMagic, testcrypto.FixedSigner(t)), db) require.NoError(t, queue.Enqueue(crypto.Rand32(), signUpdate(t, &wire.Update{ - Name: header.Name, - Timestamp: header.Timestamp.Add(1 * time.Second), + Name: header.Name, + EpochHeight: header.EpochHeight, + SectorSize: header.SectorSize + 1, }))) require.Equal(t, ErrUpdateQueueStaleTimestamp, queue.Enqueue(crypto.Rand32(), signUpdate(t, &wire.Update{ - Name: header.Name, - Timestamp: header.Timestamp.Add(-10 * time.Second), + Name: header.Name, + EpochHeight: header.EpochHeight, + SectorSize: header.SectorSize - 10, }))) require.Equal(t, ErrUpdateQueueSpltBrain, queue.Enqueue(crypto.Rand32(), signUpdate(t, &wire.Update{ - Name: header.Name, - Timestamp: header.Timestamp.Add(1 * time.Second), - MerkleRoot: crypto.Rand32(), + Name: header.Name, + EpochHeight: header.EpochHeight, + SectorSize: header.SectorSize + 1, + SectorTipHash: crypto.Rand32(), }))) } @@ -189,9 +188,10 @@ func TestUpdateQueue_EnqueueDequeue(t *testing.T) { defer done() header := signHeader(t, &store.Header{ - Name: "somename", - Timestamp: time.Unix(100, 0), - ReceivedAt: time.Unix(1, 0), + Name: "somename", + EpochHeight: uint16(0), + SectorSize: uint16(100), + EpochStartAt: time.Unix(1, 0), }) _, pub := testcrypto.FixedKey(t) @@ -202,7 +202,7 @@ func TestUpdateQueue_EnqueueDequeue(t *testing.T) { if err := store.SetNameInfoTx(tx, header.Name, pub, 10); err != nil { return err } - if err := store.SetHeaderTx(tx, header, blob.ZeroMerkleBase); err != nil { + if err := store.SetHeaderTx(tx, header, blob.ZeroSectorHashes); err != nil { return err } return nil @@ -214,8 +214,9 @@ func TestUpdateQueue_EnqueueDequeue(t *testing.T) { } queue := NewUpdateQueue(p2p.NewPeerMuxer(testutil.TestMagic, testcrypto.FixedSigner(t)), db) update := signUpdate(t, &wire.Update{ - Name: header.Name, - Timestamp: header.Timestamp.Add(time.Second), + Name: header.Name, + EpochHeight: header.EpochHeight, + SectorSize: header.SectorSize + 1, }) for _, pid := range pids { require.NoError(t, queue.Enqueue(pid, update)) @@ -226,8 +227,9 @@ func TestUpdateQueue_EnqueueDequeue(t *testing.T) { require.True(t, item.PeerIDs.Has(pid)) } require.Equal(t, update.Name, item.Name) - require.Equal(t, update.Timestamp, item.Timestamp) - require.Equal(t, update.MerkleRoot, item.MerkleRoot) + require.Equal(t, update.EpochHeight, item.EpochHeight) + require.Equal(t, update.SectorSize, item.SectorSize) + require.Equal(t, update.SectorTipHash, item.SectorTipHash) require.Equal(t, update.ReservedRoot, item.ReservedRoot) require.Equal(t, update.Signature, item.Signature) require.True(t, pub.IsEqual(item.Pub)) @@ -235,14 +237,14 @@ func TestUpdateQueue_EnqueueDequeue(t *testing.T) { } func signHeader(t *testing.T, header *store.Header) *store.Header { - sig, err := blob.SignSeal(testcrypto.FixedSigner(t), header.Name, header.Timestamp, header.MerkleRoot, header.ReservedRoot) + sig, err := blob.SignSeal(testcrypto.FixedSigner(t), header.Name, header.EpochHeight, header.SectorSize, header.SectorTipHash, header.ReservedRoot) require.NoError(t, err) header.Signature = sig return header } func signUpdate(t *testing.T, update *wire.Update) *wire.Update { - sig, err := blob.SignSeal(testcrypto.FixedSigner(t), update.Name, update.Timestamp, update.MerkleRoot, update.ReservedRoot) + sig, err := blob.SignSeal(testcrypto.FixedSigner(t), update.Name, update.EpochHeight, update.SectorSize, update.SectorTipHash, update.ReservedRoot) require.NoError(t, err) update.Signature = sig return update diff --git a/protocol/update_server.go b/protocol/update_server.go index 9250555..698027e 100644 --- a/protocol/update_server.go +++ b/protocol/update_server.go @@ -1,12 +1,12 @@ package protocol import ( - "fnd/crypto" - "fnd/log" - "fnd/p2p" - "fnd/store" - "fnd/util" - "fnd/wire" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/util" + "github.com/ddrp-org/ddrp/wire" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" ) @@ -38,7 +38,7 @@ func (u *UpdateServer) Stop() error { func (u *UpdateServer) UpdateReqHandler(peerID crypto.Hash, envelope *wire.Envelope) { msg := envelope.Message.(*wire.UpdateReq) - u.lgr.Debug("receive update req", "name", msg.Name, "ts", msg.Timestamp) + u.lgr.Debug("receive update req", "name", msg.Name, "epoch", msg.EpochHeight, "sector", msg.SectorSize) if !u.nameLocker.TryRLock(msg.Name) { if err := u.mux.Send(peerID, wire.NewNilUpdate(msg.Name)); err != nil { @@ -69,7 +69,7 @@ func (u *UpdateServer) UpdateReqHandler(peerID crypto.Hash, envelope *wire.Envel return } - if header.Timestamp.Before(msg.Timestamp) || header.Timestamp.Equal(msg.Timestamp) { + if header.SectorSize < msg.SectorSize || header.SectorSize == msg.SectorSize { if err := u.mux.Send(peerID, wire.NewNilUpdate(msg.Name)); err != nil { u.lgr.Error("error sending response to update req", "name", msg.Name, "err", err) } else { @@ -79,10 +79,11 @@ func (u *UpdateServer) UpdateReqHandler(peerID crypto.Hash, envelope *wire.Envel } err = u.mux.Send(peerID, &wire.Update{ - Name: msg.Name, - Timestamp: header.Timestamp, - MerkleRoot: header.MerkleRoot, - Signature: header.Signature, + Name: msg.Name, + EpochHeight: header.EpochHeight, + SectorSize: header.SectorSize, + SectorTipHash: header.SectorTipHash, + Signature: header.Signature, }) if err != nil { u.lgr.Error("error serving update", "name", msg.Name, "err", err) diff --git a/protocol/update_server_test.go b/protocol/update_server_test.go index f6bbf46..e5c981e 100644 --- a/protocol/update_server_test.go +++ b/protocol/update_server_test.go @@ -1,19 +1,19 @@ package protocol import ( - "fnd/blob" - "fnd/crypto" - "fnd/p2p" - "fnd/store" - "fnd/testutil" - "fnd/testutil/testcrypto" - "fnd/util" - "fnd/wire" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" "io" "testing" - "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/testutil" + "github.com/ddrp-org/ddrp/testutil/testcrypto" + "github.com/ddrp-org/ddrp/util" + "github.com/ddrp-org/ddrp/wire" + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" ) func TestUpdateServer(t *testing.T) { @@ -40,8 +40,9 @@ func TestUpdateServer(t *testing.T) { { "sends a nil update for locked names", &wire.UpdateReq{ - Name: "locked", - Timestamp: time.Now(), + Name: "locked", + EpochHeight: uint16(0), + SectorSize: uint16(0), }, func(t *testing.T) { require.True(t, nameLocker.TryLock("locked")) @@ -53,8 +54,9 @@ func TestUpdateServer(t *testing.T) { { "sends a nil update for unknown names", &wire.UpdateReq{ - Name: "unknown", - Timestamp: time.Now(), + Name: "unknown", + EpochHeight: uint16(0), + SectorSize: uint16(0), }, func(t *testing.T) {}, func(t *testing.T) { @@ -64,15 +66,17 @@ func TestUpdateServer(t *testing.T) { { "sends a nil update for update requests with future timestamps", &wire.UpdateReq{ - Name: "future", - Timestamp: time.Unix(10, 0), + Name: "future", + EpochHeight: uint16(0), + SectorSize: uint16(10), }, func(t *testing.T) { require.NoError(t, store.WithTx(db, func(tx *leveldb.Transaction) error { return store.SetHeaderTx(tx, &store.Header{ - Name: "future", - Timestamp: time.Unix(5, 0), - }, blob.ZeroMerkleBase) + Name: "future", + EpochHeight: uint16(0), + SectorSize: uint16(5), + }, blob.ZeroSectorHashes) })) }, func(t *testing.T) { @@ -82,15 +86,17 @@ func TestUpdateServer(t *testing.T) { { "sends a nil update for update requests with timestamps equal to stored", &wire.UpdateReq{ - Name: "equal", - Timestamp: time.Unix(10, 0), + Name: "equal", + EpochHeight: uint16(0), + SectorSize: uint16(10), }, func(t *testing.T) { require.NoError(t, store.WithTx(db, func(tx *leveldb.Transaction) error { return store.SetHeaderTx(tx, &store.Header{ - Name: "equal", - Timestamp: time.Unix(10, 0), - }, blob.ZeroMerkleBase) + Name: "equal", + EpochHeight: uint16(0), + SectorSize: uint16(10), + }, blob.ZeroSectorHashes) })) }, func(t *testing.T) { @@ -100,21 +106,24 @@ func TestUpdateServer(t *testing.T) { { "sends an update for valid update requests with past timestamps", &wire.UpdateReq{ - Name: "valid", - Timestamp: time.Unix(5, 0), + Name: "valid", + EpochHeight: uint16(0), + SectorSize: uint16(5), }, func(t *testing.T) { - ts := time.Unix(10, 0) + epochHeight := uint16(0) + sectorSize := uint16(10) tree := blob.MakeTreeFromBase(blob.ZeroMerkleBase) - sig, err := blob.SignSeal(signer, "valid", ts, tree.Root(), crypto.ZeroHash) + sig, err := blob.SignSeal(signer, "valid", epochHeight, sectorSize, tree.Root(), crypto.ZeroHash) require.NoError(t, err) require.NoError(t, store.WithTx(db, func(tx *leveldb.Transaction) error { return store.SetHeaderTx(tx, &store.Header{ - Name: "valid", - Timestamp: ts, - MerkleRoot: tree.Root(), - Signature: sig, - }, blob.ZeroMerkleBase) + Name: "valid", + EpochHeight: epochHeight, + SectorSize: sectorSize, + SectorTipHash: tree.Root(), + Signature: sig, + }, blob.ZeroSectorHashes) })) }, func(t *testing.T) { @@ -122,10 +131,11 @@ func TestUpdateServer(t *testing.T) { require.NoError(t, err) envelope := testutil.ReceiveEnvelope(t, clientConn) require.EqualValues(t, &wire.Update{ - Name: header.Name, - Timestamp: header.Timestamp, - MerkleRoot: header.MerkleRoot, - Signature: header.Signature, + Name: header.Name, + EpochHeight: header.EpochHeight, + SectorSize: header.SectorSize, + SectorTipHash: header.SectorTipHash, + Signature: header.Signature, }, envelope.Message) }, }, diff --git a/protocol/updater.go b/protocol/updater.go index ef2e7f4..4c0cf1e 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -1,24 +1,30 @@ package protocol import ( - "fnd/blob" - "fnd/config" - "fnd/log" - "fnd/p2p" - "fnd/store" - "fnd/util" - "fnd/wire" - "github.com/pkg/errors" - "github.com/syndtr/goleveldb/leveldb" "sync" "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/config" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/util" + "github.com/ddrp-org/ddrp/wire" + "github.com/pkg/errors" + "github.com/syndtr/goleveldb/leveldb" ) var ( - ErrUpdaterAlreadySynchronized = errors.New("updater already synchronized") - ErrUpdaterMerkleRootMismatch = errors.New("updater merkle root mismatch") - ErrNameLocked = errors.New("name is locked") - ErrInsufficientTimebank = errors.New("insufficient timebank") + ErrUpdaterAlreadySynchronized = errors.New("updater already synchronized") + ErrUpdaterSectorTipHashMismatch = errors.New("updater sector tip hash mismatch") + ErrNameLocked = errors.New("name is locked") + ErrNameBanned = errors.New("name is banned") + ErrInvalidEpochCurrent = errors.New("name epoch invalid current") + ErrInvalidEpochThrottled = errors.New("name epoch invalid throttled") + ErrInvalidEpochBackdated = errors.New("name epoch invalid backdated") + ErrInvalidEpochFuturedated = errors.New("name epoch invalid futuredated") updaterLogger = log.WithModule("updater") ) @@ -119,26 +125,53 @@ func UpdateBlob(cfg *UpdateConfig) error { if err != nil && !errors.Is(err, leveldb.ErrNotFound) { return errors.Wrap(err, "error getting header") } - if header != nil && header.Timestamp.Equal(item.Timestamp) { + if header != nil && header.EpochHeight == item.EpochHeight && header.SectorSize == item.SectorSize { return ErrUpdaterAlreadySynchronized } + var prevHash crypto.Hash = blob.ZeroHash + var epochHeight, sectorSize uint16 + var epochUpdated bool + if header != nil { + epochHeight = header.EpochHeight + sectorSize = header.SectorSize + prevHash = header.SectorTipHash + } + + if item.EpochHeight < epochHeight { + return ErrInvalidEpochBackdated + } + + if item.EpochHeight > epochHeight { + if header != nil && header.Banned { + if header.BannedAt.Add(7 * 24 * time.Duration(time.Hour)).After(time.Now()) { + return ErrNameBanned + } + + if item.EpochHeight >= CurrentEpoch(item.Name) { + return ErrInvalidEpochCurrent + } + } + + if header != nil && time.Now().Before(header.EpochStartAt.Add(7*24*time.Duration(time.Hour))) { + if item.EpochHeight != CurrentEpoch(item.Name) { + return ErrInvalidEpochThrottled + } + } + if item.EpochHeight > CurrentEpoch(item.Name) { + return ErrInvalidEpochFuturedated + } + + // Sync the entire blob on epoch rollover + epochUpdated = true + sectorSize = 0 + } + if !cfg.NameLocker.TryLock(item.Name) { return ErrNameLocked } defer cfg.NameLocker.Unlock(item.Name) - newMerkleBase, err := SyncTreeBases(&SyncTreeBasesOpts{ - Timeout: DefaultSyncerTreeBaseResTimeout, - Mux: cfg.Mux, - Peers: item.PeerIDs, - MerkleRoot: item.MerkleRoot, - Name: item.Name, - }) - if err != nil { - return errors.Wrap(err, "error syncing merkle base") - } - bl, err := cfg.BlobStore.Open(item.Name) if err != nil { return errors.Wrap(err, "error getting blob") @@ -149,65 +182,7 @@ func UpdateBlob(cfg *UpdateConfig) error { } }() - var sectorsNeeded []uint8 - var prevUpdateTime time.Time - var prevTimebank int - var payableSectorCount int - if header == nil { - sectorsNeeded = blob.ZeroMerkleBase.DiffWith(newMerkleBase) - } else { - base, err := store.GetMerkleBase(cfg.DB, item.Name) - if err != nil { - return errors.Wrap(err, "error getting merkle base") - } - sectorsNeeded = base.DiffWith(newMerkleBase) - prevUpdateTime = header.ReceivedAt - prevTimebank = header.Timebank - } - for _, sectorID := range sectorsNeeded { - if newMerkleBase[sectorID] == blob.EmptyBlobBaseHash { - continue - } - payableSectorCount++ - } - if payableSectorCount == 0 { - l.Debug( - "no payable sectors, truncating", - "count", len(sectorsNeeded), - ) - tx, err := bl.Transaction() - if err != nil { - return errors.Wrap(err, "error starting transaction") - } - for _, sectorID := range sectorsNeeded { - if err := tx.WriteSector(sectorID, blob.ZeroSector); err != nil { - return errors.Wrap(err, "error truncating sector") - } - } - if err := tx.Commit(); err != nil { - return errors.Wrap(err, "error committing blob") - } - return nil - } - l.Debug( - "calculated needed sectors", - "total", len(sectorsNeeded), - "payable", payableSectorCount, - ) - - newTimebank := CheckTimebank(&TimebankParams{ - TimebankDuration: 48 * time.Hour, - MinUpdateInterval: 2 * time.Minute, - FullUpdatesPerPeriod: 2, - }, prevUpdateTime, prevTimebank, payableSectorCount) - l.Debug( - "calculated new timebank", - "prev", prevTimebank, - "new", newTimebank, - ) - if newTimebank == -1 { - return ErrInsufficientTimebank - } + bl.Seek(sectorSize) tx, err := bl.Transaction() if err != nil { @@ -215,12 +190,14 @@ func UpdateBlob(cfg *UpdateConfig) error { } err = SyncSectors(&SyncSectorsOpts{ - Timeout: DefaultSyncerSectorResTimeout, + Timeout: DefaultSyncerBlobResTimeout, Mux: cfg.Mux, Tx: tx, Peers: item.PeerIDs, - MerkleBase: newMerkleBase, - SectorsNeeded: sectorsNeeded, + EpochHeight: epochHeight, + SectorSize: sectorSize, + SectorTipHash: item.SectorTipHash, + PrevHash: prevHash, Name: item.Name, }) if err != nil { @@ -229,31 +206,59 @@ func UpdateBlob(cfg *UpdateConfig) error { } return errors.Wrap(err, "error during sync") } - - tree, err := blob.Merkleize(blob.NewReader(tx)) + tree, err := blob.SerialHash(blob.NewReader(tx), blob.ZeroHash, item.SectorSize) if err != nil { if err := tx.Rollback(); err != nil { updaterLogger.Error("error rolling back blob transaction", "err", err) } - return errors.Wrap(err, "error calculating new blob merkle root") + return errors.Wrap(err, "error calculating new blob sector tip hash") } - if tree.Root() != item.MerkleRoot { + if tree.Tip() != item.SectorTipHash { if err := tx.Rollback(); err != nil { updaterLogger.Error("error rolling back blob transaction", "err", err) } - return ErrUpdaterMerkleRootMismatch + err = store.WithTx(cfg.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: item.Name, + EpochHeight: item.EpochHeight, + SectorSize: item.SectorSize, + SectorTipHash: item.SectorTipHash, + Signature: item.Signature, + ReservedRoot: item.ReservedRoot, + Banned: true, + BannedAt: time.Now(), + }, blob.ZeroSectorHashes) + }) + return ErrUpdaterSectorTipHashMismatch + } + + var sectorsNeeded uint16 + + if header == nil { + sectorsNeeded = item.SectorSize + } else { + sectorsNeeded = item.SectorSize - header.SectorSize + } + l.Debug( + "calculated needed sectors", + "total", sectorsNeeded, + ) + + var epochStart time.Time + if epochUpdated { + epochStart = time.Now() } err = store.WithTx(cfg.DB, func(tx *leveldb.Transaction) error { return store.SetHeaderTx(tx, &store.Header{ - Name: item.Name, - Timestamp: item.Timestamp, - MerkleRoot: item.MerkleRoot, - Signature: item.Signature, - ReservedRoot: item.ReservedRoot, - ReceivedAt: time.Now(), - Timebank: newTimebank, - }, tree.ProtocolBase()) + Name: item.Name, + EpochHeight: item.EpochHeight, + SectorSize: item.SectorSize, + SectorTipHash: item.SectorTipHash, + Signature: item.Signature, + ReservedRoot: item.ReservedRoot, + EpochStartAt: epochStart, + }, tree) }) if err != nil { if err := tx.Rollback(); err != nil { @@ -274,11 +279,10 @@ func UpdateBlob(cfg *UpdateConfig) error { } update := &wire.Update{ - Name: item.Name, - Timestamp: item.Timestamp, - MerkleRoot: item.MerkleRoot, - Signature: item.Signature, - ReservedRoot: item.ReservedRoot, + Name: item.Name, + EpochHeight: item.EpochHeight, + SectorSize: item.SectorSize, + SectorTipHash: item.SectorTipHash, } p2p.GossipAll(cfg.Mux, update) return nil diff --git a/protocol/updater_test.go b/protocol/updater_test.go index ba875b1..729700d 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -1,17 +1,20 @@ package protocol import ( + "crypto/rand" "errors" - "fnd/crypto" - "fnd/p2p" - "fnd/store" - "fnd/testutil/mockapp" - "fnd/util" - "fnd/wire" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" "testing" "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/testutil/mockapp" + "github.com/ddrp-org/ddrp/util" + "github.com/ddrp-org/ddrp/wire" + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" ) type updaterTestSetup struct { @@ -36,7 +39,8 @@ func TestUpdater(t *testing.T) { setup.rs.BlobStore, setup.tp.RemoteSigner, name, - ts, + CurrentEpoch(name), + blob.SectorCount, ts, ) cfg := &UpdateConfig{ @@ -48,12 +52,13 @@ func TestUpdater(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - Timestamp: update.Timestamp, - MerkleRoot: update.MerkleRoot, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: setup.tp.RemoteSigner.Pub(), }, } require.NoError(t, UpdateBlob(cfg)) @@ -64,26 +69,30 @@ func TestUpdater(t *testing.T) { "syncs sectors when the local node has an older blob", func(t *testing.T, setup *updaterTestSetup) { ts := time.Now() - // insert the blob locally, ensuring that - // there will be enough time bank - mockapp.FillBlobRandom( + epochHeight := CurrentEpoch(name) + sectorSize := uint16(10) + mockapp.FillBlobReader( t, setup.ls.DB, setup.ls.BlobStore, setup.tp.RemoteSigner, name, + epochHeight, + sectorSize, ts.Add(-48*time.Hour), - ts.Add(-48*time.Hour), + mockapp.NullReader, ) // create the new blob remotely - update := mockapp.FillBlobRandom( + update := mockapp.FillBlobReader( t, setup.rs.DB, setup.rs.BlobStore, setup.tp.RemoteSigner, name, + epochHeight, + sectorSize+10, ts, - ts, + mockapp.NullReader, ) cfg := &UpdateConfig{ Mux: setup.tp.LocalMux, @@ -94,12 +103,13 @@ func TestUpdater(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - Timestamp: update.Timestamp, - MerkleRoot: update.MerkleRoot, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: setup.tp.RemoteSigner.Pub(), }, } require.NoError(t, UpdateBlob(cfg)) @@ -107,17 +117,33 @@ func TestUpdater(t *testing.T) { }, }, { - "aborts sync if the new timestamp is equal to the stored timestamp", + "aborts sync when there is a sector tip hash mismatch", func(t *testing.T, setup *updaterTestSetup) { ts := time.Now() - update := mockapp.FillBlobRandom( + epochHeight := CurrentEpoch(name) + sectorSize := uint16(10) + mockapp.FillBlobReader( t, setup.ls.DB, setup.ls.BlobStore, setup.tp.RemoteSigner, name, + epochHeight, + sectorSize, + ts.Add(-48*time.Hour), + rand.Reader, + ) + // create the new blob remotely + update := mockapp.FillBlobReader( + t, + setup.rs.DB, + setup.rs.BlobStore, + setup.tp.RemoteSigner, + name, + epochHeight, + sectorSize+10, ts, - ts, + rand.Reader, ) cfg := &UpdateConfig{ Mux: setup.tp.LocalMux, @@ -128,86 +154,89 @@ func TestUpdater(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - Timestamp: update.Timestamp, - MerkleRoot: update.MerkleRoot, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: setup.tp.RemoteSigner.Pub(), }, } err := UpdateBlob(cfg) require.NotNil(t, err) - require.True(t, errors.Is(err, ErrUpdaterAlreadySynchronized)) + require.True(t, errors.Is(err, ErrUpdaterSectorTipHashMismatch)) + header, err := store.GetHeader(setup.ls.DB, name) + require.True(t, header.Banned) }, }, { - "aborts sync if the name is locked", + "aborts sync if the new sector size is equal to the stored sector size", func(t *testing.T, setup *updaterTestSetup) { - locker := util.NewMultiLocker() - require.True(t, locker.TryLock(name)) + ts := time.Now() + epochHeight := CurrentEpoch(name) + sectorSize := uint16(0) + update := mockapp.FillBlobRandom( + t, + setup.ls.DB, + setup.ls.BlobStore, + setup.tp.RemoteSigner, + name, + epochHeight, + sectorSize, + ts, + ) cfg := &UpdateConfig{ Mux: setup.tp.LocalMux, DB: setup.ls.DB, - NameLocker: locker, + NameLocker: util.NewMultiLocker(), BlobStore: setup.ls.BlobStore, Item: &UpdateQueueItem{ PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: setup.tp.RemoteSigner.Pub(), }, } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: epochHeight, + SectorSize: sectorSize, + }, blob.ZeroSectorHashes) + })) err := UpdateBlob(cfg) require.NotNil(t, err) - require.True(t, errors.Is(err, ErrNameLocked)) + require.True(t, errors.Is(err, ErrUpdaterAlreadySynchronized)) }, }, { - "aborts sync if there is insufficient time bank to support the update", + "aborts sync if the name is locked", func(t *testing.T, setup *updaterTestSetup) { - ts := time.Now() - // insert the blob locally, ensuring that - // there will be enough time bank - mockapp.FillBlobRandom( - t, - setup.ls.DB, - setup.ls.BlobStore, - setup.tp.RemoteSigner, - name, - ts.Add(-12*time.Hour), - ts.Add(-12*time.Hour), - ) - // create the new blob remotely - update := mockapp.FillBlobRandom( - t, - setup.rs.DB, - setup.rs.BlobStore, - setup.tp.RemoteSigner, - name, - ts, - ts, - ) + locker := util.NewMultiLocker() + require.True(t, locker.TryLock(name)) cfg := &UpdateConfig{ Mux: setup.tp.LocalMux, DB: setup.ls.DB, - NameLocker: util.NewMultiLocker(), + NameLocker: locker, BlobStore: setup.ls.BlobStore, Item: &UpdateQueueItem{ PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - Timestamp: update.Timestamp, - MerkleRoot: update.MerkleRoot, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), + Name: name, + EpochHeight: CurrentEpoch(name), }, } err := UpdateBlob(cfg) - require.Error(t, err) - require.True(t, errors.Is(err, ErrInsufficientTimebank)) + require.NotNil(t, err) + require.True(t, errors.Is(err, ErrNameLocked)) }, }, { @@ -217,6 +246,8 @@ func TestUpdater(t *testing.T) { return store.SetLastNameImportHeightTx(tx, 100) })) ts := time.Now() + epochHeight := CurrentEpoch(name) + sectorSize := uint16(0) updateCh := make(chan struct{}) unsub := setup.tp.RemoteMux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeUpdate, func(id crypto.Hash, envelope *wire.Envelope) { updateCh <- struct{}{} @@ -228,7 +259,8 @@ func TestUpdater(t *testing.T) { setup.rs.BlobStore, setup.tp.RemoteSigner, name, - ts, + epochHeight, + sectorSize, ts, ) cfg := &UpdateConfig{ @@ -240,13 +272,14 @@ func TestUpdater(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - Timestamp: update.Timestamp, - MerkleRoot: update.MerkleRoot, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), - Height: 101, + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: setup.tp.RemoteSigner.Pub(), + Height: 101, }, } require.NoError(t, UpdateBlob(cfg)) @@ -266,6 +299,8 @@ func TestUpdater(t *testing.T) { return store.SetLastNameImportHeightTx(tx, 100) })) ts := time.Now() + epochHeight := CurrentEpoch(name) + sectorSize := uint16(0) updateCh := make(chan *wire.Envelope, 1) unsub := setup.tp.RemoteMux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeUpdate, func(id crypto.Hash, envelope *wire.Envelope) { updateCh <- envelope @@ -277,7 +312,8 @@ func TestUpdater(t *testing.T) { setup.rs.BlobStore, setup.tp.RemoteSigner, name, - ts, + epochHeight, + sectorSize, ts, ) cfg := &UpdateConfig{ @@ -289,13 +325,14 @@ func TestUpdater(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - Timestamp: update.Timestamp, - MerkleRoot: update.MerkleRoot, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), - Height: 80, + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: setup.tp.RemoteSigner.Pub(), + Height: 80, }, } require.NoError(t, UpdateBlob(cfg)) @@ -305,8 +342,6 @@ func TestUpdater(t *testing.T) { case envelope := <-updateCh: msg := envelope.Message.(*wire.Update) require.Equal(t, name, msg.Name) - require.Equal(t, update.MerkleRoot, msg.MerkleRoot) - require.Equal(t, update.Signature, msg.Signature) case <-timeout.C: t.Fail() } diff --git a/protocol/util_test.go b/protocol/util_test.go index 5416c99..ec971a0 100644 --- a/protocol/util_test.go +++ b/protocol/util_test.go @@ -2,7 +2,7 @@ package protocol import ( "fmt" - "fnd/store" + "github.com/ddrp-org/ddrp/store" "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" "io/ioutil" diff --git a/rpc/blob.go b/rpc/blob.go index 98cb01b..d6e4bb6 100644 --- a/rpc/blob.go +++ b/rpc/blob.go @@ -2,20 +2,21 @@ package rpc import ( "context" - "github.com/btcsuite/btcd/btcec" - "fnd/crypto" - apiv1 "fnd/rpc/v1" - "fnd/store" - "github.com/pkg/errors" "io" "time" + + "github.com/btcsuite/btcd/btcec" + "github.com/ddrp-org/ddrp/crypto" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + "github.com/ddrp-org/ddrp/store" + "github.com/pkg/errors" ) -func GetBlobInfo(client apiv1.Footnotev1Client, name string) (*store.BlobInfo, error) { +func GetBlobInfo(client apiv1.DDRPv1Client, name string) (*store.BlobInfo, error) { return GetBlobInfoContext(context.Background(), client, name) } -func GetBlobInfoContext(ctx context.Context, client apiv1.Footnotev1Client, name string) (*store.BlobInfo, error) { +func GetBlobInfoContext(ctx context.Context, client apiv1.DDRPv1Client, name string) (*store.BlobInfo, error) { res, err := client.GetBlobInfo(ctx, &apiv1.BlobInfoReq{ Name: name, }) @@ -25,11 +26,11 @@ func GetBlobInfoContext(ctx context.Context, client apiv1.Footnotev1Client, name return parseBlobInfoRes(res) } -func ListBlobInfo(client apiv1.Footnotev1Client, after string, cb func(info *store.BlobInfo) bool) error { +func ListBlobInfo(client apiv1.DDRPv1Client, after string, cb func(info *store.BlobInfo) bool) error { return ListBlobInfoContext(context.Background(), client, after, cb) } -func ListBlobInfoContext(ctx context.Context, client apiv1.Footnotev1Client, start string, cb func(info *store.BlobInfo) bool) error { +func ListBlobInfoContext(ctx context.Context, client apiv1.DDRPv1Client, start string, cb func(info *store.BlobInfo) bool) error { stream, err := client.ListBlobInfo(ctx, &apiv1.ListBlobInfoReq{ Start: start, }) @@ -78,11 +79,11 @@ func parseBlobInfoRes(res *apiv1.BlobInfoRes) (*store.BlobInfo, error) { Name: res.Name, PublicKey: pub, ImportHeight: int(res.ImportHeight), - Timestamp: time.Unix(int64(res.Timestamp), 0), + EpochHeight: uint16(res.EpochHeight), + SectorSize: uint16(res.SectorSize), MerkleRoot: merkleRoot, ReservedRoot: reservedRoot, ReceivedAt: time.Unix(int64(res.ReceivedAt), 0), Signature: sig, - Timebank: int(res.Timebank), }, nil } diff --git a/rpc/blob_reader.go b/rpc/blob_reader.go index 1c5bdb5..dc52c68 100644 --- a/rpc/blob_reader.go +++ b/rpc/blob_reader.go @@ -3,18 +3,18 @@ package rpc import ( "context" "errors" - "fnd/blob" - apiv1 "fnd/rpc/v1" + "github.com/ddrp-org/ddrp/blob" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" "io" ) type BlobReader struct { - client apiv1.Footnotev1Client + client apiv1.DDRPv1Client name string off int64 } -func NewBlobReader(client apiv1.Footnotev1Client, name string) *BlobReader { +func NewBlobReader(client apiv1.DDRPv1Client, name string) *BlobReader { return &BlobReader{ client: client, name: name, diff --git a/rpc/blob_writer.go b/rpc/blob_writer.go index 2cb0ef6..068ab0b 100644 --- a/rpc/blob_writer.go +++ b/rpc/blob_writer.go @@ -2,25 +2,27 @@ package rpc import ( "context" - "fnd/blob" - "fnd/crypto" - apiv1 "fnd/rpc/v1" - "github.com/pkg/errors" - "io" "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + "github.com/pkg/errors" ) type BlobWriter struct { - client apiv1.Footnotev1Client - signer crypto.Signer - name string - txID uint32 - opened bool - committed bool - offset int64 + client apiv1.DDRPv1Client + signer crypto.Signer + name string + epochHeight uint16 + sectorSize uint16 + sectorTipHash crypto.Hash + txID uint32 + opened bool + committed bool } -func NewBlobWriter(client apiv1.Footnotev1Client, signer crypto.Signer, name string) *BlobWriter { +func NewBlobWriter(client apiv1.DDRPv1Client, signer crypto.Signer, name string) *BlobWriter { return &BlobWriter{ client: client, signer: signer, @@ -42,129 +44,69 @@ func (b *BlobWriter) Open() error { return errors.Wrap(err, "failed to check out blob") } b.txID = checkoutRes.TxID - b.opened = true - return nil -} - -func (b *BlobWriter) Truncate() error { - if !b.opened { - panic("writer not open") - } - if b.committed { - panic("writer committed") - } - _, err := b.client.Truncate(context.Background(), &apiv1.TruncateReq{ - TxID: b.txID, - }) + b.epochHeight = uint16(checkoutRes.EpochHeight) + b.sectorSize = uint16(checkoutRes.SectorSize) + sectorTipHash, err := crypto.NewHashFromBytes(checkoutRes.SectorTipHash) if err != nil { - return errors.Wrap(err, "error truncating blob") + return errors.Wrap(err, "failed to check out blob") } + b.sectorTipHash = sectorTipHash + b.opened = true return nil } -func (b *BlobWriter) Seek(offset int64, whence int) (int64, error) { - if !b.opened { - panic("writer not open") - } - if b.committed { - panic("writer committed") - } - - switch whence { - case io.SeekStart: - if b.offset > blob.Size { - return b.offset, errors.New("seek beyond blob bounds") - } - b.offset = offset - case io.SeekCurrent: - next := b.offset + offset - if next > blob.Size { - return b.offset, errors.New("seek beyond blob bounds") - } - b.offset = next - case io.SeekEnd: - next := blob.Size - offset - if next < 0 { - return b.offset, errors.New("seek beyond blob bounds") - } - b.offset = next - default: - panic("invalid whence") - } - return b.offset, nil -} - -func (b *BlobWriter) WriteAt(p []byte, off int64) (int, error) { +func (b *BlobWriter) WriteSector(p []byte) (crypto.Hash, error) { if !b.opened { panic("writer not open") } if b.committed { panic("writer committed") } + var sector blob.Sector + copy(sector[:], p) - var clientErr error - n := len(p) - if off+int64(n) > blob.Size { - clientErr = errors.New("write beyond blob bounds") - n = blob.Size - int(off) - } - - res, err := b.client.WriteAt(context.Background(), &apiv1.WriteAtReq{ - TxID: b.txID, - Offset: uint32(b.offset), - Data: p[:n], + res, err := b.client.WriteSector(context.Background(), &apiv1.WriteSectorReq{ + TxID: b.txID, + Data: p, }) if err != nil { - return 0, errors.Wrap(err, "error writing blob") + return blob.ZeroHash, errors.Wrap(err, "error writing blob") } if res.WriteErr != "" { - return int(res.BytesWritten), errors.Wrap(errors.New(res.WriteErr), "error writing blob") + return blob.ZeroHash, errors.Wrap(errors.New(res.WriteErr), "error writing blob") } - return n, clientErr -} -func (b *BlobWriter) Write(p []byte) (int, error) { - if len(p) == 0 { - return 0, nil - } + b.sectorSize++ + b.sectorTipHash = blob.SerialHashSector(sector, b.sectorTipHash) - n, err := b.WriteAt(p, b.offset) - b.offset += int64(n) - if err != nil { - return n, errors.Wrap(err, "error writing blob") - } - return n, nil + return b.sectorTipHash, nil } -func (b *BlobWriter) Commit(broadcast bool) error { +func (b *BlobWriter) Commit(broadcast bool) (crypto.Hash, error) { if !b.opened { panic("writer not open") } if b.committed { panic("writer committed") } - precommitRes, err := b.client.PreCommit(context.Background(), &apiv1.PreCommitReq{ - TxID: b.txID, - }) - if err != nil { - return errors.Wrap(err, "error retrieving precommit") - } ts := time.Now() - var mr crypto.Hash - copy(mr[:], precommitRes.MerkleRoot) - sig, err := blob.SignSeal(b.signer, b.name, ts, mr, crypto.ZeroHash) + + sig, err := blob.SignSeal(b.signer, b.name, b.epochHeight, b.sectorSize, b.sectorTipHash, crypto.ZeroHash) if err != nil { - return errors.Wrap(err, "error sealing blob") + return blob.ZeroHash, errors.Wrap(err, "error sealing blob") } _, err = b.client.Commit(context.Background(), &apiv1.CommitReq{ - TxID: b.txID, - Timestamp: uint64(ts.Unix()), - Signature: sig[:], - Broadcast: broadcast, + TxID: b.txID, + Timestamp: uint64(ts.Unix()), + Signature: sig[:], + Broadcast: broadcast, + EpochHeight: uint32(b.epochHeight), + SectorSize: uint32(b.sectorSize), + SectorTipHash: b.sectorTipHash.Bytes(), }) if err != nil { - return errors.Wrap(err, "error sending commit") + return blob.ZeroHash, errors.Wrap(err, "error sending commit") } b.committed = true - return nil + return b.sectorTipHash, nil } diff --git a/rpc/net.go b/rpc/net.go index 254d229..9aa2ad6 100644 --- a/rpc/net.go +++ b/rpc/net.go @@ -3,7 +3,7 @@ package rpc import ( "context" "encoding/hex" - apiv1 "fnd/rpc/v1" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" "io" ) @@ -17,11 +17,11 @@ type Peer struct { RxBytes uint64 } -func ListPeers(client apiv1.Footnotev1Client) ([]*Peer, error) { +func ListPeers(client apiv1.DDRPv1Client) ([]*Peer, error) { return ListPeersContext(context.Background(), client) } -func ListPeersContext(ctx context.Context, client apiv1.Footnotev1Client) ([]*Peer, error) { +func ListPeersContext(ctx context.Context, client apiv1.DDRPv1Client) ([]*Peer, error) { stream, err := client.ListPeers(ctx, &apiv1.ListPeersReq{}) if err != nil { return nil, err @@ -51,11 +51,11 @@ func ListPeersContext(ctx context.Context, client apiv1.Footnotev1Client) ([]*Pe return peers, nil } -func BanPeer(client apiv1.Footnotev1Client, ip string, duration int) error { +func BanPeer(client apiv1.DDRPv1Client, ip string, duration int) error { return BanPeerContext(context.Background(), client, ip, duration) } -func BanPeerContext(ctx context.Context, client apiv1.Footnotev1Client, ip string, duration int) error { +func BanPeerContext(ctx context.Context, client apiv1.DDRPv1Client, ip string, duration int) error { _, err := client.BanPeer(ctx, &apiv1.BanPeerReq{ Ip: ip, DurationMS: uint32(duration), @@ -63,11 +63,11 @@ func BanPeerContext(ctx context.Context, client apiv1.Footnotev1Client, ip strin return err } -func UnbanPeer(client apiv1.Footnotev1Client, ip string) error { +func UnbanPeer(client apiv1.DDRPv1Client, ip string) error { return UnbanPeerContext(context.Background(), client, ip) } -func UnbanPeerContext(ctx context.Context, client apiv1.Footnotev1Client, ip string) error { +func UnbanPeerContext(ctx context.Context, client apiv1.DDRPv1Client, ip string) error { _, err := client.UnbanPeer(ctx, &apiv1.UnbanPeerReq{ Ip: ip, }) @@ -82,11 +82,11 @@ type Status struct { RxBytes uint64 } -func GetStatus(client apiv1.Footnotev1Client) (*Status, error) { +func GetStatus(client apiv1.DDRPv1Client) (*Status, error) { return GetStatusContext(context.Background(), client) } -func GetStatusContext(ctx context.Context, client apiv1.Footnotev1Client) (*Status, error) { +func GetStatusContext(ctx context.Context, client apiv1.DDRPv1Client) (*Status, error) { res, err := client.GetStatus(ctx, &apiv1.Empty{}) if err != nil { return nil, err @@ -101,11 +101,11 @@ func GetStatusContext(ctx context.Context, client apiv1.Footnotev1Client) (*Stat }, nil } -func AddPeer(client apiv1.Footnotev1Client, peerID string, ip string, verify bool) error { +func AddPeer(client apiv1.DDRPv1Client, peerID string, ip string, verify bool) error { return AddPeerContext(context.Background(), client, peerID, ip, verify) } -func AddPeerContext(ctx context.Context, client apiv1.Footnotev1Client, peerID string, ip string, verify bool) error { +func AddPeerContext(ctx context.Context, client apiv1.DDRPv1Client, peerID string, ip string, verify bool) error { pIDBytes, err := hex.DecodeString(peerID) if err != nil { return err diff --git a/rpc/server.go b/rpc/server.go index 8782170..ebc5989 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -2,21 +2,23 @@ package rpc import ( "context" - "fnd/blob" - "fnd/crypto" - "fnd/log" - "fnd/p2p" - apiv1 "fnd/rpc/v1" - "fnd/store" - "fnd/util" - "fnd/wire" - "github.com/pkg/errors" - "github.com/syndtr/goleveldb/leveldb" - "google.golang.org/grpc" "net" "strconv" "sync/atomic" "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/log" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/protocol" + apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/util" + "github.com/ddrp-org/ddrp/wire" + "github.com/pkg/errors" + "github.com/syndtr/goleveldb/leveldb" + "google.golang.org/grpc" ) const ( @@ -92,7 +94,7 @@ func (s *Server) Start() error { return err } s.srv = grpc.NewServer() - apiv1.RegisterFootnotev1Server(s.srv, s) + apiv1.RegisterDDRPv1Server(s.srv, s) go s.srv.Serve(lis) return nil } @@ -175,7 +177,7 @@ func (s *Server) UnbanPeer(_ context.Context, req *apiv1.UnbanPeerReq) (*apiv1.E return emptyRes, nil } -func (s *Server) ListPeers(req *apiv1.ListPeersReq, stream apiv1.Footnotev1_ListPeersServer) error { +func (s *Server) ListPeers(req *apiv1.ListPeersReq, stream apiv1.DDRPv1_ListPeersServer) error { connectedPeers := s.mux.Peers() storedPeers, err := store.StreamPeers(s.db, true) if err != nil { @@ -221,6 +223,19 @@ func (s *Server) Checkout(ctx context.Context, req *apiv1.CheckoutReq) (*apiv1.C if err != nil { return nil, err } + var epochHeight, sectorSize uint16 + var sectorTipHash crypto.Hash = blob.ZeroHash + header, err := store.GetHeader(s.db, req.Name) + if err != nil { + epochHeight = protocol.CurrentEpoch(req.Name) + } else { + epochHeight = header.EpochHeight + sectorSize = header.SectorSize + sectorTipHash = header.SectorTipHash + } + + bl.Seek(sectorSize) + tx, err := bl.Transaction() if err != nil { return nil, err @@ -232,58 +247,30 @@ func (s *Server) Checkout(ctx context.Context, req *apiv1.CheckoutReq) (*apiv1.C }, TransactionExpiry) return &apiv1.CheckoutRes{ - TxID: txID, + TxID: txID, + EpochHeight: uint32(epochHeight), + SectorSize: uint32(sectorSize), + SectorTipHash: sectorTipHash.Bytes(), }, nil } -func (s *Server) WriteAt(ctx context.Context, req *apiv1.WriteAtReq) (*apiv1.WriteAtRes, error) { +func (s *Server) WriteSector(ctx context.Context, req *apiv1.WriteSectorReq) (*apiv1.WriteSectorRes, error) { awaiting := s.txStore.Get(strconv.FormatUint(uint64(req.TxID), 32)).(*awaitingTx) if awaiting == nil { return nil, errors.New("transaction ID not found") } tx := awaiting.tx // we want clients to handle partial writes - n, err := tx.WriteAt(req.Data, int64(req.Offset)) - res := &apiv1.WriteAtRes{ - BytesWritten: uint32(n), - } + var sector blob.Sector + copy(sector[:], req.Data) + err := tx.WriteSector(sector) + res := &apiv1.WriteSectorRes{} if err != nil { res.WriteErr = err.Error() } return res, nil } -func (s *Server) Truncate(ctx context.Context, req *apiv1.TruncateReq) (*apiv1.Empty, error) { - awaiting := s.txStore.Get(strconv.FormatUint(uint64(req.TxID), 32)).(*awaitingTx) - if awaiting == nil { - return nil, errors.New("transaction ID not found") - } - - tx := awaiting.tx - if err := tx.Truncate(); err != nil { - return nil, errors.Wrap(err, "error truncating blob") - } - - return emptyRes, nil -} - -func (s *Server) PreCommit(ctx context.Context, req *apiv1.PreCommitReq) (*apiv1.PreCommitRes, error) { - awaiting := s.txStore.Get(strconv.FormatUint(uint64(req.TxID), 32)) - if awaiting == nil { - return nil, errors.New("transaction ID not found") - } - - tx := awaiting.(*awaitingTx).tx - mt, err := blob.Merkleize(blob.NewReader(tx)) - if err != nil { - return nil, errors.Wrap(err, "error generating blob merkle root") - } - - return &apiv1.PreCommitRes{ - MerkleRoot: mt.Root().Bytes(), - }, nil -} - func (s *Server) Commit(ctx context.Context, req *apiv1.CommitReq) (*apiv1.CommitRes, error) { id := strconv.FormatUint(uint64(req.TxID), 32) awaiting := s.txStore.Get(id).(*awaitingTx) @@ -297,15 +284,26 @@ func (s *Server) Commit(ctx context.Context, req *apiv1.CommitReq) (*apiv1.Commi if err != nil { return nil, errors.Wrap(err, "error getting name info") } - mt, err := blob.Merkleize(blob.NewReader(tx)) + + epochHeight := uint16(req.EpochHeight) + sectorSize := uint16(req.SectorSize) + sectorTipHash, err := crypto.NewHashFromBytes(req.SectorTipHash) + if err != nil { + return nil, errors.Wrap(err, "error parsing sector tip hash") + } + + hashes, err := blob.SerialHash(blob.NewReader(tx), crypto.ZeroHash, sectorSize) if err != nil { - return nil, errors.Wrap(err, "error generating blob merkle root") + return nil, errors.Wrap(err, "error getting sector hashes") + } + + if hashes.Tip() != sectorTipHash { + return nil, errors.New("sector tip hash mismatch") } var sig crypto.Signature copy(sig[:], req.Signature) - ts := time.Unix(int64(req.Timestamp), 0) - h := blob.SealHash(name, ts, mt.Root(), crypto.ZeroHash) + h := blob.SealHash(name, epochHeight, sectorSize, sectorTipHash, crypto.ZeroHash) if !crypto.VerifySigPub(info.PublicKey, sig, h) { return nil, errors.New("signature verification failed") } @@ -317,13 +315,14 @@ func (s *Server) Commit(ctx context.Context, req *apiv1.CommitReq) (*apiv1.Commi err = store.WithTx(s.db, func(tx *leveldb.Transaction) error { return store.SetHeaderTx(tx, &store.Header{ - Name: name, - Timestamp: ts, - MerkleRoot: mt.Root(), - Signature: sig, - ReservedRoot: crypto.ZeroHash, - ReceivedAt: time.Now(), - }, mt.ProtocolBase()) + Name: name, + EpochHeight: epochHeight, + SectorSize: sectorSize, + SectorTipHash: sectorTipHash, + Signature: sig, + ReservedRoot: crypto.ZeroHash, + EpochStartAt: time.Now(), + }, hashes) }) if err != nil { return nil, errors.Wrap(err, "error storing header") @@ -340,10 +339,11 @@ func (s *Server) Commit(ctx context.Context, req *apiv1.CommitReq) (*apiv1.Commi var recips []crypto.Hash if req.Broadcast { recips, _ = p2p.GossipAll(s.mux, &wire.Update{ - Name: name, - Timestamp: ts, - MerkleRoot: mt.Root(), - Signature: sig, + Name: name, + EpochHeight: epochHeight, + SectorSize: sectorSize, + SectorTipHash: sectorTipHash, + Signature: sig, }) } s.lgr.Info("committed blob", "name", name, "recipient_count", len(recips)) @@ -399,16 +399,16 @@ func (s *Server) GetBlobInfo(_ context.Context, req *apiv1.BlobInfoReq) (*apiv1. Name: name, PublicKey: info.PublicKey.SerializeCompressed(), ImportHeight: uint32(info.ImportHeight), - Timestamp: uint64(header.Timestamp.Unix()), - MerkleRoot: header.MerkleRoot[:], + EpochHeight: uint32(header.EpochHeight), + SectorSize: uint32(header.SectorSize), + MerkleRoot: header.SectorTipHash[:], ReservedRoot: header.ReservedRoot[:], - ReceivedAt: uint64(header.ReceivedAt.Unix()), + ReceivedAt: uint64(header.EpochStartAt.Unix()), Signature: header.Signature[:], - Timebank: uint32(header.Timebank), }, nil } -func (s *Server) ListBlobInfo(req *apiv1.ListBlobInfoReq, srv apiv1.Footnotev1_ListBlobInfoServer) error { +func (s *Server) ListBlobInfo(req *apiv1.ListBlobInfoReq, srv apiv1.DDRPv1_ListBlobInfoServer) error { stream, err := store.StreamBlobInfo(s.db, req.Start) if err != nil { return errors.Wrap(err, "error opening header stream") @@ -427,12 +427,12 @@ func (s *Server) ListBlobInfo(req *apiv1.ListBlobInfoReq, srv apiv1.Footnotev1_L Name: info.Name, PublicKey: info.PublicKey.SerializeCompressed(), ImportHeight: uint32(info.ImportHeight), - Timestamp: uint64(info.Timestamp.Unix()), + EpochHeight: uint32(info.EpochHeight), + SectorSize: uint32(info.SectorSize), MerkleRoot: info.MerkleRoot[:], ReservedRoot: info.ReservedRoot[:], ReceivedAt: uint64(info.ReceivedAt.Unix()), Signature: info.Signature[:], - Timebank: uint32(info.Timebank), } if err = srv.Send(res); err != nil { return errors.Wrap(err, "error sending info") @@ -447,10 +447,11 @@ func (s *Server) SendUpdate(_ context.Context, req *apiv1.SendUpdateReq) (*apiv1 } recips, _ := p2p.GossipAll(s.mux, &wire.Update{ - Name: req.Name, - Timestamp: header.Timestamp, - MerkleRoot: header.MerkleRoot, - Signature: header.Signature, + Name: req.Name, + EpochHeight: header.EpochHeight, + SectorSize: header.SectorSize, + SectorTipHash: header.SectorTipHash, + Signature: header.Signature, }) return &apiv1.SendUpdateRes{ diff --git a/rpc/v1/api.pb.go b/rpc/v1/api.pb.go index f697a73..14f6381 100644 --- a/rpc/v1/api.pb.go +++ b/rpc/v1/api.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.24.0 -// protoc v3.11.4 +// protoc-gen-go v1.25.0-devel +// protoc v3.12.4 // source: api.proto package v1 @@ -606,7 +606,10 @@ type CheckoutRes struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TxID uint32 `protobuf:"varint,1,opt,name=txID,proto3" json:"txID,omitempty"` + TxID uint32 `protobuf:"varint,1,opt,name=txID,proto3" json:"txID,omitempty"` + EpochHeight uint32 `protobuf:"varint,2,opt,name=epochHeight,proto3" json:"epochHeight,omitempty"` + SectorSize uint32 `protobuf:"varint,3,opt,name=sectorSize,proto3" json:"sectorSize,omitempty"` + SectorTipHash []byte `protobuf:"bytes,4,opt,name=sectorTipHash,proto3" json:"sectorTipHash,omitempty"` } func (x *CheckoutRes) Reset() { @@ -648,149 +651,53 @@ func (x *CheckoutRes) GetTxID() uint32 { return 0 } -type WriteAtReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TxID uint32 `protobuf:"varint,1,opt,name=txID,proto3" json:"txID,omitempty"` - Offset uint32 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"` - Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` -} - -func (x *WriteAtReq) Reset() { - *x = WriteAtReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *WriteAtReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*WriteAtReq) ProtoMessage() {} - -func (x *WriteAtReq) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use WriteAtReq.ProtoReflect.Descriptor instead. -func (*WriteAtReq) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{11} -} - -func (x *WriteAtReq) GetTxID() uint32 { +func (x *CheckoutRes) GetEpochHeight() uint32 { if x != nil { - return x.TxID + return x.EpochHeight } return 0 } -func (x *WriteAtReq) GetOffset() uint32 { +func (x *CheckoutRes) GetSectorSize() uint32 { if x != nil { - return x.Offset + return x.SectorSize } return 0 } -func (x *WriteAtReq) GetData() []byte { +func (x *CheckoutRes) GetSectorTipHash() []byte { if x != nil { - return x.Data + return x.SectorTipHash } return nil } -type WriteAtRes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - BytesWritten uint32 `protobuf:"varint,1,opt,name=bytesWritten,proto3" json:"bytesWritten,omitempty"` - WriteErr string `protobuf:"bytes,2,opt,name=writeErr,proto3" json:"writeErr,omitempty"` -} - -func (x *WriteAtRes) Reset() { - *x = WriteAtRes{} - if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *WriteAtRes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*WriteAtRes) ProtoMessage() {} - -func (x *WriteAtRes) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use WriteAtRes.ProtoReflect.Descriptor instead. -func (*WriteAtRes) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{12} -} - -func (x *WriteAtRes) GetBytesWritten() uint32 { - if x != nil { - return x.BytesWritten - } - return 0 -} - -func (x *WriteAtRes) GetWriteErr() string { - if x != nil { - return x.WriteErr - } - return "" -} - -type TruncateReq struct { +type WriteSectorReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields TxID uint32 `protobuf:"varint,1,opt,name=txID,proto3" json:"txID,omitempty"` + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` } -func (x *TruncateReq) Reset() { - *x = TruncateReq{} +func (x *WriteSectorReq) Reset() { + *x = WriteSectorReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[13] + mi := &file_api_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *TruncateReq) String() string { +func (x *WriteSectorReq) String() string { return protoimpl.X.MessageStringOf(x) } -func (*TruncateReq) ProtoMessage() {} +func (*WriteSectorReq) ProtoMessage() {} -func (x *TruncateReq) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[13] +func (x *WriteSectorReq) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -801,128 +708,50 @@ func (x *TruncateReq) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use TruncateReq.ProtoReflect.Descriptor instead. -func (*TruncateReq) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{13} +// Deprecated: Use WriteSectorReq.ProtoReflect.Descriptor instead. +func (*WriteSectorReq) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{11} } -func (x *TruncateReq) GetTxID() uint32 { +func (x *WriteSectorReq) GetTxID() uint32 { if x != nil { return x.TxID } return 0 } -type TruncateRes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *TruncateRes) Reset() { - *x = TruncateRes{} - if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TruncateRes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TruncateRes) ProtoMessage() {} - -func (x *TruncateRes) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TruncateRes.ProtoReflect.Descriptor instead. -func (*TruncateRes) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{14} -} - -type PreCommitReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TxID uint32 `protobuf:"varint,1,opt,name=txID,proto3" json:"txID,omitempty"` -} - -func (x *PreCommitReq) Reset() { - *x = PreCommitReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PreCommitReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PreCommitReq) ProtoMessage() {} - -func (x *PreCommitReq) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PreCommitReq.ProtoReflect.Descriptor instead. -func (*PreCommitReq) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{15} -} - -func (x *PreCommitReq) GetTxID() uint32 { +func (x *WriteSectorReq) GetData() []byte { if x != nil { - return x.TxID + return x.Data } - return 0 + return nil } -type PreCommitRes struct { +type WriteSectorRes struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MerkleRoot []byte `protobuf:"bytes,1,opt,name=merkleRoot,proto3" json:"merkleRoot,omitempty"` + WriteErr string `protobuf:"bytes,1,opt,name=writeErr,proto3" json:"writeErr,omitempty"` } -func (x *PreCommitRes) Reset() { - *x = PreCommitRes{} +func (x *WriteSectorRes) Reset() { + *x = WriteSectorRes{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[16] + mi := &file_api_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *PreCommitRes) String() string { +func (x *WriteSectorRes) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PreCommitRes) ProtoMessage() {} +func (*WriteSectorRes) ProtoMessage() {} -func (x *PreCommitRes) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[16] +func (x *WriteSectorRes) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -933,16 +762,16 @@ func (x *PreCommitRes) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PreCommitRes.ProtoReflect.Descriptor instead. -func (*PreCommitRes) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{16} +// Deprecated: Use WriteSectorRes.ProtoReflect.Descriptor instead. +func (*WriteSectorRes) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{12} } -func (x *PreCommitRes) GetMerkleRoot() []byte { +func (x *WriteSectorRes) GetWriteErr() string { if x != nil { - return x.MerkleRoot + return x.WriteErr } - return nil + return "" } type CommitReq struct { @@ -950,16 +779,19 @@ type CommitReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - TxID uint32 `protobuf:"varint,1,opt,name=txID,proto3" json:"txID,omitempty"` - Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - Signature []byte `protobuf:"bytes,3,opt,name=signature,proto3" json:"signature,omitempty"` - Broadcast bool `protobuf:"varint,4,opt,name=broadcast,proto3" json:"broadcast,omitempty"` + TxID uint32 `protobuf:"varint,1,opt,name=txID,proto3" json:"txID,omitempty"` + Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Signature []byte `protobuf:"bytes,3,opt,name=signature,proto3" json:"signature,omitempty"` + Broadcast bool `protobuf:"varint,4,opt,name=broadcast,proto3" json:"broadcast,omitempty"` + EpochHeight uint32 `protobuf:"varint,5,opt,name=epochHeight,proto3" json:"epochHeight,omitempty"` + SectorSize uint32 `protobuf:"varint,6,opt,name=sectorSize,proto3" json:"sectorSize,omitempty"` + SectorTipHash []byte `protobuf:"bytes,7,opt,name=sectorTipHash,proto3" json:"sectorTipHash,omitempty"` } func (x *CommitReq) Reset() { *x = CommitReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[17] + mi := &file_api_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -972,7 +804,7 @@ func (x *CommitReq) String() string { func (*CommitReq) ProtoMessage() {} func (x *CommitReq) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[17] + mi := &file_api_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -985,7 +817,7 @@ func (x *CommitReq) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitReq.ProtoReflect.Descriptor instead. func (*CommitReq) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{17} + return file_api_proto_rawDescGZIP(), []int{13} } func (x *CommitReq) GetTxID() uint32 { @@ -1016,6 +848,27 @@ func (x *CommitReq) GetBroadcast() bool { return false } +func (x *CommitReq) GetEpochHeight() uint32 { + if x != nil { + return x.EpochHeight + } + return 0 +} + +func (x *CommitReq) GetSectorSize() uint32 { + if x != nil { + return x.SectorSize + } + return 0 +} + +func (x *CommitReq) GetSectorTipHash() []byte { + if x != nil { + return x.SectorTipHash + } + return nil +} + type CommitRes struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1025,7 +878,7 @@ type CommitRes struct { func (x *CommitRes) Reset() { *x = CommitRes{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[18] + mi := &file_api_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1038,7 +891,7 @@ func (x *CommitRes) String() string { func (*CommitRes) ProtoMessage() {} func (x *CommitRes) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[18] + mi := &file_api_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1051,7 +904,7 @@ func (x *CommitRes) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitRes.ProtoReflect.Descriptor instead. func (*CommitRes) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{18} + return file_api_proto_rawDescGZIP(), []int{14} } type ReadAtReq struct { @@ -1067,7 +920,7 @@ type ReadAtReq struct { func (x *ReadAtReq) Reset() { *x = ReadAtReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[19] + mi := &file_api_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1080,7 +933,7 @@ func (x *ReadAtReq) String() string { func (*ReadAtReq) ProtoMessage() {} func (x *ReadAtReq) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[19] + mi := &file_api_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1093,7 +946,7 @@ func (x *ReadAtReq) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadAtReq.ProtoReflect.Descriptor instead. func (*ReadAtReq) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{19} + return file_api_proto_rawDescGZIP(), []int{15} } func (x *ReadAtReq) GetName() string { @@ -1129,7 +982,7 @@ type ReadAtRes struct { func (x *ReadAtRes) Reset() { *x = ReadAtRes{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[20] + mi := &file_api_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1142,7 +995,7 @@ func (x *ReadAtRes) String() string { func (*ReadAtRes) ProtoMessage() {} func (x *ReadAtRes) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[20] + mi := &file_api_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1155,7 +1008,7 @@ func (x *ReadAtRes) ProtoReflect() protoreflect.Message { // Deprecated: Use ReadAtRes.ProtoReflect.Descriptor instead. func (*ReadAtRes) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{20} + return file_api_proto_rawDescGZIP(), []int{16} } func (x *ReadAtRes) GetOffset() uint32 { @@ -1183,7 +1036,7 @@ type BlobInfoReq struct { func (x *BlobInfoReq) Reset() { *x = BlobInfoReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[21] + mi := &file_api_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1196,7 +1049,7 @@ func (x *BlobInfoReq) String() string { func (*BlobInfoReq) ProtoMessage() {} func (x *BlobInfoReq) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[21] + mi := &file_api_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1209,7 +1062,7 @@ func (x *BlobInfoReq) ProtoReflect() protoreflect.Message { // Deprecated: Use BlobInfoReq.ProtoReflect.Descriptor instead. func (*BlobInfoReq) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{21} + return file_api_proto_rawDescGZIP(), []int{17} } func (x *BlobInfoReq) GetName() string { @@ -1230,7 +1083,7 @@ type ListBlobInfoReq struct { func (x *ListBlobInfoReq) Reset() { *x = ListBlobInfoReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[22] + mi := &file_api_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1243,7 +1096,7 @@ func (x *ListBlobInfoReq) String() string { func (*ListBlobInfoReq) ProtoMessage() {} func (x *ListBlobInfoReq) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[22] + mi := &file_api_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1256,7 +1109,7 @@ func (x *ListBlobInfoReq) ProtoReflect() protoreflect.Message { // Deprecated: Use ListBlobInfoReq.ProtoReflect.Descriptor instead. func (*ListBlobInfoReq) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{22} + return file_api_proto_rawDescGZIP(), []int{18} } func (x *ListBlobInfoReq) GetStart() string { @@ -1274,18 +1127,18 @@ type BlobInfoRes struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` PublicKey []byte `protobuf:"bytes,2,opt,name=publicKey,proto3" json:"publicKey,omitempty"` ImportHeight uint32 `protobuf:"varint,3,opt,name=importHeight,proto3" json:"importHeight,omitempty"` - Timestamp uint64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - MerkleRoot []byte `protobuf:"bytes,5,opt,name=merkleRoot,proto3" json:"merkleRoot,omitempty"` - ReservedRoot []byte `protobuf:"bytes,6,opt,name=reservedRoot,proto3" json:"reservedRoot,omitempty"` - ReceivedAt uint64 `protobuf:"varint,7,opt,name=receivedAt,proto3" json:"receivedAt,omitempty"` - Signature []byte `protobuf:"bytes,8,opt,name=signature,proto3" json:"signature,omitempty"` - Timebank uint32 `protobuf:"varint,9,opt,name=timebank,proto3" json:"timebank,omitempty"` + EpochHeight uint32 `protobuf:"varint,4,opt,name=epochHeight,proto3" json:"epochHeight,omitempty"` // protobuf doesn't have uint16 + SectorSize uint32 `protobuf:"varint,5,opt,name=sectorSize,proto3" json:"sectorSize,omitempty"` // ditto ^ + MerkleRoot []byte `protobuf:"bytes,6,opt,name=merkleRoot,proto3" json:"merkleRoot,omitempty"` + ReservedRoot []byte `protobuf:"bytes,7,opt,name=reservedRoot,proto3" json:"reservedRoot,omitempty"` + ReceivedAt uint64 `protobuf:"varint,8,opt,name=receivedAt,proto3" json:"receivedAt,omitempty"` + Signature []byte `protobuf:"bytes,9,opt,name=signature,proto3" json:"signature,omitempty"` } func (x *BlobInfoRes) Reset() { *x = BlobInfoRes{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[23] + mi := &file_api_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1298,7 +1151,7 @@ func (x *BlobInfoRes) String() string { func (*BlobInfoRes) ProtoMessage() {} func (x *BlobInfoRes) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[23] + mi := &file_api_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1311,7 +1164,7 @@ func (x *BlobInfoRes) ProtoReflect() protoreflect.Message { // Deprecated: Use BlobInfoRes.ProtoReflect.Descriptor instead. func (*BlobInfoRes) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{23} + return file_api_proto_rawDescGZIP(), []int{19} } func (x *BlobInfoRes) GetName() string { @@ -1335,9 +1188,16 @@ func (x *BlobInfoRes) GetImportHeight() uint32 { return 0 } -func (x *BlobInfoRes) GetTimestamp() uint64 { +func (x *BlobInfoRes) GetEpochHeight() uint32 { if x != nil { - return x.Timestamp + return x.EpochHeight + } + return 0 +} + +func (x *BlobInfoRes) GetSectorSize() uint32 { + if x != nil { + return x.SectorSize } return 0 } @@ -1370,13 +1230,6 @@ func (x *BlobInfoRes) GetSignature() []byte { return nil } -func (x *BlobInfoRes) GetTimebank() uint32 { - if x != nil { - return x.Timebank - } - return 0 -} - type SendUpdateReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1388,7 +1241,7 @@ type SendUpdateReq struct { func (x *SendUpdateReq) Reset() { *x = SendUpdateReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[24] + mi := &file_api_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1401,7 +1254,7 @@ func (x *SendUpdateReq) String() string { func (*SendUpdateReq) ProtoMessage() {} func (x *SendUpdateReq) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[24] + mi := &file_api_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1414,7 +1267,7 @@ func (x *SendUpdateReq) ProtoReflect() protoreflect.Message { // Deprecated: Use SendUpdateReq.ProtoReflect.Descriptor instead. func (*SendUpdateReq) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{24} + return file_api_proto_rawDescGZIP(), []int{20} } func (x *SendUpdateReq) GetName() string { @@ -1435,7 +1288,7 @@ type SendUpdateRes struct { func (x *SendUpdateRes) Reset() { *x = SendUpdateRes{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[25] + mi := &file_api_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1448,7 +1301,7 @@ func (x *SendUpdateRes) String() string { func (*SendUpdateRes) ProtoMessage() {} func (x *SendUpdateRes) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[25] + mi := &file_api_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1461,7 +1314,7 @@ func (x *SendUpdateRes) ProtoReflect() protoreflect.Message { // Deprecated: Use SendUpdateRes.ProtoReflect.Descriptor instead. func (*SendUpdateRes) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{25} + return file_api_proto_rawDescGZIP(), []int{21} } func (x *SendUpdateRes) GetRecipientCount() uint32 { @@ -1519,109 +1372,106 @@ var file_api_proto_rawDesc = []byte{ 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x22, 0x21, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x21, 0x0a, - 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, - 0x74, 0x78, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x78, 0x49, 0x44, - 0x22, 0x4c, 0x0a, 0x0a, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, 0x74, 0x52, 0x65, 0x71, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x78, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x78, - 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x4c, - 0x0a, 0x0a, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, 0x74, 0x52, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0c, 0x62, 0x79, 0x74, 0x65, 0x73, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, - 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x72, 0x69, 0x74, 0x65, 0x45, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x65, 0x45, 0x72, 0x72, 0x22, 0x21, 0x0a, 0x0b, - 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x74, - 0x78, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x78, 0x49, 0x44, 0x22, - 0x0d, 0x0a, 0x0b, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x22, 0x22, - 0x0a, 0x0c, 0x50, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x78, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x78, - 0x49, 0x44, 0x22, 0x2e, 0x0a, 0x0c, 0x50, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, - 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, - 0x6f, 0x74, 0x22, 0x79, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x12, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x89, 0x01, + 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x78, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x78, 0x49, + 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x7a, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, + 0x69, 0x7a, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, 0x70, + 0x48, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x54, 0x69, 0x70, 0x48, 0x61, 0x73, 0x68, 0x22, 0x38, 0x0a, 0x0e, 0x57, 0x72, 0x69, + 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x74, + 0x78, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x78, 0x49, 0x44, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x22, 0x2c, 0x0a, 0x0e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x52, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x72, 0x69, 0x74, 0x65, 0x45, 0x72, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x65, 0x45, 0x72, + 0x72, 0x22, 0xe1, 0x01, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x78, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x22, 0x0b, 0x0a, - 0x09, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x22, 0x49, 0x0a, 0x09, 0x52, 0x65, - 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, - 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, - 0x73, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x03, 0x6c, 0x65, 0x6e, 0x22, 0x37, 0x0a, 0x09, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, - 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x21, - 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x22, 0x27, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x9f, 0x02, 0x0a, 0x0b, 0x42, - 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, - 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0c, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1e, - 0x0a, 0x0a, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0a, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, - 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x6f, - 0x6f, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, - 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x62, 0x61, 0x6e, 0x6b, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x62, 0x61, 0x6e, 0x6b, 0x22, 0x23, 0x0a, 0x0d, + 0x28, 0x08, 0x52, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x12, 0x20, 0x0a, + 0x0b, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0b, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, + 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, + 0x24, 0x0a, 0x0d, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, 0x70, 0x48, 0x61, 0x73, 0x68, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, + 0x70, 0x48, 0x61, 0x73, 0x68, 0x22, 0x0b, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, + 0x65, 0x73, 0x22, 0x49, 0x0a, 0x09, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x71, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, + 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6c, 0x65, 0x6e, 0x22, 0x37, 0x0a, + 0x09, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, + 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x21, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x27, 0x0a, 0x0f, 0x4c, 0x69, 0x73, + 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x22, 0xa7, 0x02, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x70, 0x6f, 0x63, + 0x68, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, + 0x70, 0x6f, 0x63, 0x68, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, + 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, + 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, + 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1e, + 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, + 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x23, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x37, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x69, - 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0xaa, 0x04, 0x0a, 0x0a, 0x46, - 0x6f, 0x6f, 0x74, 0x6e, 0x6f, 0x74, 0x65, 0x76, 0x31, 0x12, 0x22, 0x0a, 0x09, 0x47, 0x65, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, - 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, - 0x07, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x1e, 0x0a, - 0x07, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x42, 0x61, 0x6e, 0x50, 0x65, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x22, 0x0a, - 0x09, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x55, 0x6e, 0x62, - 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x12, 0x2b, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x0d, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x26, - 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x0c, 0x2e, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x07, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, - 0x74, 0x12, 0x0b, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0b, - 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, 0x74, 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x08, 0x54, - 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x12, 0x0c, 0x2e, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x29, 0x0a, - 0x09, 0x50, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x0d, 0x2e, 0x50, 0x72, 0x65, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x50, 0x72, 0x65, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x12, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, - 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x52, 0x65, - 0x61, 0x64, 0x41, 0x74, 0x12, 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x71, - 0x1a, 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x0b, - 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0c, 0x2e, 0x42, 0x6c, - 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x42, - 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, - 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x2c, 0x0a, 0x0a, 0x53, 0x65, 0x6e, - 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x42, 0x04, 0x5a, 0x02, 0x76, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0xe5, 0x03, 0x0a, 0x06, 0x44, + 0x44, 0x52, 0x50, 0x76, 0x31, 0x12, 0x22, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x47, 0x65, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x07, 0x41, 0x64, 0x64, + 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x07, 0x42, 0x61, 0x6e, + 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x22, 0x0a, 0x09, 0x55, 0x6e, 0x62, + 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2b, 0x0a, + 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x0d, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x26, 0x0a, 0x08, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, + 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, + 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x0b, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x12, 0x0f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, + 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x0a, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x12, + 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x52, 0x65, + 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x42, 0x6c, + 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x73, 0x12, 0x30, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x10, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x73, 0x30, 0x01, 0x12, 0x2c, 0x0a, 0x0a, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x12, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x42, 0x04, 0x5a, 0x02, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1636,7 +1486,7 @@ func file_api_proto_rawDescGZIP() []byte { return file_api_proto_rawDescData } -var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 26) +var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 22) var file_api_proto_goTypes = []interface{}{ (*Empty)(nil), // 0: Empty (*GetStatusRes)(nil), // 1: GetStatusRes @@ -1649,53 +1499,45 @@ var file_api_proto_goTypes = []interface{}{ (*ListPeersRes)(nil), // 8: ListPeersRes (*CheckoutReq)(nil), // 9: CheckoutReq (*CheckoutRes)(nil), // 10: CheckoutRes - (*WriteAtReq)(nil), // 11: WriteAtReq - (*WriteAtRes)(nil), // 12: WriteAtRes - (*TruncateReq)(nil), // 13: TruncateReq - (*TruncateRes)(nil), // 14: TruncateRes - (*PreCommitReq)(nil), // 15: PreCommitReq - (*PreCommitRes)(nil), // 16: PreCommitRes - (*CommitReq)(nil), // 17: CommitReq - (*CommitRes)(nil), // 18: CommitRes - (*ReadAtReq)(nil), // 19: ReadAtReq - (*ReadAtRes)(nil), // 20: ReadAtRes - (*BlobInfoReq)(nil), // 21: BlobInfoReq - (*ListBlobInfoReq)(nil), // 22: ListBlobInfoReq - (*BlobInfoRes)(nil), // 23: BlobInfoRes - (*SendUpdateReq)(nil), // 24: SendUpdateReq - (*SendUpdateRes)(nil), // 25: SendUpdateRes + (*WriteSectorReq)(nil), // 11: WriteSectorReq + (*WriteSectorRes)(nil), // 12: WriteSectorRes + (*CommitReq)(nil), // 13: CommitReq + (*CommitRes)(nil), // 14: CommitRes + (*ReadAtReq)(nil), // 15: ReadAtReq + (*ReadAtRes)(nil), // 16: ReadAtRes + (*BlobInfoReq)(nil), // 17: BlobInfoReq + (*ListBlobInfoReq)(nil), // 18: ListBlobInfoReq + (*BlobInfoRes)(nil), // 19: BlobInfoRes + (*SendUpdateReq)(nil), // 20: SendUpdateReq + (*SendUpdateRes)(nil), // 21: SendUpdateRes } var file_api_proto_depIdxs = []int32{ - 0, // 0: Footnotev1.GetStatus:input_type -> Empty - 4, // 1: Footnotev1.AddPeer:input_type -> AddPeerReq - 5, // 2: Footnotev1.BanPeer:input_type -> BanPeerReq - 6, // 3: Footnotev1.UnbanPeer:input_type -> UnbanPeerReq - 7, // 4: Footnotev1.ListPeers:input_type -> ListPeersReq - 9, // 5: Footnotev1.Checkout:input_type -> CheckoutReq - 11, // 6: Footnotev1.WriteAt:input_type -> WriteAtReq - 13, // 7: Footnotev1.Truncate:input_type -> TruncateReq - 15, // 8: Footnotev1.PreCommit:input_type -> PreCommitReq - 17, // 9: Footnotev1.Commit:input_type -> CommitReq - 19, // 10: Footnotev1.ReadAt:input_type -> ReadAtReq - 21, // 11: Footnotev1.GetBlobInfo:input_type -> BlobInfoReq - 22, // 12: Footnotev1.ListBlobInfo:input_type -> ListBlobInfoReq - 24, // 13: Footnotev1.SendUpdate:input_type -> SendUpdateReq - 1, // 14: Footnotev1.GetStatus:output_type -> GetStatusRes - 0, // 15: Footnotev1.AddPeer:output_type -> Empty - 0, // 16: Footnotev1.BanPeer:output_type -> Empty - 0, // 17: Footnotev1.UnbanPeer:output_type -> Empty - 8, // 18: Footnotev1.ListPeers:output_type -> ListPeersRes - 10, // 19: Footnotev1.Checkout:output_type -> CheckoutRes - 12, // 20: Footnotev1.WriteAt:output_type -> WriteAtRes - 0, // 21: Footnotev1.Truncate:output_type -> Empty - 16, // 22: Footnotev1.PreCommit:output_type -> PreCommitRes - 18, // 23: Footnotev1.Commit:output_type -> CommitRes - 20, // 24: Footnotev1.ReadAt:output_type -> ReadAtRes - 23, // 25: Footnotev1.GetBlobInfo:output_type -> BlobInfoRes - 23, // 26: Footnotev1.ListBlobInfo:output_type -> BlobInfoRes - 25, // 27: Footnotev1.SendUpdate:output_type -> SendUpdateRes - 14, // [14:28] is the sub-list for method output_type - 0, // [0:14] is the sub-list for method input_type + 0, // 0: DDRPv1.GetStatus:input_type -> Empty + 4, // 1: DDRPv1.AddPeer:input_type -> AddPeerReq + 5, // 2: DDRPv1.BanPeer:input_type -> BanPeerReq + 6, // 3: DDRPv1.UnbanPeer:input_type -> UnbanPeerReq + 7, // 4: DDRPv1.ListPeers:input_type -> ListPeersReq + 9, // 5: DDRPv1.Checkout:input_type -> CheckoutReq + 11, // 6: DDRPv1.WriteSector:input_type -> WriteSectorReq + 13, // 7: DDRPv1.Commit:input_type -> CommitReq + 15, // 8: DDRPv1.ReadAt:input_type -> ReadAtReq + 17, // 9: DDRPv1.GetBlobInfo:input_type -> BlobInfoReq + 18, // 10: DDRPv1.ListBlobInfo:input_type -> ListBlobInfoReq + 20, // 11: DDRPv1.SendUpdate:input_type -> SendUpdateReq + 1, // 12: DDRPv1.GetStatus:output_type -> GetStatusRes + 0, // 13: DDRPv1.AddPeer:output_type -> Empty + 0, // 14: DDRPv1.BanPeer:output_type -> Empty + 0, // 15: DDRPv1.UnbanPeer:output_type -> Empty + 8, // 16: DDRPv1.ListPeers:output_type -> ListPeersRes + 10, // 17: DDRPv1.Checkout:output_type -> CheckoutRes + 12, // 18: DDRPv1.WriteSector:output_type -> WriteSectorRes + 14, // 19: DDRPv1.Commit:output_type -> CommitRes + 16, // 20: DDRPv1.ReadAt:output_type -> ReadAtRes + 19, // 21: DDRPv1.GetBlobInfo:output_type -> BlobInfoRes + 19, // 22: DDRPv1.ListBlobInfo:output_type -> BlobInfoRes + 21, // 23: DDRPv1.SendUpdate:output_type -> SendUpdateRes + 12, // [12:24] is the sub-list for method output_type + 0, // [0:12] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name @@ -1840,7 +1682,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WriteAtReq); i { + switch v := v.(*WriteSectorReq); i { case 0: return &v.state case 1: @@ -1852,7 +1694,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WriteAtRes); i { + switch v := v.(*WriteSectorRes); i { case 0: return &v.state case 1: @@ -1864,54 +1706,6 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TruncateReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TruncateRes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PreCommitReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PreCommitRes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CommitReq); i { case 0: return &v.state @@ -1923,7 +1717,7 @@ func file_api_proto_init() { return nil } } - file_api_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_api_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CommitRes); i { case 0: return &v.state @@ -1935,7 +1729,7 @@ func file_api_proto_init() { return nil } } - file_api_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_api_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReadAtReq); i { case 0: return &v.state @@ -1947,7 +1741,7 @@ func file_api_proto_init() { return nil } } - file_api_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_api_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReadAtRes); i { case 0: return &v.state @@ -1959,7 +1753,7 @@ func file_api_proto_init() { return nil } } - file_api_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + file_api_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BlobInfoReq); i { case 0: return &v.state @@ -1971,7 +1765,7 @@ func file_api_proto_init() { return nil } } - file_api_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + file_api_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListBlobInfoReq); i { case 0: return &v.state @@ -1983,7 +1777,7 @@ func file_api_proto_init() { return nil } } - file_api_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + file_api_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BlobInfoRes); i { case 0: return &v.state @@ -1995,7 +1789,7 @@ func file_api_proto_init() { return nil } } - file_api_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + file_api_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SendUpdateReq); i { case 0: return &v.state @@ -2007,7 +1801,7 @@ func file_api_proto_init() { return nil } } - file_api_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + file_api_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SendUpdateRes); i { case 0: return &v.state @@ -2026,7 +1820,7 @@ func file_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_proto_rawDesc, NumEnums: 0, - NumMessages: 26, + NumMessages: 22, NumExtensions: 0, NumServices: 1, }, @@ -2048,76 +1842,74 @@ var _ grpc.ClientConnInterface // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion6 -// Footnotev1Client is the client API for Footnotev1 service. +// DDRPv1Client is the client API for DDRPv1 service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type Footnotev1Client interface { +type DDRPv1Client interface { GetStatus(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetStatusRes, error) AddPeer(ctx context.Context, in *AddPeerReq, opts ...grpc.CallOption) (*Empty, error) BanPeer(ctx context.Context, in *BanPeerReq, opts ...grpc.CallOption) (*Empty, error) UnbanPeer(ctx context.Context, in *UnbanPeerReq, opts ...grpc.CallOption) (*Empty, error) - ListPeers(ctx context.Context, in *ListPeersReq, opts ...grpc.CallOption) (Footnotev1_ListPeersClient, error) + ListPeers(ctx context.Context, in *ListPeersReq, opts ...grpc.CallOption) (DDRPv1_ListPeersClient, error) Checkout(ctx context.Context, in *CheckoutReq, opts ...grpc.CallOption) (*CheckoutRes, error) - WriteAt(ctx context.Context, in *WriteAtReq, opts ...grpc.CallOption) (*WriteAtRes, error) - Truncate(ctx context.Context, in *TruncateReq, opts ...grpc.CallOption) (*Empty, error) - PreCommit(ctx context.Context, in *PreCommitReq, opts ...grpc.CallOption) (*PreCommitRes, error) + WriteSector(ctx context.Context, in *WriteSectorReq, opts ...grpc.CallOption) (*WriteSectorRes, error) Commit(ctx context.Context, in *CommitReq, opts ...grpc.CallOption) (*CommitRes, error) ReadAt(ctx context.Context, in *ReadAtReq, opts ...grpc.CallOption) (*ReadAtRes, error) GetBlobInfo(ctx context.Context, in *BlobInfoReq, opts ...grpc.CallOption) (*BlobInfoRes, error) - ListBlobInfo(ctx context.Context, in *ListBlobInfoReq, opts ...grpc.CallOption) (Footnotev1_ListBlobInfoClient, error) + ListBlobInfo(ctx context.Context, in *ListBlobInfoReq, opts ...grpc.CallOption) (DDRPv1_ListBlobInfoClient, error) SendUpdate(ctx context.Context, in *SendUpdateReq, opts ...grpc.CallOption) (*SendUpdateRes, error) } -type footnotev1Client struct { +type dDRPv1Client struct { cc grpc.ClientConnInterface } -func NewFootnotev1Client(cc grpc.ClientConnInterface) Footnotev1Client { - return &footnotev1Client{cc} +func NewDDRPv1Client(cc grpc.ClientConnInterface) DDRPv1Client { + return &dDRPv1Client{cc} } -func (c *footnotev1Client) GetStatus(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetStatusRes, error) { +func (c *dDRPv1Client) GetStatus(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetStatusRes, error) { out := new(GetStatusRes) - err := c.cc.Invoke(ctx, "/Footnotev1/GetStatus", in, out, opts...) + err := c.cc.Invoke(ctx, "/DDRPv1/GetStatus", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *footnotev1Client) AddPeer(ctx context.Context, in *AddPeerReq, opts ...grpc.CallOption) (*Empty, error) { +func (c *dDRPv1Client) AddPeer(ctx context.Context, in *AddPeerReq, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := c.cc.Invoke(ctx, "/Footnotev1/AddPeer", in, out, opts...) + err := c.cc.Invoke(ctx, "/DDRPv1/AddPeer", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *footnotev1Client) BanPeer(ctx context.Context, in *BanPeerReq, opts ...grpc.CallOption) (*Empty, error) { +func (c *dDRPv1Client) BanPeer(ctx context.Context, in *BanPeerReq, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := c.cc.Invoke(ctx, "/Footnotev1/BanPeer", in, out, opts...) + err := c.cc.Invoke(ctx, "/DDRPv1/BanPeer", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *footnotev1Client) UnbanPeer(ctx context.Context, in *UnbanPeerReq, opts ...grpc.CallOption) (*Empty, error) { +func (c *dDRPv1Client) UnbanPeer(ctx context.Context, in *UnbanPeerReq, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := c.cc.Invoke(ctx, "/Footnotev1/UnbanPeer", in, out, opts...) + err := c.cc.Invoke(ctx, "/DDRPv1/UnbanPeer", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *footnotev1Client) ListPeers(ctx context.Context, in *ListPeersReq, opts ...grpc.CallOption) (Footnotev1_ListPeersClient, error) { - stream, err := c.cc.NewStream(ctx, &_Footnotev1_serviceDesc.Streams[0], "/Footnotev1/ListPeers", opts...) +func (c *dDRPv1Client) ListPeers(ctx context.Context, in *ListPeersReq, opts ...grpc.CallOption) (DDRPv1_ListPeersClient, error) { + stream, err := c.cc.NewStream(ctx, &_DDRPv1_serviceDesc.Streams[0], "/DDRPv1/ListPeers", opts...) if err != nil { return nil, err } - x := &footnotev1ListPeersClient{stream} + x := &dDRPv1ListPeersClient{stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -2127,16 +1919,16 @@ func (c *footnotev1Client) ListPeers(ctx context.Context, in *ListPeersReq, opts return x, nil } -type Footnotev1_ListPeersClient interface { +type DDRPv1_ListPeersClient interface { Recv() (*ListPeersRes, error) grpc.ClientStream } -type footnotev1ListPeersClient struct { +type dDRPv1ListPeersClient struct { grpc.ClientStream } -func (x *footnotev1ListPeersClient) Recv() (*ListPeersRes, error) { +func (x *dDRPv1ListPeersClient) Recv() (*ListPeersRes, error) { m := new(ListPeersRes) if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err @@ -2144,75 +1936,57 @@ func (x *footnotev1ListPeersClient) Recv() (*ListPeersRes, error) { return m, nil } -func (c *footnotev1Client) Checkout(ctx context.Context, in *CheckoutReq, opts ...grpc.CallOption) (*CheckoutRes, error) { +func (c *dDRPv1Client) Checkout(ctx context.Context, in *CheckoutReq, opts ...grpc.CallOption) (*CheckoutRes, error) { out := new(CheckoutRes) - err := c.cc.Invoke(ctx, "/Footnotev1/Checkout", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *footnotev1Client) WriteAt(ctx context.Context, in *WriteAtReq, opts ...grpc.CallOption) (*WriteAtRes, error) { - out := new(WriteAtRes) - err := c.cc.Invoke(ctx, "/Footnotev1/WriteAt", in, out, opts...) + err := c.cc.Invoke(ctx, "/DDRPv1/Checkout", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *footnotev1Client) Truncate(ctx context.Context, in *TruncateReq, opts ...grpc.CallOption) (*Empty, error) { - out := new(Empty) - err := c.cc.Invoke(ctx, "/Footnotev1/Truncate", in, out, opts...) +func (c *dDRPv1Client) WriteSector(ctx context.Context, in *WriteSectorReq, opts ...grpc.CallOption) (*WriteSectorRes, error) { + out := new(WriteSectorRes) + err := c.cc.Invoke(ctx, "/DDRPv1/WriteSector", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *footnotev1Client) PreCommit(ctx context.Context, in *PreCommitReq, opts ...grpc.CallOption) (*PreCommitRes, error) { - out := new(PreCommitRes) - err := c.cc.Invoke(ctx, "/Footnotev1/PreCommit", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *footnotev1Client) Commit(ctx context.Context, in *CommitReq, opts ...grpc.CallOption) (*CommitRes, error) { +func (c *dDRPv1Client) Commit(ctx context.Context, in *CommitReq, opts ...grpc.CallOption) (*CommitRes, error) { out := new(CommitRes) - err := c.cc.Invoke(ctx, "/Footnotev1/Commit", in, out, opts...) + err := c.cc.Invoke(ctx, "/DDRPv1/Commit", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *footnotev1Client) ReadAt(ctx context.Context, in *ReadAtReq, opts ...grpc.CallOption) (*ReadAtRes, error) { +func (c *dDRPv1Client) ReadAt(ctx context.Context, in *ReadAtReq, opts ...grpc.CallOption) (*ReadAtRes, error) { out := new(ReadAtRes) - err := c.cc.Invoke(ctx, "/Footnotev1/ReadAt", in, out, opts...) + err := c.cc.Invoke(ctx, "/DDRPv1/ReadAt", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *footnotev1Client) GetBlobInfo(ctx context.Context, in *BlobInfoReq, opts ...grpc.CallOption) (*BlobInfoRes, error) { +func (c *dDRPv1Client) GetBlobInfo(ctx context.Context, in *BlobInfoReq, opts ...grpc.CallOption) (*BlobInfoRes, error) { out := new(BlobInfoRes) - err := c.cc.Invoke(ctx, "/Footnotev1/GetBlobInfo", in, out, opts...) + err := c.cc.Invoke(ctx, "/DDRPv1/GetBlobInfo", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *footnotev1Client) ListBlobInfo(ctx context.Context, in *ListBlobInfoReq, opts ...grpc.CallOption) (Footnotev1_ListBlobInfoClient, error) { - stream, err := c.cc.NewStream(ctx, &_Footnotev1_serviceDesc.Streams[1], "/Footnotev1/ListBlobInfo", opts...) +func (c *dDRPv1Client) ListBlobInfo(ctx context.Context, in *ListBlobInfoReq, opts ...grpc.CallOption) (DDRPv1_ListBlobInfoClient, error) { + stream, err := c.cc.NewStream(ctx, &_DDRPv1_serviceDesc.Streams[1], "/DDRPv1/ListBlobInfo", opts...) if err != nil { return nil, err } - x := &footnotev1ListBlobInfoClient{stream} + x := &dDRPv1ListBlobInfoClient{stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -2222,16 +1996,16 @@ func (c *footnotev1Client) ListBlobInfo(ctx context.Context, in *ListBlobInfoReq return x, nil } -type Footnotev1_ListBlobInfoClient interface { +type DDRPv1_ListBlobInfoClient interface { Recv() (*BlobInfoRes, error) grpc.ClientStream } -type footnotev1ListBlobInfoClient struct { +type dDRPv1ListBlobInfoClient struct { grpc.ClientStream } -func (x *footnotev1ListBlobInfoClient) Recv() (*BlobInfoRes, error) { +func (x *dDRPv1ListBlobInfoClient) Recv() (*BlobInfoRes, error) { m := new(BlobInfoRes) if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err @@ -2239,404 +2013,352 @@ func (x *footnotev1ListBlobInfoClient) Recv() (*BlobInfoRes, error) { return m, nil } -func (c *footnotev1Client) SendUpdate(ctx context.Context, in *SendUpdateReq, opts ...grpc.CallOption) (*SendUpdateRes, error) { +func (c *dDRPv1Client) SendUpdate(ctx context.Context, in *SendUpdateReq, opts ...grpc.CallOption) (*SendUpdateRes, error) { out := new(SendUpdateRes) - err := c.cc.Invoke(ctx, "/Footnotev1/SendUpdate", in, out, opts...) + err := c.cc.Invoke(ctx, "/DDRPv1/SendUpdate", in, out, opts...) if err != nil { return nil, err } return out, nil } -// Footnotev1Server is the server API for Footnotev1 service. -type Footnotev1Server interface { +// DDRPv1Server is the server API for DDRPv1 service. +type DDRPv1Server interface { GetStatus(context.Context, *Empty) (*GetStatusRes, error) AddPeer(context.Context, *AddPeerReq) (*Empty, error) BanPeer(context.Context, *BanPeerReq) (*Empty, error) UnbanPeer(context.Context, *UnbanPeerReq) (*Empty, error) - ListPeers(*ListPeersReq, Footnotev1_ListPeersServer) error + ListPeers(*ListPeersReq, DDRPv1_ListPeersServer) error Checkout(context.Context, *CheckoutReq) (*CheckoutRes, error) - WriteAt(context.Context, *WriteAtReq) (*WriteAtRes, error) - Truncate(context.Context, *TruncateReq) (*Empty, error) - PreCommit(context.Context, *PreCommitReq) (*PreCommitRes, error) + WriteSector(context.Context, *WriteSectorReq) (*WriteSectorRes, error) Commit(context.Context, *CommitReq) (*CommitRes, error) ReadAt(context.Context, *ReadAtReq) (*ReadAtRes, error) GetBlobInfo(context.Context, *BlobInfoReq) (*BlobInfoRes, error) - ListBlobInfo(*ListBlobInfoReq, Footnotev1_ListBlobInfoServer) error + ListBlobInfo(*ListBlobInfoReq, DDRPv1_ListBlobInfoServer) error SendUpdate(context.Context, *SendUpdateReq) (*SendUpdateRes, error) } -// UnimplementedFootnotev1Server can be embedded to have forward compatible implementations. -type UnimplementedFootnotev1Server struct { +// UnimplementedDDRPv1Server can be embedded to have forward compatible implementations. +type UnimplementedDDRPv1Server struct { } -func (*UnimplementedFootnotev1Server) GetStatus(context.Context, *Empty) (*GetStatusRes, error) { +func (*UnimplementedDDRPv1Server) GetStatus(context.Context, *Empty) (*GetStatusRes, error) { return nil, status.Errorf(codes.Unimplemented, "method GetStatus not implemented") } -func (*UnimplementedFootnotev1Server) AddPeer(context.Context, *AddPeerReq) (*Empty, error) { +func (*UnimplementedDDRPv1Server) AddPeer(context.Context, *AddPeerReq) (*Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method AddPeer not implemented") } -func (*UnimplementedFootnotev1Server) BanPeer(context.Context, *BanPeerReq) (*Empty, error) { +func (*UnimplementedDDRPv1Server) BanPeer(context.Context, *BanPeerReq) (*Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method BanPeer not implemented") } -func (*UnimplementedFootnotev1Server) UnbanPeer(context.Context, *UnbanPeerReq) (*Empty, error) { +func (*UnimplementedDDRPv1Server) UnbanPeer(context.Context, *UnbanPeerReq) (*Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method UnbanPeer not implemented") } -func (*UnimplementedFootnotev1Server) ListPeers(*ListPeersReq, Footnotev1_ListPeersServer) error { +func (*UnimplementedDDRPv1Server) ListPeers(*ListPeersReq, DDRPv1_ListPeersServer) error { return status.Errorf(codes.Unimplemented, "method ListPeers not implemented") } -func (*UnimplementedFootnotev1Server) Checkout(context.Context, *CheckoutReq) (*CheckoutRes, error) { +func (*UnimplementedDDRPv1Server) Checkout(context.Context, *CheckoutReq) (*CheckoutRes, error) { return nil, status.Errorf(codes.Unimplemented, "method Checkout not implemented") } -func (*UnimplementedFootnotev1Server) WriteAt(context.Context, *WriteAtReq) (*WriteAtRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method WriteAt not implemented") -} -func (*UnimplementedFootnotev1Server) Truncate(context.Context, *TruncateReq) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method Truncate not implemented") -} -func (*UnimplementedFootnotev1Server) PreCommit(context.Context, *PreCommitReq) (*PreCommitRes, error) { - return nil, status.Errorf(codes.Unimplemented, "method PreCommit not implemented") +func (*UnimplementedDDRPv1Server) WriteSector(context.Context, *WriteSectorReq) (*WriteSectorRes, error) { + return nil, status.Errorf(codes.Unimplemented, "method WriteSector not implemented") } -func (*UnimplementedFootnotev1Server) Commit(context.Context, *CommitReq) (*CommitRes, error) { +func (*UnimplementedDDRPv1Server) Commit(context.Context, *CommitReq) (*CommitRes, error) { return nil, status.Errorf(codes.Unimplemented, "method Commit not implemented") } -func (*UnimplementedFootnotev1Server) ReadAt(context.Context, *ReadAtReq) (*ReadAtRes, error) { +func (*UnimplementedDDRPv1Server) ReadAt(context.Context, *ReadAtReq) (*ReadAtRes, error) { return nil, status.Errorf(codes.Unimplemented, "method ReadAt not implemented") } -func (*UnimplementedFootnotev1Server) GetBlobInfo(context.Context, *BlobInfoReq) (*BlobInfoRes, error) { +func (*UnimplementedDDRPv1Server) GetBlobInfo(context.Context, *BlobInfoReq) (*BlobInfoRes, error) { return nil, status.Errorf(codes.Unimplemented, "method GetBlobInfo not implemented") } -func (*UnimplementedFootnotev1Server) ListBlobInfo(*ListBlobInfoReq, Footnotev1_ListBlobInfoServer) error { +func (*UnimplementedDDRPv1Server) ListBlobInfo(*ListBlobInfoReq, DDRPv1_ListBlobInfoServer) error { return status.Errorf(codes.Unimplemented, "method ListBlobInfo not implemented") } -func (*UnimplementedFootnotev1Server) SendUpdate(context.Context, *SendUpdateReq) (*SendUpdateRes, error) { +func (*UnimplementedDDRPv1Server) SendUpdate(context.Context, *SendUpdateReq) (*SendUpdateRes, error) { return nil, status.Errorf(codes.Unimplemented, "method SendUpdate not implemented") } -func RegisterFootnotev1Server(s *grpc.Server, srv Footnotev1Server) { - s.RegisterService(&_Footnotev1_serviceDesc, srv) +func RegisterDDRPv1Server(s *grpc.Server, srv DDRPv1Server) { + s.RegisterService(&_DDRPv1_serviceDesc, srv) } -func _Footnotev1_GetStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _DDRPv1_GetStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(Footnotev1Server).GetStatus(ctx, in) + return srv.(DDRPv1Server).GetStatus(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/Footnotev1/GetStatus", + FullMethod: "/DDRPv1/GetStatus", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(Footnotev1Server).GetStatus(ctx, req.(*Empty)) + return srv.(DDRPv1Server).GetStatus(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } -func _Footnotev1_AddPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _DDRPv1_AddPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AddPeerReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(Footnotev1Server).AddPeer(ctx, in) + return srv.(DDRPv1Server).AddPeer(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/Footnotev1/AddPeer", + FullMethod: "/DDRPv1/AddPeer", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(Footnotev1Server).AddPeer(ctx, req.(*AddPeerReq)) + return srv.(DDRPv1Server).AddPeer(ctx, req.(*AddPeerReq)) } return interceptor(ctx, in, info, handler) } -func _Footnotev1_BanPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _DDRPv1_BanPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(BanPeerReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(Footnotev1Server).BanPeer(ctx, in) + return srv.(DDRPv1Server).BanPeer(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/Footnotev1/BanPeer", + FullMethod: "/DDRPv1/BanPeer", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(Footnotev1Server).BanPeer(ctx, req.(*BanPeerReq)) + return srv.(DDRPv1Server).BanPeer(ctx, req.(*BanPeerReq)) } return interceptor(ctx, in, info, handler) } -func _Footnotev1_UnbanPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _DDRPv1_UnbanPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(UnbanPeerReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(Footnotev1Server).UnbanPeer(ctx, in) + return srv.(DDRPv1Server).UnbanPeer(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/Footnotev1/UnbanPeer", + FullMethod: "/DDRPv1/UnbanPeer", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(Footnotev1Server).UnbanPeer(ctx, req.(*UnbanPeerReq)) + return srv.(DDRPv1Server).UnbanPeer(ctx, req.(*UnbanPeerReq)) } return interceptor(ctx, in, info, handler) } -func _Footnotev1_ListPeers_Handler(srv interface{}, stream grpc.ServerStream) error { +func _DDRPv1_ListPeers_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(ListPeersReq) if err := stream.RecvMsg(m); err != nil { return err } - return srv.(Footnotev1Server).ListPeers(m, &footnotev1ListPeersServer{stream}) + return srv.(DDRPv1Server).ListPeers(m, &dDRPv1ListPeersServer{stream}) } -type Footnotev1_ListPeersServer interface { +type DDRPv1_ListPeersServer interface { Send(*ListPeersRes) error grpc.ServerStream } -type footnotev1ListPeersServer struct { +type dDRPv1ListPeersServer struct { grpc.ServerStream } -func (x *footnotev1ListPeersServer) Send(m *ListPeersRes) error { +func (x *dDRPv1ListPeersServer) Send(m *ListPeersRes) error { return x.ServerStream.SendMsg(m) } -func _Footnotev1_Checkout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _DDRPv1_Checkout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CheckoutReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(Footnotev1Server).Checkout(ctx, in) + return srv.(DDRPv1Server).Checkout(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/Footnotev1/Checkout", + FullMethod: "/DDRPv1/Checkout", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(Footnotev1Server).Checkout(ctx, req.(*CheckoutReq)) + return srv.(DDRPv1Server).Checkout(ctx, req.(*CheckoutReq)) } return interceptor(ctx, in, info, handler) } -func _Footnotev1_WriteAt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(WriteAtReq) +func _DDRPv1_WriteSector_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(WriteSectorReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(Footnotev1Server).WriteAt(ctx, in) + return srv.(DDRPv1Server).WriteSector(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/Footnotev1/WriteAt", + FullMethod: "/DDRPv1/WriteSector", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(Footnotev1Server).WriteAt(ctx, req.(*WriteAtReq)) + return srv.(DDRPv1Server).WriteSector(ctx, req.(*WriteSectorReq)) } return interceptor(ctx, in, info, handler) } -func _Footnotev1_Truncate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TruncateReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(Footnotev1Server).Truncate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/Footnotev1/Truncate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(Footnotev1Server).Truncate(ctx, req.(*TruncateReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _Footnotev1_PreCommit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PreCommitReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(Footnotev1Server).PreCommit(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/Footnotev1/PreCommit", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(Footnotev1Server).PreCommit(ctx, req.(*PreCommitReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _Footnotev1_Commit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _DDRPv1_Commit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CommitReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(Footnotev1Server).Commit(ctx, in) + return srv.(DDRPv1Server).Commit(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/Footnotev1/Commit", + FullMethod: "/DDRPv1/Commit", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(Footnotev1Server).Commit(ctx, req.(*CommitReq)) + return srv.(DDRPv1Server).Commit(ctx, req.(*CommitReq)) } return interceptor(ctx, in, info, handler) } -func _Footnotev1_ReadAt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _DDRPv1_ReadAt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ReadAtReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(Footnotev1Server).ReadAt(ctx, in) + return srv.(DDRPv1Server).ReadAt(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/Footnotev1/ReadAt", + FullMethod: "/DDRPv1/ReadAt", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(Footnotev1Server).ReadAt(ctx, req.(*ReadAtReq)) + return srv.(DDRPv1Server).ReadAt(ctx, req.(*ReadAtReq)) } return interceptor(ctx, in, info, handler) } -func _Footnotev1_GetBlobInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _DDRPv1_GetBlobInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(BlobInfoReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(Footnotev1Server).GetBlobInfo(ctx, in) + return srv.(DDRPv1Server).GetBlobInfo(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/Footnotev1/GetBlobInfo", + FullMethod: "/DDRPv1/GetBlobInfo", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(Footnotev1Server).GetBlobInfo(ctx, req.(*BlobInfoReq)) + return srv.(DDRPv1Server).GetBlobInfo(ctx, req.(*BlobInfoReq)) } return interceptor(ctx, in, info, handler) } -func _Footnotev1_ListBlobInfo_Handler(srv interface{}, stream grpc.ServerStream) error { +func _DDRPv1_ListBlobInfo_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(ListBlobInfoReq) if err := stream.RecvMsg(m); err != nil { return err } - return srv.(Footnotev1Server).ListBlobInfo(m, &footnotev1ListBlobInfoServer{stream}) + return srv.(DDRPv1Server).ListBlobInfo(m, &dDRPv1ListBlobInfoServer{stream}) } -type Footnotev1_ListBlobInfoServer interface { +type DDRPv1_ListBlobInfoServer interface { Send(*BlobInfoRes) error grpc.ServerStream } -type footnotev1ListBlobInfoServer struct { +type dDRPv1ListBlobInfoServer struct { grpc.ServerStream } -func (x *footnotev1ListBlobInfoServer) Send(m *BlobInfoRes) error { +func (x *dDRPv1ListBlobInfoServer) Send(m *BlobInfoRes) error { return x.ServerStream.SendMsg(m) } -func _Footnotev1_SendUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _DDRPv1_SendUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SendUpdateReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(Footnotev1Server).SendUpdate(ctx, in) + return srv.(DDRPv1Server).SendUpdate(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/Footnotev1/SendUpdate", + FullMethod: "/DDRPv1/SendUpdate", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(Footnotev1Server).SendUpdate(ctx, req.(*SendUpdateReq)) + return srv.(DDRPv1Server).SendUpdate(ctx, req.(*SendUpdateReq)) } return interceptor(ctx, in, info, handler) } -var _Footnotev1_serviceDesc = grpc.ServiceDesc{ - ServiceName: "Footnotev1", - HandlerType: (*Footnotev1Server)(nil), +var _DDRPv1_serviceDesc = grpc.ServiceDesc{ + ServiceName: "DDRPv1", + HandlerType: (*DDRPv1Server)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetStatus", - Handler: _Footnotev1_GetStatus_Handler, + Handler: _DDRPv1_GetStatus_Handler, }, { MethodName: "AddPeer", - Handler: _Footnotev1_AddPeer_Handler, + Handler: _DDRPv1_AddPeer_Handler, }, { MethodName: "BanPeer", - Handler: _Footnotev1_BanPeer_Handler, + Handler: _DDRPv1_BanPeer_Handler, }, { MethodName: "UnbanPeer", - Handler: _Footnotev1_UnbanPeer_Handler, + Handler: _DDRPv1_UnbanPeer_Handler, }, { MethodName: "Checkout", - Handler: _Footnotev1_Checkout_Handler, - }, - { - MethodName: "WriteAt", - Handler: _Footnotev1_WriteAt_Handler, - }, - { - MethodName: "Truncate", - Handler: _Footnotev1_Truncate_Handler, + Handler: _DDRPv1_Checkout_Handler, }, { - MethodName: "PreCommit", - Handler: _Footnotev1_PreCommit_Handler, + MethodName: "WriteSector", + Handler: _DDRPv1_WriteSector_Handler, }, { MethodName: "Commit", - Handler: _Footnotev1_Commit_Handler, + Handler: _DDRPv1_Commit_Handler, }, { MethodName: "ReadAt", - Handler: _Footnotev1_ReadAt_Handler, + Handler: _DDRPv1_ReadAt_Handler, }, { MethodName: "GetBlobInfo", - Handler: _Footnotev1_GetBlobInfo_Handler, + Handler: _DDRPv1_GetBlobInfo_Handler, }, { MethodName: "SendUpdate", - Handler: _Footnotev1_SendUpdate_Handler, + Handler: _DDRPv1_SendUpdate_Handler, }, }, Streams: []grpc.StreamDesc{ { StreamName: "ListPeers", - Handler: _Footnotev1_ListPeers_Handler, + Handler: _DDRPv1_ListPeers_Handler, ServerStreams: true, }, { StreamName: "ListBlobInfo", - Handler: _Footnotev1_ListBlobInfo_Handler, + Handler: _DDRPv1_ListBlobInfo_Handler, ServerStreams: true, }, }, diff --git a/rpc/v1/api.proto b/rpc/v1/api.proto index 14eb0d7..c1b4c7e 100644 --- a/rpc/v1/api.proto +++ b/rpc/v1/api.proto @@ -1,7 +1,7 @@ syntax = "proto3"; option go_package = "v1"; -service Footnotev1 { +service DDRPv1 { rpc GetStatus (Empty) returns (GetStatusRes); rpc AddPeer (AddPeerReq) returns (Empty); @@ -10,9 +10,7 @@ service Footnotev1 { rpc ListPeers (ListPeersReq) returns (stream ListPeersRes); rpc Checkout (CheckoutReq) returns (CheckoutRes); - rpc WriteAt (WriteAtReq) returns (WriteAtRes); - rpc Truncate (TruncateReq) returns (Empty); - rpc PreCommit (PreCommitReq) returns (PreCommitRes); + rpc WriteSector (WriteSectorReq) returns (WriteSectorRes); rpc Commit (CommitReq) returns (CommitRes); rpc ReadAt (ReadAtReq) returns (ReadAtRes); @@ -78,32 +76,18 @@ message CheckoutReq { message CheckoutRes { uint32 txID = 1; + uint32 epochHeight = 2; + uint32 sectorSize = 3; + bytes sectorTipHash = 4; } -message WriteAtReq { - uint32 txID = 1; - uint32 offset = 2; - bytes data = 3; -} - -message WriteAtRes { - uint32 bytesWritten = 1; - string writeErr = 2; -} - -message TruncateReq { - uint32 txID = 1; -} - -message TruncateRes { -} - -message PreCommitReq { +message WriteSectorReq { uint32 txID = 1; + bytes data = 2; } -message PreCommitRes { - bytes merkleRoot = 1; +message WriteSectorRes { + string writeErr = 1; } message CommitReq { @@ -111,6 +95,9 @@ message CommitReq { uint64 timestamp = 2; bytes signature = 3; bool broadcast = 4; + uint32 epochHeight = 5; + uint32 sectorSize = 6; + bytes sectorTipHash = 7; } message CommitRes { @@ -139,12 +126,12 @@ message BlobInfoRes { string name = 1; bytes publicKey = 2; uint32 importHeight = 3; - uint64 timestamp = 4; - bytes merkleRoot = 5; - bytes reservedRoot = 6; - uint64 receivedAt = 7; - bytes signature = 8; - uint32 timebank = 9; + uint32 epochHeight = 4; // protobuf doesn't have uint16 + uint32 sectorSize = 5; // ditto ^ + bytes merkleRoot = 6; + bytes reservedRoot = 7; + uint64 receivedAt = 8; + bytes signature = 9; } message SendUpdateReq { diff --git a/scripts/gen-node-bindings.sh b/scripts/gen-node-bindings.sh index 17baf5b..3bcafc4 100755 --- a/scripts/gen-node-bindings.sh +++ b/scripts/gen-node-bindings.sh @@ -20,4 +20,4 @@ protoc \ --ts_out="service=grpc-node:${OUT_DIR}" \ --grpc_out="${OUT_DIR}" \ -I "$DIR/../rpc/v1/" \ - "$DIR/../rpc/v1/api.proto" + "$DIR/../rpc/v1/api.proto" \ No newline at end of file diff --git a/scripts/release-public.sh b/scripts/release-public.sh index a4929f3..b0c10d6 100755 --- a/scripts/release-public.sh +++ b/scripts/release-public.sh @@ -8,16 +8,16 @@ tag="$(git describe --tags --abbrev=0)" version="${tag:1}" create_tarball() { - mv -f "$build_dir/fnd-$1-amd64" "$build_dir/fnd" - mv -f "$build_dir/fnd-cli-$1-amd64" "$build_dir/fnd-cli" - tar -czvf "$build_dir/fnd-$version-$1-amd64.tgz" -C "$build_dir" "fnd" "fnd-cli" - gpg2 --detach-sig --default-key D4B604F1 --output "$build_dir/fnd-$version-$1-amd64.tgz.sig" "$build_dir/fnd-$version-$1-amd64.tgz" + mv -f "$build_dir/ddrpd-$1-amd64" "$build_dir/ddrpd" + mv -f "$build_dir/ddrpcli-$1-amd64" "$build_dir/ddrpcli" + tar -czvf "$build_dir/ddrp-$version-$1-amd64.tgz" -C "$build_dir" "ddrpd" "ddrpcli" + gpg2 --detach-sig --default-key D4B604F1 --output "$build_dir/ddrp-$version-$1-amd64.tgz.sig" "$build_dir/ddrp-$version-$1-amd64.tgz" } upload_binary() { echo "Uploading $1 binary..." - gothub upload --user fnd-org --repo fnd --tag "$tag" --file "$build_dir/fnd-$version-$1-amd64.tgz" --name "fnd-$version-$1-amd64.tgz" - gothub upload --user fnd-org --repo fnd --tag "$tag" --file "$build_dir/fnd-$version-$1-amd64.tgz.sig" --name "fnd-$version-$1-amd64.tgz.sig" + gothub upload --user ddrp-org --repo ddrp --tag "$tag" --file "$build_dir/ddrp-$version-$1-amd64.tgz" --name "ddrp-$version-$1-amd64.tgz" + gothub upload --user ddrp-org --repo ddrp --tag "$tag" --file "$build_dir/ddrp-$version-$1-amd64.tgz.sig" --name "ddrp-$version-$1-amd64.tgz.sig" } make clean @@ -26,22 +26,22 @@ make package-deb version="$version" create_tarball "linux" create_tarball "darwin" -gpg2 --detach-sig --default-key D4B604F1 --output "$build_dir/fnd-$version-amd64.deb.sig" "$build_dir/fnd-$version-amd64.deb" +gpg2 --detach-sig --default-key D4B604F1 --output "$build_dir/ddrp-$version-amd64.deb.sig" "$build_dir/ddrp-$version-amd64.deb" -gothub release --user fnd-org --repo fnd --tag "$tag" --name "$tag" --description "" +gothub release --user ddrp-org --repo ddrp --tag "$tag" --name "$tag" --description "" upload_binary "linux" upload_binary "darwin" echo "Uploading .deb..." -gothub upload --user fnd-org --repo fnd --tag "$tag" --file "$build_dir/fnd-$version-amd64.deb" --name "fnd-$version-amd64.deb" -gothub upload --user fnd-org --repo fnd --tag "$tag" --file "$build_dir/fnd-$version-amd64.deb.sig" --name "fnd-$version-amd64.deb.sig" +gothub upload --user ddrp-org --repo ddrp --tag "$tag" --file "$build_dir/ddrp-$version-amd64.deb" --name "ddrp-$version-amd64.deb" +gothub upload --user ddrp-org --repo ddrp --tag "$tag" --file "$build_dir/ddrp-$version-amd64.deb.sig" --name "ddrp-$version-amd64.deb.sig" # for seed node deployments -s3cmd put "$build_dir/fnd-$version-linux-amd64.tgz" s3://fnd-releases/fnd-linux-amd64.tgz -s3cmd setacl s3://fnd-releases/fnd-linux-amd64.tgz --acl-public -s3cmd put "$build_dir/fnd-$version-linux-amd64.tgz.sig" s3://fnd-releases/fnd-linux-amd64.tgz.sig -s3cmd setacl s3://fnd-releases/fnd-linux-amd64.tgz.sig --acl-public -cp "$build_dir/fnd-$version-linux-amd64.tgz" "$build_dir/fnd-linux-amd64.tgz" -cd "$build_dir" && shasum -a 256 "fnd-linux-amd64.tgz" > /tmp/fnd-linux-amd64.tgz.sum.txt && cd "$DIR" -s3cmd put /tmp/fnd-linux-amd64.tgz.sum.txt s3://fnd-releases/fnd-linux-amd64.tgz.sum.txt -s3cmd setacl s3://fnd-releases/fnd-linux-amd64.tgz.sum.txt --acl-public +s3cmd put "$build_dir/ddrp-$version-linux-amd64.tgz" s3://ddrp-releases/ddrp-linux-amd64.tgz +s3cmd setacl s3://ddrp-releases/ddrp-linux-amd64.tgz --acl-public +s3cmd put "$build_dir/ddrp-$version-linux-amd64.tgz.sig" s3://ddrp-releases/ddrp-linux-amd64.tgz.sig +s3cmd setacl s3://ddrp-releases/ddrp-linux-amd64.tgz.sig --acl-public +cp "$build_dir/ddrp-$version-linux-amd64.tgz" "$build_dir/ddrp-linux-amd64.tgz" +cd "$build_dir" && shasum -a 256 "ddrp-linux-amd64.tgz" > /tmp/ddrp-linux-amd64.tgz.sum.txt && cd "$DIR" +s3cmd put /tmp/ddrp-linux-amd64.tgz.sum.txt s3://ddrp-releases/ddrp-linux-amd64.tgz.sum.txt +s3cmd setacl s3://ddrp-releases/ddrp-linux-amd64.tgz.sum.txt --acl-public \ No newline at end of file diff --git a/store/headers.go b/store/headers.go index 6c9efdc..a93f79d 100644 --- a/store/headers.go +++ b/store/headers.go @@ -4,44 +4,51 @@ import ( "bytes" "encoding/hex" "encoding/json" + "sync" + "time" + "github.com/btcsuite/btcd/btcec" - "fnd/blob" - "fnd/crypto" + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/iterator" "github.com/syndtr/goleveldb/leveldb/util" - "sync" - "time" ) type Header struct { - Name string - Timestamp time.Time - MerkleRoot crypto.Hash - Signature crypto.Signature - ReservedRoot crypto.Hash - ReceivedAt time.Time - Timebank int + Name string + EpochHeight uint16 + SectorSize uint16 + SectorTipHash crypto.Hash + Signature crypto.Signature + ReservedRoot crypto.Hash + EpochStartAt time.Time + Banned bool + BannedAt time.Time } func (h *Header) MarshalJSON() ([]byte, error) { out := &struct { Name string `json:"name"` - Timestamp time.Time `json:"timestamp"` + EpochHeight uint16 `json:"epoch_height"` + SectorSize uint16 `json:"sector_size"` MerkleRoot string `json:"merkle_root"` Signature string `json:"signature"` ReservedRoot string `json:"reserved_root"` - ReceivedAt time.Time `json:"received_at"` - Timebank int `json:"timebank"` + EpochStartAt time.Time `json:"epoch_start_at"` + Banned bool `json:"banned"` + BannedAt time.Time `json:"banned_at"` }{ h.Name, - h.Timestamp, - h.MerkleRoot.String(), + h.EpochHeight, + h.SectorSize, + h.SectorTipHash.String(), h.Signature.String(), h.ReservedRoot.String(), - h.ReceivedAt, - h.Timebank, + h.EpochStartAt, + h.Banned, + h.BannedAt, } return json.Marshal(out) @@ -50,12 +57,14 @@ func (h *Header) MarshalJSON() ([]byte, error) { func (h *Header) UnmarshalJSON(b []byte) error { in := &struct { Name string `json:"name"` - Timestamp time.Time `json:"timestamp"` + EpochHeight uint16 `json:"epoch_height"` + SectorSize uint16 `json:"sector_size"` MerkleRoot string `json:"merkle_root"` Signature string `json:"signature"` ReservedRoot string `json:"reserved_root"` - ReceivedAt time.Time `json:"received_at"` - Timebank int `json:"timebank"` + EpochStartAt time.Time `json:"epoch_start_at"` + Banned bool `json:"banned"` + BannedAt time.Time `json:"banned_at"` }{} if err := json.Unmarshal(b, in); err != nil { return err @@ -86,20 +95,22 @@ func (h *Header) UnmarshalJSON(b []byte) error { } h.Name = in.Name - h.Timestamp = in.Timestamp - h.MerkleRoot = mr + h.EpochHeight = in.EpochHeight + h.SectorSize = in.SectorSize + h.SectorTipHash = mr h.Signature = sig h.ReservedRoot = rr - h.ReceivedAt = in.ReceivedAt - h.Timebank = in.Timebank + h.EpochStartAt = in.EpochStartAt + h.Banned = in.Banned + h.BannedAt = in.BannedAt return nil } var ( - headersPrefix = Prefixer("headers") - headerCountKey = Prefixer(string(headersPrefix("count")))() - headerMerkleBasePrefix = Prefixer(string(headersPrefix("merkle-base"))) - headerDataPrefix = Prefixer(string(headersPrefix("header"))) + headersPrefix = Prefixer("headers") + headerCountKey = Prefixer(string(headersPrefix("count")))() + headerSectorHashesPrefix = Prefixer(string(headersPrefix("sector-hashes"))) + headerDataPrefix = Prefixer(string(headersPrefix("header"))) ) func GetHeaderCount(db *leveldb.DB) (int, error) { @@ -138,11 +149,22 @@ func GetHeader(db *leveldb.DB, name string) (*Header, error) { return header, nil } -func GetMerkleBase(db *leveldb.DB, name string) (blob.MerkleBase, error) { - var base blob.MerkleBase - baseB, err := db.Get(headerMerkleBasePrefix(name), nil) +func GetSectorHash(db *leveldb.DB, name string, index uint16) (crypto.Hash, error) { + hashes, err := GetSectorHashes(db, name) + if err != nil { + return crypto.ZeroHash, err + } + if int(index) > len(hashes) { + return crypto.ZeroHash, errors.Wrap(err, "error getting index") + } + return hashes[index], nil +} + +func GetSectorHashes(db *leveldb.DB, name string) (blob.SectorHashes, error) { + var base blob.SectorHashes + baseB, err := db.Get(headerSectorHashesPrefix(name), nil) if err != nil { - return base, errors.Wrap(err, "error getting merkle base") + return base, errors.Wrap(err, "error getting sector hashes") } if err := base.Decode(bytes.NewReader(baseB)); err != nil { panic(err) @@ -150,17 +172,17 @@ func GetMerkleBase(db *leveldb.DB, name string) (blob.MerkleBase, error) { return base, nil } -func SetHeaderTx(tx *leveldb.Transaction, header *Header, merkleBase blob.MerkleBase) error { +func SetHeaderTx(tx *leveldb.Transaction, header *Header, sectorHashes blob.SectorHashes) error { var buf bytes.Buffer - if err := merkleBase.Encode(&buf); err != nil { + if err := sectorHashes.Encode(&buf); err != nil { return errors.Wrap(err, "error encoding merkle tree") } exists, err := tx.Has(headerDataPrefix(header.Name), nil) if err != nil { return errors.Wrap(err, "error checking header existence") } - if err := tx.Put(headerMerkleBasePrefix(header.Name), buf.Bytes(), nil); err != nil { - return errors.Wrap(err, "error writing merkle tree") + if err := tx.Put(headerSectorHashesPrefix(header.Name), buf.Bytes(), nil); err != nil { + return errors.Wrap(err, "error writing sector hashes") } if err := tx.Put(headerDataPrefix(header.Name), mustMarshalJSON(header), nil); err != nil { return errors.Wrap(err, "error writing header tree") @@ -177,12 +199,12 @@ type BlobInfo struct { Name string `json:"name"` PublicKey *btcec.PublicKey `json:"public_key"` ImportHeight int `json:"import_height"` - Timestamp time.Time `json:"timestamp"` + EpochHeight uint16 `json:"epoch_height"` + SectorSize uint16 `json:"sector_size"` MerkleRoot crypto.Hash `json:"merkle_root"` Signature crypto.Signature `json:"signature"` ReservedRoot crypto.Hash `json:"reserved_root"` ReceivedAt time.Time `json:"received_at"` - Timebank int `json:"timebank"` } func (b *BlobInfo) MarshalJSON() ([]byte, error) { @@ -190,22 +212,22 @@ func (b *BlobInfo) MarshalJSON() ([]byte, error) { Name string `json:"name"` PublicKey string `json:"public_key"` ImportHeight int `json:"import_height"` - Timestamp time.Time `json:"timestamp"` + EpochHeight uint16 `json:"epoch_height"` + SectorSize uint16 `json:"sector_size"` MerkleRoot string `json:"merkle_root"` Signature string `json:"signature"` ReservedRoot string `json:"reserved_root"` ReceivedAt time.Time `json:"received_at"` - Timebank int `json:"timebank"` }{ b.Name, hex.EncodeToString(b.PublicKey.SerializeCompressed()), b.ImportHeight, - b.Timestamp, + b.EpochHeight, + b.SectorSize, hex.EncodeToString(b.MerkleRoot[:]), hex.EncodeToString(b.Signature[:]), hex.EncodeToString(b.ReservedRoot[:]), b.ReceivedAt, - b.Timebank, } return json.Marshal(jsonInfo) @@ -231,12 +253,12 @@ func (bis *BlobInfoStream) Next() (*BlobInfo, error) { Name: header.Name, PublicKey: nameInfo.PublicKey, ImportHeight: nameInfo.ImportHeight, - Timestamp: header.Timestamp, - MerkleRoot: header.MerkleRoot, + EpochHeight: header.EpochHeight, + SectorSize: header.SectorSize, + MerkleRoot: header.SectorTipHash, Signature: header.Signature, ReservedRoot: header.ReservedRoot, - ReceivedAt: header.ReceivedAt, - Timebank: header.Timebank, + ReceivedAt: header.EpochStartAt, }, nil } diff --git a/store/headers_test.go b/store/headers_test.go index f6276b7..b95d649 100644 --- a/store/headers_test.go +++ b/store/headers_test.go @@ -2,18 +2,19 @@ package store import ( "crypto/rand" - "fnd/blob" - "fnd/crypto" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" "testing" "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" ) func TestHeaders_GetSet(t *testing.T) { db, done := setupLevelDB(t) - var expMB blob.MerkleBase + var expMB blob.SectorHashes _, err := rand.Read(expMB[0][:]) require.NoError(t, err) @@ -23,12 +24,12 @@ func TestHeaders_GetSet(t *testing.T) { expHeader := &Header{ Name: "foo", - Timestamp: time.Unix(10, 0), - MerkleRoot: crypto.Rand32(), + EpochHeight: uint16(0), + SectorSize: uint16(0), + SectorTipHash: crypto.Rand32(), Signature: sig, ReservedRoot: crypto.Rand32(), - ReceivedAt: time.Unix(11, 0), - Timebank: 100, + EpochStartAt: time.Unix(11, 0), } _, err = GetHeader(db, "foo") require.Error(t, err) @@ -38,12 +39,13 @@ func TestHeaders_GetSet(t *testing.T) { actHeader, err := GetHeader(db, "foo") require.NoError(t, err) require.Equal(t, expHeader.Name, actHeader.Name) - require.Equal(t, expHeader.Timestamp.Unix(), actHeader.Timestamp.Unix()) - require.Equal(t, expHeader.MerkleRoot, actHeader.MerkleRoot) + require.Equal(t, expHeader.EpochHeight, actHeader.EpochHeight) + require.Equal(t, expHeader.SectorSize, actHeader.SectorSize) + require.Equal(t, expHeader.SectorTipHash, actHeader.SectorTipHash) require.Equal(t, expHeader.Signature, actHeader.Signature) require.Equal(t, expHeader.ReservedRoot, actHeader.ReservedRoot) - require.Equal(t, expHeader.ReceivedAt.Unix(), actHeader.ReceivedAt.Unix()) - actMB, err := GetMerkleBase(db, "foo") + require.Equal(t, expHeader.EpochStartAt.Unix(), actHeader.EpochStartAt.Unix()) + actMB, err := GetSectorHashes(db, "foo") require.NoError(t, err) require.Equal(t, expMB, actMB) diff --git a/store/naming_test.go b/store/naming_test.go index d8b8f23..c3afd6f 100644 --- a/store/naming_test.go +++ b/store/naming_test.go @@ -1,7 +1,7 @@ package store import ( - "fnd/testutil/testcrypto" + "github.com/ddrp-org/ddrp/testutil/testcrypto" "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" "testing" diff --git a/store/peers.go b/store/peers.go index 9c508dd..f0f693e 100644 --- a/store/peers.go +++ b/store/peers.go @@ -4,7 +4,7 @@ import ( "encoding/binary" "encoding/hex" "encoding/json" - "fnd/crypto" + "github.com/ddrp-org/ddrp/crypto" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/iterator" diff --git a/store/peers_test.go b/store/peers_test.go index ccec6ba..a80c758 100644 --- a/store/peers_test.go +++ b/store/peers_test.go @@ -1,7 +1,7 @@ package store import ( - "fnd/crypto" + "github.com/ddrp-org/ddrp/crypto" "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" "testing" diff --git a/store/store.go b/store/store.go index 05fd052..9ceb1a2 100644 --- a/store/store.go +++ b/store/store.go @@ -1,7 +1,7 @@ package store import ( - "fnd/log" + "github.com/ddrp-org/ddrp/log" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" ) diff --git a/testutil/mockapp/null.go b/testutil/mockapp/null.go new file mode 100644 index 0000000..8e60b8a --- /dev/null +++ b/testutil/mockapp/null.go @@ -0,0 +1,32 @@ +package mockapp + +import ( + "io" + "io/ioutil" +) + +type reader struct{} + +func (reader) Read(b []byte) (int, error) { + for i := range b { + b[i] = 0 + } + return len(b), nil +} + +var NullReader io.Reader + +func Read(b []byte) (n int, err error) { + return NullReader.Read(b) +} + +var NullWriter io.Writer + +func Write(p []byte) (n int, err error) { + return NullWriter.Write(p) +} + +func init() { + NullReader = new(reader) + NullWriter = ioutil.Discard +} diff --git a/testutil/mockapp/peer.go b/testutil/mockapp/peer.go index 4af6a01..24e9c68 100644 --- a/testutil/mockapp/peer.go +++ b/testutil/mockapp/peer.go @@ -1,10 +1,10 @@ package mockapp import ( - "fnd/crypto" - "fnd/p2p" - "fnd/testutil" - "fnd/testutil/testcrypto" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/p2p" + "github.com/ddrp-org/ddrp/testutil" + "github.com/ddrp-org/ddrp/testutil/testcrypto" "github.com/stretchr/testify/require" "testing" ) diff --git a/testutil/mockapp/storage.go b/testutil/mockapp/storage.go index b527cea..c135e50 100644 --- a/testutil/mockapp/storage.go +++ b/testutil/mockapp/storage.go @@ -2,16 +2,17 @@ package mockapp import ( "crypto/rand" - "fnd/blob" - "fnd/crypto" - "fnd/store" - "fnd/testutil/testfs" - "fnd/wire" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" "io" "testing" "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/store" + "github.com/ddrp-org/ddrp/testutil/testfs" + "github.com/ddrp-org/ddrp/wire" + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" ) type TestStorage struct { @@ -45,45 +46,48 @@ func CreateTestDB(t *testing.T) (*leveldb.DB, func()) { return db, done } -func FillBlobReader(t *testing.T, db *leveldb.DB, bs blob.Store, signer crypto.Signer, name string, ts time.Time, receivedAt time.Time, r io.Reader) *wire.Update { +func FillBlobReader(t *testing.T, db *leveldb.DB, bs blob.Store, signer crypto.Signer, name string, epochHeight, sectorSize uint16, receivedAt time.Time, r io.Reader) *wire.Update { bl, err := bs.Open(name) require.NoError(t, err) tx, err := bl.Transaction() require.NoError(t, err) _, err = io.Copy(blob.NewWriter(tx), io.LimitReader(r, blob.Size)) require.NoError(t, err) - tree, err := blob.Merkleize(blob.NewReader(tx)) + tree, err := blob.SerialHash(blob.NewReader(tx), blob.ZeroHash, sectorSize) require.NoError(t, err) - sig, err := blob.SignSeal(signer, name, ts, tree.Root(), crypto.ZeroHash) + sig, err := blob.SignSeal(signer, name, epochHeight, sectorSize, tree.Tip(), crypto.ZeroHash) require.NoError(t, err) require.NoError(t, store.WithTx(db, func(tx *leveldb.Transaction) error { return store.SetHeaderTx(tx, &store.Header{ - Name: name, - Timestamp: ts, - MerkleRoot: tree.Root(), - Signature: sig, - ReservedRoot: crypto.ZeroHash, - ReceivedAt: receivedAt, - }, tree.ProtocolBase()) + Name: name, + EpochHeight: epochHeight, + SectorSize: sectorSize, + SectorTipHash: tree.Tip(), + Signature: sig, + ReservedRoot: crypto.ZeroHash, + EpochStartAt: receivedAt, + }, tree) })) require.NoError(t, tx.Commit()) return &wire.Update{ - Name: name, - Timestamp: ts, - MerkleRoot: tree.Root(), - ReservedRoot: crypto.ZeroHash, - Signature: sig, + Name: name, + EpochHeight: epochHeight, + SectorSize: sectorSize, + SectorTipHash: tree.Tip(), + ReservedRoot: crypto.ZeroHash, + Signature: sig, } } -func FillBlobRandom(t *testing.T, db *leveldb.DB, bs blob.Store, signer crypto.Signer, name string, ts time.Time, receivedAt time.Time) *wire.Update { +func FillBlobRandom(t *testing.T, db *leveldb.DB, bs blob.Store, signer crypto.Signer, name string, epochHeight, sectorSize uint16, receivedAt time.Time) *wire.Update { return FillBlobReader( t, db, bs, signer, name, - ts, + epochHeight, + sectorSize, receivedAt, rand.Reader, ) diff --git a/testutil/net.go b/testutil/net.go index 467ad18..faa5a66 100644 --- a/testutil/net.go +++ b/testutil/net.go @@ -1,8 +1,8 @@ package testutil import ( - "fnd/testutil/testcrypto" - "fnd/wire" + "github.com/ddrp-org/ddrp/testutil/testcrypto" + "github.com/ddrp-org/ddrp/wire" "github.com/stretchr/testify/require" "io" "net" diff --git a/testutil/testcrypto/crypto.go b/testutil/testcrypto/crypto.go index 34eef5a..237dbb2 100644 --- a/testutil/testcrypto/crypto.go +++ b/testutil/testcrypto/crypto.go @@ -4,7 +4,7 @@ import ( "crypto/rand" "encoding/hex" "github.com/btcsuite/btcd/btcec" - "fnd/crypto" + "github.com/ddrp-org/ddrp/crypto" "github.com/stretchr/testify/require" "testing" ) diff --git a/testutil/testflags/flags.go b/testutil/testflags/flags.go index 22b119d..d584c97 100644 --- a/testutil/testflags/flags.go +++ b/testutil/testflags/flags.go @@ -6,7 +6,7 @@ import ( ) func IntegrationTest(t *testing.T) { - _, ok := os.LookupEnv("Footnote_ENABLE_INTEGRATION_TESTS") + _, ok := os.LookupEnv("DDRP_ENABLE_INTEGRATION_TESTS") if !ok { t.SkipNow() } @@ -14,7 +14,7 @@ func IntegrationTest(t *testing.T) { } func HandshakeTest(t *testing.T) { - _, ok := os.LookupEnv("Footnote_ENABLE_HANDSHAKE_TESTS") + _, ok := os.LookupEnv("DDRP_ENABLE_HANDSHAKE_TESTS") if !ok { t.SkipNow() } diff --git a/testutil/testfs/fs.go b/testutil/testfs/fs.go index ef36d6d..fef13a3 100644 --- a/testutil/testfs/fs.go +++ b/testutil/testfs/fs.go @@ -8,7 +8,7 @@ import ( ) func NewTempDir(t *testing.T) (string, func()) { - dir, err := ioutil.TempDir("", "fndtest_") + dir, err := ioutil.TempDir("", "ddrptest_") require.NoError(t, err) return dir, func() { require.NoError(t, os.RemoveAll(dir)) @@ -16,7 +16,7 @@ func NewTempDir(t *testing.T) (string, func()) { } func NewTempFile(t *testing.T) (*os.File, func()) { - f, err := ioutil.TempFile("", "fndtest_") + f, err := ioutil.TempFile("", "ddrptest_") require.NoError(t, err) return f, func() { require.NoError(t, f.Close()) diff --git a/version/version.go b/version/version.go index 2811260..020dbae 100644 --- a/version/version.go +++ b/version/version.go @@ -7,5 +7,5 @@ var GitTag string var UserAgent string func init() { - UserAgent = fmt.Sprintf("fnd/%s+%s", GitTag, GitCommit) + UserAgent = fmt.Sprintf("ddrpd/%s+%s", GitTag, GitCommit) } diff --git a/wire/blob_req.go b/wire/blob_req.go new file mode 100644 index 0000000..14548b1 --- /dev/null +++ b/wire/blob_req.go @@ -0,0 +1,55 @@ +package wire + +import ( + "io" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" +) + +type BlobReq struct { + HashCacher + + Name string + EpochHeight uint16 + SectorSize uint16 +} + +var _ Message = (*BlobReq)(nil) + +func (u *BlobReq) MsgType() MessageType { + return MessageTypeBlobReq +} + +func (u *BlobReq) Equals(other Message) bool { + cast, ok := other.(*BlobReq) + if !ok { + return false + } + + return u.Name == cast.Name && + u.EpochHeight == cast.EpochHeight && + u.SectorSize == cast.SectorSize +} + +func (u *BlobReq) Encode(w io.Writer) error { + return dwire.EncodeFields( + w, + u.Name, + u.EpochHeight, + u.SectorSize, + ) +} + +func (u *BlobReq) Decode(r io.Reader) error { + return dwire.DecodeFields( + r, + &u.Name, + &u.EpochHeight, + &u.SectorSize, + ) +} + +func (u *BlobReq) Hash() (crypto.Hash, error) { + return u.HashCacher.Hash(u) +} diff --git a/wire/blob_req_test.go b/wire/blob_req_test.go new file mode 100644 index 0000000..8dc6f0e --- /dev/null +++ b/wire/blob_req_test.go @@ -0,0 +1,15 @@ +package wire + +import ( + "testing" +) + +func TestBlobReq_Encoding(t *testing.T) { + blobReq := &BlobReq{ + Name: "testname.", + EpochHeight: 0, + SectorSize: 1, + } + + testMessageEncoding(t, "blob_req", blobReq, &BlobReq{}) +} diff --git a/wire/blob_res.go b/wire/blob_res.go new file mode 100644 index 0000000..78ffead --- /dev/null +++ b/wire/blob_res.go @@ -0,0 +1,67 @@ +package wire + +import ( + "io" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" +) + +type BlobRes struct { + HashCacher + + Name string + EpochHeight uint16 + PayloadPosition uint16 + PrevHash crypto.Hash + ReservedRoot crypto.Hash + Payload []blob.Sector +} + +var _ Message = (*BlobRes)(nil) + +func (s *BlobRes) MsgType() MessageType { + return MessageTypeBlobRes +} + +func (s *BlobRes) Equals(other Message) bool { + cast, ok := other.(*BlobRes) + if !ok { + return false + } + + return s.Name == cast.Name && + s.EpochHeight == cast.EpochHeight && + s.PayloadPosition == cast.PayloadPosition && + s.PrevHash == cast.PrevHash && + s.ReservedRoot == cast.ReservedRoot +} + +func (s *BlobRes) Encode(w io.Writer) error { + return dwire.EncodeFields( + w, + s.Name, + s.EpochHeight, + s.PayloadPosition, + s.PrevHash, + s.ReservedRoot, + s.Payload, + ) +} + +func (s *BlobRes) Decode(r io.Reader) error { + return dwire.DecodeFields( + r, + &s.Name, + &s.EpochHeight, + &s.PayloadPosition, + &s.PrevHash, + &s.ReservedRoot, + &s.Payload, + ) +} + +func (s *BlobRes) Hash() (crypto.Hash, error) { + return s.HashCacher.Hash(s) +} diff --git a/wire/blob_res_test.go b/wire/blob_res_test.go new file mode 100644 index 0000000..83163c1 --- /dev/null +++ b/wire/blob_res_test.go @@ -0,0 +1,18 @@ +package wire + +import ( + "testing" +) + +func TestBlobRes_Encoding(t *testing.T) { + blobRes := &BlobRes{ + Name: "testname.", + EpochHeight: 0, + PayloadPosition: 0, + PrevHash: fixedHash, + ReservedRoot: fixedHash, + Payload: nil, + } + + testMessageEncoding(t, "blob_res", blobRes, &BlobRes{}) +} diff --git a/wire/envelope.go b/wire/envelope.go index e0480fa..cc8e392 100644 --- a/wire/envelope.go +++ b/wire/envelope.go @@ -3,10 +3,11 @@ package wire import ( "bytes" "fmt" - "fnd/crypto" - "fnd.localhost/dwire" "io" "time" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" ) type Envelope struct { @@ -82,14 +83,10 @@ func (e *Envelope) Decode(r io.Reader) error { msg = &Update{} case MessageTypeNilUpdate: msg = &NilUpdate{} - case MessageTypeTreeBaseReq: - msg = &TreeBaseReq{} - case MessageTypeTreeBaseRes: - msg = &TreeBaseRes{} - case MessageTypeSectorReq: - msg = &SectorReq{} - case MessageTypeSectorRes: - msg = &SectorRes{} + case MessageTypeBlobReq: + msg = &BlobReq{} + case MessageTypeBlobRes: + msg = &BlobRes{} case MessageTypePeerReq: msg = &PeerReq{} case MessageTypePeerRes: diff --git a/wire/hash_cacher.go b/wire/hash_cacher.go index 3d99c0e..067d0f4 100644 --- a/wire/hash_cacher.go +++ b/wire/hash_cacher.go @@ -2,9 +2,10 @@ package wire import ( "bytes" - "fnd/crypto" - "fnd.localhost/dwire" "sync" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" ) var hashCacherBufPool = sync.Pool{ diff --git a/wire/hash_cacher_test.go b/wire/hash_cacher_test.go index c6e3e36..7d88e71 100644 --- a/wire/hash_cacher_test.go +++ b/wire/hash_cacher_test.go @@ -2,12 +2,13 @@ package wire import ( "encoding/hex" - "fnd/crypto" - "fnd.localhost/dwire" - "github.com/stretchr/testify/require" "io" "sync" "testing" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" + "github.com/stretchr/testify/require" ) type input struct { diff --git a/wire/hello.go b/wire/hello.go index e09d614..24aed01 100644 --- a/wire/hello.go +++ b/wire/hello.go @@ -1,10 +1,11 @@ package wire import ( - "github.com/btcsuite/btcd/btcec" - "fnd/crypto" - "fnd.localhost/dwire" "io" + + "github.com/btcsuite/btcd/btcec" + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" ) type Hello struct { diff --git a/wire/hello_ack.go b/wire/hello_ack.go index 2363e95..029caf2 100644 --- a/wire/hello_ack.go +++ b/wire/hello_ack.go @@ -1,9 +1,10 @@ package wire import ( - "fnd/crypto" - "fnd.localhost/dwire" "io" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" ) type HelloAck struct { diff --git a/wire/hello_test.go b/wire/hello_test.go index d4e2a13..9ebf100 100644 --- a/wire/hello_test.go +++ b/wire/hello_test.go @@ -1,7 +1,7 @@ package wire import ( - "fnd/testutil/testcrypto" + "github.com/ddrp-org/ddrp/testutil/testcrypto" "testing" ) diff --git a/wire/message.go b/wire/message.go index bfde66d..f3454a9 100644 --- a/wire/message.go +++ b/wire/message.go @@ -1,9 +1,10 @@ package wire import ( - "fnd/crypto" - "fnd.localhost/dwire" "io" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" ) type Message interface { @@ -21,10 +22,8 @@ const ( MessageTypePing MessageTypeUpdate MessageTypeNilUpdate - MessageTypeTreeBaseReq - MessageTypeTreeBaseRes - MessageTypeSectorReq - MessageTypeSectorRes + MessageTypeBlobReq + MessageTypeBlobRes MessageTypePeerReq MessageTypePeerRes MessageTypeUpdateReq @@ -43,14 +42,10 @@ func (t MessageType) String() string { return "Update" case MessageTypeNilUpdate: return "NilUpdate" - case MessageTypeTreeBaseReq: - return "TreeBaseReq" - case MessageTypeTreeBaseRes: - return "TreeBaseRes" - case MessageTypeSectorReq: - return "SectorReq" - case MessageTypeSectorRes: - return "SectorRes" + case MessageTypeBlobReq: + return "BlobReq" + case MessageTypeBlobRes: + return "BlobRes" case MessageTypePeerReq: return "PeerReq" case MessageTypePeerRes: diff --git a/wire/nil_update.go b/wire/nil_update.go index 312151c..95a907c 100644 --- a/wire/nil_update.go +++ b/wire/nil_update.go @@ -1,9 +1,10 @@ package wire import ( - "fnd/crypto" - "fnd.localhost/dwire" "io" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" ) type NilUpdate struct { diff --git a/wire/peer_req.go b/wire/peer_req.go index c76ae45..77e3e1c 100644 --- a/wire/peer_req.go +++ b/wire/peer_req.go @@ -1,7 +1,7 @@ package wire import ( - "fnd/crypto" + "github.com/ddrp-org/ddrp/crypto" "io" ) diff --git a/wire/peer_res.go b/wire/peer_res.go index b3cbe53..df61cd6 100644 --- a/wire/peer_res.go +++ b/wire/peer_res.go @@ -2,10 +2,11 @@ package wire import ( "bytes" - "fnd/crypto" - "fnd.localhost/dwire" "io" "net" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" ) type Peer struct { diff --git a/wire/ping.go b/wire/ping.go index 036c2c2..f5476f7 100644 --- a/wire/ping.go +++ b/wire/ping.go @@ -1,7 +1,7 @@ package wire import ( - "fnd/crypto" + "github.com/ddrp-org/ddrp/crypto" "io" ) diff --git a/wire/sector_req.go b/wire/sector_req.go deleted file mode 100644 index a43b910..0000000 --- a/wire/sector_req.go +++ /dev/null @@ -1,50 +0,0 @@ -package wire - -import ( - "fnd/crypto" - "fnd.localhost/dwire" - "io" -) - -type SectorReq struct { - HashCacher - - Name string - SectorID uint8 -} - -var _ Message = (*SectorReq)(nil) - -func (s *SectorReq) MsgType() MessageType { - return MessageTypeSectorReq -} - -func (s *SectorReq) Equals(other Message) bool { - cast, ok := other.(*SectorReq) - if !ok { - return false - } - - return s.Name == cast.Name && - s.SectorID == cast.SectorID -} - -func (s *SectorReq) Encode(w io.Writer) error { - return dwire.EncodeFields( - w, - s.Name, - s.SectorID, - ) -} - -func (s *SectorReq) Decode(r io.Reader) error { - return dwire.DecodeFields( - r, - &s.Name, - &s.SectorID, - ) -} - -func (s *SectorReq) Hash() (crypto.Hash, error) { - return s.HashCacher.Hash(s) -} diff --git a/wire/sector_req_test.go b/wire/sector_req_test.go deleted file mode 100644 index f8d055b..0000000 --- a/wire/sector_req_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package wire - -import ( - "testing" -) - -func TestSectorReq_Encoding(t *testing.T) { - sectorReq := &SectorReq{ - Name: "testname.", - SectorID: 16, - } - - testMessageEncoding(t, "sector_req", sectorReq, &SectorReq{}) -} diff --git a/wire/sector_res.go b/wire/sector_res.go deleted file mode 100644 index 75dcca7..0000000 --- a/wire/sector_res.go +++ /dev/null @@ -1,55 +0,0 @@ -package wire - -import ( - "fnd/blob" - "fnd/crypto" - "fnd.localhost/dwire" - "io" -) - -type SectorRes struct { - HashCacher - - Name string - SectorID uint8 - Sector blob.Sector -} - -var _ Message = (*SectorRes)(nil) - -func (s *SectorRes) MsgType() MessageType { - return MessageTypeSectorRes -} - -func (s *SectorRes) Equals(other Message) bool { - cast, ok := other.(*SectorRes) - if !ok { - return false - } - - return s.Name == cast.Name && - s.SectorID == cast.SectorID && - s.Sector == cast.Sector -} - -func (s *SectorRes) Encode(w io.Writer) error { - return dwire.EncodeFields( - w, - s.Name, - s.SectorID, - s.Sector, - ) -} - -func (s *SectorRes) Decode(r io.Reader) error { - return dwire.DecodeFields( - r, - &s.Name, - &s.SectorID, - &s.Sector, - ) -} - -func (s *SectorRes) Hash() (crypto.Hash, error) { - return s.HashCacher.Hash(s) -} diff --git a/wire/sector_res_test.go b/wire/sector_res_test.go deleted file mode 100644 index d7457ee..0000000 --- a/wire/sector_res_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package wire - -import ( - "fnd/blob" - "testing" -) - -func TestSectorRes_Encoding(t *testing.T) { - sectorRes := &SectorRes{ - Name: "testname.", - SectorID: 16, - Sector: blob.Sector{}, - } - - testMessageEncoding(t, "sector_res", sectorRes, &SectorRes{}) -} diff --git a/wire/testdata/blob_req b/wire/testdata/blob_req new file mode 100644 index 0000000000000000000000000000000000000000..e0d606641254d820af2b07b5d135b3e15b8d5813 GIT binary patch literal 14 Vcmd-qNi8nPOUzBxV_;xl1OOq+1DXH; literal 0 HcmV?d00001 diff --git a/wire/testdata/blob_res b/wire/testdata/blob_res new file mode 100644 index 0000000000000000000000000000000000000000..c8bec84beaea98fcc983bb6914a6d62183bfccfb GIT binary patch literal 79 acmd-qNi8nPOUzBxV*r8wU=lY$NFD%dQU#X) literal 0 HcmV?d00001 diff --git a/wire/testdata/hello b/wire/testdata/hello index a238b5509dada53ce6b11c8ef12d589127bf09b3..a6e5d4ff8ed3a565bdbacf249a3b1f04c699d1ef 100644 GIT binary patch delta 4 Lcmd1JnUDhj1c(9F delta 6 Ncmd1Fosh%G1po*?0pS1u diff --git a/wire/testdata/hello_ack b/wire/testdata/hello_ack index c952a9f99ee80bd421805a9c40d77674698832b9..ed43e9374f30c2c714540587cf9ea9f685fd2d95 100644 GIT binary patch delta 4 LcmY#Xn4kav0w@6T literal 33 NcmZSh&wv+j0RSKi0SW*B diff --git a/wire/testdata/nil_update b/wire/testdata/nil_update index 8554269..197ca51 100644 --- a/wire/testdata/nil_update +++ b/wire/testdata/nil_update @@ -1 +1 @@ - testname. + testname. \ No newline at end of file diff --git a/wire/testdata/peer_res b/wire/testdata/peer_res index 6a5836c372da911004de62752126aea68ccb6b0c..20d344a80de5c7e74aebb8167f6c1c78101faefc 100644 GIT binary patch delta 4 LcmYdFoRA0r1TX=$ delta 6 NcmYdHnvlrI1po)70l)wN diff --git a/wire/testdata/update b/wire/testdata/update index c1df062ad9424f4e3f8c85eddc782df837e8c2aa..e528fbeefc51a0b8acabd93b8be82f7024f607b1 100755 GIT binary patch literal 142 dcmd-mNi8nPOUzAW0D=Et5;sAqJZ_UAG63|{24?^O literal 143 gcmd-mNi8nPOUzC6oW^vC;Xea@K&d=_(-|1J0NeHmBme*a diff --git a/wire/testdata/update_req b/wire/testdata/update_req index 91e240ddf97325fe32ab631dec0cdcc8c44b233d..ba2bf1290b1ee6418ee43a99aebc7cc5c11b6ad9 100644 GIT binary patch literal 13 Scmd-mNi8nPOUzAW00ICVYy)Zl literal 14 Vcmd-mNi8nPOUzAW5W3dR1pp+t1mgez diff --git a/wire/tree_base_req.go b/wire/tree_base_req.go deleted file mode 100644 index 64200ad..0000000 --- a/wire/tree_base_req.go +++ /dev/null @@ -1,46 +0,0 @@ -package wire - -import ( - "fnd/crypto" - "fnd.localhost/dwire" - "io" -) - -type TreeBaseReq struct { - HashCacher - - Name string -} - -var _ Message = (*TreeBaseReq)(nil) - -func (d *TreeBaseReq) MsgType() MessageType { - return MessageTypeTreeBaseReq -} - -func (d *TreeBaseReq) Equals(other Message) bool { - cast, ok := other.(*TreeBaseReq) - if !ok { - return false - } - - return d.Name == cast.Name -} - -func (d *TreeBaseReq) Encode(w io.Writer) error { - return dwire.EncodeFields( - w, - d.Name, - ) -} - -func (d *TreeBaseReq) Decode(r io.Reader) error { - return dwire.DecodeFields( - r, - &d.Name, - ) -} - -func (d *TreeBaseReq) Hash() (crypto.Hash, error) { - return d.HashCacher.Hash(d) -} diff --git a/wire/tree_base_req_test.go b/wire/tree_base_req_test.go deleted file mode 100644 index 76d167f..0000000 --- a/wire/tree_base_req_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package wire - -import ( - "testing" -) - -func TestTreeBaseReq_Encoding(t *testing.T) { - treeBaseReq := &TreeBaseReq{ - Name: "testname.", - } - - testMessageEncoding(t, "tree_base_req", treeBaseReq, &TreeBaseReq{}) -} diff --git a/wire/tree_base_res.go b/wire/tree_base_res.go deleted file mode 100644 index 3f76676..0000000 --- a/wire/tree_base_res.go +++ /dev/null @@ -1,49 +0,0 @@ -package wire - -import ( - "fnd/blob" - "fnd/crypto" - "fnd.localhost/dwire" - "io" -) - -type TreeBaseRes struct { - HashCacher - - Name string - MerkleBase blob.MerkleBase -} - -func (d *TreeBaseRes) MsgType() MessageType { - return MessageTypeTreeBaseRes -} - -func (d *TreeBaseRes) Equals(other Message) bool { - cast, ok := other.(*TreeBaseRes) - if !ok { - return false - } - - return d.Name == cast.Name && - d.MerkleBase == cast.MerkleBase -} - -func (d *TreeBaseRes) Encode(w io.Writer) error { - return dwire.EncodeFields( - w, - d.Name, - d.MerkleBase, - ) -} - -func (d *TreeBaseRes) Decode(r io.Reader) error { - return dwire.DecodeFields( - r, - &d.Name, - &d.MerkleBase, - ) -} - -func (d *TreeBaseRes) Hash() (crypto.Hash, error) { - return d.HashCacher.Hash(d) -} diff --git a/wire/tree_base_res_test.go b/wire/tree_base_res_test.go deleted file mode 100644 index 66e5eea..0000000 --- a/wire/tree_base_res_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package wire - -import ( - "fnd/blob" - "testing" -) - -func TestTreeBaseRes_Encoding(t *testing.T) { - treeBaseRes := &TreeBaseRes{ - Name: "testname.", - MerkleBase: blob.ZeroMerkleBase, - } - - testMessageEncoding(t, "tree_base_res", treeBaseRes, &TreeBaseRes{}) -} diff --git a/wire/update.go b/wire/update.go index d328a28..f512bea 100644 --- a/wire/update.go +++ b/wire/update.go @@ -1,20 +1,21 @@ package wire import ( - "fnd/crypto" - "fnd.localhost/dwire" "io" - "time" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" ) type Update struct { HashCacher - Name string - Timestamp time.Time - MerkleRoot crypto.Hash - ReservedRoot crypto.Hash - Signature crypto.Signature + Name string + EpochHeight uint16 + SectorSize uint16 + SectorTipHash crypto.Hash + ReservedRoot crypto.Hash + Signature crypto.Signature } var _ Message = (*Update)(nil) @@ -30,8 +31,9 @@ func (u *Update) Equals(other Message) bool { } return u.Name == cast.Name && - u.Timestamp.Equal(cast.Timestamp) && - u.MerkleRoot == cast.MerkleRoot && + u.EpochHeight == cast.EpochHeight && + u.SectorSize == cast.SectorSize && + u.SectorTipHash == cast.SectorTipHash && u.ReservedRoot == cast.ReservedRoot && u.Signature == cast.Signature } @@ -40,8 +42,9 @@ func (u *Update) Encode(w io.Writer) error { return dwire.EncodeFields( w, u.Name, - u.Timestamp, - u.MerkleRoot, + u.EpochHeight, + u.SectorSize, + u.SectorTipHash, u.ReservedRoot, u.Signature, ) @@ -51,8 +54,9 @@ func (u *Update) Decode(r io.Reader) error { return dwire.DecodeFields( r, &u.Name, - &u.Timestamp, - &u.MerkleRoot, + &u.EpochHeight, + &u.SectorSize, + &u.SectorTipHash, &u.ReservedRoot, &u.Signature, ) diff --git a/wire/update_req.go b/wire/update_req.go index 7c263d2..0f1d565 100644 --- a/wire/update_req.go +++ b/wire/update_req.go @@ -1,17 +1,18 @@ package wire import ( - "fnd/crypto" - "fnd.localhost/dwire" "io" - "time" + + "github.com/ddrp-org/ddrp/crypto" + "github.com/ddrp-org/ddrp/dwire" ) type UpdateReq struct { HashCacher - Name string - Timestamp time.Time + Name string + EpochHeight uint16 + SectorSize uint16 } var _ Message = (*UpdateReq)(nil) @@ -27,14 +28,16 @@ func (n *UpdateReq) Equals(other Message) bool { } return n.Name == cast.Name && - n.Timestamp.Unix() == cast.Timestamp.Unix() + n.EpochHeight == cast.EpochHeight && + n.SectorSize == cast.SectorSize } func (n *UpdateReq) Encode(w io.Writer) error { return dwire.EncodeFields( w, n.Name, - n.Timestamp, + n.EpochHeight, + n.SectorSize, ) } @@ -42,7 +45,8 @@ func (n *UpdateReq) Decode(r io.Reader) error { return dwire.DecodeFields( r, &n.Name, - &n.Timestamp, + &n.EpochHeight, + &n.SectorSize, ) } diff --git a/wire/update_req_test.go b/wire/update_req_test.go index f98cbcc..2ef6738 100644 --- a/wire/update_req_test.go +++ b/wire/update_req_test.go @@ -2,13 +2,13 @@ package wire import ( "testing" - "time" ) func TestUpdateReq_Encoding(t *testing.T) { updateReq := &UpdateReq{ - Name: "testname", - Timestamp: time.Unix(1234567, 0), + Name: "testname", + EpochHeight: 0, + SectorSize: 0, } testMessageEncoding(t, "update_req", updateReq, &UpdateReq{}) diff --git a/wire/update_test.go b/wire/update_test.go index 23e3bf5..2e4c5d0 100644 --- a/wire/update_test.go +++ b/wire/update_test.go @@ -6,11 +6,12 @@ import ( func TestUpdate_Encoding(t *testing.T) { update := &Update{ - Name: "testname", - Timestamp: fixedTime, - MerkleRoot: fixedHash, - ReservedRoot: fixedHash, - Signature: fixedSig, + Name: "testname", + EpochHeight: fixedEpochHeight, + SectorSize: fixedSectorSize, + SectorTipHash: fixedHash, + ReservedRoot: fixedHash, + Signature: fixedSig, } testMessageEncoding(t, "update", update, &Update{}) diff --git a/wire/util_test.go b/wire/util_test.go index d611171..2bede66 100644 --- a/wire/util_test.go +++ b/wire/util_test.go @@ -3,19 +3,20 @@ package wire import ( "bytes" "fmt" - "fnd/blob" - "fnd/crypto" - "github.com/stretchr/testify/require" "io/ioutil" "testing" - "time" + + "github.com/ddrp-org/ddrp/blob" + "github.com/ddrp-org/ddrp/crypto" + "github.com/stretchr/testify/require" ) var ( fixedSig crypto.Signature fixedHash crypto.Hash fixedMerkleProof blob.MerkleProof - fixedTime = time.Unix(1234567890, 0) + fixedEpochHeight = uint16(0) + fixedSectorSize = uint16(0) ) func testMessageEncoding(t *testing.T, fixtureName string, input Message, proto interface{}) { From cf10384888d7c7f11044c6a48521c2adb1526e84 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sun, 17 Jan 2021 10:43:39 +0530 Subject: [PATCH 02/71] replace github.com/ddrp-org/ddrp -> fnd --- Makefile | 2 +- blob/hash.go | 3 +- blob/merkle.go | 3 +- blob/merkle_test.go | 3 +- blob/seal.go | 5 +- blob/seal_test.go | 5 +- blob/store_test.go | 7 +-- blob/util_test.go | 5 +- cli/homedir.go | 3 +- cli/signer.go | 4 +- cmd/ddrpcli/cmd/blob/info.go | 7 +-- cmd/ddrpcli/cmd/blob/list.go | 11 +++-- cmd/ddrpcli/cmd/blob/read.go | 9 ++-- cmd/ddrpcli/cmd/blob/write.go | 9 ++-- cmd/ddrpcli/cmd/identity.go | 5 +- cmd/ddrpcli/cmd/init.go | 3 +- cmd/ddrpcli/cmd/net/add_peer.go | 9 ++-- cmd/ddrpcli/cmd/net/ban_peer.go | 9 ++-- cmd/ddrpcli/cmd/net/peer_info.go | 9 ++-- cmd/ddrpcli/cmd/net/status.go | 11 +++-- cmd/ddrpcli/cmd/net/unban_peer.go | 7 +-- cmd/ddrpcli/cmd/root.go | 11 +++-- cmd/ddrpcli/cmd/unsafe/reset_blobs.go | 7 +-- cmd/ddrpcli/cmd/unsafe/reset_name_store.go | 5 +- cmd/ddrpcli/cmd/unsafe/reset_peer_store.go | 5 +- cmd/ddrpcli/cmd/version.go | 3 +- cmd/ddrpcli/main.go | 2 +- cmd/ddrpd/cmd/init.go | 3 +- cmd/ddrpd/cmd/root.go | 7 +-- cmd/ddrpd/cmd/start.go | 25 +++++----- cmd/ddrpd/cmd/version.go | 3 +- cmd/ddrpd/main.go | 2 +- config/default.go | 3 +- go.mod | 2 +- p2p/counting_reader_test.go | 5 +- p2p/envelope_io.go | 4 +- p2p/incoming_handshake.go | 5 +- p2p/incoming_handshake_test.go | 5 +- p2p/listener.go | 7 +-- p2p/outgoing_handshake.go | 9 ++-- p2p/outgoing_handshake_test.go | 13 ++--- p2p/peer.go | 7 +-- p2p/peer_manager.go | 17 +++---- p2p/peer_muxer.go | 11 +++-- p2p/peer_test.go | 7 +-- p2p/seeds.go | 5 +- protocol/epoch_test.go | 11 +++-- protocol/heartbeater.go | 11 +++-- protocol/heartbeater_test.go | 7 +-- protocol/moderation.go | 9 ++-- protocol/moderation_test.go | 9 ++-- protocol/name_importer.go | 15 +++--- protocol/name_importer_test.go | 5 +- protocol/name_syncer.go | 15 +++--- protocol/peer_exchanger.go | 17 +++---- protocol/peer_set.go | 2 +- protocol/peer_set_test.go | 5 +- protocol/pinger.go | 8 ++-- protocol/pinger_test.go | 13 ++--- protocol/sector_server.go | 17 +++---- protocol/syncer.go | 11 +++-- protocol/syncer_test.go | 8 ++-- protocol/transaction_mock_test.go | 3 +- protocol/update_queue.go | 15 +++--- protocol/update_queue_test.go | 55 +++++++++++----------- protocol/update_server.go | 13 ++--- protocol/update_server_test.go | 27 ++++++----- protocol/updater.go | 17 +++---- protocol/updater_test.go | 15 +++--- protocol/util_test.go | 7 +-- rpc/blob.go | 7 +-- rpc/blob_reader.go | 4 +- rpc/blob_writer.go | 7 +-- rpc/net.go | 2 +- rpc/server.go | 19 ++++---- store/headers.go | 5 +- store/headers_test.go | 19 ++++---- store/naming_test.go | 5 +- store/peers.go | 7 +-- store/peers_test.go | 7 +-- store/store.go | 3 +- testutil/mockapp/peer.go | 11 +++-- testutil/mockapp/storage.go | 11 +++-- testutil/net.go | 7 +-- testutil/testcrypto/crypto.go | 5 +- wire/blob_req.go | 4 +- wire/blob_res.go | 6 +-- wire/envelope.go | 4 +- wire/hash_cacher.go | 4 +- wire/hash_cacher_test.go | 5 +- wire/hello.go | 5 +- wire/hello_ack.go | 4 +- wire/hello_test.go | 2 +- wire/message.go | 4 +- wire/nil_update.go | 4 +- wire/peer_req.go | 2 +- wire/peer_res.go | 4 +- wire/ping.go | 2 +- wire/update.go | 4 +- wire/update_req.go | 4 +- wire/util_test.go | 5 +- 101 files changed, 438 insertions(+), 361 deletions(-) diff --git a/Makefile b/Makefile index 3ab6814..b08d4e4 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ fpm = @docker run --rm -i -v "$(CURDIR):$(CURDIR)" -w "$(CURDIR)" -u $(shell id -u) digitalocean/fpm:latest git_commit := $(shell git log -1 --format='%H') git_tag := $(shell git describe --tags --abbrev=0) -ldflags = -X github.com/ddrp-org/ddrp/version.GitCommit=$(git_commit) -X github.com/ddrp-org/ddrp/version.GitTag=$(git_tag) +ldflags = -X fnd/version.GitCommit=$(git_commit) -X fnd/version.GitTag=$(git_tag) build_flags := -ldflags '$(ldflags)' all: ddrpd ddrpcli diff --git a/blob/hash.go b/blob/hash.go index 06559f6..3b196ae 100644 --- a/blob/hash.go +++ b/blob/hash.go @@ -3,7 +3,8 @@ package blob import ( "io" - "github.com/ddrp-org/ddrp/crypto" + "fnd/crypto" + "golang.org/x/crypto/blake2b" ) diff --git a/blob/merkle.go b/blob/merkle.go index e5112e6..ee4a814 100644 --- a/blob/merkle.go +++ b/blob/merkle.go @@ -7,7 +7,8 @@ import ( "math/bits" "strings" - "github.com/ddrp-org/ddrp/crypto" + "fnd/crypto" + "github.com/pkg/errors" ) diff --git a/blob/merkle_test.go b/blob/merkle_test.go index 5fba05a..f91b430 100644 --- a/blob/merkle_test.go +++ b/blob/merkle_test.go @@ -7,7 +7,8 @@ import ( "io" "testing" - "github.com/ddrp-org/ddrp/testutil/testfs" + "fnd/testutil/testfs" + "github.com/stretchr/testify/require" ) diff --git a/blob/seal.go b/blob/seal.go index d4eb2eb..2fc986f 100644 --- a/blob/seal.go +++ b/blob/seal.go @@ -1,8 +1,9 @@ package blob import ( - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" + "fnd/crypto" + "fnd/dwire" + "golang.org/x/crypto/blake2b" ) diff --git a/blob/seal_test.go b/blob/seal_test.go index 54be6e8..81bc970 100644 --- a/blob/seal_test.go +++ b/blob/seal_test.go @@ -4,8 +4,9 @@ import ( "encoding/hex" "testing" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/testutil/testcrypto" + "fnd/crypto" + "fnd/testutil/testcrypto" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/blob/store_test.go b/blob/store_test.go index 290bf86..c8601bb 100644 --- a/blob/store_test.go +++ b/blob/store_test.go @@ -2,13 +2,14 @@ package blob import ( "crypto/rand" - "github.com/ddrp-org/ddrp/testutil/testfs" - "github.com/stretchr/testify/require" - "golang.org/x/crypto/blake2b" + "fnd/testutil/testfs" "io" "os" "path" "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/blake2b" ) func TestBlobStore(t *testing.T) { diff --git a/blob/util_test.go b/blob/util_test.go index cb09d01..37248ba 100644 --- a/blob/util_test.go +++ b/blob/util_test.go @@ -1,10 +1,11 @@ package blob import ( - "github.com/ddrp-org/ddrp/testutil/testfs" - "github.com/stretchr/testify/require" + "fnd/testutil/testfs" "os" "testing" + + "github.com/stretchr/testify/require" ) func newTempBlobFile(t *testing.T) (*os.File, func()) { diff --git a/cli/homedir.go b/cli/homedir.go index efaaf5d..a0a5a07 100644 --- a/cli/homedir.go +++ b/cli/homedir.go @@ -2,7 +2,8 @@ package cli import ( "errors" - "github.com/ddrp-org/ddrp/config" + "fnd/config" + "github.com/spf13/cobra" ) diff --git a/cli/signer.go b/cli/signer.go index 0115ba8..22db766 100644 --- a/cli/signer.go +++ b/cli/signer.go @@ -1,8 +1,8 @@ package cli import ( - "github.com/ddrp-org/ddrp/config" - "github.com/ddrp-org/ddrp/crypto" + "fnd/config" + "fnd/crypto" ) func GetSigner(homeDir string) (crypto.Signer, error) { diff --git a/cmd/ddrpcli/cmd/blob/info.go b/cmd/ddrpcli/cmd/blob/info.go index 3133a87..ae64043 100644 --- a/cmd/ddrpcli/cmd/blob/info.go +++ b/cmd/ddrpcli/cmd/blob/info.go @@ -7,9 +7,10 @@ import ( "strconv" "strings" - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/rpc" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + "fnd/cli" + "fnd/rpc" + apiv1 "fnd/rpc/v1" + "github.com/mslipper/handshake/primitives" "github.com/olekukonko/tablewriter" "github.com/pkg/errors" diff --git a/cmd/ddrpcli/cmd/blob/list.go b/cmd/ddrpcli/cmd/blob/list.go index 13e00a9..92b4676 100644 --- a/cmd/ddrpcli/cmd/blob/list.go +++ b/cmd/ddrpcli/cmd/blob/list.go @@ -2,14 +2,15 @@ package blob import ( "encoding/json" - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/rpc" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" - "github.com/ddrp-org/ddrp/store" - "github.com/spf13/cobra" + "fnd/cli" + "fnd/rpc" + apiv1 "fnd/rpc/v1" + "fnd/store" "math" "os" "strconv" + + "github.com/spf13/cobra" ) var listCmd = &cobra.Command{ diff --git a/cmd/ddrpcli/cmd/blob/read.go b/cmd/ddrpcli/cmd/blob/read.go index 7f1d42b..164de6a 100644 --- a/cmd/ddrpcli/cmd/blob/read.go +++ b/cmd/ddrpcli/cmd/blob/read.go @@ -1,12 +1,13 @@ package blob import ( - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/rpc" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" - "github.com/spf13/cobra" + "fnd/cli" + "fnd/rpc" + apiv1 "fnd/rpc/v1" "io" "os" + + "github.com/spf13/cobra" ) var readCmd = &cobra.Command{ diff --git a/cmd/ddrpcli/cmd/blob/write.go b/cmd/ddrpcli/cmd/blob/write.go index 05e7df9..d03e095 100644 --- a/cmd/ddrpcli/cmd/blob/write.go +++ b/cmd/ddrpcli/cmd/blob/write.go @@ -7,10 +7,11 @@ import ( "io" "os" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/rpc" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + "fnd/blob" + "fnd/cli" + "fnd/rpc" + apiv1 "fnd/rpc/v1" + "github.com/mattn/go-isatty" "github.com/spf13/cobra" ) diff --git a/cmd/ddrpcli/cmd/identity.go b/cmd/ddrpcli/cmd/identity.go index a77675d..f76e26d 100644 --- a/cmd/ddrpcli/cmd/identity.go +++ b/cmd/ddrpcli/cmd/identity.go @@ -3,8 +3,9 @@ package cmd import ( "encoding/hex" "fmt" - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/config" + "fnd/cli" + "fnd/config" + "github.com/spf13/cobra" ) diff --git a/cmd/ddrpcli/cmd/init.go b/cmd/ddrpcli/cmd/init.go index 244069d..b039341 100644 --- a/cmd/ddrpcli/cmd/init.go +++ b/cmd/ddrpcli/cmd/init.go @@ -2,7 +2,8 @@ package cmd import ( "fmt" - "github.com/ddrp-org/ddrp/cli" + "fnd/cli" + "github.com/spf13/cobra" ) diff --git a/cmd/ddrpcli/cmd/net/add_peer.go b/cmd/ddrpcli/cmd/net/add_peer.go index 41d1833..265ad22 100644 --- a/cmd/ddrpcli/cmd/net/add_peer.go +++ b/cmd/ddrpcli/cmd/net/add_peer.go @@ -2,11 +2,12 @@ package net import ( "errors" - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/rpc" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" - "github.com/spf13/cobra" + "fnd/cli" + "fnd/rpc" + apiv1 "fnd/rpc/v1" "strings" + + "github.com/spf13/cobra" ) var ( diff --git a/cmd/ddrpcli/cmd/net/ban_peer.go b/cmd/ddrpcli/cmd/net/ban_peer.go index 99237a7..1262a6f 100644 --- a/cmd/ddrpcli/cmd/net/ban_peer.go +++ b/cmd/ddrpcli/cmd/net/ban_peer.go @@ -1,11 +1,12 @@ package net import ( - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/rpc" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" - "github.com/spf13/cobra" + "fnd/cli" + "fnd/rpc" + apiv1 "fnd/rpc/v1" "strconv" + + "github.com/spf13/cobra" ) var banPeerCmd = &cobra.Command{ diff --git a/cmd/ddrpcli/cmd/net/peer_info.go b/cmd/ddrpcli/cmd/net/peer_info.go index 27976c5..48882d0 100644 --- a/cmd/ddrpcli/cmd/net/peer_info.go +++ b/cmd/ddrpcli/cmd/net/peer_info.go @@ -3,12 +3,13 @@ package net import ( "encoding/json" "fmt" - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/rpc" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + "fnd/cli" + "fnd/rpc" + apiv1 "fnd/rpc/v1" + "os" + "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" - "os" ) type peerJSON struct { diff --git a/cmd/ddrpcli/cmd/net/status.go b/cmd/ddrpcli/cmd/net/status.go index add8f20..1d36f06 100644 --- a/cmd/ddrpcli/cmd/net/status.go +++ b/cmd/ddrpcli/cmd/net/status.go @@ -1,13 +1,14 @@ package net import ( - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/rpc" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" - "github.com/olekukonko/tablewriter" - "github.com/spf13/cobra" + "fnd/cli" + "fnd/rpc" + apiv1 "fnd/rpc/v1" "os" "strconv" + + "github.com/olekukonko/tablewriter" + "github.com/spf13/cobra" ) var statusCmd = &cobra.Command{ diff --git a/cmd/ddrpcli/cmd/net/unban_peer.go b/cmd/ddrpcli/cmd/net/unban_peer.go index 379d9b9..0ff9880 100644 --- a/cmd/ddrpcli/cmd/net/unban_peer.go +++ b/cmd/ddrpcli/cmd/net/unban_peer.go @@ -1,9 +1,10 @@ package net import ( - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/rpc" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + "fnd/cli" + "fnd/rpc" + apiv1 "fnd/rpc/v1" + "github.com/spf13/cobra" ) diff --git a/cmd/ddrpcli/cmd/root.go b/cmd/ddrpcli/cmd/root.go index 80bcb12..6e37434 100644 --- a/cmd/ddrpcli/cmd/root.go +++ b/cmd/ddrpcli/cmd/root.go @@ -2,12 +2,13 @@ package cmd import ( "fmt" - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/cmd/ddrpcli/cmd/blob" - "github.com/ddrp-org/ddrp/cmd/ddrpcli/cmd/net" - "github.com/ddrp-org/ddrp/cmd/ddrpcli/cmd/unsafe" - "github.com/spf13/cobra" + "fnd/cli" + "fnd/cmd/ddrpcli/cmd/blob" + "fnd/cmd/ddrpcli/cmd/net" + "fnd/cmd/ddrpcli/cmd/unsafe" "os" + + "github.com/spf13/cobra" ) var rootCmd = &cobra.Command{ diff --git a/cmd/ddrpcli/cmd/unsafe/reset_blobs.go b/cmd/ddrpcli/cmd/unsafe/reset_blobs.go index 60161b8..7906673 100644 --- a/cmd/ddrpcli/cmd/unsafe/reset_blobs.go +++ b/cmd/ddrpcli/cmd/unsafe/reset_blobs.go @@ -2,11 +2,12 @@ package unsafe import ( "fmt" - "github.com/ddrp-org/ddrp/config" - "github.com/ddrp-org/ddrp/store" + "fnd/config" + "fnd/store" + "os" + "github.com/pkg/errors" "github.com/spf13/cobra" - "os" ) var resetBlobsCmd = &cobra.Command{ diff --git a/cmd/ddrpcli/cmd/unsafe/reset_name_store.go b/cmd/ddrpcli/cmd/unsafe/reset_name_store.go index b274aa4..148858b 100644 --- a/cmd/ddrpcli/cmd/unsafe/reset_name_store.go +++ b/cmd/ddrpcli/cmd/unsafe/reset_name_store.go @@ -2,8 +2,9 @@ package unsafe import ( "fmt" - "github.com/ddrp-org/ddrp/config" - "github.com/ddrp-org/ddrp/store" + "fnd/config" + "fnd/store" + "github.com/pkg/errors" "github.com/spf13/cobra" ) diff --git a/cmd/ddrpcli/cmd/unsafe/reset_peer_store.go b/cmd/ddrpcli/cmd/unsafe/reset_peer_store.go index 5e0e1b1..3904add 100644 --- a/cmd/ddrpcli/cmd/unsafe/reset_peer_store.go +++ b/cmd/ddrpcli/cmd/unsafe/reset_peer_store.go @@ -2,8 +2,9 @@ package unsafe import ( "fmt" - "github.com/ddrp-org/ddrp/config" - "github.com/ddrp-org/ddrp/store" + "fnd/config" + "fnd/store" + "github.com/pkg/errors" "github.com/spf13/cobra" ) diff --git a/cmd/ddrpcli/cmd/version.go b/cmd/ddrpcli/cmd/version.go index b473e11..e7b3c8a 100644 --- a/cmd/ddrpcli/cmd/version.go +++ b/cmd/ddrpcli/cmd/version.go @@ -2,7 +2,8 @@ package cmd import ( "fmt" - "github.com/ddrp-org/ddrp/version" + "fnd/version" + "github.com/spf13/cobra" ) diff --git a/cmd/ddrpcli/main.go b/cmd/ddrpcli/main.go index 9b2c1c2..1d2575e 100644 --- a/cmd/ddrpcli/main.go +++ b/cmd/ddrpcli/main.go @@ -1,6 +1,6 @@ package main -import "github.com/ddrp-org/ddrp/cmd/ddrpcli/cmd" +import "fnd/cmd/ddrpcli/cmd" func main() { cmd.Execute() diff --git a/cmd/ddrpd/cmd/init.go b/cmd/ddrpd/cmd/init.go index cfa4882..1e5baa6 100644 --- a/cmd/ddrpd/cmd/init.go +++ b/cmd/ddrpd/cmd/init.go @@ -2,7 +2,8 @@ package cmd import ( "fmt" - "github.com/ddrp-org/ddrp/cli" + "fnd/cli" + "github.com/spf13/cobra" ) diff --git a/cmd/ddrpd/cmd/root.go b/cmd/ddrpd/cmd/root.go index 3f59b60..0bd88ad 100644 --- a/cmd/ddrpd/cmd/root.go +++ b/cmd/ddrpd/cmd/root.go @@ -2,11 +2,12 @@ package cmd import ( "fmt" - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/config" + "fnd/cli" + "fnd/config" + "os" + "github.com/pkg/errors" "github.com/spf13/cobra" - "os" ) var configuredHomeDir string diff --git a/cmd/ddrpd/cmd/start.go b/cmd/ddrpd/cmd/start.go index b81681e..929cabc 100644 --- a/cmd/ddrpd/cmd/start.go +++ b/cmd/ddrpd/cmd/start.go @@ -10,18 +10,19 @@ import ( "syscall" "time" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/cli" - "github.com/ddrp-org/ddrp/config" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/protocol" - "github.com/ddrp-org/ddrp/rpc" - "github.com/ddrp-org/ddrp/service" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/util" - "github.com/ddrp-org/ddrp/version" + "fnd/blob" + "fnd/cli" + "fnd/config" + "fnd/crypto" + "fnd/log" + "fnd/p2p" + "fnd/protocol" + "fnd/rpc" + "fnd/service" + "fnd/store" + "fnd/util" + "fnd/version" + "github.com/mslipper/handshake/client" "github.com/pkg/errors" "github.com/spf13/cobra" diff --git a/cmd/ddrpd/cmd/version.go b/cmd/ddrpd/cmd/version.go index ff36a7a..9b2493e 100644 --- a/cmd/ddrpd/cmd/version.go +++ b/cmd/ddrpd/cmd/version.go @@ -2,7 +2,8 @@ package cmd import ( "fmt" - "github.com/ddrp-org/ddrp/version" + "fnd/version" + "github.com/spf13/cobra" ) diff --git a/cmd/ddrpd/main.go b/cmd/ddrpd/main.go index 6222198..1f90db6 100644 --- a/cmd/ddrpd/main.go +++ b/cmd/ddrpd/main.go @@ -1,7 +1,7 @@ package main import ( - "github.com/ddrp-org/ddrp/cmd/ddrpd/cmd" + "fnd/cmd/ddrpd/cmd" ) func main() { diff --git a/config/default.go b/config/default.go index 4c8061d..b504a19 100644 --- a/config/default.go +++ b/config/default.go @@ -7,7 +7,8 @@ import ( "path" "text/template" - "github.com/ddrp-org/ddrp/log" + "fnd/log" + "github.com/pkg/errors" ) diff --git a/go.mod b/go.mod index 240849d..6f7e536 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/ddrp-org/ddrp +module fnd go 1.12 diff --git a/p2p/counting_reader_test.go b/p2p/counting_reader_test.go index 0e45a1f..7900e92 100644 --- a/p2p/counting_reader_test.go +++ b/p2p/counting_reader_test.go @@ -2,10 +2,11 @@ package p2p import ( "bytes" - "github.com/ddrp-org/ddrp/crypto" + "fnd/crypto" + "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "testing" ) func TestCountingReader(t *testing.T) { diff --git a/p2p/envelope_io.go b/p2p/envelope_io.go index 48428ae..25b20cd 100644 --- a/p2p/envelope_io.go +++ b/p2p/envelope_io.go @@ -3,8 +3,8 @@ package p2p import ( "context" "errors" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/wire" + "fnd/crypto" + "fnd/wire" "time" ) diff --git a/p2p/incoming_handshake.go b/p2p/incoming_handshake.go index 7b329d6..62ba806 100644 --- a/p2p/incoming_handshake.go +++ b/p2p/incoming_handshake.go @@ -2,8 +2,9 @@ package p2p import ( "context" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/wire" + "fnd/crypto" + "fnd/wire" + "github.com/pkg/errors" ) diff --git a/p2p/incoming_handshake_test.go b/p2p/incoming_handshake_test.go index a12570a..7288d64 100644 --- a/p2p/incoming_handshake_test.go +++ b/p2p/incoming_handshake_test.go @@ -6,8 +6,9 @@ import ( "testing" "time" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/wire" + "fnd/crypto" + "fnd/wire" + "github.com/stretchr/testify/require" ) diff --git a/p2p/listener.go b/p2p/listener.go index b4233a4..ee5edde 100644 --- a/p2p/listener.go +++ b/p2p/listener.go @@ -2,11 +2,12 @@ package p2p import ( "fmt" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/service" - "github.com/pkg/errors" + "fnd/log" + "fnd/service" "net" "sync" + + "github.com/pkg/errors" ) type Listener struct { diff --git a/p2p/outgoing_handshake.go b/p2p/outgoing_handshake.go index eebf325..5502193 100644 --- a/p2p/outgoing_handshake.go +++ b/p2p/outgoing_handshake.go @@ -2,11 +2,12 @@ package p2p import ( "context" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/version" - "github.com/ddrp-org/ddrp/wire" - "github.com/pkg/errors" + "fnd/crypto" + "fnd/version" + "fnd/wire" "time" + + "github.com/pkg/errors" ) var ( diff --git a/p2p/outgoing_handshake_test.go b/p2p/outgoing_handshake_test.go index 29910e0..7377509 100644 --- a/p2p/outgoing_handshake_test.go +++ b/p2p/outgoing_handshake_test.go @@ -4,15 +4,16 @@ import ( "context" "errors" "fmt" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/testutil" - "github.com/ddrp-org/ddrp/testutil/testcrypto" - "github.com/ddrp-org/ddrp/wire" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "fnd/crypto" + "fnd/testutil" + "fnd/testutil/testcrypto" + "fnd/wire" "net" "testing" "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type handshakeSetup struct { diff --git a/p2p/peer.go b/p2p/peer.go index 4cb027b..51ddf2b 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -4,14 +4,15 @@ import ( "bufio" "context" "errors" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/wire" - "golang.org/x/time/rate" + "fnd/log" + "fnd/wire" "io" "math" "net" "sync" "time" + + "golang.org/x/time/rate" ) var ( diff --git a/p2p/peer_manager.go b/p2p/peer_manager.go index 44cdec0..7119a28 100644 --- a/p2p/peer_manager.go +++ b/p2p/peer_manager.go @@ -3,17 +3,18 @@ package p2p import ( "context" "fmt" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/service" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/util" - "github.com/pkg/errors" - "github.com/syndtr/goleveldb/leveldb" - "golang.org/x/sync/semaphore" + "fnd/crypto" + "fnd/log" + "fnd/service" + "fnd/store" + "fnd/util" "net" "sync" "time" + + "github.com/pkg/errors" + "github.com/syndtr/goleveldb/leveldb" + "golang.org/x/sync/semaphore" ) const ( diff --git a/p2p/peer_muxer.go b/p2p/peer_muxer.go index 1afa96b..d5ac4bb 100644 --- a/p2p/peer_muxer.go +++ b/p2p/peer_muxer.go @@ -2,13 +2,14 @@ package p2p import ( "fmt" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/util" - "github.com/ddrp-org/ddrp/wire" - "github.com/pkg/errors" + "fnd/crypto" + "fnd/log" + "fnd/util" + "fnd/wire" "sync" "sync/atomic" + + "github.com/pkg/errors" ) const ( diff --git a/p2p/peer_test.go b/p2p/peer_test.go index a321327..2730a02 100644 --- a/p2p/peer_test.go +++ b/p2p/peer_test.go @@ -4,13 +4,14 @@ import ( "bytes" "context" "errors" - "github.com/ddrp-org/ddrp/testutil/testcrypto" - "github.com/ddrp-org/ddrp/wire" - "github.com/stretchr/testify/require" + "fnd/testutil/testcrypto" + "fnd/wire" "io" "sync" "testing" "time" + + "github.com/stretchr/testify/require" ) type blockingReadWriter struct { diff --git a/p2p/seeds.go b/p2p/seeds.go index 6d7eea0..1f897b7 100644 --- a/p2p/seeds.go +++ b/p2p/seeds.go @@ -1,10 +1,11 @@ package p2p import ( - "github.com/ddrp-org/ddrp/crypto" - "github.com/pkg/errors" + "fnd/crypto" "net" "strings" + + "github.com/pkg/errors" ) type SeedPeer struct { diff --git a/protocol/epoch_test.go b/protocol/epoch_test.go index 61aacb4..4ed07a1 100644 --- a/protocol/epoch_test.go +++ b/protocol/epoch_test.go @@ -5,11 +5,12 @@ import ( "testing" "time" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/testutil/mockapp" - "github.com/ddrp-org/ddrp/util" + "fnd/blob" + "fnd/crypto" + "fnd/store" + "fnd/testutil/mockapp" + "fnd/util" + "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" ) diff --git a/protocol/heartbeater.go b/protocol/heartbeater.go index 046613f..169e438 100644 --- a/protocol/heartbeater.go +++ b/protocol/heartbeater.go @@ -3,14 +3,15 @@ package protocol import ( "bytes" "encoding/json" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/service" - "github.com/ddrp-org/ddrp/version" - "github.com/pkg/errors" + "fnd/crypto" + "fnd/log" + "fnd/service" + "fnd/version" "net/http" "sync" "time" + + "github.com/pkg/errors" ) const ( diff --git a/protocol/heartbeater_test.go b/protocol/heartbeater_test.go index f44ceb1..288eb95 100644 --- a/protocol/heartbeater_test.go +++ b/protocol/heartbeater_test.go @@ -2,15 +2,16 @@ package protocol import ( "encoding/json" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/testutil/testcrypto" - "github.com/stretchr/testify/require" + "fnd/crypto" + "fnd/testutil/testcrypto" "io/ioutil" "net/http" "net/http/httptest" "sync" "testing" "time" + + "github.com/stretchr/testify/require" ) func TestHeartbeater_SendHeartbeats(t *testing.T) { diff --git a/protocol/moderation.go b/protocol/moderation.go index 3d14ac0..4f4210b 100644 --- a/protocol/moderation.go +++ b/protocol/moderation.go @@ -1,12 +1,13 @@ package protocol import ( - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/store" + "fnd/blob" + "fnd/log" + "fnd/store" + "time" + "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" - "time" ) const ( diff --git a/protocol/moderation_test.go b/protocol/moderation_test.go index 293143e..7dbfa63 100644 --- a/protocol/moderation_test.go +++ b/protocol/moderation_test.go @@ -1,11 +1,12 @@ package protocol import ( - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/testutil/testfs" - "github.com/stretchr/testify/require" + "fnd/blob" + "fnd/store" + "fnd/testutil/testfs" "testing" + + "github.com/stretchr/testify/require" ) // TODO: refactor to use the httptest server diff --git a/protocol/name_importer.go b/protocol/name_importer.go index 75e63a7..0f601a7 100644 --- a/protocol/name_importer.go +++ b/protocol/name_importer.go @@ -4,19 +4,20 @@ import ( "bytes" "encoding/hex" "fmt" + "fnd/config" + "fnd/log" + "fnd/store" + "strings" + "sync" + "sync/atomic" + "time" + "github.com/btcsuite/btcd/btcec" - "github.com/ddrp-org/ddrp/config" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/store" "github.com/mslipper/handshake/client" "github.com/mslipper/handshake/dns" "github.com/mslipper/handshake/primitives" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" - "strings" - "sync" - "sync/atomic" - "time" ) type NameImporter struct { diff --git a/protocol/name_importer_test.go b/protocol/name_importer_test.go index e0174e5..ac43f63 100644 --- a/protocol/name_importer_test.go +++ b/protocol/name_importer_test.go @@ -2,9 +2,10 @@ package protocol import ( "fmt" - "github.com/ddrp-org/ddrp/testutil/testcrypto" - "github.com/stretchr/testify/require" + "fnd/testutil/testcrypto" "testing" + + "github.com/stretchr/testify/require" ) func TestParseDDRPKeyRecord(t *testing.T) { diff --git a/protocol/name_syncer.go b/protocol/name_syncer.go index 8891ab2..e1c2e55 100644 --- a/protocol/name_syncer.go +++ b/protocol/name_syncer.go @@ -5,13 +5,14 @@ import ( "sync/atomic" "time" - "github.com/ddrp-org/ddrp/config" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/util" - "github.com/ddrp-org/ddrp/wire" + "fnd/config" + "fnd/crypto" + "fnd/log" + "fnd/p2p" + "fnd/store" + "fnd/util" + "fnd/wire" + "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" ) diff --git a/protocol/peer_exchanger.go b/protocol/peer_exchanger.go index b1638e4..9a1cdf1 100644 --- a/protocol/peer_exchanger.go +++ b/protocol/peer_exchanger.go @@ -1,19 +1,20 @@ package protocol import ( - "github.com/ddrp-org/ddrp/config" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/util" - "github.com/ddrp-org/ddrp/wire" - "github.com/syndtr/goleveldb/leveldb" + "fnd/config" + "fnd/crypto" + "fnd/log" + "fnd/p2p" + "fnd/store" + "fnd/util" + "fnd/wire" "math" "math/rand" "net" "sync" "time" + + "github.com/syndtr/goleveldb/leveldb" ) const ( diff --git a/protocol/peer_set.go b/protocol/peer_set.go index 60a942b..6fe15af 100644 --- a/protocol/peer_set.go +++ b/protocol/peer_set.go @@ -1,7 +1,7 @@ package protocol import ( - "github.com/ddrp-org/ddrp/crypto" + "fnd/crypto" "sync" ) diff --git a/protocol/peer_set_test.go b/protocol/peer_set_test.go index 3f1d583..1b4e0b7 100644 --- a/protocol/peer_set_test.go +++ b/protocol/peer_set_test.go @@ -1,9 +1,10 @@ package protocol import ( - "github.com/ddrp-org/ddrp/crypto" - "github.com/stretchr/testify/require" + "fnd/crypto" "testing" + + "github.com/stretchr/testify/require" ) func TestPeerSet(t *testing.T) { diff --git a/protocol/pinger.go b/protocol/pinger.go index 1465d35..62dab89 100644 --- a/protocol/pinger.go +++ b/protocol/pinger.go @@ -3,10 +3,10 @@ package protocol import ( "context" "errors" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/wire" + "fnd/crypto" + "fnd/log" + "fnd/p2p" + "fnd/wire" "sync" "sync/atomic" "time" diff --git a/protocol/pinger_test.go b/protocol/pinger_test.go index cec8e43..bf9ea25 100644 --- a/protocol/pinger_test.go +++ b/protocol/pinger_test.go @@ -2,16 +2,17 @@ package protocol import ( "context" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/testutil" - "github.com/ddrp-org/ddrp/testutil/testcrypto" - "github.com/ddrp-org/ddrp/wire" - "github.com/stretchr/testify/require" + "fnd/crypto" + "fnd/p2p" + "fnd/testutil" + "fnd/testutil/testcrypto" + "fnd/wire" "io" "io/ioutil" "testing" "time" + + "github.com/stretchr/testify/require" ) func TestPinger_SendsPingsOnInterval(t *testing.T) { diff --git a/protocol/sector_server.go b/protocol/sector_server.go index d78bd90..e8c0a94 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -4,14 +4,15 @@ import ( "fmt" "time" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/config" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/util" - "github.com/ddrp-org/ddrp/wire" + "fnd/blob" + "fnd/config" + "fnd/crypto" + "fnd/log" + "fnd/p2p" + "fnd/store" + "fnd/util" + "fnd/wire" + "github.com/syndtr/goleveldb/leveldb" ) diff --git a/protocol/syncer.go b/protocol/syncer.go index b4b51da..71ee893 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -3,11 +3,12 @@ package protocol import ( "time" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/wire" + "fnd/blob" + "fnd/crypto" + "fnd/log" + "fnd/p2p" + "fnd/wire" + "github.com/pkg/errors" ) diff --git a/protocol/syncer_test.go b/protocol/syncer_test.go index 2a8e3bd..76dda72 100644 --- a/protocol/syncer_test.go +++ b/protocol/syncer_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/testutil/mockapp" - "github.com/ddrp-org/ddrp/util" + "fnd/blob" + "fnd/crypto" + "fnd/testutil/mockapp" + "fnd/util" "github.com/stretchr/testify/require" ) diff --git a/protocol/transaction_mock_test.go b/protocol/transaction_mock_test.go index cf91160..1f13c49 100644 --- a/protocol/transaction_mock_test.go +++ b/protocol/transaction_mock_test.go @@ -1,7 +1,8 @@ package protocol import ( - "github.com/ddrp-org/ddrp/blob" + "fnd/blob" + "github.com/stretchr/testify/mock" ) diff --git a/protocol/update_queue.go b/protocol/update_queue.go index 60559e3..e2bf695 100644 --- a/protocol/update_queue.go +++ b/protocol/update_queue.go @@ -5,14 +5,15 @@ import ( "sync/atomic" "time" + "fnd/blob" + "fnd/config" + "fnd/crypto" + "fnd/log" + "fnd/p2p" + "fnd/store" + "fnd/wire" + "github.com/btcsuite/btcd/btcec" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/config" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/wire" "github.com/mslipper/handshake/primitives" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" diff --git a/protocol/update_queue_test.go b/protocol/update_queue_test.go index 31d0906..f3a6e42 100644 --- a/protocol/update_queue_test.go +++ b/protocol/update_queue_test.go @@ -4,13 +4,14 @@ import ( "testing" "time" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/testutil" - "github.com/ddrp-org/ddrp/testutil/testcrypto" - "github.com/ddrp-org/ddrp/wire" + "fnd/blob" + "fnd/crypto" + "fnd/p2p" + "fnd/store" + "fnd/testutil" + "fnd/testutil/testcrypto" + "fnd/wire" + "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" ) @@ -20,22 +21,22 @@ func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { defer done() identicalHeader := signHeader(t, &store.Header{ - Name: "identical", - EpochHeight: uint16(0), - SectorSize: uint16(1), - EpochStartAt: time.Unix(1, 0), + Name: "identical", + EpochHeight: uint16(0), + SectorSize: uint16(1), + EpochStartAt: time.Unix(1, 0), }) throttledHeader := signHeader(t, &store.Header{ - Name: "throttled", - EpochHeight: uint16(0), - SectorSize: uint16(1), - EpochStartAt: time.Now(), + Name: "throttled", + EpochHeight: uint16(0), + SectorSize: uint16(1), + EpochStartAt: time.Now(), }) staleHeader := signHeader(t, &store.Header{ - Name: "stale", - EpochHeight: uint16(0), - SectorSize: uint16(100), - EpochStartAt: time.Unix(1, 0), + Name: "stale", + EpochHeight: uint16(0), + SectorSize: uint16(100), + EpochStartAt: time.Unix(1, 0), }) headers := []*store.Header{ @@ -144,10 +145,10 @@ func TestUpdateQueue_Enqueue_InvalidAfterEnqueue(t *testing.T) { defer done() header := signHeader(t, &store.Header{ - Name: "somename", - EpochHeight: uint16(0), - SectorSize: uint16(100), - EpochStartAt: time.Unix(1, 0), + Name: "somename", + EpochHeight: uint16(0), + SectorSize: uint16(100), + EpochStartAt: time.Unix(1, 0), }) _, pub := testcrypto.FixedKey(t) @@ -188,10 +189,10 @@ func TestUpdateQueue_EnqueueDequeue(t *testing.T) { defer done() header := signHeader(t, &store.Header{ - Name: "somename", - EpochHeight: uint16(0), - SectorSize: uint16(100), - EpochStartAt: time.Unix(1, 0), + Name: "somename", + EpochHeight: uint16(0), + SectorSize: uint16(100), + EpochStartAt: time.Unix(1, 0), }) _, pub := testcrypto.FixedKey(t) diff --git a/protocol/update_server.go b/protocol/update_server.go index 698027e..4f22df4 100644 --- a/protocol/update_server.go +++ b/protocol/update_server.go @@ -1,12 +1,13 @@ package protocol import ( - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/util" - "github.com/ddrp-org/ddrp/wire" + "fnd/crypto" + "fnd/log" + "fnd/p2p" + "fnd/store" + "fnd/util" + "fnd/wire" + "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" ) diff --git a/protocol/update_server_test.go b/protocol/update_server_test.go index e5c981e..955069e 100644 --- a/protocol/update_server_test.go +++ b/protocol/update_server_test.go @@ -4,14 +4,15 @@ import ( "io" "testing" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/testutil" - "github.com/ddrp-org/ddrp/testutil/testcrypto" - "github.com/ddrp-org/ddrp/util" - "github.com/ddrp-org/ddrp/wire" + "fnd/blob" + "fnd/crypto" + "fnd/p2p" + "fnd/store" + "fnd/testutil" + "fnd/testutil/testcrypto" + "fnd/util" + "fnd/wire" + "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" ) @@ -118,11 +119,11 @@ func TestUpdateServer(t *testing.T) { require.NoError(t, err) require.NoError(t, store.WithTx(db, func(tx *leveldb.Transaction) error { return store.SetHeaderTx(tx, &store.Header{ - Name: "valid", - EpochHeight: epochHeight, - SectorSize: sectorSize, - SectorTipHash: tree.Root(), - Signature: sig, + Name: "valid", + EpochHeight: epochHeight, + SectorSize: sectorSize, + SectorTipHash: tree.Root(), + Signature: sig, }, blob.ZeroSectorHashes) })) }, diff --git a/protocol/updater.go b/protocol/updater.go index 4c0cf1e..c375a03 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -4,14 +4,15 @@ import ( "sync" "time" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/config" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/util" - "github.com/ddrp-org/ddrp/wire" + "fnd/blob" + "fnd/config" + "fnd/crypto" + "fnd/log" + "fnd/p2p" + "fnd/store" + "fnd/util" + "fnd/wire" + "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" ) diff --git a/protocol/updater_test.go b/protocol/updater_test.go index 729700d..c3196b1 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -6,13 +6,14 @@ import ( "testing" "time" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/testutil/mockapp" - "github.com/ddrp-org/ddrp/util" - "github.com/ddrp-org/ddrp/wire" + "fnd/blob" + "fnd/crypto" + "fnd/p2p" + "fnd/store" + "fnd/testutil/mockapp" + "fnd/util" + "fnd/wire" + "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" ) diff --git a/protocol/util_test.go b/protocol/util_test.go index ec971a0..e201ffa 100644 --- a/protocol/util_test.go +++ b/protocol/util_test.go @@ -2,12 +2,13 @@ package protocol import ( "fmt" - "github.com/ddrp-org/ddrp/store" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" + "fnd/store" "io/ioutil" "os" "testing" + + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" ) func setupDB(t *testing.T) (*leveldb.DB, func()) { diff --git a/rpc/blob.go b/rpc/blob.go index d6e4bb6..3bebadb 100644 --- a/rpc/blob.go +++ b/rpc/blob.go @@ -5,10 +5,11 @@ import ( "io" "time" + "fnd/crypto" + apiv1 "fnd/rpc/v1" + "fnd/store" + "github.com/btcsuite/btcd/btcec" - "github.com/ddrp-org/ddrp/crypto" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" - "github.com/ddrp-org/ddrp/store" "github.com/pkg/errors" ) diff --git a/rpc/blob_reader.go b/rpc/blob_reader.go index dc52c68..f9a550f 100644 --- a/rpc/blob_reader.go +++ b/rpc/blob_reader.go @@ -3,8 +3,8 @@ package rpc import ( "context" "errors" - "github.com/ddrp-org/ddrp/blob" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + "fnd/blob" + apiv1 "fnd/rpc/v1" "io" ) diff --git a/rpc/blob_writer.go b/rpc/blob_writer.go index 068ab0b..3327ed8 100644 --- a/rpc/blob_writer.go +++ b/rpc/blob_writer.go @@ -4,9 +4,10 @@ import ( "context" "time" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + "fnd/blob" + "fnd/crypto" + apiv1 "fnd/rpc/v1" + "github.com/pkg/errors" ) diff --git a/rpc/net.go b/rpc/net.go index 9aa2ad6..b7fb28e 100644 --- a/rpc/net.go +++ b/rpc/net.go @@ -3,7 +3,7 @@ package rpc import ( "context" "encoding/hex" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" + apiv1 "fnd/rpc/v1" "io" ) diff --git a/rpc/server.go b/rpc/server.go index ebc5989..8f6545f 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -7,15 +7,16 @@ import ( "sync/atomic" "time" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/log" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/protocol" - apiv1 "github.com/ddrp-org/ddrp/rpc/v1" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/util" - "github.com/ddrp-org/ddrp/wire" + "fnd/blob" + "fnd/crypto" + "fnd/log" + "fnd/p2p" + "fnd/protocol" + apiv1 "fnd/rpc/v1" + "fnd/store" + "fnd/util" + "fnd/wire" + "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" "google.golang.org/grpc" diff --git a/store/headers.go b/store/headers.go index a93f79d..4e02d81 100644 --- a/store/headers.go +++ b/store/headers.go @@ -7,9 +7,10 @@ import ( "sync" "time" + "fnd/blob" + "fnd/crypto" + "github.com/btcsuite/btcd/btcec" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/iterator" diff --git a/store/headers_test.go b/store/headers_test.go index b95d649..d366617 100644 --- a/store/headers_test.go +++ b/store/headers_test.go @@ -5,8 +5,9 @@ import ( "testing" "time" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" + "fnd/blob" + "fnd/crypto" + "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" ) @@ -23,13 +24,13 @@ func TestHeaders_GetSet(t *testing.T) { require.NoError(t, err) expHeader := &Header{ - Name: "foo", - EpochHeight: uint16(0), - SectorSize: uint16(0), - SectorTipHash: crypto.Rand32(), - Signature: sig, - ReservedRoot: crypto.Rand32(), - EpochStartAt: time.Unix(11, 0), + Name: "foo", + EpochHeight: uint16(0), + SectorSize: uint16(0), + SectorTipHash: crypto.Rand32(), + Signature: sig, + ReservedRoot: crypto.Rand32(), + EpochStartAt: time.Unix(11, 0), } _, err = GetHeader(db, "foo") require.Error(t, err) diff --git a/store/naming_test.go b/store/naming_test.go index c3afd6f..9ef0907 100644 --- a/store/naming_test.go +++ b/store/naming_test.go @@ -1,10 +1,11 @@ package store import ( - "github.com/ddrp-org/ddrp/testutil/testcrypto" + "fnd/testutil/testcrypto" + "testing" + "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" - "testing" ) func TestNaming_Meta(t *testing.T) { diff --git a/store/peers.go b/store/peers.go index f0f693e..2f17cf5 100644 --- a/store/peers.go +++ b/store/peers.go @@ -4,13 +4,14 @@ import ( "encoding/binary" "encoding/hex" "encoding/json" - "github.com/ddrp-org/ddrp/crypto" + "fnd/crypto" + "math" + "time" + "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/iterator" "github.com/syndtr/goleveldb/leveldb/util" - "math" - "time" ) type Peer struct { diff --git a/store/peers_test.go b/store/peers_test.go index a80c758..6c3141e 100644 --- a/store/peers_test.go +++ b/store/peers_test.go @@ -1,11 +1,12 @@ package store import ( - "github.com/ddrp-org/ddrp/crypto" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" + "fnd/crypto" "testing" "time" + + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" ) func TestPeers(t *testing.T) { diff --git a/store/store.go b/store/store.go index 9ceb1a2..0b7e566 100644 --- a/store/store.go +++ b/store/store.go @@ -1,7 +1,8 @@ package store import ( - "github.com/ddrp-org/ddrp/log" + "fnd/log" + "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" ) diff --git a/testutil/mockapp/peer.go b/testutil/mockapp/peer.go index 24e9c68..a9c25e2 100644 --- a/testutil/mockapp/peer.go +++ b/testutil/mockapp/peer.go @@ -1,12 +1,13 @@ package mockapp import ( - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/p2p" - "github.com/ddrp-org/ddrp/testutil" - "github.com/ddrp-org/ddrp/testutil/testcrypto" - "github.com/stretchr/testify/require" + "fnd/crypto" + "fnd/p2p" + "fnd/testutil" + "fnd/testutil/testcrypto" "testing" + + "github.com/stretchr/testify/require" ) type TestPeers struct { diff --git a/testutil/mockapp/storage.go b/testutil/mockapp/storage.go index c135e50..4edc7b6 100644 --- a/testutil/mockapp/storage.go +++ b/testutil/mockapp/storage.go @@ -6,11 +6,12 @@ import ( "testing" "time" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/store" - "github.com/ddrp-org/ddrp/testutil/testfs" - "github.com/ddrp-org/ddrp/wire" + "fnd/blob" + "fnd/crypto" + "fnd/store" + "fnd/testutil/testfs" + "fnd/wire" + "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" ) diff --git a/testutil/net.go b/testutil/net.go index faa5a66..6e551db 100644 --- a/testutil/net.go +++ b/testutil/net.go @@ -1,12 +1,13 @@ package testutil import ( - "github.com/ddrp-org/ddrp/testutil/testcrypto" - "github.com/ddrp-org/ddrp/wire" - "github.com/stretchr/testify/require" + "fnd/testutil/testcrypto" + "fnd/wire" "io" "net" "testing" + + "github.com/stretchr/testify/require" ) const ( diff --git a/testutil/testcrypto/crypto.go b/testutil/testcrypto/crypto.go index 237dbb2..9cab2e4 100644 --- a/testutil/testcrypto/crypto.go +++ b/testutil/testcrypto/crypto.go @@ -3,10 +3,11 @@ package testcrypto import ( "crypto/rand" "encoding/hex" + "fnd/crypto" + "testing" + "github.com/btcsuite/btcd/btcec" - "github.com/ddrp-org/ddrp/crypto" "github.com/stretchr/testify/require" - "testing" ) func RandKey() (*btcec.PrivateKey, *btcec.PublicKey) { diff --git a/wire/blob_req.go b/wire/blob_req.go index 14548b1..2c545af 100644 --- a/wire/blob_req.go +++ b/wire/blob_req.go @@ -3,8 +3,8 @@ package wire import ( "io" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" + "fnd/crypto" + "fnd/dwire" ) type BlobReq struct { diff --git a/wire/blob_res.go b/wire/blob_res.go index 78ffead..b4d48bb 100644 --- a/wire/blob_res.go +++ b/wire/blob_res.go @@ -3,9 +3,9 @@ package wire import ( "io" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" + "fnd/blob" + "fnd/crypto" + "fnd/dwire" ) type BlobRes struct { diff --git a/wire/envelope.go b/wire/envelope.go index cc8e392..6ffba2a 100644 --- a/wire/envelope.go +++ b/wire/envelope.go @@ -6,8 +6,8 @@ import ( "io" "time" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" + "fnd/crypto" + "fnd/dwire" ) type Envelope struct { diff --git a/wire/hash_cacher.go b/wire/hash_cacher.go index 067d0f4..2007e40 100644 --- a/wire/hash_cacher.go +++ b/wire/hash_cacher.go @@ -4,8 +4,8 @@ import ( "bytes" "sync" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" + "fnd/crypto" + "fnd/dwire" ) var hashCacherBufPool = sync.Pool{ diff --git a/wire/hash_cacher_test.go b/wire/hash_cacher_test.go index 7d88e71..2566daa 100644 --- a/wire/hash_cacher_test.go +++ b/wire/hash_cacher_test.go @@ -6,8 +6,9 @@ import ( "sync" "testing" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" + "fnd/crypto" + "fnd/dwire" + "github.com/stretchr/testify/require" ) diff --git a/wire/hello.go b/wire/hello.go index 24aed01..e5f4fe0 100644 --- a/wire/hello.go +++ b/wire/hello.go @@ -3,9 +3,10 @@ package wire import ( "io" + "fnd/crypto" + "fnd/dwire" + "github.com/btcsuite/btcd/btcec" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" ) type Hello struct { diff --git a/wire/hello_ack.go b/wire/hello_ack.go index 029caf2..3fff7b0 100644 --- a/wire/hello_ack.go +++ b/wire/hello_ack.go @@ -3,8 +3,8 @@ package wire import ( "io" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" + "fnd/crypto" + "fnd/dwire" ) type HelloAck struct { diff --git a/wire/hello_test.go b/wire/hello_test.go index 9ebf100..d4e2a13 100644 --- a/wire/hello_test.go +++ b/wire/hello_test.go @@ -1,7 +1,7 @@ package wire import ( - "github.com/ddrp-org/ddrp/testutil/testcrypto" + "fnd/testutil/testcrypto" "testing" ) diff --git a/wire/message.go b/wire/message.go index f3454a9..32914f6 100644 --- a/wire/message.go +++ b/wire/message.go @@ -3,8 +3,8 @@ package wire import ( "io" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" + "fnd/crypto" + "fnd/dwire" ) type Message interface { diff --git a/wire/nil_update.go b/wire/nil_update.go index 95a907c..702c2e8 100644 --- a/wire/nil_update.go +++ b/wire/nil_update.go @@ -3,8 +3,8 @@ package wire import ( "io" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" + "fnd/crypto" + "fnd/dwire" ) type NilUpdate struct { diff --git a/wire/peer_req.go b/wire/peer_req.go index 77e3e1c..c76ae45 100644 --- a/wire/peer_req.go +++ b/wire/peer_req.go @@ -1,7 +1,7 @@ package wire import ( - "github.com/ddrp-org/ddrp/crypto" + "fnd/crypto" "io" ) diff --git a/wire/peer_res.go b/wire/peer_res.go index df61cd6..994fbc9 100644 --- a/wire/peer_res.go +++ b/wire/peer_res.go @@ -5,8 +5,8 @@ import ( "io" "net" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" + "fnd/crypto" + "fnd/dwire" ) type Peer struct { diff --git a/wire/ping.go b/wire/ping.go index f5476f7..036c2c2 100644 --- a/wire/ping.go +++ b/wire/ping.go @@ -1,7 +1,7 @@ package wire import ( - "github.com/ddrp-org/ddrp/crypto" + "fnd/crypto" "io" ) diff --git a/wire/update.go b/wire/update.go index f512bea..bb8960c 100644 --- a/wire/update.go +++ b/wire/update.go @@ -3,8 +3,8 @@ package wire import ( "io" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" + "fnd/crypto" + "fnd/dwire" ) type Update struct { diff --git a/wire/update_req.go b/wire/update_req.go index 0f1d565..fa13aaf 100644 --- a/wire/update_req.go +++ b/wire/update_req.go @@ -3,8 +3,8 @@ package wire import ( "io" - "github.com/ddrp-org/ddrp/crypto" - "github.com/ddrp-org/ddrp/dwire" + "fnd/crypto" + "fnd/dwire" ) type UpdateReq struct { diff --git a/wire/util_test.go b/wire/util_test.go index 2bede66..70f3288 100644 --- a/wire/util_test.go +++ b/wire/util_test.go @@ -6,8 +6,9 @@ import ( "io/ioutil" "testing" - "github.com/ddrp-org/ddrp/blob" - "github.com/ddrp-org/ddrp/crypto" + "fnd/blob" + "fnd/crypto" + "github.com/stretchr/testify/require" ) From 0afbc257809fa6a55eaba70fe737d1e3f1eea272 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sun, 17 Jan 2021 11:05:19 +0530 Subject: [PATCH 03/71] rename ddrpd -> fnd --- Makefile | 50 +-- cmd/{ddrpcli => fnd-cli}/cmd/blob/blob.go | 2 +- cmd/{ddrpcli => fnd-cli}/cmd/blob/info.go | 4 +- cmd/{ddrpcli => fnd-cli}/cmd/blob/list.go | 2 +- cmd/{ddrpcli => fnd-cli}/cmd/blob/read.go | 2 +- cmd/{ddrpcli => fnd-cli}/cmd/blob/write.go | 2 +- cmd/{ddrpcli => fnd-cli}/cmd/identity.go | 0 cmd/{ddrpcli => fnd-cli}/cmd/init.go | 2 +- cmd/{ddrpcli => fnd-cli}/cmd/net/add_peer.go | 2 +- cmd/{ddrpcli => fnd-cli}/cmd/net/ban_peer.go | 2 +- cmd/{ddrpcli => fnd-cli}/cmd/net/net.go | 2 +- cmd/{ddrpcli => fnd-cli}/cmd/net/peer_info.go | 4 +- cmd/{ddrpcli => fnd-cli}/cmd/net/status.go | 2 +- .../cmd/net/unban_peer.go | 4 +- cmd/{ddrpcli => fnd-cli}/cmd/root.go | 12 +- .../cmd/unsafe/reset_blobs.go | 6 +- .../cmd/unsafe/reset_name_store.go | 6 +- .../cmd/unsafe/reset_peer_store.go | 6 +- cmd/{ddrpcli => fnd-cli}/cmd/unsafe/unsafe.go | 2 +- cmd/{ddrpcli => fnd-cli}/cmd/version.go | 2 +- cmd/{ddrpcli => fnd-cli}/main.go | 2 +- cmd/{ddrpd => fnd}/cmd/init.go | 4 +- cmd/{ddrpd => fnd}/cmd/root.go | 6 +- cmd/{ddrpd => fnd}/cmd/start.go | 0 cmd/{ddrpd => fnd}/cmd/version.go | 2 +- cmd/{ddrpd => fnd}/main.go | 2 +- config/default.go | 50 +-- config/home.go | 5 +- go.sum | 7 + packaging/scripts/after_install.sh | 12 +- packaging/scripts/after_remove.sh | 4 +- protocol/heartbeater_test.go | 2 +- rpc/blob.go | 8 +- rpc/blob_reader.go | 4 +- rpc/blob_writer.go | 4 +- rpc/net.go | 20 +- rpc/server.go | 6 +- rpc/v1/api.pb.go | 361 +++++++++--------- rpc/v1/api.proto | 2 +- scripts/release-public.sh | 8 +- version/version.go | 2 +- 41 files changed, 318 insertions(+), 307 deletions(-) rename cmd/{ddrpcli => fnd-cli}/cmd/blob/blob.go (76%) rename cmd/{ddrpcli => fnd-cli}/cmd/blob/info.go (93%) rename cmd/{ddrpcli => fnd-cli}/cmd/blob/list.go (95%) rename cmd/{ddrpcli => fnd-cli}/cmd/blob/read.go (88%) rename cmd/{ddrpcli => fnd-cli}/cmd/blob/write.go (96%) rename cmd/{ddrpcli => fnd-cli}/cmd/identity.go (100%) rename cmd/{ddrpcli => fnd-cli}/cmd/init.go (85%) rename cmd/{ddrpcli => fnd-cli}/cmd/net/add_peer.go (95%) rename cmd/{ddrpcli => fnd-cli}/cmd/net/ban_peer.go (93%) rename cmd/{ddrpcli => fnd-cli}/cmd/net/net.go (73%) rename cmd/{ddrpcli => fnd-cli}/cmd/net/peer_info.go (94%) rename cmd/{ddrpcli => fnd-cli}/cmd/net/status.go (95%) rename cmd/{ddrpcli => fnd-cli}/cmd/net/unban_peer.go (82%) rename cmd/{ddrpcli => fnd-cli}/cmd/root.go (72%) rename cmd/{ddrpcli => fnd-cli}/cmd/unsafe/reset_blobs.go (81%) rename cmd/{ddrpcli => fnd-cli}/cmd/unsafe/reset_name_store.go (76%) rename cmd/{ddrpcli => fnd-cli}/cmd/unsafe/reset_peer_store.go (76%) rename cmd/{ddrpcli => fnd-cli}/cmd/unsafe/unsafe.go (92%) rename cmd/{ddrpcli => fnd-cli}/cmd/version.go (79%) rename cmd/{ddrpcli => fnd-cli}/main.go (61%) rename cmd/{ddrpd => fnd}/cmd/init.go (72%) rename cmd/{ddrpd => fnd}/cmd/root.go (79%) rename cmd/{ddrpd => fnd}/cmd/start.go (100%) rename cmd/{ddrpd => fnd}/cmd/version.go (78%) rename cmd/{ddrpd => fnd}/main.go (73%) diff --git a/Makefile b/Makefile index b08d4e4..ba653d0 100644 --- a/Makefile +++ b/Makefile @@ -4,30 +4,32 @@ git_tag := $(shell git describe --tags --abbrev=0) ldflags = -X fnd/version.GitCommit=$(git_commit) -X fnd/version.GitTag=$(git_tag) build_flags := -ldflags '$(ldflags)' -all: ddrpd ddrpcli +all: fnd fnd-cli .PHONY: all all-cross: - GOOS=darwin GOARCH=amd64 go build $(build_flags) -o ./build/ddrpd-darwin-amd64 ./cmd/ddrpd/main.go - GOOS=darwin GOARCH=amd64 go build $(build_flags) -o ./build/ddrpcli-darwin-amd64 ./cmd/ddrpcli/main.go - GOOS=linux GOARCH=amd64 go build $(build_flags) -o ./build/ddrpd-linux-amd64 ./cmd/ddrpd/main.go - GOOS=linux GOARCH=amd64 go build $(build_flags) -o ./build/ddrpcli-linux-amd64 ./cmd/ddrpcli/main.go + GOOS=darwin GOARCH=amd64 go build $(build_flags) -o ./build/fnd-darwin-amd64 ./cmd/fnd/main.go + GOOS=darwin GOARCH=amd64 go build $(build_flags) -o ./build/fnd-cli-darwin-amd64 ./cmd/fnd-cli/main.go + GOOS=linux GOARCH=amd64 go build $(build_flags) -o ./build/fnd-linux-amd64 ./cmd/fnd/main.go + GOOS=windows GOARCH=amd64 go build $(build_flags) -o ./build/fnd-win-amd64.exe ./cmd/fnd/main.go + GOOS=windows GOARCH=amd64 go build $(build_flags) -o ./build/fnd-cli-win-amd64.exe ./cmd/fnd/main.go + GOOS=linux GOARCH=amd64 go build $(build_flags) -o ./build/fnd-cli-linux-amd64 ./cmd/fnd-cli/main.go .PHONY: all-cross -ddrpcli: proto - go build $(build_flags) -o ./build/ddrpcli ./cmd/ddrpcli/main.go -.PHONY: ddrpcli +fnd-cli: proto + go build $(build_flags) -o ./build/fnd-cli ./cmd/fnd-cli/main.go +.PHONY: fnd-cli -ddrpd: proto - go build $(build_flags) -o ./build/ddrpd ./cmd/ddrpd/main.go -.PHONY: ddrpd +fnd: proto + go build $(build_flags) -o ./build/fnd ./cmd/fnd/main.go +.PHONY: fnd proto: protoc -I rpc/v1/ rpc/v1/api.proto --go_out=plugins=grpc:rpc/v1 .PHONY: proto test: proto - go test ./... -v -timeout 1m + go test ./... -v .PHONY: test install: all @@ -51,23 +53,23 @@ package-deb: all-cross --input-type dir \ --force \ --architecture amd64 \ - --package ./build/ddrp-$(version)-amd64.deb \ + --package ./build/fnd-$(version)-amd64.deb \ --no-depends \ - --name ddrp \ - --maintainer "The DDRP Maintainers" \ + --name fnd \ + --maintainer "The Footnote Maintainers" \ --version $(version) \ - --description "DDRP Network Daemon" \ + --description "Footnote Network Daemon" \ --license MIT \ - --vendor "The DDRP Maintainers" \ - --url "https://ddrp.network" \ + --vendor "The Footnote Maintainers" \ + --url "https://fnd.network" \ --log info \ - --deb-user ddrp \ + --deb-user fnd \ --deb-group nobody \ --after-install packaging/scripts/after_install.sh \ --after-remove packaging/scripts/after_remove.sh \ - --config-files /lib/systemd/system/ddrpd.service \ - build/ddrpd-linux-amd64=/usr/bin/ddrpd \ - build/ddrpcli-linux-amd64=/usr/bin/ddrpcli \ - packaging/lib/systemd/system/ddrpd.service=/lib/systemd/system/ddrpd.service - @docker run --rm -i -v "$(CURDIR):$(CURDIR)" -w "$(CURDIR)" ubuntu:xenial /bin/bash -c 'dpkg --info ./build/ddrp-$(version)-amd64.deb && dpkg -c ./build/ddrp-$(version)-amd64.deb' + --config-files /lib/systemd/system/fnd.service \ + build/fnd-linux-amd64=/usr/bin/fnd \ + build/fnd-cli-linux-amd64=/usr/bin/fnd-cli \ + packaging/lib/systemd/system/fnd.service=/lib/systemd/system/fnd.service + @docker run --rm -i -v "$(CURDIR):$(CURDIR)" -w "$(CURDIR)" ubuntu:xenial /bin/bash -c 'dpkg --info ./build/fnd-$(version)-amd64.deb && dpkg -c ./build/fnd-$(version)-amd64.deb' .PHONY: package-deb diff --git a/cmd/ddrpcli/cmd/blob/blob.go b/cmd/fnd-cli/cmd/blob/blob.go similarity index 76% rename from cmd/ddrpcli/cmd/blob/blob.go rename to cmd/fnd-cli/cmd/blob/blob.go index 3b4ba0b..7905f73 100644 --- a/cmd/ddrpcli/cmd/blob/blob.go +++ b/cmd/fnd-cli/cmd/blob/blob.go @@ -4,7 +4,7 @@ import "github.com/spf13/cobra" var cmd = &cobra.Command{ Use: "blob", - Short: "Commands related to DDRP blobs.", + Short: "Commands related to Footnote blobs.", } func AddCmd(parent *cobra.Command) { diff --git a/cmd/ddrpcli/cmd/blob/info.go b/cmd/fnd-cli/cmd/blob/info.go similarity index 93% rename from cmd/ddrpcli/cmd/blob/info.go rename to cmd/fnd-cli/cmd/blob/info.go index ae64043..7ebe468 100644 --- a/cmd/ddrpcli/cmd/blob/info.go +++ b/cmd/fnd-cli/cmd/blob/info.go @@ -19,7 +19,7 @@ import ( var infoCmd = &cobra.Command{ Use: "info ", - Short: "Returns metadata about DDRP blobs.", + Short: "Returns metadata about Footnote blobs.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { names := strings.Split(args[0], ",") @@ -33,7 +33,7 @@ var infoCmd = &cobra.Command{ if err != nil { return err } - grpcClient := apiv1.NewDDRPv1Client(conn) + grpcClient := apiv1.NewFootnotev1Client(conn) table := tablewriter.NewWriter(os.Stdout) table.SetHeader([]string{ "Name", diff --git a/cmd/ddrpcli/cmd/blob/list.go b/cmd/fnd-cli/cmd/blob/list.go similarity index 95% rename from cmd/ddrpcli/cmd/blob/list.go rename to cmd/fnd-cli/cmd/blob/list.go index 92b4676..550f331 100644 --- a/cmd/ddrpcli/cmd/blob/list.go +++ b/cmd/fnd-cli/cmd/blob/list.go @@ -35,7 +35,7 @@ var listCmd = &cobra.Command{ if err != nil { return err } - grpcClient := apiv1.NewDDRPv1Client(conn) + grpcClient := apiv1.NewFootnotev1Client(conn) var count int encoder := json.NewEncoder(os.Stdout) var innerErr error diff --git a/cmd/ddrpcli/cmd/blob/read.go b/cmd/fnd-cli/cmd/blob/read.go similarity index 88% rename from cmd/ddrpcli/cmd/blob/read.go rename to cmd/fnd-cli/cmd/blob/read.go index 164de6a..35d4f2b 100644 --- a/cmd/ddrpcli/cmd/blob/read.go +++ b/cmd/fnd-cli/cmd/blob/read.go @@ -21,7 +21,7 @@ var readCmd = &cobra.Command{ return err } - br := rpc.NewBlobReader(apiv1.NewDDRPv1Client(conn), name) + br := rpc.NewBlobReader(apiv1.NewFootnotev1Client(conn), name) if _, err := io.Copy(os.Stdout, br); err != nil { return err } diff --git a/cmd/ddrpcli/cmd/blob/write.go b/cmd/fnd-cli/cmd/blob/write.go similarity index 96% rename from cmd/ddrpcli/cmd/blob/write.go rename to cmd/fnd-cli/cmd/blob/write.go index d03e095..e14fce4 100644 --- a/cmd/ddrpcli/cmd/blob/write.go +++ b/cmd/fnd-cli/cmd/blob/write.go @@ -40,7 +40,7 @@ var writeCmd = &cobra.Command{ } name := args[0] - wr := rpc.NewBlobWriter(apiv1.NewDDRPv1Client(conn), signer, name) + wr := rpc.NewBlobWriter(apiv1.NewFootnotev1Client(conn), signer, name) if err := wr.Open(); err != nil { return err diff --git a/cmd/ddrpcli/cmd/identity.go b/cmd/fnd-cli/cmd/identity.go similarity index 100% rename from cmd/ddrpcli/cmd/identity.go rename to cmd/fnd-cli/cmd/identity.go diff --git a/cmd/ddrpcli/cmd/init.go b/cmd/fnd-cli/cmd/init.go similarity index 85% rename from cmd/ddrpcli/cmd/init.go rename to cmd/fnd-cli/cmd/init.go index b039341..95bf377 100644 --- a/cmd/ddrpcli/cmd/init.go +++ b/cmd/fnd-cli/cmd/init.go @@ -16,7 +16,7 @@ var initCmd = &cobra.Command{ return err } - fmt.Printf("Successfully initialized ddrpcli in %s.\n", dir) + fmt.Printf("Successfully initialized fnd-cli in %s.\n", dir) return nil }, } diff --git a/cmd/ddrpcli/cmd/net/add_peer.go b/cmd/fnd-cli/cmd/net/add_peer.go similarity index 95% rename from cmd/ddrpcli/cmd/net/add_peer.go rename to cmd/fnd-cli/cmd/net/add_peer.go index 265ad22..7acacb9 100644 --- a/cmd/ddrpcli/cmd/net/add_peer.go +++ b/cmd/fnd-cli/cmd/net/add_peer.go @@ -24,7 +24,7 @@ var addPeerCmd = &cobra.Command{ if err != nil { return err } - grpcClient := apiv1.NewDDRPv1Client(conn) + grpcClient := apiv1.NewFootnotev1Client(conn) splits := strings.Split(args[0], "@") if verifyPeerID && len(splits) == 1 { return errors.New("must define a peer ID if the peer ID is to be verified") diff --git a/cmd/ddrpcli/cmd/net/ban_peer.go b/cmd/fnd-cli/cmd/net/ban_peer.go similarity index 93% rename from cmd/ddrpcli/cmd/net/ban_peer.go rename to cmd/fnd-cli/cmd/net/ban_peer.go index 1262a6f..8ac28a3 100644 --- a/cmd/ddrpcli/cmd/net/ban_peer.go +++ b/cmd/fnd-cli/cmd/net/ban_peer.go @@ -20,7 +20,7 @@ to this peer will be closed.`, if err != nil { return err } - grpcClient := apiv1.NewDDRPv1Client(conn) + grpcClient := apiv1.NewFootnotev1Client(conn) peerID := args[0] duration, err := strconv.Atoi(args[1]) if err != nil { diff --git a/cmd/ddrpcli/cmd/net/net.go b/cmd/fnd-cli/cmd/net/net.go similarity index 73% rename from cmd/ddrpcli/cmd/net/net.go rename to cmd/fnd-cli/cmd/net/net.go index 7baeef1..95d04d6 100644 --- a/cmd/ddrpcli/cmd/net/net.go +++ b/cmd/fnd-cli/cmd/net/net.go @@ -6,7 +6,7 @@ import ( var cmd = &cobra.Command{ Use: "net", - Short: "Commands related to DDRP's network connection.", + Short: "Commands related to fnd's network connection.", } func AddCmd(parent *cobra.Command) { diff --git a/cmd/ddrpcli/cmd/net/peer_info.go b/cmd/fnd-cli/cmd/net/peer_info.go similarity index 94% rename from cmd/ddrpcli/cmd/net/peer_info.go rename to cmd/fnd-cli/cmd/net/peer_info.go index 48882d0..fe01e32 100644 --- a/cmd/ddrpcli/cmd/net/peer_info.go +++ b/cmd/fnd-cli/cmd/net/peer_info.go @@ -24,13 +24,13 @@ type peerJSON struct { var peerInfoCmd = &cobra.Command{ Use: "peer-info", - Short: "Returns information about all peers DDRP has heard of.", + Short: "Returns information about all peers Footnote has heard of.", RunE: func(cmd *cobra.Command, args []string) error { conn, err := cli.DialRPC(cmd) if err != nil { return err } - grpcClient := apiv1.NewDDRPv1Client(conn) + grpcClient := apiv1.NewFootnotev1Client(conn) peers, err := rpc.ListPeers(grpcClient) if err != nil { return err diff --git a/cmd/ddrpcli/cmd/net/status.go b/cmd/fnd-cli/cmd/net/status.go similarity index 95% rename from cmd/ddrpcli/cmd/net/status.go rename to cmd/fnd-cli/cmd/net/status.go index 1d36f06..72eebce 100644 --- a/cmd/ddrpcli/cmd/net/status.go +++ b/cmd/fnd-cli/cmd/net/status.go @@ -19,7 +19,7 @@ var statusCmd = &cobra.Command{ if err != nil { return err } - grpcClient := apiv1.NewDDRPv1Client(conn) + grpcClient := apiv1.NewFootnotev1Client(conn) res, err := rpc.GetStatus(grpcClient) if err != nil { diff --git a/cmd/ddrpcli/cmd/net/unban_peer.go b/cmd/fnd-cli/cmd/net/unban_peer.go similarity index 82% rename from cmd/ddrpcli/cmd/net/unban_peer.go rename to cmd/fnd-cli/cmd/net/unban_peer.go index 0ff9880..d964f11 100644 --- a/cmd/ddrpcli/cmd/net/unban_peer.go +++ b/cmd/fnd-cli/cmd/net/unban_peer.go @@ -12,7 +12,7 @@ var unbanPeerCmd = &cobra.Command{ Use: "unban-peer ", Short: "Unbans a peer.", Long: `Unbans a peer. A connection with the peer will not be automatically reestablished; -ddrpd will either reconnect to the unbanned peer the next time it refills its +fnd will either reconnect to the unbanned peer the next time it refills its peer list or following the add-peer CLI command.`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -20,7 +20,7 @@ peer list or following the add-peer CLI command.`, if err != nil { return err } - grpcClient := apiv1.NewDDRPv1Client(conn) + grpcClient := apiv1.NewFootnotev1Client(conn) return rpc.UnbanPeer(grpcClient, args[0]) }, } diff --git a/cmd/ddrpcli/cmd/root.go b/cmd/fnd-cli/cmd/root.go similarity index 72% rename from cmd/ddrpcli/cmd/root.go rename to cmd/fnd-cli/cmd/root.go index 6e37434..ce0f002 100644 --- a/cmd/ddrpcli/cmd/root.go +++ b/cmd/fnd-cli/cmd/root.go @@ -3,17 +3,17 @@ package cmd import ( "fmt" "fnd/cli" - "fnd/cmd/ddrpcli/cmd/blob" - "fnd/cmd/ddrpcli/cmd/net" - "fnd/cmd/ddrpcli/cmd/unsafe" + "fnd/cmd/fnd-cli/cmd/blob" + "fnd/cmd/fnd-cli/cmd/net" + "fnd/cmd/fnd-cli/cmd/unsafe" "os" "github.com/spf13/cobra" ) var rootCmd = &cobra.Command{ - Use: "ddrpcli", - Short: "Command-line RPC interface for DDRP.", + Use: "fnd-cli", + Short: "Command-line RPC interface for fnd.", } func Execute() { @@ -26,7 +26,7 @@ func Execute() { func init() { rootCmd.PersistentFlags().Int(cli.FlagRPCPort, 9098, "RPC port to connect to.") rootCmd.PersistentFlags().String(cli.FlagRPCHost, "127.0.0.1", "RPC host to connect to.") - rootCmd.PersistentFlags().String(cli.FlagHome, "~/.ddrpcli", "Home directory for the CLI's configuration.") + rootCmd.PersistentFlags().String(cli.FlagHome, "~/.fnd-cli", "Home directory for the CLI's configuration.") rootCmd.PersistentFlags().String(cli.FlagFormat, "text", "Output format") net.AddCmd(rootCmd) blob.AddCmd(rootCmd) diff --git a/cmd/ddrpcli/cmd/unsafe/reset_blobs.go b/cmd/fnd-cli/cmd/unsafe/reset_blobs.go similarity index 81% rename from cmd/ddrpcli/cmd/unsafe/reset_blobs.go rename to cmd/fnd-cli/cmd/unsafe/reset_blobs.go index 7906673..eb352b5 100644 --- a/cmd/ddrpcli/cmd/unsafe/reset_blobs.go +++ b/cmd/fnd-cli/cmd/unsafe/reset_blobs.go @@ -12,9 +12,9 @@ import ( var resetBlobsCmd = &cobra.Command{ Use: "reset-blobs", - Short: "Wipes ddrpd's blob data directly on disk", + Short: "Wipes fnd's blob data directly on disk", RunE: func(cmd *cobra.Command, args []string) error { - homePath := config.ExpandHomePath(ddrpdHome) + homePath := config.ExpandHomePath(fndHome) db, err := store.Open(config.ExpandDBPath(homePath)) if err != nil { return errors.Wrap(err, "error opening store") @@ -38,6 +38,6 @@ var resetBlobsCmd = &cobra.Command{ } func init() { - resetBlobsCmd.Flags().StringVar(&ddrpdHome, "ddrpd-home", "~/.ddrpd", "Path to DDRPD's home directory.") + resetBlobsCmd.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to fnd's home directory.") cmd.AddCommand(resetBlobsCmd) } diff --git a/cmd/ddrpcli/cmd/unsafe/reset_name_store.go b/cmd/fnd-cli/cmd/unsafe/reset_name_store.go similarity index 76% rename from cmd/ddrpcli/cmd/unsafe/reset_name_store.go rename to cmd/fnd-cli/cmd/unsafe/reset_name_store.go index 148858b..0c10124 100644 --- a/cmd/ddrpcli/cmd/unsafe/reset_name_store.go +++ b/cmd/fnd-cli/cmd/unsafe/reset_name_store.go @@ -11,9 +11,9 @@ import ( var resetNameStore = &cobra.Command{ Use: "reset-name-store", - Short: "Wipes ddrpd's naming data directly on disk", + Short: "Wipes fnd's naming data directly on disk", RunE: func(cmd *cobra.Command, args []string) error { - homePath := config.ExpandHomePath(ddrpdHome) + homePath := config.ExpandHomePath(fndHome) db, err := store.Open(config.ExpandDBPath(homePath)) if err != nil { return errors.Wrap(err, "failed to open store") @@ -30,6 +30,6 @@ var resetNameStore = &cobra.Command{ } func init() { - resetNameStore.Flags().StringVar(&ddrpdHome, "ddrpd-home", "~/.ddrpd", "Path to DDRPD's home directory.") + resetNameStore.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to fnd's home directory.") cmd.AddCommand(resetNameStore) } diff --git a/cmd/ddrpcli/cmd/unsafe/reset_peer_store.go b/cmd/fnd-cli/cmd/unsafe/reset_peer_store.go similarity index 76% rename from cmd/ddrpcli/cmd/unsafe/reset_peer_store.go rename to cmd/fnd-cli/cmd/unsafe/reset_peer_store.go index 3904add..bf28a67 100644 --- a/cmd/ddrpcli/cmd/unsafe/reset_peer_store.go +++ b/cmd/fnd-cli/cmd/unsafe/reset_peer_store.go @@ -11,9 +11,9 @@ import ( var resetPeerStoreCmd = &cobra.Command{ Use: "reset-peer-store", - Short: "Wipes ddrpd's peer store directly on disk", + Short: "Wipes fnd's peer store directly on disk", RunE: func(cmd *cobra.Command, args []string) error { - homePath := config.ExpandHomePath(ddrpdHome) + homePath := config.ExpandHomePath(fndHome) db, err := store.Open(config.ExpandDBPath(homePath)) if err != nil { return errors.Wrap(err, "error opening store") @@ -30,6 +30,6 @@ var resetPeerStoreCmd = &cobra.Command{ } func init() { - resetPeerStoreCmd.Flags().StringVar(&ddrpdHome, "ddrpd-home", "~/.ddrpd", "Path to DDRPD's home directory.") + resetPeerStoreCmd.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to fnd's home directory.") cmd.AddCommand(resetPeerStoreCmd) } diff --git a/cmd/ddrpcli/cmd/unsafe/unsafe.go b/cmd/fnd-cli/cmd/unsafe/unsafe.go similarity index 92% rename from cmd/ddrpcli/cmd/unsafe/unsafe.go rename to cmd/fnd-cli/cmd/unsafe/unsafe.go index db061e8..116c5a8 100644 --- a/cmd/ddrpcli/cmd/unsafe/unsafe.go +++ b/cmd/fnd-cli/cmd/unsafe/unsafe.go @@ -2,7 +2,7 @@ package unsafe import "github.com/spf13/cobra" -var ddrpdHome string +var fndHome string var cmd = &cobra.Command{ Use: "unsafe", diff --git a/cmd/ddrpcli/cmd/version.go b/cmd/fnd-cli/cmd/version.go similarity index 79% rename from cmd/ddrpcli/cmd/version.go rename to cmd/fnd-cli/cmd/version.go index e7b3c8a..103b87a 100644 --- a/cmd/ddrpcli/cmd/version.go +++ b/cmd/fnd-cli/cmd/version.go @@ -10,7 +10,7 @@ import ( var versionCmd = &cobra.Command{ Use: "version", RunE: func(cmd *cobra.Command, args []string) error { - fmt.Printf("ddrpcli %s (%s)\n", version.GitTag, version.GitCommit) + fmt.Printf("fnd-cli %s (%s)\n", version.GitTag, version.GitCommit) return nil }, } diff --git a/cmd/ddrpcli/main.go b/cmd/fnd-cli/main.go similarity index 61% rename from cmd/ddrpcli/main.go rename to cmd/fnd-cli/main.go index 1d2575e..4bd892e 100644 --- a/cmd/ddrpcli/main.go +++ b/cmd/fnd-cli/main.go @@ -1,6 +1,6 @@ package main -import "fnd/cmd/ddrpcli/cmd" +import "fnd/cmd/fnd-cli/cmd" func main() { cmd.Execute() diff --git a/cmd/ddrpd/cmd/init.go b/cmd/fnd/cmd/init.go similarity index 72% rename from cmd/ddrpd/cmd/init.go rename to cmd/fnd/cmd/init.go index 1e5baa6..d04cae0 100644 --- a/cmd/ddrpd/cmd/init.go +++ b/cmd/fnd/cmd/init.go @@ -9,13 +9,13 @@ import ( var initCmd = &cobra.Command{ Use: "init", - Short: "Initializes the ddrpd daemon's home directory.", + Short: "Initializes the fnd daemon's home directory.", RunE: func(cmd *cobra.Command, args []string) error { dir, err := cli.InitHomeDir(cmd) if err != nil { return err } - fmt.Printf("Successfully initialized ddrpd in %s.\n", dir) + fmt.Printf("Successfully initialized fnd in %s.\n", dir) return nil }, } diff --git a/cmd/ddrpd/cmd/root.go b/cmd/fnd/cmd/root.go similarity index 79% rename from cmd/ddrpd/cmd/root.go rename to cmd/fnd/cmd/root.go index 0bd88ad..80cd1c1 100644 --- a/cmd/ddrpd/cmd/root.go +++ b/cmd/fnd/cmd/root.go @@ -13,8 +13,8 @@ import ( var configuredHomeDir string var rootCmd = &cobra.Command{ - Use: "ddrpd", - Short: "DDRP Daemon", + Use: "fnd", + Short: "fnd Daemon", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { if cmd.CalledAs() == "init" { return nil @@ -28,7 +28,7 @@ var rootCmd = &cobra.Command{ } func init() { - rootCmd.PersistentFlags().String(cli.FlagHome, "~/.ddrpd", "Home directory for the daemon's config and database.") + rootCmd.PersistentFlags().String(cli.FlagHome, "~/.fnd", "Home directory for the daemon's config and database.") } func Execute() { diff --git a/cmd/ddrpd/cmd/start.go b/cmd/fnd/cmd/start.go similarity index 100% rename from cmd/ddrpd/cmd/start.go rename to cmd/fnd/cmd/start.go diff --git a/cmd/ddrpd/cmd/version.go b/cmd/fnd/cmd/version.go similarity index 78% rename from cmd/ddrpd/cmd/version.go rename to cmd/fnd/cmd/version.go index 9b2493e..de3d61e 100644 --- a/cmd/ddrpd/cmd/version.go +++ b/cmd/fnd/cmd/version.go @@ -10,7 +10,7 @@ import ( var versionCmd = &cobra.Command{ Use: "version", RunE: func(cmd *cobra.Command, args []string) error { - fmt.Printf("ddrpd %s (%s)\n", version.GitTag, version.GitCommit) + fmt.Printf("fnd %s (%s)\n", version.GitTag, version.GitCommit) return nil }, } diff --git a/cmd/ddrpd/main.go b/cmd/fnd/main.go similarity index 73% rename from cmd/ddrpd/main.go rename to cmd/fnd/main.go index 1f90db6..e060065 100644 --- a/cmd/ddrpd/main.go +++ b/cmd/fnd/main.go @@ -1,7 +1,7 @@ package main import ( - "fnd/cmd/ddrpd/cmd" + "fnd/cmd/fnd/cmd" ) func main() { diff --git a/config/default.go b/config/default.go index b504a19..cc3af50 100644 --- a/config/default.go +++ b/config/default.go @@ -83,7 +83,7 @@ var DefaultConfig = Config{ }, } -const defaultConfigTemplateText = `# DDRPD Config File +const defaultConfigTemplateText = `# fnd Config File # List of ban list URLs. ban_lists = [] @@ -107,7 +107,7 @@ log_level = "{{.LogLevel}}" # Sets the URL the node will heartbeat to. url = "{{.Heartbeat.URL}}" -# Configures the connection to the Handshake network. DDRP assumes +# Configures the connection to the Handshake network. Footnote assumes # that HSD is hosted at a url with the following format: # :/. [hns_resolver] @@ -148,7 +148,7 @@ log_level = "{{.LogLevel}}" [rpc] # Sets the IP this node should listen for RPC requests on. # For the most part, this should be set to 127.0.0.1. Exposing - # ddrpd's RPC port to the public internet is not safe. + # fnd's RPC port to the public internet is not safe. host = "{{.RPC.Host}}" # Sets the port this node should listen for RPC requests on. port = {{.RPC.Port}} @@ -158,29 +158,29 @@ log_level = "{{.LogLevel}}" # defaults. [tuning] - # Configures how often ddrpd will perform heartbeats and + # Configures how often fnd will perform heartbeats and # when to time out heartbeat requests. [tuning.heartbeat] interval_ms = {{.Tuning.Heartbeat.IntervalMS}} timeout_ms = {{.Tuning.Heartbeat.TimeoutMS}} - # Configures how ddrpd scans the Handshake blockchain for + # Configures how fnd scans the Handshake blockchain for # new DDRPKEY records. [tuning.name_importer] - # Sets how often ddrpd scans for new names. + # Sets how often fnd scans for new names. check_interval_ms = {{.Tuning.NameImporter.CheckIntervalMS}} - # Sets how many blocks ddrpd will wait before considering + # Sets how many blocks fnd will wait before considering # a Handshake name record to be finalized. Changing this # value to something lower than the default will lead to # the network rejecting updates originating from this node. confirmation_depth = {{.Tuning.NameImporter.ConfirmationDepth}} # Sets how many blocks should be fetched from HSD concurrently. workers = {{.Tuning.NameImporter.Workers}} - # Sets the minimum sync percentage ddrpd will accept from HSD before + # Sets the minimum sync percentage fnd will accept from HSD before # importing names. verification_threshold = {{.Tuning.NameImporter.VerificationThreshold}} - # Configures how ddrpd scans for updates in the background. + # Configures how fnd scans for updates in the background. [tuning.name_syncer] # Sets how often updates will be scanned for. interval_ms = {{.Tuning.NameSyncer.IntervalMS}} @@ -195,49 +195,49 @@ log_level = "{{.LogLevel}}" # Sets how many names will be synchronized concurrently. workers = {{.Tuning.NameSyncer.Workers}} - # Configures how ddrpd exchanges peers with the rest of the network. + # Configures how fnd exchanges peers with the rest of the network. [tuning.peer_exchanger] - # Sets how many concurrent dials ddrpd will make when it + # Sets how many concurrent dials fnd will make when it # receives exchanged peers. max_concurrent_dials = {{.Tuning.PeerExchanger.MaxConcurrentDials}} - # Sets the maximum number of peers ddrpd will process after + # Sets the maximum number of peers fnd will process after # receiving exchanged peers. max_received_peers = {{.Tuning.PeerExchanger.MaxReceivedPeers}} - # Sets the maximum number of peers ddrpd will send after receiving a + # Sets the maximum number of peers fnd will send after receiving a # request for peers. max_sent_peers = {{.Tuning.PeerExchanger.MaxSentPeers}} - # Sets how often ddrpd will request new peers. + # Sets how often fnd will request new peers. request_interval_ms = {{.Tuning.PeerExchanger.RequestIntervalMS}} - # Sets how many peers ddrpd will request new peers from during each + # Sets how many peers fnd will request new peers from during each # peer exchange operation. sample_size = {{.Tuning.PeerExchanger.SampleSize}} - # Configures how ddrpd serves sector data to peers that request it. + # Configures how fnd serves sector data to peers that request it. [tuning.sector_server] - # Sets how often ddrpd will reap in-memory cached sectors. + # Sets how often fnd will reap in-memory cached sectors. cache_expiry_ms = {{.Tuning.SectorServer.CacheExpiryMS}} - # Configures how ddrpd synchronizes sectors with remote peers. + # Configures how fnd synchronizes sectors with remote peers. [tuning.syncer] - # Sets how long ddrpd will wait for remote peers to return + # Sets how long fnd will wait for remote peers to return # sector data before retrying. sector_response_timeout_ms = {{.Tuning.Syncer.SectorResponseTimeoutMS}} - # Sets how long ddrpd will wait for a remote peers to return + # Sets how long fnd will wait for a remote peers to return # tree base data before trying another peer. tree_base_response_timeout_ms = {{.Tuning.Syncer.TreeBaseResponseTimeoutMS}} - # Configures how ddrpd enqueues blob updates. + # Configures how fnd enqueues blob updates. [tuning.update_queue] # Sets the maximum length of the update queue. max_len = {{.Tuning.UpdateQueue.MaxLen}} - # Sets how often ddrpd will reap disposed of queue entries. + # Sets how often fnd will reap disposed of queue entries. reap_interval_ms = {{.Tuning.UpdateQueue.ReapIntervalMS}} - # Configures how ddrpd updates blobs. + # Configures how fnd updates blobs. [tuning.updater] - # Sets how often ddrpd will check the update queue for new updates. + # Sets how often fnd will check the update queue for new updates. poll_interval_ms = {{.Tuning.Updater.PollIntervalMS}} - # Sets how many updates ddrpd will process concurrently. + # Sets how many updates fnd will process concurrently. workers = {{.Tuning.Updater.Workers}} ` diff --git a/config/home.go b/config/home.go index 7de7347..7b133c3 100644 --- a/config/home.go +++ b/config/home.go @@ -1,8 +1,9 @@ package config import ( - "github.com/pkg/errors" "os" + + "github.com/pkg/errors" ) func HomeDirExists(path string) (bool, error) { @@ -26,7 +27,7 @@ func EnsureHomeDir(path string) error { return err } if !exists { - return errors.New("home directory does not exist - try running ddrpd init") + return errors.New("home directory does not exist - try running fnd init") } return nil } diff --git a/go.sum b/go.sum index 097834c..5d6ca22 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,10 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 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= +fnd v0.2.3 h1:sDSD+Pu4c5KJlHj8Q/PYWu6tqzLyXHOGclVro089rQs= +fnd v0.2.3/go.mod h1:6/1wpeEE7b1oWDZXEj6l3dB34ofQMT5X3CU0vAkE65c= +github.com/ddrp-org/dwire v1.0.1 h1:OD5D5aRahOuy0QGCHxXrZf5ZJlX0IBcT/3P0k97elpQ= +github.com/ddrp-org/dwire v1.0.1/go.mod h1:BkHitp5E9PSDVLq5nPLXWzQFEwFSR5aNhTL7M9xeC7I= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= @@ -114,6 +118,7 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH 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/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= @@ -173,9 +178,11 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= diff --git a/packaging/scripts/after_install.sh b/packaging/scripts/after_install.sh index 3e94175..4b7d27b 100644 --- a/packaging/scripts/after_install.sh +++ b/packaging/scripts/after_install.sh @@ -6,16 +6,16 @@ set -ue -USERNAME="ddrp" -SERVICE="ddrpd" +USERNAME="fnd" +SERVICE="fnd" UNIT_FILE="/etc/systemd/system/${SERVICE}.service" main() { echo "Adding ${USERNAME} user..." useradd -s /bin/false -M --system $USERNAME - echo "Initializing ddrpd config in /etc/ddrpd.." - /usr/bin/ddrpd init --home /etc/ddrpd || true - chown -R $USERNAME:$USERNAME /etc/ddrpd + echo "Initializing fnd config in /etc/fnd.." + /usr/bin/fnd init --home /etc/fnd || true + chown -R $USERNAME:$USERNAME /etc/fnd if command -v systemctl >/dev/null 2>&1; then rm -f "${UNIT_FILE}" @@ -31,4 +31,4 @@ main() { echo "Done." } -main \ No newline at end of file +main diff --git a/packaging/scripts/after_remove.sh b/packaging/scripts/after_remove.sh index 9d9eee1..d2e018c 100644 --- a/packaging/scripts/after_remove.sh +++ b/packaging/scripts/after_remove.sh @@ -6,7 +6,7 @@ set -ue -SERVICE="ddrpd" +SERVICE="fnd" # fix an issue where this script runs on upgrades for rpm # see https://github.com/jordansissel/fpm/issues/1175#issuecomment-240086016 @@ -33,4 +33,4 @@ clean_systemd() { systemctl daemon-reload || true } -main \ No newline at end of file +main diff --git a/protocol/heartbeater_test.go b/protocol/heartbeater_test.go index 288eb95..388697d 100644 --- a/protocol/heartbeater_test.go +++ b/protocol/heartbeater_test.go @@ -38,7 +38,7 @@ func TestHeartbeater_SendHeartbeats(t *testing.T) { beat := <-resCh require.Equal(t, "test moniker", beat.Moniker) require.Equal(t, peerID, beat.PeerID) - require.Equal(t, "ddrpd/+", beat.UserAgent) + require.Equal(t, "fnd/+", beat.UserAgent) require.NoError(t, heartbeater.Stop()) server.Close() diff --git a/rpc/blob.go b/rpc/blob.go index 3bebadb..8723d01 100644 --- a/rpc/blob.go +++ b/rpc/blob.go @@ -13,11 +13,11 @@ import ( "github.com/pkg/errors" ) -func GetBlobInfo(client apiv1.DDRPv1Client, name string) (*store.BlobInfo, error) { +func GetBlobInfo(client apiv1.Footnotev1Client, name string) (*store.BlobInfo, error) { return GetBlobInfoContext(context.Background(), client, name) } -func GetBlobInfoContext(ctx context.Context, client apiv1.DDRPv1Client, name string) (*store.BlobInfo, error) { +func GetBlobInfoContext(ctx context.Context, client apiv1.Footnotev1Client, name string) (*store.BlobInfo, error) { res, err := client.GetBlobInfo(ctx, &apiv1.BlobInfoReq{ Name: name, }) @@ -27,11 +27,11 @@ func GetBlobInfoContext(ctx context.Context, client apiv1.DDRPv1Client, name str return parseBlobInfoRes(res) } -func ListBlobInfo(client apiv1.DDRPv1Client, after string, cb func(info *store.BlobInfo) bool) error { +func ListBlobInfo(client apiv1.Footnotev1Client, after string, cb func(info *store.BlobInfo) bool) error { return ListBlobInfoContext(context.Background(), client, after, cb) } -func ListBlobInfoContext(ctx context.Context, client apiv1.DDRPv1Client, start string, cb func(info *store.BlobInfo) bool) error { +func ListBlobInfoContext(ctx context.Context, client apiv1.Footnotev1Client, start string, cb func(info *store.BlobInfo) bool) error { stream, err := client.ListBlobInfo(ctx, &apiv1.ListBlobInfoReq{ Start: start, }) diff --git a/rpc/blob_reader.go b/rpc/blob_reader.go index f9a550f..1c5bdb5 100644 --- a/rpc/blob_reader.go +++ b/rpc/blob_reader.go @@ -9,12 +9,12 @@ import ( ) type BlobReader struct { - client apiv1.DDRPv1Client + client apiv1.Footnotev1Client name string off int64 } -func NewBlobReader(client apiv1.DDRPv1Client, name string) *BlobReader { +func NewBlobReader(client apiv1.Footnotev1Client, name string) *BlobReader { return &BlobReader{ client: client, name: name, diff --git a/rpc/blob_writer.go b/rpc/blob_writer.go index 3327ed8..938bc86 100644 --- a/rpc/blob_writer.go +++ b/rpc/blob_writer.go @@ -12,7 +12,7 @@ import ( ) type BlobWriter struct { - client apiv1.DDRPv1Client + client apiv1.Footnotev1Client signer crypto.Signer name string epochHeight uint16 @@ -23,7 +23,7 @@ type BlobWriter struct { committed bool } -func NewBlobWriter(client apiv1.DDRPv1Client, signer crypto.Signer, name string) *BlobWriter { +func NewBlobWriter(client apiv1.Footnotev1Client, signer crypto.Signer, name string) *BlobWriter { return &BlobWriter{ client: client, signer: signer, diff --git a/rpc/net.go b/rpc/net.go index b7fb28e..254d229 100644 --- a/rpc/net.go +++ b/rpc/net.go @@ -17,11 +17,11 @@ type Peer struct { RxBytes uint64 } -func ListPeers(client apiv1.DDRPv1Client) ([]*Peer, error) { +func ListPeers(client apiv1.Footnotev1Client) ([]*Peer, error) { return ListPeersContext(context.Background(), client) } -func ListPeersContext(ctx context.Context, client apiv1.DDRPv1Client) ([]*Peer, error) { +func ListPeersContext(ctx context.Context, client apiv1.Footnotev1Client) ([]*Peer, error) { stream, err := client.ListPeers(ctx, &apiv1.ListPeersReq{}) if err != nil { return nil, err @@ -51,11 +51,11 @@ func ListPeersContext(ctx context.Context, client apiv1.DDRPv1Client) ([]*Peer, return peers, nil } -func BanPeer(client apiv1.DDRPv1Client, ip string, duration int) error { +func BanPeer(client apiv1.Footnotev1Client, ip string, duration int) error { return BanPeerContext(context.Background(), client, ip, duration) } -func BanPeerContext(ctx context.Context, client apiv1.DDRPv1Client, ip string, duration int) error { +func BanPeerContext(ctx context.Context, client apiv1.Footnotev1Client, ip string, duration int) error { _, err := client.BanPeer(ctx, &apiv1.BanPeerReq{ Ip: ip, DurationMS: uint32(duration), @@ -63,11 +63,11 @@ func BanPeerContext(ctx context.Context, client apiv1.DDRPv1Client, ip string, d return err } -func UnbanPeer(client apiv1.DDRPv1Client, ip string) error { +func UnbanPeer(client apiv1.Footnotev1Client, ip string) error { return UnbanPeerContext(context.Background(), client, ip) } -func UnbanPeerContext(ctx context.Context, client apiv1.DDRPv1Client, ip string) error { +func UnbanPeerContext(ctx context.Context, client apiv1.Footnotev1Client, ip string) error { _, err := client.UnbanPeer(ctx, &apiv1.UnbanPeerReq{ Ip: ip, }) @@ -82,11 +82,11 @@ type Status struct { RxBytes uint64 } -func GetStatus(client apiv1.DDRPv1Client) (*Status, error) { +func GetStatus(client apiv1.Footnotev1Client) (*Status, error) { return GetStatusContext(context.Background(), client) } -func GetStatusContext(ctx context.Context, client apiv1.DDRPv1Client) (*Status, error) { +func GetStatusContext(ctx context.Context, client apiv1.Footnotev1Client) (*Status, error) { res, err := client.GetStatus(ctx, &apiv1.Empty{}) if err != nil { return nil, err @@ -101,11 +101,11 @@ func GetStatusContext(ctx context.Context, client apiv1.DDRPv1Client) (*Status, }, nil } -func AddPeer(client apiv1.DDRPv1Client, peerID string, ip string, verify bool) error { +func AddPeer(client apiv1.Footnotev1Client, peerID string, ip string, verify bool) error { return AddPeerContext(context.Background(), client, peerID, ip, verify) } -func AddPeerContext(ctx context.Context, client apiv1.DDRPv1Client, peerID string, ip string, verify bool) error { +func AddPeerContext(ctx context.Context, client apiv1.Footnotev1Client, peerID string, ip string, verify bool) error { pIDBytes, err := hex.DecodeString(peerID) if err != nil { return err diff --git a/rpc/server.go b/rpc/server.go index 8f6545f..2dcfbac 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -95,7 +95,7 @@ func (s *Server) Start() error { return err } s.srv = grpc.NewServer() - apiv1.RegisterDDRPv1Server(s.srv, s) + apiv1.RegisterFootnotev1Server(s.srv, s) go s.srv.Serve(lis) return nil } @@ -178,7 +178,7 @@ func (s *Server) UnbanPeer(_ context.Context, req *apiv1.UnbanPeerReq) (*apiv1.E return emptyRes, nil } -func (s *Server) ListPeers(req *apiv1.ListPeersReq, stream apiv1.DDRPv1_ListPeersServer) error { +func (s *Server) ListPeers(req *apiv1.ListPeersReq, stream apiv1.Footnotev1_ListPeersServer) error { connectedPeers := s.mux.Peers() storedPeers, err := store.StreamPeers(s.db, true) if err != nil { @@ -409,7 +409,7 @@ func (s *Server) GetBlobInfo(_ context.Context, req *apiv1.BlobInfoReq) (*apiv1. }, nil } -func (s *Server) ListBlobInfo(req *apiv1.ListBlobInfoReq, srv apiv1.DDRPv1_ListBlobInfoServer) error { +func (s *Server) ListBlobInfo(req *apiv1.ListBlobInfoReq, srv apiv1.Footnotev1_ListBlobInfoServer) error { stream, err := store.StreamBlobInfo(s.db, req.Start) if err != nil { return errors.Wrap(err, "error opening header stream") diff --git a/rpc/v1/api.pb.go b/rpc/v1/api.pb.go index 14f6381..e9b5f6d 100644 --- a/rpc/v1/api.pb.go +++ b/rpc/v1/api.pb.go @@ -1440,38 +1440,39 @@ var file_api_proto_rawDesc = []byte{ 0x65, 0x22, 0x37, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x69, - 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0xe5, 0x03, 0x0a, 0x06, 0x44, - 0x44, 0x52, 0x50, 0x76, 0x31, 0x12, 0x22, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x47, 0x65, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x07, 0x41, 0x64, 0x64, - 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x07, 0x42, 0x61, 0x6e, - 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x22, 0x0a, 0x09, 0x55, 0x6e, 0x62, - 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2b, 0x0a, - 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x0d, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x26, 0x0a, 0x08, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, - 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, - 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x0b, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x12, 0x0f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, - 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x0a, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x12, - 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x52, 0x65, - 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x42, 0x6c, - 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x73, 0x12, 0x30, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x10, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x73, 0x30, 0x01, 0x12, 0x2c, 0x0a, 0x0a, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x12, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x42, 0x04, 0x5a, 0x02, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0xe9, 0x03, 0x0a, 0x0a, 0x46, + 0x6f, 0x6f, 0x74, 0x6e, 0x6f, 0x74, 0x65, 0x76, 0x31, 0x12, 0x22, 0x0a, 0x09, 0x47, 0x65, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, + 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, + 0x07, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x1e, 0x0a, + 0x07, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x42, 0x61, 0x6e, 0x50, 0x65, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x22, 0x0a, + 0x09, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x55, 0x6e, 0x62, + 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x2b, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x0d, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x26, + 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x0c, 0x2e, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x0b, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x0f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x12, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x52, 0x65, 0x61, + 0x64, 0x41, 0x74, 0x12, 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x71, 0x1a, + 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x0b, 0x47, + 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, + 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, + 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, + 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x2c, 0x0a, 0x0a, 0x53, 0x65, 0x6e, 0x64, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x42, 0x04, 0x5a, 0x02, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1512,30 +1513,30 @@ var file_api_proto_goTypes = []interface{}{ (*SendUpdateRes)(nil), // 21: SendUpdateRes } var file_api_proto_depIdxs = []int32{ - 0, // 0: DDRPv1.GetStatus:input_type -> Empty - 4, // 1: DDRPv1.AddPeer:input_type -> AddPeerReq - 5, // 2: DDRPv1.BanPeer:input_type -> BanPeerReq - 6, // 3: DDRPv1.UnbanPeer:input_type -> UnbanPeerReq - 7, // 4: DDRPv1.ListPeers:input_type -> ListPeersReq - 9, // 5: DDRPv1.Checkout:input_type -> CheckoutReq - 11, // 6: DDRPv1.WriteSector:input_type -> WriteSectorReq - 13, // 7: DDRPv1.Commit:input_type -> CommitReq - 15, // 8: DDRPv1.ReadAt:input_type -> ReadAtReq - 17, // 9: DDRPv1.GetBlobInfo:input_type -> BlobInfoReq - 18, // 10: DDRPv1.ListBlobInfo:input_type -> ListBlobInfoReq - 20, // 11: DDRPv1.SendUpdate:input_type -> SendUpdateReq - 1, // 12: DDRPv1.GetStatus:output_type -> GetStatusRes - 0, // 13: DDRPv1.AddPeer:output_type -> Empty - 0, // 14: DDRPv1.BanPeer:output_type -> Empty - 0, // 15: DDRPv1.UnbanPeer:output_type -> Empty - 8, // 16: DDRPv1.ListPeers:output_type -> ListPeersRes - 10, // 17: DDRPv1.Checkout:output_type -> CheckoutRes - 12, // 18: DDRPv1.WriteSector:output_type -> WriteSectorRes - 14, // 19: DDRPv1.Commit:output_type -> CommitRes - 16, // 20: DDRPv1.ReadAt:output_type -> ReadAtRes - 19, // 21: DDRPv1.GetBlobInfo:output_type -> BlobInfoRes - 19, // 22: DDRPv1.ListBlobInfo:output_type -> BlobInfoRes - 21, // 23: DDRPv1.SendUpdate:output_type -> SendUpdateRes + 0, // 0: Footnotev1.GetStatus:input_type -> Empty + 4, // 1: Footnotev1.AddPeer:input_type -> AddPeerReq + 5, // 2: Footnotev1.BanPeer:input_type -> BanPeerReq + 6, // 3: Footnotev1.UnbanPeer:input_type -> UnbanPeerReq + 7, // 4: Footnotev1.ListPeers:input_type -> ListPeersReq + 9, // 5: Footnotev1.Checkout:input_type -> CheckoutReq + 11, // 6: Footnotev1.WriteSector:input_type -> WriteSectorReq + 13, // 7: Footnotev1.Commit:input_type -> CommitReq + 15, // 8: Footnotev1.ReadAt:input_type -> ReadAtReq + 17, // 9: Footnotev1.GetBlobInfo:input_type -> BlobInfoReq + 18, // 10: Footnotev1.ListBlobInfo:input_type -> ListBlobInfoReq + 20, // 11: Footnotev1.SendUpdate:input_type -> SendUpdateReq + 1, // 12: Footnotev1.GetStatus:output_type -> GetStatusRes + 0, // 13: Footnotev1.AddPeer:output_type -> Empty + 0, // 14: Footnotev1.BanPeer:output_type -> Empty + 0, // 15: Footnotev1.UnbanPeer:output_type -> Empty + 8, // 16: Footnotev1.ListPeers:output_type -> ListPeersRes + 10, // 17: Footnotev1.Checkout:output_type -> CheckoutRes + 12, // 18: Footnotev1.WriteSector:output_type -> WriteSectorRes + 14, // 19: Footnotev1.Commit:output_type -> CommitRes + 16, // 20: Footnotev1.ReadAt:output_type -> ReadAtRes + 19, // 21: Footnotev1.GetBlobInfo:output_type -> BlobInfoRes + 19, // 22: Footnotev1.ListBlobInfo:output_type -> BlobInfoRes + 21, // 23: Footnotev1.SendUpdate:output_type -> SendUpdateRes 12, // [12:24] is the sub-list for method output_type 0, // [0:12] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name @@ -1842,74 +1843,74 @@ var _ grpc.ClientConnInterface // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion6 -// DDRPv1Client is the client API for DDRPv1 service. +// Footnotev1Client is the client API for Footnotev1 service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type DDRPv1Client interface { +type Footnotev1Client interface { GetStatus(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetStatusRes, error) AddPeer(ctx context.Context, in *AddPeerReq, opts ...grpc.CallOption) (*Empty, error) BanPeer(ctx context.Context, in *BanPeerReq, opts ...grpc.CallOption) (*Empty, error) UnbanPeer(ctx context.Context, in *UnbanPeerReq, opts ...grpc.CallOption) (*Empty, error) - ListPeers(ctx context.Context, in *ListPeersReq, opts ...grpc.CallOption) (DDRPv1_ListPeersClient, error) + ListPeers(ctx context.Context, in *ListPeersReq, opts ...grpc.CallOption) (Footnotev1_ListPeersClient, error) Checkout(ctx context.Context, in *CheckoutReq, opts ...grpc.CallOption) (*CheckoutRes, error) WriteSector(ctx context.Context, in *WriteSectorReq, opts ...grpc.CallOption) (*WriteSectorRes, error) Commit(ctx context.Context, in *CommitReq, opts ...grpc.CallOption) (*CommitRes, error) ReadAt(ctx context.Context, in *ReadAtReq, opts ...grpc.CallOption) (*ReadAtRes, error) GetBlobInfo(ctx context.Context, in *BlobInfoReq, opts ...grpc.CallOption) (*BlobInfoRes, error) - ListBlobInfo(ctx context.Context, in *ListBlobInfoReq, opts ...grpc.CallOption) (DDRPv1_ListBlobInfoClient, error) + ListBlobInfo(ctx context.Context, in *ListBlobInfoReq, opts ...grpc.CallOption) (Footnotev1_ListBlobInfoClient, error) SendUpdate(ctx context.Context, in *SendUpdateReq, opts ...grpc.CallOption) (*SendUpdateRes, error) } -type dDRPv1Client struct { +type footnotev1Client struct { cc grpc.ClientConnInterface } -func NewDDRPv1Client(cc grpc.ClientConnInterface) DDRPv1Client { - return &dDRPv1Client{cc} +func NewFootnotev1Client(cc grpc.ClientConnInterface) Footnotev1Client { + return &footnotev1Client{cc} } -func (c *dDRPv1Client) GetStatus(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetStatusRes, error) { +func (c *footnotev1Client) GetStatus(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetStatusRes, error) { out := new(GetStatusRes) - err := c.cc.Invoke(ctx, "/DDRPv1/GetStatus", in, out, opts...) + err := c.cc.Invoke(ctx, "/Footnotev1/GetStatus", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *dDRPv1Client) AddPeer(ctx context.Context, in *AddPeerReq, opts ...grpc.CallOption) (*Empty, error) { +func (c *footnotev1Client) AddPeer(ctx context.Context, in *AddPeerReq, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := c.cc.Invoke(ctx, "/DDRPv1/AddPeer", in, out, opts...) + err := c.cc.Invoke(ctx, "/Footnotev1/AddPeer", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *dDRPv1Client) BanPeer(ctx context.Context, in *BanPeerReq, opts ...grpc.CallOption) (*Empty, error) { +func (c *footnotev1Client) BanPeer(ctx context.Context, in *BanPeerReq, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := c.cc.Invoke(ctx, "/DDRPv1/BanPeer", in, out, opts...) + err := c.cc.Invoke(ctx, "/Footnotev1/BanPeer", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *dDRPv1Client) UnbanPeer(ctx context.Context, in *UnbanPeerReq, opts ...grpc.CallOption) (*Empty, error) { +func (c *footnotev1Client) UnbanPeer(ctx context.Context, in *UnbanPeerReq, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := c.cc.Invoke(ctx, "/DDRPv1/UnbanPeer", in, out, opts...) + err := c.cc.Invoke(ctx, "/Footnotev1/UnbanPeer", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *dDRPv1Client) ListPeers(ctx context.Context, in *ListPeersReq, opts ...grpc.CallOption) (DDRPv1_ListPeersClient, error) { - stream, err := c.cc.NewStream(ctx, &_DDRPv1_serviceDesc.Streams[0], "/DDRPv1/ListPeers", opts...) +func (c *footnotev1Client) ListPeers(ctx context.Context, in *ListPeersReq, opts ...grpc.CallOption) (Footnotev1_ListPeersClient, error) { + stream, err := c.cc.NewStream(ctx, &_Footnotev1_serviceDesc.Streams[0], "/Footnotev1/ListPeers", opts...) if err != nil { return nil, err } - x := &dDRPv1ListPeersClient{stream} + x := &footnotev1ListPeersClient{stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -1919,16 +1920,16 @@ func (c *dDRPv1Client) ListPeers(ctx context.Context, in *ListPeersReq, opts ... return x, nil } -type DDRPv1_ListPeersClient interface { +type Footnotev1_ListPeersClient interface { Recv() (*ListPeersRes, error) grpc.ClientStream } -type dDRPv1ListPeersClient struct { +type footnotev1ListPeersClient struct { grpc.ClientStream } -func (x *dDRPv1ListPeersClient) Recv() (*ListPeersRes, error) { +func (x *footnotev1ListPeersClient) Recv() (*ListPeersRes, error) { m := new(ListPeersRes) if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err @@ -1936,57 +1937,57 @@ func (x *dDRPv1ListPeersClient) Recv() (*ListPeersRes, error) { return m, nil } -func (c *dDRPv1Client) Checkout(ctx context.Context, in *CheckoutReq, opts ...grpc.CallOption) (*CheckoutRes, error) { +func (c *footnotev1Client) Checkout(ctx context.Context, in *CheckoutReq, opts ...grpc.CallOption) (*CheckoutRes, error) { out := new(CheckoutRes) - err := c.cc.Invoke(ctx, "/DDRPv1/Checkout", in, out, opts...) + err := c.cc.Invoke(ctx, "/Footnotev1/Checkout", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *dDRPv1Client) WriteSector(ctx context.Context, in *WriteSectorReq, opts ...grpc.CallOption) (*WriteSectorRes, error) { +func (c *footnotev1Client) WriteSector(ctx context.Context, in *WriteSectorReq, opts ...grpc.CallOption) (*WriteSectorRes, error) { out := new(WriteSectorRes) - err := c.cc.Invoke(ctx, "/DDRPv1/WriteSector", in, out, opts...) + err := c.cc.Invoke(ctx, "/Footnotev1/WriteSector", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *dDRPv1Client) Commit(ctx context.Context, in *CommitReq, opts ...grpc.CallOption) (*CommitRes, error) { +func (c *footnotev1Client) Commit(ctx context.Context, in *CommitReq, opts ...grpc.CallOption) (*CommitRes, error) { out := new(CommitRes) - err := c.cc.Invoke(ctx, "/DDRPv1/Commit", in, out, opts...) + err := c.cc.Invoke(ctx, "/Footnotev1/Commit", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *dDRPv1Client) ReadAt(ctx context.Context, in *ReadAtReq, opts ...grpc.CallOption) (*ReadAtRes, error) { +func (c *footnotev1Client) ReadAt(ctx context.Context, in *ReadAtReq, opts ...grpc.CallOption) (*ReadAtRes, error) { out := new(ReadAtRes) - err := c.cc.Invoke(ctx, "/DDRPv1/ReadAt", in, out, opts...) + err := c.cc.Invoke(ctx, "/Footnotev1/ReadAt", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *dDRPv1Client) GetBlobInfo(ctx context.Context, in *BlobInfoReq, opts ...grpc.CallOption) (*BlobInfoRes, error) { +func (c *footnotev1Client) GetBlobInfo(ctx context.Context, in *BlobInfoReq, opts ...grpc.CallOption) (*BlobInfoRes, error) { out := new(BlobInfoRes) - err := c.cc.Invoke(ctx, "/DDRPv1/GetBlobInfo", in, out, opts...) + err := c.cc.Invoke(ctx, "/Footnotev1/GetBlobInfo", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *dDRPv1Client) ListBlobInfo(ctx context.Context, in *ListBlobInfoReq, opts ...grpc.CallOption) (DDRPv1_ListBlobInfoClient, error) { - stream, err := c.cc.NewStream(ctx, &_DDRPv1_serviceDesc.Streams[1], "/DDRPv1/ListBlobInfo", opts...) +func (c *footnotev1Client) ListBlobInfo(ctx context.Context, in *ListBlobInfoReq, opts ...grpc.CallOption) (Footnotev1_ListBlobInfoClient, error) { + stream, err := c.cc.NewStream(ctx, &_Footnotev1_serviceDesc.Streams[1], "/Footnotev1/ListBlobInfo", opts...) if err != nil { return nil, err } - x := &dDRPv1ListBlobInfoClient{stream} + x := &footnotev1ListBlobInfoClient{stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -1996,16 +1997,16 @@ func (c *dDRPv1Client) ListBlobInfo(ctx context.Context, in *ListBlobInfoReq, op return x, nil } -type DDRPv1_ListBlobInfoClient interface { +type Footnotev1_ListBlobInfoClient interface { Recv() (*BlobInfoRes, error) grpc.ClientStream } -type dDRPv1ListBlobInfoClient struct { +type footnotev1ListBlobInfoClient struct { grpc.ClientStream } -func (x *dDRPv1ListBlobInfoClient) Recv() (*BlobInfoRes, error) { +func (x *footnotev1ListBlobInfoClient) Recv() (*BlobInfoRes, error) { m := new(BlobInfoRes) if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err @@ -2013,352 +2014,352 @@ func (x *dDRPv1ListBlobInfoClient) Recv() (*BlobInfoRes, error) { return m, nil } -func (c *dDRPv1Client) SendUpdate(ctx context.Context, in *SendUpdateReq, opts ...grpc.CallOption) (*SendUpdateRes, error) { +func (c *footnotev1Client) SendUpdate(ctx context.Context, in *SendUpdateReq, opts ...grpc.CallOption) (*SendUpdateRes, error) { out := new(SendUpdateRes) - err := c.cc.Invoke(ctx, "/DDRPv1/SendUpdate", in, out, opts...) + err := c.cc.Invoke(ctx, "/Footnotev1/SendUpdate", in, out, opts...) if err != nil { return nil, err } return out, nil } -// DDRPv1Server is the server API for DDRPv1 service. -type DDRPv1Server interface { +// Footnotev1Server is the server API for Footnotev1 service. +type Footnotev1Server interface { GetStatus(context.Context, *Empty) (*GetStatusRes, error) AddPeer(context.Context, *AddPeerReq) (*Empty, error) BanPeer(context.Context, *BanPeerReq) (*Empty, error) UnbanPeer(context.Context, *UnbanPeerReq) (*Empty, error) - ListPeers(*ListPeersReq, DDRPv1_ListPeersServer) error + ListPeers(*ListPeersReq, Footnotev1_ListPeersServer) error Checkout(context.Context, *CheckoutReq) (*CheckoutRes, error) WriteSector(context.Context, *WriteSectorReq) (*WriteSectorRes, error) Commit(context.Context, *CommitReq) (*CommitRes, error) ReadAt(context.Context, *ReadAtReq) (*ReadAtRes, error) GetBlobInfo(context.Context, *BlobInfoReq) (*BlobInfoRes, error) - ListBlobInfo(*ListBlobInfoReq, DDRPv1_ListBlobInfoServer) error + ListBlobInfo(*ListBlobInfoReq, Footnotev1_ListBlobInfoServer) error SendUpdate(context.Context, *SendUpdateReq) (*SendUpdateRes, error) } -// UnimplementedDDRPv1Server can be embedded to have forward compatible implementations. -type UnimplementedDDRPv1Server struct { +// UnimplementedFootnotev1Server can be embedded to have forward compatible implementations. +type UnimplementedFootnotev1Server struct { } -func (*UnimplementedDDRPv1Server) GetStatus(context.Context, *Empty) (*GetStatusRes, error) { +func (*UnimplementedFootnotev1Server) GetStatus(context.Context, *Empty) (*GetStatusRes, error) { return nil, status.Errorf(codes.Unimplemented, "method GetStatus not implemented") } -func (*UnimplementedDDRPv1Server) AddPeer(context.Context, *AddPeerReq) (*Empty, error) { +func (*UnimplementedFootnotev1Server) AddPeer(context.Context, *AddPeerReq) (*Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method AddPeer not implemented") } -func (*UnimplementedDDRPv1Server) BanPeer(context.Context, *BanPeerReq) (*Empty, error) { +func (*UnimplementedFootnotev1Server) BanPeer(context.Context, *BanPeerReq) (*Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method BanPeer not implemented") } -func (*UnimplementedDDRPv1Server) UnbanPeer(context.Context, *UnbanPeerReq) (*Empty, error) { +func (*UnimplementedFootnotev1Server) UnbanPeer(context.Context, *UnbanPeerReq) (*Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method UnbanPeer not implemented") } -func (*UnimplementedDDRPv1Server) ListPeers(*ListPeersReq, DDRPv1_ListPeersServer) error { +func (*UnimplementedFootnotev1Server) ListPeers(*ListPeersReq, Footnotev1_ListPeersServer) error { return status.Errorf(codes.Unimplemented, "method ListPeers not implemented") } -func (*UnimplementedDDRPv1Server) Checkout(context.Context, *CheckoutReq) (*CheckoutRes, error) { +func (*UnimplementedFootnotev1Server) Checkout(context.Context, *CheckoutReq) (*CheckoutRes, error) { return nil, status.Errorf(codes.Unimplemented, "method Checkout not implemented") } -func (*UnimplementedDDRPv1Server) WriteSector(context.Context, *WriteSectorReq) (*WriteSectorRes, error) { +func (*UnimplementedFootnotev1Server) WriteSector(context.Context, *WriteSectorReq) (*WriteSectorRes, error) { return nil, status.Errorf(codes.Unimplemented, "method WriteSector not implemented") } -func (*UnimplementedDDRPv1Server) Commit(context.Context, *CommitReq) (*CommitRes, error) { +func (*UnimplementedFootnotev1Server) Commit(context.Context, *CommitReq) (*CommitRes, error) { return nil, status.Errorf(codes.Unimplemented, "method Commit not implemented") } -func (*UnimplementedDDRPv1Server) ReadAt(context.Context, *ReadAtReq) (*ReadAtRes, error) { +func (*UnimplementedFootnotev1Server) ReadAt(context.Context, *ReadAtReq) (*ReadAtRes, error) { return nil, status.Errorf(codes.Unimplemented, "method ReadAt not implemented") } -func (*UnimplementedDDRPv1Server) GetBlobInfo(context.Context, *BlobInfoReq) (*BlobInfoRes, error) { +func (*UnimplementedFootnotev1Server) GetBlobInfo(context.Context, *BlobInfoReq) (*BlobInfoRes, error) { return nil, status.Errorf(codes.Unimplemented, "method GetBlobInfo not implemented") } -func (*UnimplementedDDRPv1Server) ListBlobInfo(*ListBlobInfoReq, DDRPv1_ListBlobInfoServer) error { +func (*UnimplementedFootnotev1Server) ListBlobInfo(*ListBlobInfoReq, Footnotev1_ListBlobInfoServer) error { return status.Errorf(codes.Unimplemented, "method ListBlobInfo not implemented") } -func (*UnimplementedDDRPv1Server) SendUpdate(context.Context, *SendUpdateReq) (*SendUpdateRes, error) { +func (*UnimplementedFootnotev1Server) SendUpdate(context.Context, *SendUpdateReq) (*SendUpdateRes, error) { return nil, status.Errorf(codes.Unimplemented, "method SendUpdate not implemented") } -func RegisterDDRPv1Server(s *grpc.Server, srv DDRPv1Server) { - s.RegisterService(&_DDRPv1_serviceDesc, srv) +func RegisterFootnotev1Server(s *grpc.Server, srv Footnotev1Server) { + s.RegisterService(&_Footnotev1_serviceDesc, srv) } -func _DDRPv1_GetStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Footnotev1_GetStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(DDRPv1Server).GetStatus(ctx, in) + return srv.(Footnotev1Server).GetStatus(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/DDRPv1/GetStatus", + FullMethod: "/Footnotev1/GetStatus", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DDRPv1Server).GetStatus(ctx, req.(*Empty)) + return srv.(Footnotev1Server).GetStatus(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } -func _DDRPv1_AddPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Footnotev1_AddPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AddPeerReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(DDRPv1Server).AddPeer(ctx, in) + return srv.(Footnotev1Server).AddPeer(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/DDRPv1/AddPeer", + FullMethod: "/Footnotev1/AddPeer", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DDRPv1Server).AddPeer(ctx, req.(*AddPeerReq)) + return srv.(Footnotev1Server).AddPeer(ctx, req.(*AddPeerReq)) } return interceptor(ctx, in, info, handler) } -func _DDRPv1_BanPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Footnotev1_BanPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(BanPeerReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(DDRPv1Server).BanPeer(ctx, in) + return srv.(Footnotev1Server).BanPeer(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/DDRPv1/BanPeer", + FullMethod: "/Footnotev1/BanPeer", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DDRPv1Server).BanPeer(ctx, req.(*BanPeerReq)) + return srv.(Footnotev1Server).BanPeer(ctx, req.(*BanPeerReq)) } return interceptor(ctx, in, info, handler) } -func _DDRPv1_UnbanPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Footnotev1_UnbanPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(UnbanPeerReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(DDRPv1Server).UnbanPeer(ctx, in) + return srv.(Footnotev1Server).UnbanPeer(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/DDRPv1/UnbanPeer", + FullMethod: "/Footnotev1/UnbanPeer", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DDRPv1Server).UnbanPeer(ctx, req.(*UnbanPeerReq)) + return srv.(Footnotev1Server).UnbanPeer(ctx, req.(*UnbanPeerReq)) } return interceptor(ctx, in, info, handler) } -func _DDRPv1_ListPeers_Handler(srv interface{}, stream grpc.ServerStream) error { +func _Footnotev1_ListPeers_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(ListPeersReq) if err := stream.RecvMsg(m); err != nil { return err } - return srv.(DDRPv1Server).ListPeers(m, &dDRPv1ListPeersServer{stream}) + return srv.(Footnotev1Server).ListPeers(m, &footnotev1ListPeersServer{stream}) } -type DDRPv1_ListPeersServer interface { +type Footnotev1_ListPeersServer interface { Send(*ListPeersRes) error grpc.ServerStream } -type dDRPv1ListPeersServer struct { +type footnotev1ListPeersServer struct { grpc.ServerStream } -func (x *dDRPv1ListPeersServer) Send(m *ListPeersRes) error { +func (x *footnotev1ListPeersServer) Send(m *ListPeersRes) error { return x.ServerStream.SendMsg(m) } -func _DDRPv1_Checkout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Footnotev1_Checkout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CheckoutReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(DDRPv1Server).Checkout(ctx, in) + return srv.(Footnotev1Server).Checkout(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/DDRPv1/Checkout", + FullMethod: "/Footnotev1/Checkout", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DDRPv1Server).Checkout(ctx, req.(*CheckoutReq)) + return srv.(Footnotev1Server).Checkout(ctx, req.(*CheckoutReq)) } return interceptor(ctx, in, info, handler) } -func _DDRPv1_WriteSector_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Footnotev1_WriteSector_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(WriteSectorReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(DDRPv1Server).WriteSector(ctx, in) + return srv.(Footnotev1Server).WriteSector(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/DDRPv1/WriteSector", + FullMethod: "/Footnotev1/WriteSector", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DDRPv1Server).WriteSector(ctx, req.(*WriteSectorReq)) + return srv.(Footnotev1Server).WriteSector(ctx, req.(*WriteSectorReq)) } return interceptor(ctx, in, info, handler) } -func _DDRPv1_Commit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Footnotev1_Commit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CommitReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(DDRPv1Server).Commit(ctx, in) + return srv.(Footnotev1Server).Commit(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/DDRPv1/Commit", + FullMethod: "/Footnotev1/Commit", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DDRPv1Server).Commit(ctx, req.(*CommitReq)) + return srv.(Footnotev1Server).Commit(ctx, req.(*CommitReq)) } return interceptor(ctx, in, info, handler) } -func _DDRPv1_ReadAt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Footnotev1_ReadAt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ReadAtReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(DDRPv1Server).ReadAt(ctx, in) + return srv.(Footnotev1Server).ReadAt(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/DDRPv1/ReadAt", + FullMethod: "/Footnotev1/ReadAt", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DDRPv1Server).ReadAt(ctx, req.(*ReadAtReq)) + return srv.(Footnotev1Server).ReadAt(ctx, req.(*ReadAtReq)) } return interceptor(ctx, in, info, handler) } -func _DDRPv1_GetBlobInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Footnotev1_GetBlobInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(BlobInfoReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(DDRPv1Server).GetBlobInfo(ctx, in) + return srv.(Footnotev1Server).GetBlobInfo(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/DDRPv1/GetBlobInfo", + FullMethod: "/Footnotev1/GetBlobInfo", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DDRPv1Server).GetBlobInfo(ctx, req.(*BlobInfoReq)) + return srv.(Footnotev1Server).GetBlobInfo(ctx, req.(*BlobInfoReq)) } return interceptor(ctx, in, info, handler) } -func _DDRPv1_ListBlobInfo_Handler(srv interface{}, stream grpc.ServerStream) error { +func _Footnotev1_ListBlobInfo_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(ListBlobInfoReq) if err := stream.RecvMsg(m); err != nil { return err } - return srv.(DDRPv1Server).ListBlobInfo(m, &dDRPv1ListBlobInfoServer{stream}) + return srv.(Footnotev1Server).ListBlobInfo(m, &footnotev1ListBlobInfoServer{stream}) } -type DDRPv1_ListBlobInfoServer interface { +type Footnotev1_ListBlobInfoServer interface { Send(*BlobInfoRes) error grpc.ServerStream } -type dDRPv1ListBlobInfoServer struct { +type footnotev1ListBlobInfoServer struct { grpc.ServerStream } -func (x *dDRPv1ListBlobInfoServer) Send(m *BlobInfoRes) error { +func (x *footnotev1ListBlobInfoServer) Send(m *BlobInfoRes) error { return x.ServerStream.SendMsg(m) } -func _DDRPv1_SendUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Footnotev1_SendUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SendUpdateReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(DDRPv1Server).SendUpdate(ctx, in) + return srv.(Footnotev1Server).SendUpdate(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/DDRPv1/SendUpdate", + FullMethod: "/Footnotev1/SendUpdate", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DDRPv1Server).SendUpdate(ctx, req.(*SendUpdateReq)) + return srv.(Footnotev1Server).SendUpdate(ctx, req.(*SendUpdateReq)) } return interceptor(ctx, in, info, handler) } -var _DDRPv1_serviceDesc = grpc.ServiceDesc{ - ServiceName: "DDRPv1", - HandlerType: (*DDRPv1Server)(nil), +var _Footnotev1_serviceDesc = grpc.ServiceDesc{ + ServiceName: "Footnotev1", + HandlerType: (*Footnotev1Server)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GetStatus", - Handler: _DDRPv1_GetStatus_Handler, + Handler: _Footnotev1_GetStatus_Handler, }, { MethodName: "AddPeer", - Handler: _DDRPv1_AddPeer_Handler, + Handler: _Footnotev1_AddPeer_Handler, }, { MethodName: "BanPeer", - Handler: _DDRPv1_BanPeer_Handler, + Handler: _Footnotev1_BanPeer_Handler, }, { MethodName: "UnbanPeer", - Handler: _DDRPv1_UnbanPeer_Handler, + Handler: _Footnotev1_UnbanPeer_Handler, }, { MethodName: "Checkout", - Handler: _DDRPv1_Checkout_Handler, + Handler: _Footnotev1_Checkout_Handler, }, { MethodName: "WriteSector", - Handler: _DDRPv1_WriteSector_Handler, + Handler: _Footnotev1_WriteSector_Handler, }, { MethodName: "Commit", - Handler: _DDRPv1_Commit_Handler, + Handler: _Footnotev1_Commit_Handler, }, { MethodName: "ReadAt", - Handler: _DDRPv1_ReadAt_Handler, + Handler: _Footnotev1_ReadAt_Handler, }, { MethodName: "GetBlobInfo", - Handler: _DDRPv1_GetBlobInfo_Handler, + Handler: _Footnotev1_GetBlobInfo_Handler, }, { MethodName: "SendUpdate", - Handler: _DDRPv1_SendUpdate_Handler, + Handler: _Footnotev1_SendUpdate_Handler, }, }, Streams: []grpc.StreamDesc{ { StreamName: "ListPeers", - Handler: _DDRPv1_ListPeers_Handler, + Handler: _Footnotev1_ListPeers_Handler, ServerStreams: true, }, { StreamName: "ListBlobInfo", - Handler: _DDRPv1_ListBlobInfo_Handler, + Handler: _Footnotev1_ListBlobInfo_Handler, ServerStreams: true, }, }, diff --git a/rpc/v1/api.proto b/rpc/v1/api.proto index c1b4c7e..f84062d 100644 --- a/rpc/v1/api.proto +++ b/rpc/v1/api.proto @@ -1,7 +1,7 @@ syntax = "proto3"; option go_package = "v1"; -service DDRPv1 { +service Footnotev1 { rpc GetStatus (Empty) returns (GetStatusRes); rpc AddPeer (AddPeerReq) returns (Empty); diff --git a/scripts/release-public.sh b/scripts/release-public.sh index b0c10d6..ec69060 100755 --- a/scripts/release-public.sh +++ b/scripts/release-public.sh @@ -8,9 +8,9 @@ tag="$(git describe --tags --abbrev=0)" version="${tag:1}" create_tarball() { - mv -f "$build_dir/ddrpd-$1-amd64" "$build_dir/ddrpd" - mv -f "$build_dir/ddrpcli-$1-amd64" "$build_dir/ddrpcli" - tar -czvf "$build_dir/ddrp-$version-$1-amd64.tgz" -C "$build_dir" "ddrpd" "ddrpcli" + mv -f "$build_dir/fnd-$1-amd64" "$build_dir/ddrpd" + mv -f "$build_dir/fnd-cli-$1-amd64" "$build_dir/fnd-cli" + tar -czvf "$build_dir/ddrp-$version-$1-amd64.tgz" -C "$build_dir" "fnd" "fnd-cli" gpg2 --detach-sig --default-key D4B604F1 --output "$build_dir/ddrp-$version-$1-amd64.tgz.sig" "$build_dir/ddrp-$version-$1-amd64.tgz" } @@ -44,4 +44,4 @@ s3cmd setacl s3://ddrp-releases/ddrp-linux-amd64.tgz.sig --acl-public cp "$build_dir/ddrp-$version-linux-amd64.tgz" "$build_dir/ddrp-linux-amd64.tgz" cd "$build_dir" && shasum -a 256 "ddrp-linux-amd64.tgz" > /tmp/ddrp-linux-amd64.tgz.sum.txt && cd "$DIR" s3cmd put /tmp/ddrp-linux-amd64.tgz.sum.txt s3://ddrp-releases/ddrp-linux-amd64.tgz.sum.txt -s3cmd setacl s3://ddrp-releases/ddrp-linux-amd64.tgz.sum.txt --acl-public \ No newline at end of file +s3cmd setacl s3://ddrp-releases/ddrp-linux-amd64.tgz.sum.txt --acl-public diff --git a/version/version.go b/version/version.go index 020dbae..2811260 100644 --- a/version/version.go +++ b/version/version.go @@ -7,5 +7,5 @@ var GitTag string var UserAgent string func init() { - UserAgent = fmt.Sprintf("ddrpd/%s+%s", GitTag, GitCommit) + UserAgent = fmt.Sprintf("fnd/%s+%s", GitTag, GitCommit) } From 33b74f19d19e2185411f8d6587b363503d66bf5c Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 18 Jan 2021 20:05:18 +0530 Subject: [PATCH 04/71] all: cleanup --- blob/blob.go | 3 +- blob/blob_mock_test.go | 7 + blob/blob_test.go | 7 +- blob/consts.go | 4 +- blob/io.go | 3 +- blob/io_test.go | 9 +- blob/merkle.go | 316 --------------------- blob/merkle_test.go | 95 ------- blob/pathify.go | 2 +- blob/seal.go | 3 +- blob/seal_test.go | 4 +- blob/store_test.go | 5 +- blob/transaction.go | 3 +- blob/transaction_test.go | 6 +- blob/util_test.go | 3 +- cli/homedir.go | 1 - cmd/fnd-cli/cmd/blob/info.go | 10 +- cmd/fnd-cli/cmd/blob/list.go | 3 +- cmd/fnd-cli/cmd/blob/read.go | 3 +- cmd/fnd-cli/cmd/blob/write.go | 6 +- cmd/fnd-cli/cmd/identity.go | 6 +- cmd/fnd-cli/cmd/init.go | 1 - cmd/fnd-cli/cmd/net/add_peer.go | 3 +- cmd/fnd-cli/cmd/net/ban_peer.go | 3 +- cmd/fnd-cli/cmd/net/net.go | 2 +- cmd/fnd-cli/cmd/net/peer_info.go | 3 +- cmd/fnd-cli/cmd/net/status.go | 5 +- cmd/fnd-cli/cmd/net/unban_peer.go | 1 - cmd/fnd-cli/cmd/root.go | 5 +- cmd/fnd-cli/cmd/unsafe/reset_blobs.go | 5 +- cmd/fnd-cli/cmd/unsafe/reset_name_store.go | 3 +- cmd/fnd-cli/cmd/unsafe/reset_peer_store.go | 3 +- cmd/fnd-cli/cmd/version.go | 1 - cmd/fnd/cmd/init.go | 1 - cmd/fnd/cmd/root.go | 5 +- cmd/fnd/cmd/start.go | 20 +- cmd/fnd/cmd/version.go | 1 - config/config.go | 5 +- config/default.go | 23 +- config/home.go | 3 +- dwire/.gitignore | 18 -- dwire/Makefile | 8 - dwire/README.md | 167 ----------- dwire/decode.go | 228 --------------- dwire/decode_test.go | 166 ----------- dwire/doc.go | 54 ---- dwire/encode.go | 135 --------- dwire/encode_test.go | 105 ------- dwire/encoder.go | 42 --- dwire/encoding_bench_test.go | 107 ------- dwire/well_known.go | 62 ---- dwire/well_known_test.go | 37 --- go.mod | 15 +- go.sum | 35 ++- p2p/counting_reader_test.go | 3 +- p2p/incoming_handshake.go | 1 - p2p/incoming_handshake_test.go | 36 ++- p2p/listener.go | 3 +- p2p/outgoing_handshake.go | 3 +- p2p/outgoing_handshake_test.go | 5 +- p2p/peer.go | 3 +- p2p/peer_manager.go | 7 +- p2p/peer_muxer.go | 3 +- p2p/peer_test.go | 3 +- p2p/seed_test.go | 10 +- p2p/seeds.go | 3 +- protocol/ban_list.go | 6 +- protocol/ban_list_test.go | 36 +-- protocol/epoch.go | 2 +- protocol/heartbeater.go | 3 +- protocol/heartbeater_test.go | 3 +- protocol/moderation.go | 3 +- protocol/moderation_test.go | 7 +- protocol/name_importer.go | 47 +-- protocol/name_importer_test.go | 23 +- protocol/name_syncer.go | 19 +- protocol/peer_exchanger.go | 3 +- protocol/peer_set_test.go | 3 +- protocol/pinger_test.go | 3 +- protocol/sector_server.go | 4 +- protocol/syncer.go | 5 +- protocol/syncer_test.go | 209 -------------- protocol/testdata/blob | Bin 16777216 -> 16777217 bytes protocol/testdata/block8506.json | 2 +- protocol/timebank.go | 39 --- protocol/timebank_test.go | 100 ------- protocol/transaction_mock_test.go | 1 - protocol/update_queue.go | 12 +- protocol/update_queue_test.go | 6 +- protocol/update_server_test.go | 12 +- protocol/updater.go | 6 +- protocol/updater_test.go | 6 +- protocol/util_test.go | 5 +- rpc/blob.go | 8 +- rpc/blob_writer.go | 4 +- rpc/server.go | 10 +- rpc/v1/api.pb.go | 4 +- scripts/gen-node-bindings.sh | 2 +- scripts/release-public.sh | 34 +-- store/headers.go | 8 +- store/headers_test.go | 6 +- store/naming_test.go | 3 +- store/peers.go | 5 +- store/peers_test.go | 5 +- store/store.go | 1 - testutil/mockapp/peer.go | 3 +- testutil/mockapp/storage.go | 8 +- testutil/net.go | 3 +- testutil/testcrypto/crypto.go | 5 +- wire/blob_req.go | 2 +- wire/blob_res.go | 2 +- wire/envelope.go | 5 +- wire/hash_cacher.go | 5 +- wire/hash_cacher_test.go | 8 +- wire/hello.go | 8 +- wire/hello_ack.go | 5 +- wire/message.go | 5 +- wire/nil_update.go | 5 +- wire/peer_res.go | 5 +- wire/testdata/hello | Bin 108 -> 109 bytes wire/testdata/hello_ack | Bin 32 -> 33 bytes wire/testdata/nil_update | 2 +- wire/testdata/peer_res | Bin 97 -> 98 bytes wire/update.go | 5 +- wire/update_req.go | 5 +- wire/util_test.go | 9 +- 126 files changed, 326 insertions(+), 2270 deletions(-) delete mode 100644 blob/merkle.go delete mode 100644 blob/merkle_test.go delete mode 100644 dwire/.gitignore delete mode 100644 dwire/Makefile delete mode 100644 dwire/README.md delete mode 100644 dwire/decode.go delete mode 100644 dwire/decode_test.go delete mode 100644 dwire/doc.go delete mode 100644 dwire/encode.go delete mode 100644 dwire/encode_test.go delete mode 100644 dwire/encoder.go delete mode 100644 dwire/encoding_bench_test.go delete mode 100644 dwire/well_known.go delete mode 100644 dwire/well_known_test.go delete mode 100644 protocol/syncer_test.go delete mode 100644 protocol/timebank.go delete mode 100644 protocol/timebank_test.go diff --git a/blob/blob.go b/blob/blob.go index 58c848b..73884c2 100644 --- a/blob/blob.go +++ b/blob/blob.go @@ -1,12 +1,11 @@ package blob import ( + "github.com/pkg/errors" "io" "io/ioutil" "os" "sync" - - "github.com/pkg/errors" ) type SectorReader interface { diff --git a/blob/blob_mock_test.go b/blob/blob_mock_test.go index 1b49adb..11762fe 100644 --- a/blob/blob_mock_test.go +++ b/blob/blob_mock_test.go @@ -26,6 +26,13 @@ func (b BlobMock) Name() string { return args.String(0) } +func (b BlobMock) Seek(sectorSize uint16) { +} + +func (b BlobMock) At() uint16 { + return 0 +} + func (b BlobMock) Transaction() (Transaction, error) { args := b.Called() return args.Get(0).(Transaction), args.Error(1) diff --git a/blob/blob_test.go b/blob/blob_test.go index af709b8..e5e430e 100644 --- a/blob/blob_test.go +++ b/blob/blob_test.go @@ -2,10 +2,9 @@ package blob import ( "crypto/rand" + "github.com/stretchr/testify/require" "io" "testing" - - "github.com/stretchr/testify/require" ) // note: transaction functionality is tested in transaction_test.go @@ -19,13 +18,13 @@ func TestBlob_Reading(t *testing.T) { require.Equal(t, "foobar", bl.Name()) var expSector Sector - _, err = f.ReadAt(expSector[:], 256) + _, err = f.ReadAt(expSector[:], 65536) require.NoError(t, err) actSector, err := bl.ReadSector(1) require.NoError(t, err) require.Equal(t, expSector, actSector) actData := make([]byte, 10, 10) - _, err = bl.ReadAt(actData, 256) + _, err = bl.ReadAt(actData, 65536) require.NoError(t, err) require.EqualValues(t, expSector[:10], actData) } diff --git a/blob/consts.go b/blob/consts.go index e406d6a..43e0668 100644 --- a/blob/consts.go +++ b/blob/consts.go @@ -2,8 +2,8 @@ package blob const ( HeaderLen = 1 + 1 + 63 + 8 + 32 + 65 - SectorLen = 256 - SectorCount = 4096 + SectorLen = 4096 + SectorCount = 256 Size = SectorLen * SectorCount CurrentVersion = 1 ) diff --git a/blob/io.go b/blob/io.go index 0b3cb7e..8272ec1 100644 --- a/blob/io.go +++ b/blob/io.go @@ -1,9 +1,8 @@ package blob import ( - "io" - "github.com/pkg/errors" + "io" ) var ( diff --git a/blob/io_test.go b/blob/io_test.go index 2dd6995..b266c47 100644 --- a/blob/io_test.go +++ b/blob/io_test.go @@ -1,10 +1,9 @@ package blob import ( + "github.com/stretchr/testify/require" "io" "testing" - - "github.com/stretchr/testify/require" ) type zeroReader struct{} @@ -111,7 +110,7 @@ func TestReadSector(t *testing.T) { }, { 255, - 65280, + 16711680, }, } r := &readerWrapper{ @@ -181,7 +180,7 @@ func TestWriteBlobAt(t *testing.T) { func TestWriteSector(t *testing.T) { tests := []struct { - id uint8 + id uint16 offset int64 }{ { @@ -190,7 +189,7 @@ func TestWriteSector(t *testing.T) { }, { 255, - 65280, + 16711680, }, } w := &writerWrapper{ diff --git a/blob/merkle.go b/blob/merkle.go deleted file mode 100644 index ee4a814..0000000 --- a/blob/merkle.go +++ /dev/null @@ -1,316 +0,0 @@ -package blob - -import ( - "bytes" - "io" - "math" - "math/bits" - "strings" - - "fnd/crypto" - - "github.com/pkg/errors" -) - -const ( - MerkleTreeHeight = 8 - MerkleProofLen = 8 * 32 - - SubsectorSize = 256 - SubsectorCountBlob = Size / SubsectorSize - SubsectorCountSector = SectorLen / SubsectorSize - SubsectorProofLevel = 8 -) - -var ( - precomputes = map[crypto.Hash]crypto.Hash{ - // merkle tree levels, starting from base - // assuming 4096 byte sub-sectors - {0x68, 0x6e, 0xde, 0x92, 0x88, 0xc3, 0x91, 0xe7, 0xe0, 0x50, 0x26, 0xe5, 0x6f, 0x2f, 0x91, 0xbf, 0xd8, 0x79, 0x98, 0x7a, 0x04, 0x0e, 0xa9, 0x84, 0x45, 0xda, 0xbc, 0x76, 0xf5, 0x5b, 0x8e, 0x5f}: {0x49, 0xe4, 0xb8, 0x0d, 0x5b, 0x7d, 0x8d, 0x93, 0x22, 0x48, 0x25, 0xf2, 0x6c, 0x45, 0x98, 0x7e, 0x10, 0x7b, 0xbf, 0x2f, 0x87, 0x1d, 0x4e, 0x56, 0x36, 0xac, 0x55, 0x0f, 0xf1, 0x25, 0xe0, 0x82}, - {0x49, 0xe4, 0xb8, 0x0d, 0x5b, 0x7d, 0x8d, 0x93, 0x22, 0x48, 0x25, 0xf2, 0x6c, 0x45, 0x98, 0x7e, 0x10, 0x7b, 0xbf, 0x2f, 0x87, 0x1d, 0x4e, 0x56, 0x36, 0xac, 0x55, 0x0f, 0xf1, 0x25, 0xe0, 0x82}: {0xb7, 0x95, 0x51, 0x37, 0x10, 0x7e, 0x8c, 0x87, 0x98, 0x94, 0xa9, 0x47, 0xa2, 0x35, 0xec, 0xd2, 0xa4, 0x22, 0x5a, 0x6c, 0x82, 0x12, 0x97, 0x6e, 0x97, 0x6c, 0x50, 0x31, 0x9b, 0x59, 0x31, 0xb3}, - {0xb7, 0x95, 0x51, 0x37, 0x10, 0x7e, 0x8c, 0x87, 0x98, 0x94, 0xa9, 0x47, 0xa2, 0x35, 0xec, 0xd2, 0xa4, 0x22, 0x5a, 0x6c, 0x82, 0x12, 0x97, 0x6e, 0x97, 0x6c, 0x50, 0x31, 0x9b, 0x59, 0x31, 0xb3}: {0x47, 0x19, 0x5c, 0x0c, 0xa9, 0x4e, 0x02, 0x20, 0xcd, 0x01, 0xbe, 0x88, 0x32, 0x00, 0xfd, 0xbf, 0x71, 0x48, 0x13, 0x64, 0x94, 0x2b, 0xa1, 0xe8, 0xd3, 0xef, 0x4c, 0x9a, 0x3d, 0xc4, 0xb6, 0xa5}, - {0x47, 0x19, 0x5c, 0x0c, 0xa9, 0x4e, 0x02, 0x20, 0xcd, 0x01, 0xbe, 0x88, 0x32, 0x00, 0xfd, 0xbf, 0x71, 0x48, 0x13, 0x64, 0x94, 0x2b, 0xa1, 0xe8, 0xd3, 0xef, 0x4c, 0x9a, 0x3d, 0xc4, 0xb6, 0xa5}: {0x53, 0x2a, 0x12, 0xf0, 0x9f, 0xeb, 0xf8, 0x52, 0x14, 0x19, 0x95, 0x99, 0x73, 0xad, 0x53, 0x46, 0x94, 0x4c, 0x2b, 0x22, 0xbf, 0x76, 0x4d, 0x0e, 0x1a, 0x34, 0x25, 0x5b, 0x65, 0x64, 0xfe, 0x4b}, - {0x53, 0x2a, 0x12, 0xf0, 0x9f, 0xeb, 0xf8, 0x52, 0x14, 0x19, 0x95, 0x99, 0x73, 0xad, 0x53, 0x46, 0x94, 0x4c, 0x2b, 0x22, 0xbf, 0x76, 0x4d, 0x0e, 0x1a, 0x34, 0x25, 0x5b, 0x65, 0x64, 0xfe, 0x4b}: {0xff, 0xe2, 0xcf, 0x7e, 0xcd, 0x1b, 0x99, 0x32, 0x35, 0x74, 0x6b, 0xe2, 0x1e, 0x91, 0xc8, 0xe6, 0x1a, 0x1e, 0x22, 0xda, 0xce, 0x98, 0x50, 0x91, 0x25, 0x85, 0x41, 0x65, 0x01, 0xe9, 0x84, 0x47}, - {0xff, 0xe2, 0xcf, 0x7e, 0xcd, 0x1b, 0x99, 0x32, 0x35, 0x74, 0x6b, 0xe2, 0x1e, 0x91, 0xc8, 0xe6, 0x1a, 0x1e, 0x22, 0xda, 0xce, 0x98, 0x50, 0x91, 0x25, 0x85, 0x41, 0x65, 0x01, 0xe9, 0x84, 0x47}: {0x60, 0x52, 0x2e, 0x01, 0x34, 0x1f, 0xe9, 0x62, 0x54, 0x66, 0x8b, 0xa1, 0xbc, 0x2c, 0x79, 0xdd, 0x6f, 0xc6, 0x6b, 0x37, 0x84, 0xc2, 0xeb, 0x39, 0xd4, 0xf0, 0x73, 0x19, 0xc6, 0x23, 0x26, 0x57}, - {0x60, 0x52, 0x2e, 0x01, 0x34, 0x1f, 0xe9, 0x62, 0x54, 0x66, 0x8b, 0xa1, 0xbc, 0x2c, 0x79, 0xdd, 0x6f, 0xc6, 0x6b, 0x37, 0x84, 0xc2, 0xeb, 0x39, 0xd4, 0xf0, 0x73, 0x19, 0xc6, 0x23, 0x26, 0x57}: {0xae, 0x01, 0x82, 0xab, 0x78, 0x03, 0xfc, 0x44, 0xd0, 0x85, 0xc1, 0xc7, 0x34, 0xa5, 0x52, 0xff, 0xfd, 0xb0, 0xf7, 0x44, 0x17, 0x9f, 0x0d, 0x95, 0xbd, 0x60, 0xdd, 0x6f, 0x8f, 0x18, 0x18, 0xaf}, - {0xae, 0x01, 0x82, 0xab, 0x78, 0x03, 0xfc, 0x44, 0xd0, 0x85, 0xc1, 0xc7, 0x34, 0xa5, 0x52, 0xff, 0xfd, 0xb0, 0xf7, 0x44, 0x17, 0x9f, 0x0d, 0x95, 0xbd, 0x60, 0xdd, 0x6f, 0x8f, 0x18, 0x18, 0xaf}: {0xf3, 0x4c, 0x7d, 0x70, 0xb6, 0x52, 0xeb, 0xa4, 0x8e, 0x02, 0xb4, 0x71, 0x7e, 0x1f, 0x0a, 0x2b, 0xe9, 0x33, 0x7b, 0x07, 0x51, 0xcc, 0xf7, 0xbf, 0x36, 0x44, 0x67, 0x4c, 0xbe, 0x64, 0x23, 0xd5}, - {0xf3, 0x4c, 0x7d, 0x70, 0xb6, 0x52, 0xeb, 0xa4, 0x8e, 0x02, 0xb4, 0x71, 0x7e, 0x1f, 0x0a, 0x2b, 0xe9, 0x33, 0x7b, 0x07, 0x51, 0xcc, 0xf7, 0xbf, 0x36, 0x44, 0x67, 0x4c, 0xbe, 0x64, 0x23, 0xd5}: {0x32, 0x00, 0xb9, 0x9b, 0xfc, 0xd8, 0x2c, 0x64, 0xc8, 0x18, 0xb1, 0xa2, 0xb2, 0x6e, 0x14, 0xbf, 0x78, 0x4f, 0xe9, 0x18, 0x8a, 0x55, 0x9b, 0x6b, 0x38, 0xa6, 0xdd, 0xa4, 0xfb, 0x55, 0x31, 0x47}, - {0x32, 0x00, 0xb9, 0x9b, 0xfc, 0xd8, 0x2c, 0x64, 0xc8, 0x18, 0xb1, 0xa2, 0xb2, 0x6e, 0x14, 0xbf, 0x78, 0x4f, 0xe9, 0x18, 0x8a, 0x55, 0x9b, 0x6b, 0x38, 0xa6, 0xdd, 0xa4, 0xfb, 0x55, 0x31, 0x47}: {0xb8, 0x6b, 0xe3, 0xa8, 0xb2, 0x88, 0xb0, 0xef, 0x0b, 0x7e, 0xe5, 0xa9, 0x85, 0x2d, 0x11, 0x81, 0x67, 0xa5, 0x0c, 0x84, 0x71, 0xbf, 0xb9, 0xfb, 0x8f, 0x0c, 0x79, 0x92, 0xf4, 0x52, 0xc7, 0x9c}, - {0xb8, 0x6b, 0xe3, 0xa8, 0xb2, 0x88, 0xb0, 0xef, 0x0b, 0x7e, 0xe5, 0xa9, 0x85, 0x2d, 0x11, 0x81, 0x67, 0xa5, 0x0c, 0x84, 0x71, 0xbf, 0xb9, 0xfb, 0x8f, 0x0c, 0x79, 0x92, 0xf4, 0x52, 0xc7, 0x9c}: {0xaa, 0xbd, 0xcb, 0xb2, 0x3b, 0xfc, 0xea, 0xfe, 0x71, 0xf3, 0x83, 0x4a, 0x17, 0xec, 0x1d, 0x24, 0xbd, 0x4e, 0xf2, 0xda, 0xed, 0x68, 0xd2, 0xcc, 0xc3, 0xc2, 0x98, 0x9f, 0xd0, 0x92, 0xe3, 0x53}, - {0xaa, 0xbd, 0xcb, 0xb2, 0x3b, 0xfc, 0xea, 0xfe, 0x71, 0xf3, 0x83, 0x4a, 0x17, 0xec, 0x1d, 0x24, 0xbd, 0x4e, 0xf2, 0xda, 0xed, 0x68, 0xd2, 0xcc, 0xc3, 0xc2, 0x98, 0x9f, 0xd0, 0x92, 0xe3, 0x53}: {0x7d, 0x1e, 0x84, 0xe6, 0x2d, 0x7e, 0xc9, 0xf6, 0xbc, 0x3f, 0x88, 0x66, 0x75, 0x73, 0x3d, 0xa0, 0x6d, 0xaf, 0x02, 0x77, 0xad, 0x8f, 0xfc, 0xf7, 0xc5, 0x39, 0x93, 0x8c, 0xa5, 0xee, 0x9c, 0xf2}, - } - - zero4kSector = make([]byte, 4096) - zero4kSectorHash = crypto.Hash{0x68, 0x6e, 0xde, 0x92, 0x88, 0xc3, 0x91, 0xe7, 0xe0, 0x50, 0x26, 0xe5, 0x6f, 0x2f, 0x91, 0xbf, 0xd8, 0x79, 0x98, 0x7a, 0x04, 0x0e, 0xa9, 0x84, 0x45, 0xda, 0xbc, 0x76, 0xf5, 0x5b, 0x8e, 0x5f} - EmptyBlobMerkleRoot = crypto.Hash{0x0c, 0x63, 0x8a, 0xfe, 0x73, 0x32, 0x49, 0x76, 0x16, 0x59, 0x07, 0xbc, 0x33, 0x86, 0x2e, 0xbf, 0x74, 0xe9, 0x71, 0x32, 0x66, 0x6e, 0x6a, 0x68, 0x15, 0x4f, 0xe9, 0xf7, 0x42, 0xf4, 0x45, 0x7f} - EmptyBlobBaseHash = crypto.Hash{0xe, 0x57, 0x51, 0xc0, 0x26, 0xe5, 0x43, 0xb2, 0xe8, 0xab, 0x2e, 0xb0, 0x60, 0x99, 0xda, 0xa1, 0xd1, 0xe5, 0xdf, 0x47, 0x77, 0x8f, 0x77, 0x87, 0xfa, 0xab, 0x45, 0xcd, 0xf1, 0x2f, 0xe3, 0xa8} - ZeroMerkleBase MerkleBase -) - -type MerkleBase [256]crypto.Hash - -func (m MerkleBase) Encode(w io.Writer) error { - for _, h := range m { - if _, err := w.Write(h[:]); err != nil { - return err - } - } - return nil -} - -func (m *MerkleBase) Decode(r io.Reader) error { - var res MerkleBase - var hash crypto.Hash - for i := 0; i < len(res); i++ { - if _, err := r.Read(hash[:]); err != nil { - return err - } - res[i] = hash - } - - *m = res - return nil -} - -func (m MerkleBase) DiffWith(other MerkleBase) []uint8 { - if m == other { - return nil - } - - var out []uint8 - for i := 0; i < len(m); i++ { - if m[i] != other[i] { - out = append(out, uint8(i)) - } - } - return out -} - -type MerkleProof [MerkleProofLen]byte - -func (m MerkleProof) Encode(w io.Writer) error { - _, err := w.Write(m[:]) - return err -} - -func (m *MerkleProof) Decode(r io.Reader) error { - var buf MerkleProof - if _, err := io.ReadFull(r, buf[:]); err != nil { - return err - } - *m = buf - return nil -} - -func MakeSectorProof(tree MerkleTree, sectorID uint8) MerkleProof { - var proof MerkleProof - var buf bytes.Buffer - pos := sectorID - for i := SubsectorProofLevel; i >= 1; i-- { - level := tree[i] - if pos%2 == 0 { - buf.Write(level[pos+1].Bytes()) - } else { - buf.Write(level[pos-1].Bytes()) - } - pos = pos / 2 - } - copy(proof[:], buf.Bytes()) - return proof -} - -func VerifySectorProof(sector Sector, sectorID uint8, merkleRoot crypto.Hash, proof MerkleProof) bool { - currHash := HashSector(sector) - pos := sectorID - pRdr := bytes.NewReader(proof[:]) - var proofHash crypto.Hash - for i := 0; i < MerkleTreeHeight; i++ { - _, err := io.ReadFull(pRdr, proofHash[:]) - if err != nil { - return false - } - if pos%2 == 0 { - currHash = hashLevel(currHash, proofHash) - } else { - currHash = hashLevel(proofHash, currHash) - } - pos = pos / 2 - } - - return currHash == merkleRoot -} - -func HashSector(sector Sector) crypto.Hash { - sectorTree, err := NewMerkleTreeFromReader(bytes.NewReader(sector[:]), SubsectorCountSector, SubsectorSize) - if err != nil { - // should never happen - panic(err) - } - return sectorTree.Root() -} - -type MerkleTree [][]crypto.Hash - -func Merkleize(br io.Reader) (MerkleTree, error) { - return NewMerkleTreeFromReader(br, SubsectorCountBlob, SubsectorSize) -} - -func MakeTreeFromBase(base MerkleBase) MerkleTree { - tree, err := newMerkleTreeFromHashedLeaves(base[:]) - if err != nil { - /// should never happen - panic(err) - } - return tree -} - -func NewMerkleTreeFromReader(r io.Reader, leafCount int, leafSize int) (MerkleTree, error) { - if leafCount > math.MaxUint32 { - return nil, errors.New("leafCount must be less than math.MaxUint32") - } - if bits.OnesCount64(uint64(leafCount)) != 1 { - return nil, errors.New("leafCount must be a power of two") - } - - buf := make([]byte, leafSize) - var base []crypto.Hash - for i := 0; i < leafCount; i++ { - if _, err := io.ReadFull(r, buf); err != nil { - return nil, err - } - base = append(base, hashLeaf(buf)) - } - return newMerkleTreeFromHashedLeaves(base) -} - -func newMerkleTreeFromHashedLeaves(base []crypto.Hash) (MerkleTree, error) { - if bits.OnesCount64(uint64(len(base))) != 1 { - return nil, errors.New("base must have a power of two length") - } - - tree := [][]crypto.Hash{ - base, - } - for len(tree[0]) > 1 { - var level []crypto.Hash - for i := 0; i < len(tree[0]); i += 2 { - left := tree[0][i] - right := tree[0][i+1] - level = append(level, hashLevel(left, right)) - } - tree = append([][]crypto.Hash{level}, tree...) - } - return tree, nil -} - -func (t MerkleTree) Root() crypto.Hash { - return t[0][0] -} - -func (t MerkleTree) ProtocolBase() MerkleBase { - var out MerkleBase - data := t.Level(8) - if len(data) != len(out) { - panic("invalid tree level") - } - for i := 0; i < len(out); i++ { - out[i] = data[i] - } - return out -} - -func (t MerkleTree) Height() int { - if len(t) == 0 { - panic("trying to get height of nil merkle tree") - } - - return len(t) - 1 -} - -func (t MerkleTree) Level(i int) []crypto.Hash { - level := t[i] - out := make([]crypto.Hash, len(level)) - for i := 0; i < len(level); i++ { - out[i] = level[i] - } - return out -} - -func (t MerkleTree) String() string { - var buf strings.Builder - for i := len(t) - 1; i >= 0; i-- { - level := t[i] - for _, hash := range level { - if i < len(t)-1 { - buf.WriteString(strings.Repeat(" ", len(t)-i)) - buf.WriteString("﹂") - } - - buf.WriteString(hash.String()) - buf.WriteRune('\n') - } - } - return buf.String() -} - -func (t MerkleTree) Encode(w io.Writer) error { - if _, err := w.Write([]byte{uint8(t.Height())}); err != nil { - return err - } - for i := len(t) - 1; i >= 0; i-- { - level := t[i] - for _, node := range level { - if _, err := w.Write(node.Bytes()); err != nil { - return err - } - } - } - return nil -} - -func (t *MerkleTree) Decode(r io.Reader) error { - heightB := make([]byte, 1, 1) - if _, err := io.ReadFull(r, heightB); err != nil { - return err - } - height := int(heightB[0]) - if height > 32 { - return errors.New("refusing decode tree over 32 levels deep") - } - toRead := 1 << uint8(height) - var tree MerkleTree - for { - var level []crypto.Hash - for i := 0; i < toRead; i++ { - var h crypto.Hash - if err := h.Decode(r); err != nil { - return err - } - level = append(level, h) - } - tree = append([][]crypto.Hash{level}, tree...) - if toRead == 1 { - break - } - toRead = toRead / 2 - } - *t = tree - return nil -} - -func hashLeaf(in []byte) crypto.Hash { - if bytes.Equal(zero4kSector, in) { - return zero4kSectorHash - } - - return crypto.Blake2B256(in) -} - -func hashLevel(left crypto.Hash, right crypto.Hash) crypto.Hash { - precompRes, hasPrecomp := precomputes[left] - if hasPrecomp && left == right { - return precompRes - } - - return crypto.Blake2B256(left[:], right[:]) -} diff --git a/blob/merkle_test.go b/blob/merkle_test.go deleted file mode 100644 index f91b430..0000000 --- a/blob/merkle_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package blob - -import ( - "bytes" - "crypto/rand" - "encoding/hex" - "io" - "testing" - - "fnd/testutil/testfs" - - "github.com/stretchr/testify/require" -) - -const expProof = "d87e2783f806556be18f0d7d71324c9efa47d76dcb6ab20ebfb1bd11fcdd8e16159fb570f424dd23426b626a4274af3fb0673a3d94df9ec9ea5b32a23fb4888cd394b989e56276a3b452ffc4c693c292fd3939b3b88dbb5f07caf89434e4c598ccc660bb61bf612c077f45f098cbe1c2fc417349705b9dffb4b4357dce2839bdc587910d908005e8d451b4305190ceabff410d145a569f8d2de57c89dfac823b16b0b07f28b35127b90ee00b4cc5612ae2d2d9e2a3343ac9c0261ef96d812d43a63c26e267529de752e0f066a3a882364f28da1f02e2a1dcd852580ee804d6c4fe623c1fbe4bdad753ab5a0c281c90bcc87c59fd3c65c6723a87b72b501ae0ea" - -func TestEncodeDecode(t *testing.T) { - f, done := testfs.NewTempFile(t) - defer done() - - _, err := io.CopyN(f, rand.Reader, Size) - require.NoError(t, err) - - blob := newFromFile("foobar", f) - var buf bytes.Buffer - merkleTree, err := Merkleize(NewReader(blob)) - require.NoError(t, err) - require.NoError(t, merkleTree.Encode(&buf)) - require.Equal(t, 262113, buf.Len()) - - otherTree := new(MerkleTree) - require.NoError(t, otherTree.Decode(bytes.NewReader(buf.Bytes()))) - require.EqualValues(t, merkleTree, *otherTree) -} - -func TestMerkleize(t *testing.T) { - f, done := testfs.NewTempFile(t) - defer done() - _, err := io.CopyN(f, new(zeroReader), Size) - require.NoError(t, err) - - blob := newFromFile("foobar", f) - mt, err := Merkleize(NewReader(blob)) - require.NoError(t, err) - require.Equal(t, "f60de559740b01fe11dd241dee2729782caabd36613c469806a5449aaeef0a27", hex.EncodeToString(mt.Root().Bytes())) - - _, err = f.WriteAt([]byte{0x01, 0x99, 0x99, 0x99, 0xff, 0xad, 0xfc, 0x11, 0x99}, int64(SectorLen*2)) - require.NoError(t, err) - - mt, err = Merkleize(NewReader(blob)) - require.NoError(t, err) - require.Equal(t, "75a87ea080e57925f81c6bf732bf72fb1f6465ee2ecbfaf7580b444fd3990cc7", hex.EncodeToString(mt.Root().Bytes())) -} - -func TestGenProof(t *testing.T) { - f, done := testfs.NewTempFile(t) - defer done() - _, err := io.CopyN(f, new(zeroReader), Size) - require.NoError(t, err) - blob := newFromFile("foobar", f) - mt, err := Merkleize(NewReader(blob)) - require.NoError(t, err) - - proof := MakeSectorProof(mt, 0) - require.NoError(t, err) - require.Equal(t, - expProof, - hex.EncodeToString(proof[:]), - ) -} - -func TestVerProof(t *testing.T) { - var proof MerkleProof - proofB, err := hex.DecodeString(expProof) - require.NoError(t, err) - copy(proof[:], proofB) - - ok := VerifySectorProof(Sector{}, 0, EmptyBlobMerkleRoot, proof) - require.True(t, ok) -} - -func TestProtocolBase(t *testing.T) { - f, done := testfs.NewTempFile(t) - defer done() - _, err := io.CopyN(f, new(zeroReader), Size) - require.NoError(t, err) - blob := newFromFile("foobar", f) - mt, err := Merkleize(NewReader(blob)) - require.NoError(t, err) - base := mt.ProtocolBase() - - for i := 0; i < len(base); i++ { - require.Equal(t, "d87e2783f806556be18f0d7d71324c9efa47d76dcb6ab20ebfb1bd11fcdd8e16", hex.EncodeToString(base[i][:])) - } -} diff --git a/blob/pathify.go b/blob/pathify.go index 2f449f4..ca05aaf 100644 --- a/blob/pathify.go +++ b/blob/pathify.go @@ -3,7 +3,7 @@ package blob import ( "bytes" "encoding/hex" - "github.com/mslipper/handshake/primitives" + "fnd.localhost/handshake/primitives" "path" ) diff --git a/blob/seal.go b/blob/seal.go index 2fc986f..c75f2ef 100644 --- a/blob/seal.go +++ b/blob/seal.go @@ -2,8 +2,7 @@ package blob import ( "fnd/crypto" - "fnd/dwire" - + "fnd.localhost/dwire" "golang.org/x/crypto/blake2b" ) diff --git a/blob/seal_test.go b/blob/seal_test.go index 81bc970..30f75ca 100644 --- a/blob/seal_test.go +++ b/blob/seal_test.go @@ -2,13 +2,11 @@ package blob import ( "encoding/hex" - "testing" - "fnd/crypto" "fnd/testutil/testcrypto" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "testing" ) func TestSealHash(t *testing.T) { diff --git a/blob/store_test.go b/blob/store_test.go index c8601bb..202834a 100644 --- a/blob/store_test.go +++ b/blob/store_test.go @@ -3,13 +3,12 @@ package blob import ( "crypto/rand" "fnd/testutil/testfs" + "github.com/stretchr/testify/require" + "golang.org/x/crypto/blake2b" "io" "os" "path" "testing" - - "github.com/stretchr/testify/require" - "golang.org/x/crypto/blake2b" ) func TestBlobStore(t *testing.T) { diff --git a/blob/transaction.go b/blob/transaction.go index 47e52c6..73d7f85 100644 --- a/blob/transaction.go +++ b/blob/transaction.go @@ -1,12 +1,11 @@ package blob import ( + "github.com/pkg/errors" "io" "io/ioutil" "os" "sync" - - "github.com/pkg/errors" ) var ( diff --git a/blob/transaction_test.go b/blob/transaction_test.go index ffae7a6..09358a2 100644 --- a/blob/transaction_test.go +++ b/blob/transaction_test.go @@ -99,7 +99,7 @@ func TestBlob_Transaction_Remove(t *testing.T) { return err }, func() error { - return tx.WriteSector(0, ZeroSector) + return tx.WriteSector(ZeroSector) }, func() error { _, err := tx.WriteAt(make([]byte, 8, 8), 0) @@ -176,7 +176,7 @@ func TestBlob_Transaction_Race(t *testing.T) { for i := 0; i < 255; i++ { wg.Add(1) go func(id uint8) { - _ = tx.WriteSector(id, ZeroSector) + _ = tx.WriteSector(ZeroSector) wg.Done() }(uint8(i)) } @@ -210,7 +210,7 @@ func requireTxMethodsClosed(t *testing.T, tx Transaction) { { "WriteSector", func() error { - return tx.WriteSector(0, ZeroSector) + return tx.WriteSector(ZeroSector) }, }, { diff --git a/blob/util_test.go b/blob/util_test.go index 37248ba..43e29fe 100644 --- a/blob/util_test.go +++ b/blob/util_test.go @@ -2,10 +2,9 @@ package blob import ( "fnd/testutil/testfs" + "github.com/stretchr/testify/require" "os" "testing" - - "github.com/stretchr/testify/require" ) func newTempBlobFile(t *testing.T) (*os.File, func()) { diff --git a/cli/homedir.go b/cli/homedir.go index a0a5a07..2f0eef2 100644 --- a/cli/homedir.go +++ b/cli/homedir.go @@ -3,7 +3,6 @@ package cli import ( "errors" "fnd/config" - "github.com/spf13/cobra" ) diff --git a/cmd/fnd-cli/cmd/blob/info.go b/cmd/fnd-cli/cmd/blob/info.go index 7ebe468..ec1bd9c 100644 --- a/cmd/fnd-cli/cmd/blob/info.go +++ b/cmd/fnd-cli/cmd/blob/info.go @@ -3,18 +3,16 @@ package blob import ( "encoding/hex" "fmt" - "os" - "strconv" - "strings" - "fnd/cli" "fnd/rpc" apiv1 "fnd/rpc/v1" - - "github.com/mslipper/handshake/primitives" + "fnd.localhost/handshake/primitives" "github.com/olekukonko/tablewriter" "github.com/pkg/errors" "github.com/spf13/cobra" + "os" + "strconv" + "strings" ) var infoCmd = &cobra.Command{ diff --git a/cmd/fnd-cli/cmd/blob/list.go b/cmd/fnd-cli/cmd/blob/list.go index 550f331..6aa3833 100644 --- a/cmd/fnd-cli/cmd/blob/list.go +++ b/cmd/fnd-cli/cmd/blob/list.go @@ -6,11 +6,10 @@ import ( "fnd/rpc" apiv1 "fnd/rpc/v1" "fnd/store" + "github.com/spf13/cobra" "math" "os" "strconv" - - "github.com/spf13/cobra" ) var listCmd = &cobra.Command{ diff --git a/cmd/fnd-cli/cmd/blob/read.go b/cmd/fnd-cli/cmd/blob/read.go index 35d4f2b..dfcd9f0 100644 --- a/cmd/fnd-cli/cmd/blob/read.go +++ b/cmd/fnd-cli/cmd/blob/read.go @@ -4,10 +4,9 @@ import ( "fnd/cli" "fnd/rpc" apiv1 "fnd/rpc/v1" + "github.com/spf13/cobra" "io" "os" - - "github.com/spf13/cobra" ) var readCmd = &cobra.Command{ diff --git a/cmd/fnd-cli/cmd/blob/write.go b/cmd/fnd-cli/cmd/blob/write.go index e14fce4..3d0e4ee 100644 --- a/cmd/fnd-cli/cmd/blob/write.go +++ b/cmd/fnd-cli/cmd/blob/write.go @@ -4,16 +4,14 @@ import ( "bufio" "bytes" "fmt" - "io" - "os" - "fnd/blob" "fnd/cli" "fnd/rpc" apiv1 "fnd/rpc/v1" - "github.com/mattn/go-isatty" "github.com/spf13/cobra" + "io" + "os" ) const ( diff --git a/cmd/fnd-cli/cmd/identity.go b/cmd/fnd-cli/cmd/identity.go index f76e26d..3d58f76 100644 --- a/cmd/fnd-cli/cmd/identity.go +++ b/cmd/fnd-cli/cmd/identity.go @@ -1,11 +1,10 @@ package cmd import ( - "encoding/hex" + "encoding/base64" "fmt" "fnd/cli" "fnd/config" - "github.com/spf13/cobra" ) @@ -23,8 +22,7 @@ var identityCmd = &cobra.Command{ return err } pub := signer.Pub() - - fmt.Println(hex.EncodeToString(pub.SerializeCompressed())) + fmt.Println(base64.StdEncoding.EncodeToString(pub.SerializeCompressed())) return nil }, } diff --git a/cmd/fnd-cli/cmd/init.go b/cmd/fnd-cli/cmd/init.go index 95bf377..04b4a51 100644 --- a/cmd/fnd-cli/cmd/init.go +++ b/cmd/fnd-cli/cmd/init.go @@ -3,7 +3,6 @@ package cmd import ( "fmt" "fnd/cli" - "github.com/spf13/cobra" ) diff --git a/cmd/fnd-cli/cmd/net/add_peer.go b/cmd/fnd-cli/cmd/net/add_peer.go index 7acacb9..d1df809 100644 --- a/cmd/fnd-cli/cmd/net/add_peer.go +++ b/cmd/fnd-cli/cmd/net/add_peer.go @@ -5,9 +5,8 @@ import ( "fnd/cli" "fnd/rpc" apiv1 "fnd/rpc/v1" - "strings" - "github.com/spf13/cobra" + "strings" ) var ( diff --git a/cmd/fnd-cli/cmd/net/ban_peer.go b/cmd/fnd-cli/cmd/net/ban_peer.go index 8ac28a3..b5a01ed 100644 --- a/cmd/fnd-cli/cmd/net/ban_peer.go +++ b/cmd/fnd-cli/cmd/net/ban_peer.go @@ -4,9 +4,8 @@ import ( "fnd/cli" "fnd/rpc" apiv1 "fnd/rpc/v1" - "strconv" - "github.com/spf13/cobra" + "strconv" ) var banPeerCmd = &cobra.Command{ diff --git a/cmd/fnd-cli/cmd/net/net.go b/cmd/fnd-cli/cmd/net/net.go index 95d04d6..9ef486f 100644 --- a/cmd/fnd-cli/cmd/net/net.go +++ b/cmd/fnd-cli/cmd/net/net.go @@ -6,7 +6,7 @@ import ( var cmd = &cobra.Command{ Use: "net", - Short: "Commands related to fnd's network connection.", + Short: "Commands related to Footnote's network connection.", } func AddCmd(parent *cobra.Command) { diff --git a/cmd/fnd-cli/cmd/net/peer_info.go b/cmd/fnd-cli/cmd/net/peer_info.go index fe01e32..ba76542 100644 --- a/cmd/fnd-cli/cmd/net/peer_info.go +++ b/cmd/fnd-cli/cmd/net/peer_info.go @@ -6,10 +6,9 @@ import ( "fnd/cli" "fnd/rpc" apiv1 "fnd/rpc/v1" - "os" - "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" + "os" ) type peerJSON struct { diff --git a/cmd/fnd-cli/cmd/net/status.go b/cmd/fnd-cli/cmd/net/status.go index 72eebce..a5b21ab 100644 --- a/cmd/fnd-cli/cmd/net/status.go +++ b/cmd/fnd-cli/cmd/net/status.go @@ -4,11 +4,10 @@ import ( "fnd/cli" "fnd/rpc" apiv1 "fnd/rpc/v1" - "os" - "strconv" - "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" + "os" + "strconv" ) var statusCmd = &cobra.Command{ diff --git a/cmd/fnd-cli/cmd/net/unban_peer.go b/cmd/fnd-cli/cmd/net/unban_peer.go index d964f11..0355b22 100644 --- a/cmd/fnd-cli/cmd/net/unban_peer.go +++ b/cmd/fnd-cli/cmd/net/unban_peer.go @@ -4,7 +4,6 @@ import ( "fnd/cli" "fnd/rpc" apiv1 "fnd/rpc/v1" - "github.com/spf13/cobra" ) diff --git a/cmd/fnd-cli/cmd/root.go b/cmd/fnd-cli/cmd/root.go index ce0f002..78429dd 100644 --- a/cmd/fnd-cli/cmd/root.go +++ b/cmd/fnd-cli/cmd/root.go @@ -6,14 +6,13 @@ import ( "fnd/cmd/fnd-cli/cmd/blob" "fnd/cmd/fnd-cli/cmd/net" "fnd/cmd/fnd-cli/cmd/unsafe" - "os" - "github.com/spf13/cobra" + "os" ) var rootCmd = &cobra.Command{ Use: "fnd-cli", - Short: "Command-line RPC interface for fnd.", + Short: "Command-line RPC interface for Footnote.", } func Execute() { diff --git a/cmd/fnd-cli/cmd/unsafe/reset_blobs.go b/cmd/fnd-cli/cmd/unsafe/reset_blobs.go index eb352b5..7e58d68 100644 --- a/cmd/fnd-cli/cmd/unsafe/reset_blobs.go +++ b/cmd/fnd-cli/cmd/unsafe/reset_blobs.go @@ -4,10 +4,9 @@ import ( "fmt" "fnd/config" "fnd/store" - "os" - "github.com/pkg/errors" "github.com/spf13/cobra" + "os" ) var resetBlobsCmd = &cobra.Command{ @@ -38,6 +37,6 @@ var resetBlobsCmd = &cobra.Command{ } func init() { - resetBlobsCmd.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to fnd's home directory.") + resetBlobsCmd.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to FootnoteD's home directory.") cmd.AddCommand(resetBlobsCmd) } diff --git a/cmd/fnd-cli/cmd/unsafe/reset_name_store.go b/cmd/fnd-cli/cmd/unsafe/reset_name_store.go index 0c10124..e76e3be 100644 --- a/cmd/fnd-cli/cmd/unsafe/reset_name_store.go +++ b/cmd/fnd-cli/cmd/unsafe/reset_name_store.go @@ -4,7 +4,6 @@ import ( "fmt" "fnd/config" "fnd/store" - "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -30,6 +29,6 @@ var resetNameStore = &cobra.Command{ } func init() { - resetNameStore.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to fnd's home directory.") + resetNameStore.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to FootnoteD's home directory.") cmd.AddCommand(resetNameStore) } diff --git a/cmd/fnd-cli/cmd/unsafe/reset_peer_store.go b/cmd/fnd-cli/cmd/unsafe/reset_peer_store.go index bf28a67..68e4bb6 100644 --- a/cmd/fnd-cli/cmd/unsafe/reset_peer_store.go +++ b/cmd/fnd-cli/cmd/unsafe/reset_peer_store.go @@ -4,7 +4,6 @@ import ( "fmt" "fnd/config" "fnd/store" - "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -30,6 +29,6 @@ var resetPeerStoreCmd = &cobra.Command{ } func init() { - resetPeerStoreCmd.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to fnd's home directory.") + resetPeerStoreCmd.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to FootnoteD's home directory.") cmd.AddCommand(resetPeerStoreCmd) } diff --git a/cmd/fnd-cli/cmd/version.go b/cmd/fnd-cli/cmd/version.go index 103b87a..0b88689 100644 --- a/cmd/fnd-cli/cmd/version.go +++ b/cmd/fnd-cli/cmd/version.go @@ -3,7 +3,6 @@ package cmd import ( "fmt" "fnd/version" - "github.com/spf13/cobra" ) diff --git a/cmd/fnd/cmd/init.go b/cmd/fnd/cmd/init.go index d04cae0..98a1300 100644 --- a/cmd/fnd/cmd/init.go +++ b/cmd/fnd/cmd/init.go @@ -3,7 +3,6 @@ package cmd import ( "fmt" "fnd/cli" - "github.com/spf13/cobra" ) diff --git a/cmd/fnd/cmd/root.go b/cmd/fnd/cmd/root.go index 80cd1c1..725b921 100644 --- a/cmd/fnd/cmd/root.go +++ b/cmd/fnd/cmd/root.go @@ -4,17 +4,16 @@ import ( "fmt" "fnd/cli" "fnd/config" - "os" - "github.com/pkg/errors" "github.com/spf13/cobra" + "os" ) var configuredHomeDir string var rootCmd = &cobra.Command{ Use: "fnd", - Short: "fnd Daemon", + Short: "Footnote Daemon", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { if cmd.CalledAs() == "init" { return nil diff --git a/cmd/fnd/cmd/start.go b/cmd/fnd/cmd/start.go index 929cabc..5ce7f25 100644 --- a/cmd/fnd/cmd/start.go +++ b/cmd/fnd/cmd/start.go @@ -2,14 +2,6 @@ package cmd import ( "fmt" - "net/http" - _ "net/http/pprof" - "os" - "os/signal" - "runtime" - "syscall" - "time" - "fnd/blob" "fnd/cli" "fnd/config" @@ -22,11 +14,17 @@ import ( "fnd/store" "fnd/util" "fnd/version" - - "github.com/mslipper/handshake/client" + "fnd.localhost/handshake/client" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/syndtr/goleveldb/leveldb" + "net/http" + _ "net/http/pprof" + "os" + "os/signal" + "runtime" + "syscall" + "time" ) var startCmd = &cobra.Command{ @@ -47,7 +45,7 @@ var startCmd = &cobra.Command{ log.SetLevel(logLevel) lgr := log.WithModule("main") - lgr.Info("starting ddrp", "git_commit", version.GitCommit, "git_tag", version.GitTag) + lgr.Info("starting fnd", "git_commit", version.GitCommit, "git_tag", version.GitTag) lgr.Info("opening home directory", "path", configuredHomeDir) signer, err := cli.GetSigner(configuredHomeDir) if err != nil { diff --git a/cmd/fnd/cmd/version.go b/cmd/fnd/cmd/version.go index de3d61e..5e4f242 100644 --- a/cmd/fnd/cmd/version.go +++ b/cmd/fnd/cmd/version.go @@ -3,7 +3,6 @@ package cmd import ( "fmt" "fnd/version" - "github.com/spf13/cobra" ) diff --git a/config/config.go b/config/config.go index b1e25eb..277aa8e 100644 --- a/config/config.go +++ b/config/config.go @@ -1,11 +1,10 @@ package config import ( - "io" - "time" - "github.com/pelletier/go-toml" "github.com/pkg/errors" + "io" + "time" ) type Config struct { diff --git a/config/default.go b/config/default.go index cc3af50..69d2445 100644 --- a/config/default.go +++ b/config/default.go @@ -2,14 +2,12 @@ package config import ( "bytes" + "fnd/log" + "github.com/pkg/errors" "io" "os" "path" "text/template" - - "fnd/log" - - "github.com/pkg/errors" ) var DefaultConfig = Config{ @@ -18,14 +16,15 @@ var DefaultConfig = Config{ EnableProfiler: false, Heartbeat: HeartbeatConfig{ Moniker: "", - URL: "https://www.ddrpscan.com/heartbeat", + URL: "", }, P2P: P2PConfig{ Host: "0.0.0.0", - DNSSeeds: []string{ - "seeds.ddrp.network", + DNSSeeds: []string{}, + FixedSeeds: []string{ + "3b755ceafc5811f0a50e102c96169b062ad1295edea0adf675e8647963acf89e@64.225.89.142", + "e3c8cfea75ff146db0b93c51cf8967242c43170dac702aec268ed566f4aa6f4b@45.55.99.2", }, - FixedSeeds: []string{}, MaxInboundPeers: 117, MaxOutboundPeers: 8, ConnectionTimeoutMS: 5000, @@ -83,7 +82,7 @@ var DefaultConfig = Config{ }, } -const defaultConfigTemplateText = `# fnd Config File +const defaultConfigTemplateText = `# FootnoteD Config File # List of ban list URLs. ban_lists = [] @@ -129,7 +128,7 @@ log_level = "{{.LogLevel}}" # Sets the set of domain names to query for seed nodes. # A records belonging to nodes in this list will be # connected to during node startup. - dns_seeds = ["{{index .P2P.DNSSeeds 0}}"] + dns_seeds = [] # Sets the IP this node should listen on. Should be set to 0.0.0.0 # for all Internet-accessible nodes. host = "{{.P2P.Host}}" @@ -142,7 +141,7 @@ log_level = "{{.LogLevel}}" # default of 8 was chosen to match Bitcoin. max_outbound_peers = {{.P2P.MaxOutboundPeers}} # Sets a list of fixed seed peers. Items should be formatted as @. - seed_peers = [] + seed_peers = ["{{index .P2P.FixedSeeds 0}}", "{{index .P2P.FixedSeeds 1}}"] # Configures the behavior of this node's RPC server. [rpc] @@ -165,7 +164,7 @@ log_level = "{{.LogLevel}}" timeout_ms = {{.Tuning.Heartbeat.TimeoutMS}} # Configures how fnd scans the Handshake blockchain for - # new DDRPKEY records. + # new TXT records. [tuning.name_importer] # Sets how often fnd scans for new names. check_interval_ms = {{.Tuning.NameImporter.CheckIntervalMS}} diff --git a/config/home.go b/config/home.go index 7b133c3..c35de8a 100644 --- a/config/home.go +++ b/config/home.go @@ -1,9 +1,8 @@ package config import ( - "os" - "github.com/pkg/errors" + "os" ) func HomeDirExists(path string) (bool, error) { diff --git a/dwire/.gitignore b/dwire/.gitignore deleted file mode 100644 index ea34f98..0000000 --- a/dwire/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# Created by .ignore support plugin (hsz.mobi) -### Go template -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - diff --git a/dwire/Makefile b/dwire/Makefile deleted file mode 100644 index 98eb341..0000000 --- a/dwire/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -test: - go test ./... --race - -fmt: - goimports -w . - gofmt -s -w . - -.PHONY: test fmt diff --git a/dwire/README.md b/dwire/README.md deleted file mode 100644 index 698706f..0000000 --- a/dwire/README.md +++ /dev/null @@ -1,167 +0,0 @@ - -# dwire - -A library for encoding and decoding things using Footnote's wire format. - -## Usage - -To encode a single value: - -```go -import ( - "fnd.localhost/dwire" - "fnd" -) - -value := "a string value" -var w bytes.Buffer -if err := dwire.EncodeField(&w, value); err != nil { - log.Fatal(err) -} -``` - -To encode a struct: - -```go -import ( - "fnd.localhost/dwire" - "bytes" -) - -type Foo struct { - StrField string - Uint8Field uint8 -} - -foo := &Foo{ - StrField: "some string", - Uint8Field: 1 -} - -var w bytes.Buffer -if err := dwire.EncodeFields(&w, foo.StrField, foo.Uint8Field); err != nil { - log.Fatal(err) -} -``` - -Decoding works on pointer values. For example, to decode a single value: - -```go -import ( - "fnd.localhost/dwire" - "bytes" -) - -var uint8Value uint8 -r := bytes.NewReader([]byte{ 0x01 }) -if err := dwire.DecodeField(r, &uint8Value); err != nil { - log.Fatal(err) -} -``` - -To decode a struct: - -```go -import ( - "fnd.localhost/dwire" - "bytes" -) - -type Foo struct { - Uint8Field uint8 -} - -var foo Foo -r := bytes.NewReader([]byte{0x01}) - -if err := dwire.DecodeFields(r, &foo.Uint8Field); err != nil { - log.Fatal(err) -} -``` - -For convenience, objects that implement the `Encoder` and `Decoder` interfaces can be passed directly to `dwire`'s encoding/decodig methods. For example, the first struct example above could be implemented as follows: - -```go -import ( - "fnd.localhost/dwire" - "bytes" -) - -type Foo struct { - StrField string - Uint8Field uint8 -} - -func (f *Foo) Encode(w io.Writer) error { - return dwire.EncodeFields( - w, - f.StrField, - f.Uint8Field, - ) -} - -func (f *Foo) Decode(r io.Reader) error { - return dwire.DecodeFields( - r, - &f.StrField, - &f.Uint8Field, - ) -} - -foo := &Foo{ - StrField: "some string", - Uint8Field: 1 -} - -var w bytes.Buffer -if err := dwire.EncodeField(&w, foo); err != nil { - log.Fatal(err) -} -``` - -## Wire Format Definition - -This definition is lifted from the canonical specification described in [PIP-1](https://fnd.network/docs/spec/pip-1.html). For clarity, we will use the function `Encode(t) = b`, where `t` is the inputted field and `b` represents the outputted bytes, to provide example encodings where necessary. - -`dwire` defines encodings for the following types: - -1. `bool`: Encoded as `0x01` or `0x00` if the value is `true` or `false`, respectively. -2. `uint8`, `uint16`, `uint32`, `uint64`: Encoded as big-endian unsigned integers. -3. `byte`: Encoded as `uint8`. -4. `[N]` (i.e., fixed-length arrays of element `T`): Encoded as the concatenation of `Encode()` for each array element. -5. `[]` (i.e., variable-length arrays of element `T`): Encoded as the concatenation of a `Uvarint` length prefix and `Encode()` for each array element. -6. `string`: Encoded as `[]byte`. - -### Well-Known Types - -Certain complex types are considered "well known," and are encoded/decoded directly in this package without implementing the `Encoder`/`Decoder` interfaces. These types are: - -1. `time.Time`: Encoded as a `uint64` Unix timestamp. - -## Benchmarks - -Benchmarks recorded on a mid-2018 MacBook Pro with the following specifications: - -1. 2.2GHz 6-Core Intel i7 -2. 32GB 2400MHz DDR4 - -``` -goos: darwin -goarch: amd64 -pkg: fnd.localhost/dwire -BenchmarkUint8Encoding-12 711883 1469 ns/op -BenchmarkUint16Encoding-12 867793 1472 ns/op -BenchmarkUint32Encoding-12 841219 1446 ns/op -BenchmarkUint64Encoding-12 845859 1544 ns/op -BenchmarkByteSliceEncoding1024-12 744835 1623 ns/op -BenchmarkStringEncoding1024-12 710882 1845 ns/op -BenchmarkByteArrayEncoding32-12 748132 1551 ns/op -BenchmarkByteArrayEncodingReflect-12 577855 2178 ns/op -BenchmarkUint16ArrayEncodingReflect-12 30091 41010 ns/op -BenchmarkStringArrayEncodingReflect-12 10000 121458 ns/op -BenchmarkWellKnownTimeEncoding-12 701935 1845 ns/op -``` - -## Acknowledgements - -Much of this library was directly inspired by `lnwire`, the wire encoding library used by the Lightning Network. As such, we would like to extend our deepest thanks to the Lightning team for their trailblazing work. diff --git a/dwire/decode.go b/dwire/decode.go deleted file mode 100644 index 18c622c..0000000 --- a/dwire/decode.go +++ /dev/null @@ -1,228 +0,0 @@ -package dwire - -import ( - "encoding/binary" - "fmt" - "io" - "reflect" - - "github.com/pkg/errors" -) - -type byteReader struct { - r io.Reader - buf []byte -} - -func newByteReader(r io.Reader) *byteReader { - return &byteReader{ - r: r, - buf: make([]byte, 1, 1), - } -} - -func (r *byteReader) Read(p []byte) (int, error) { - return r.r.Read(p) -} - -func (r *byteReader) ReadByte() (byte, error) { - _, err := io.ReadFull(r.r, r.buf) - if err != nil { - return 0, err - } - return r.buf[0], nil -} - -// DecodeFields decodes each field in the variadic items argument from the -// Reader using the default Encoder. Items provided to DecodeFields -// must be pointer types. -func DecodeFields(r io.Reader, items ...interface{}) error { - return defaultEncoder.DecodeFields(r, items...) -} - -// DecodeFields decodes the field in the item argument from the Reader using -// the default Encoder. The item provided to DecodeField must be a pointer type. -func DecodeField(r io.Reader, item interface{}) error { - return defaultEncoder.DecodeField(r, item) -} - -// DecodeFields decodes each field in the variadic items argument -// from the Reader. Items provided to DecodeFields must be pointer types. -func (c *ConfiguredEncoder) DecodeFields(r io.Reader, items ...interface{}) error { - for _, item := range items { - if err := c.DecodeField(r, item); err != nil { - return err - } - } - - return nil -} - -// DecodeField decodes the field in the item argument from the Reader. The item -// provided to DecodeField must be a pointer type. -func (c *ConfiguredEncoder) DecodeField(r io.Reader, item interface{}) error { - var err error - switch it := item.(type) { - case Decoder: - err = it.Decode(r) - case *bool: - b := make([]byte, 1, 1) - if _, err := io.ReadFull(r, b); err != nil { - return err - } - if b[0] == 0x00 { - *it = false - } else if b[0] == 0x01 { - *it = true - } else { - return errors.Errorf("invalid boolean value: %x", b[0]) - } - case *uint8: - b := make([]byte, 1, 1) - if _, err := io.ReadFull(r, b); err != nil { - return err - } - *it = b[0] - case *uint16: - b := make([]byte, 2, 2) - if _, err := io.ReadFull(r, b); err != nil { - return err - } - *it = binary.BigEndian.Uint16(b) - case *uint32: - b := make([]byte, 4, 4) - if _, err := io.ReadFull(r, b); err != nil { - return err - } - *it = binary.BigEndian.Uint32(b) - case *uint64: - b := make([]byte, 8, 8) - if _, err := io.ReadFull(r, b); err != nil { - return err - } - *it = binary.BigEndian.Uint64(b) - case *[]byte: - br := newByteReader(r) - l, err := binary.ReadUvarint(br) - if err != nil { - return err - } - if l > c.MaxByteFieldLen { - return errors.New("byte-assignable field length too large to decode") - } - buf := make([]byte, l, l) - if _, err := io.ReadFull(r, buf); err != nil { - return err - } - *it = buf - case *string: - var buf []byte - if err := c.DecodeField(r, &buf); err != nil { - return err - } - *it = string(buf) - case *[32]byte: - var buf [32]byte - if _, err := io.ReadFull(r, buf[:]); err != nil { - return err - } - *it = buf - default: - err = c.decodeReflect(r, item) - } - - return err -} - -func (c *ConfiguredEncoder) decodeReflect(r io.Reader, item interface{}) error { - itemT := reflect.TypeOf(item) - if itemT.Kind() != reflect.Ptr { - return errors.New("can only decode into pointer types") - } - - canonicalized := canonicalizeWellKnown(itemT.Elem()) - if wellKnownDecoders[canonicalized] != nil { - return wellKnownDecoders[canonicalized](r, item) - } - - elemKind := itemT.Elem().Kind() - if itemT.Elem().Kind() == reflect.Array { - return c.decodeArray(r, item) - } - - if elemKind == reflect.Slice { - return c.decodeSlice(r, item) - } - - return errors.New(fmt.Sprintf("type %s cannot be decoded", itemT.String())) -} - -func (c *ConfiguredEncoder) decodeArray(r io.Reader, item interface{}) error { - itemVal := reflect.ValueOf(item) - indirectVal := reflect.Indirect(itemVal) - indirectT := indirectVal.Type() - - l := indirectT.Len() - tmp := reflect.Zero(reflect.ArrayOf(l, indirectT.Elem())) - tmpPtr := reflect.New(indirectT) - tmpPtr.Elem().Set(tmp) - if indirectT.Elem().Kind() == reflect.Uint8 { - buf := make([]byte, l, l) - if _, err := io.ReadFull(r, buf); err != nil { - return err - } - reflect.Copy(tmpPtr.Elem().Slice(0, l), reflect.ValueOf(buf)) - } else { - for i := 0; i < indirectVal.Len(); i++ { - if err := c.DecodeField(r, tmpPtr.Elem().Index(i).Addr().Interface()); err != nil { - return err - } - } - } - itemVal.Elem().Set(tmpPtr.Elem()) - return nil -} - -func (c *ConfiguredEncoder) decodeSlice(r io.Reader, item interface{}) error { - itemVal := reflect.ValueOf(item) - indirectVal := reflect.Indirect(itemVal) - indirectT := indirectVal.Type() - - tmp := reflect.Zero(reflect.SliceOf(indirectT.Elem())) - tmpPtr := reflect.New(indirectT) - tmpPtr.Elem().Set(tmp) - - br := newByteReader(r) - l, err := binary.ReadUvarint(br) - if err != nil { - return err - } - if l > uint64(c.MaxVariableArrayLen) { - return errors.New("variable array field length too large to decode") - } - - if indirectT.Elem().Kind() == reflect.Ptr { - for i := 0; i < int(l); i++ { - sliceItem := reflect.Zero(indirectT.Elem().Elem()) - sliceItemPtr := reflect.New(sliceItem.Type()) - sliceItemPtr.Elem().Set(sliceItem) - if err := c.DecodeField(r, sliceItemPtr.Interface()); err != nil { - return err - } - tmpPtr.Elem().Set(reflect.Append(tmpPtr.Elem(), sliceItemPtr)) - } - } else { - for i := 0; i < int(l); i++ { - sliceItem := reflect.Zero(indirectT.Elem()) - sliceItemPtr := reflect.New(indirectT.Elem()) - sliceItemPtr.Elem().Set(sliceItem) - if err := c.DecodeField(r, sliceItemPtr.Interface()); err != nil { - return err - } - tmpPtr.Elem().Set(reflect.Append(tmpPtr.Elem(), sliceItemPtr.Elem())) - } - } - - itemVal.Elem().Set(tmpPtr.Elem()) - return nil -} diff --git a/dwire/decode_test.go b/dwire/decode_test.go deleted file mode 100644 index 2e6ac42..0000000 --- a/dwire/decode_test.go +++ /dev/null @@ -1,166 +0,0 @@ -package dwire - -import ( - "bytes" - "encoding/hex" - "errors" - "io" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -type cafeEncodeDecoder struct { - data []byte -} - -func (c *cafeEncodeDecoder) Decode(r io.Reader) error { - buf := make([]byte, 2, 2) - if _, err := io.ReadFull(r, buf); err != nil { - return err - } - if !bytes.Equal(buf, []byte{0xca, 0xfe}) { - return errors.New("invalid cafe decode") - } - c.data = buf - return nil -} - -func (c *cafeEncodeDecoder) Encode(w io.Writer) error { - _, err := w.Write([]byte{0xca, 0xfe}) - return err -} - -func TestDecodeFields(t *testing.T) { - var cafe cafeEncodeDecoder - - type testStruct struct { - f0 cafeEncodeDecoder - f1 uint8 - f2 uint16 - f3 uint32 - f4 uint64 - f5 []byte - f6 string - f7 [32]byte - f8 [2]uint8 - f9 []uint8 - f10 []string - f11 time.Time - f12 [2]string - f13 []*cafeEncodeDecoder - } - exp := &testStruct{ - f0: cafe, - f1: 1, - f2: 2, - f3: 3, - f4: 4, - f5: []byte{0xff, 0x00}, - f6: "testing", - f7: [32]byte{}, - f8: [2]uint8{ - 1, - 2, - }, - f9: []uint8{ - 3, - 4, - }, - f10: []string{ - "testing", - "testing", - }, - f11: time.Unix(1, 0), - f12: [2]string{ - "testing", - "testing", - }, - f13: []*cafeEncodeDecoder{ - &cafe, - &cafe, - }, - } - exp.f7[0] = 0x11 - - var actual testStruct - inputBytes, err := hex.DecodeString( - "cafe" + - "01" + - "0002" + - "00000003" + - "0000000000000004" + - "02ff00" + - "0774657374696e67" + - "1100000000000000000000000000000000000000000000000000000000000000" + - "0102" + - "020304" + - "020774657374696e670774657374696e67" + - "00000001" + - "0774657374696e670774657374696e67" + - "02cafecafe", - ) - require.NoError(t, err) - require.NoError(t, DecodeFields( - bytes.NewReader(inputBytes), - &actual.f0, - &actual.f1, - &actual.f2, - &actual.f3, - &actual.f4, - &actual.f5, - &actual.f6, - &actual.f7, - &actual.f8, - &actual.f9, - &actual.f10, - &actual.f11, - &actual.f12, - &actual.f13, - )) - require.EqualValues(t, exp.f0.data, exp.f0.data) - require.EqualValues(t, exp.f1, actual.f1) - require.EqualValues(t, exp.f2, actual.f2) - require.EqualValues(t, exp.f3, actual.f3) - require.EqualValues(t, exp.f4, actual.f4) - require.EqualValues(t, exp.f5, actual.f5) - require.EqualValues(t, exp.f6, actual.f6) - require.EqualValues(t, exp.f7, actual.f7) - require.EqualValues(t, exp.f8, actual.f8) - require.EqualValues(t, exp.f9, actual.f9) - require.EqualValues(t, exp.f10, actual.f10) - require.EqualValues(t, exp.f11, actual.f11) - require.EqualValues(t, exp.f12, actual.f12) - require.Equal(t, len(exp.f13), len(actual.f13)) -} - -func TestDecode_Errors(t *testing.T) { - var boolVal bool - err := DecodeField(bytes.NewReader([]byte{0x02}), &boolVal) - require.Error(t, err) - require.Contains(t, err.Error(), "invalid boolean value") - - err = DecodeField(bytes.NewReader([]byte{}), uint64(0)) - require.Error(t, err) - require.Contains(t, err.Error(), "can only decode into pointer types") - - var buf bytes.Buffer - require.NoError(t, writeUvarint(&buf, DefaultMaxByteFieldLen+DefaultMaxVariableArrayLen+1)) - var byteArrVal []byte - err = DecodeField(bytes.NewReader(buf.Bytes()), &byteArrVal) - require.Error(t, err) - require.Contains(t, err.Error(), "byte-assignable field length too large to decode") - - var strVal string - // zero out err since the err message is the same - err = nil - err = DecodeField(bytes.NewReader(buf.Bytes()), &strVal) - require.Error(t, err) - require.Contains(t, err.Error(), "byte-assignable field length too large to decode") - - var strArrVal []string - err = DecodeField(bytes.NewReader(buf.Bytes()), &strArrVal) - require.Error(t, err) - require.Contains(t, err.Error(), "variable array field length too large to decode") -} diff --git a/dwire/doc.go b/dwire/doc.go deleted file mode 100644 index 7235644..0000000 --- a/dwire/doc.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Package dwire implements the Footnote message encoding scheme as defined in -PIP-1. - -Fundamental types: - - - bool: Encoded as 0x00 or 0x01 if the value is true or false, - respectively. - - uint8: Encoded as a single byte in the range 0x00-0xff. - - uint16: Encoded as two big-endian bytes in the range 0x0000-0xffff. - - uint32: Encoded as four big-endian bytes in the range - 0x00000000-0xffffffff - - uint64: Encoded as eight big-endian bytes in the range - 0x0000000000000000-0xffffffffffffffff. - - string: Encoded as a UTF-8 []byte. - - [N]T: Encoded as the concatenation of the encoding of T. - - []T: Encoded as a binary.Uvarint length prefix followed by the - concatenation of the encoding of T. - -Well-known types: - - - time.Time: Encoded as uint32(time.Unix()). - -The easiest way to use this library is to call the EncodeField/DecodeField family -of methods. To encode a value into a Writer: - - value1 := "this is my value" - value2 := 2 - err := dwire.EncodeFields(w, value1, value2) - -To decode a value from a reader: - - var value1 string - var value2 string - err := dwire.DecodeFields(r, &value1, &value2) - -Note that values passed to DecodeField/DecodeFields MUST be pointers. - -dwire exposes Encoder and Decoder interfaces, which allow arbitrary types to be -encoded and decoded by EncodeField/DecodeField. For example: - - type Foo struct { - Value string - } - - func (f *Foo) Encode(w io.Writer) error { - return dwire.EncodeFields(w, f.Value) - } - - func (f *Foo) Decode(r io.Reader) error { - return dwire.DecodeFields(r, &f.Value) - } - */ -package dwire diff --git a/dwire/encode.go b/dwire/encode.go deleted file mode 100644 index d7abde1..0000000 --- a/dwire/encode.go +++ /dev/null @@ -1,135 +0,0 @@ -package dwire - -import ( - "encoding/binary" - "errors" - "fmt" - "io" - "reflect" -) - -var ( - trueWire = []byte{0x01} - falseWire = []byte{0x00} -) - -// EncodeFields encodes each field in the variadic items argument -// into the Writer using the default Encoder. -func EncodeFields(w io.Writer, items ...interface{}) error { - return defaultEncoder.EncodeFields(w, items...) -} - -// EncodeField encodes a single field into the Writer using the -// default Encoder. -func EncodeField(w io.Writer, item interface{}) error { - return defaultEncoder.EncodeField(w, item) -} - -// EncodeFields encodes each field in the variadic items argument -// into the Writer. -func (c *ConfiguredEncoder) EncodeFields(w io.Writer, items ...interface{}) error { - for _, item := range items { - if err := c.EncodeField(w, item); err != nil { - return err - } - } - - return nil -} - -// EncodeFields encodes a single field into the Writer. -func (c *ConfiguredEncoder) EncodeField(w io.Writer, item interface{}) error { - var err error - switch it := item.(type) { - case Encoder: - err = it.Encode(w) - case bool: - val := falseWire - if it { - val = trueWire - } - _, err = w.Write(val) - case uint8: - _, err = w.Write([]byte{it}) - case uint16: - b := make([]byte, 2, 2) - binary.BigEndian.PutUint16(b, it) - _, err = w.Write(b) - case uint32: - b := make([]byte, 4, 4) - binary.BigEndian.PutUint32(b, it) - _, err = w.Write(b) - case uint64: - b := make([]byte, 8, 8) - binary.BigEndian.PutUint64(b, it) - _, err = w.Write(b) - case []byte: - if uint64(len(it)) > c.MaxByteFieldLen { - return errors.New("byte-assignable field length too large to encode") - } - if err := writeUvarint(w, len(it)); err != nil { - return err - } - _, err = w.Write(it) - case string: - err = c.EncodeField(w, []byte(item.(string))) - case [32]byte: - _, err = w.Write(it[:]) - default: - err = c.encodeReflect(w, item) - } - - return err -} - -func (c *ConfiguredEncoder) encodeReflect(w io.Writer, item interface{}) error { - t := reflect.TypeOf(item) - - canonicalized := canonicalizeWellKnown(t) - if wellKnownEncoders[canonicalized] != nil { - return wellKnownEncoders[canonicalized](w, item) - } - - if t.Kind() == reflect.Array { - itemVal := reflect.ValueOf(item) - if t.Elem().Kind() == reflect.Uint8 { - itemPtr := reflect.New(t) - itemPtr.Elem().Set(itemVal) - _, err := w.Write(itemPtr.Elem().Slice(0, itemVal.Len()).Bytes()) - return err - } - - for i := 0; i < itemVal.Len(); i++ { - if err := c.EncodeField(w, itemVal.Index(i).Interface()); err != nil { - return err - } - } - return nil - } - - if t.Kind() == reflect.Slice { - val := reflect.ValueOf(item) - if val.Len() > c.MaxVariableArrayLen { - return errors.New("variable array field length too large to encode") - } - - if err := writeUvarint(w, val.Len()); err != nil { - return err - } - for i := 0; i < val.Len(); i++ { - if err := c.EncodeField(w, val.Index(i).Interface()); err != nil { - return err - } - } - return nil - } - - return errors.New(fmt.Sprintf("type %s cannot be encoded", t.String())) -} - -func writeUvarint(w io.Writer, n int) error { - lenBuf := make([]byte, binary.MaxVarintLen64, binary.MaxVarintLen64) - bytesWritten := binary.PutUvarint(lenBuf, uint64(n)) - _, err := w.Write(lenBuf[:bytesWritten]) - return err -} diff --git a/dwire/encode_test.go b/dwire/encode_test.go deleted file mode 100644 index 7061395..0000000 --- a/dwire/encode_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package dwire - -import ( - "bytes" - "encoding/hex" - "math" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestEncodeFields(t *testing.T) { - cafe := new(cafeEncodeDecoder) - - var threeTwoByte [32]byte - threeTwoByte[1] = 0xff - - var buf bytes.Buffer - require.NoError(t, EncodeFields( - &buf, - cafe, - []*cafeEncodeDecoder{ - cafe, - cafe, - }, - true, - false, - uint8(0), - uint16(0), - uint32(0), - uint64(0), - uint8(math.MaxUint8), - uint16(math.MaxUint16), - uint32(math.MaxUint32), - uint64(math.MaxUint64), - threeTwoByte, - [2]string{ - "testing", - "testing", - }, - []byte{ - 0x01, 0x02, - }, - []string{ - "testing", - "testing", - }, - "hello there", - time.Unix(1, 0), - )) - require.Equal( - t, - "cafe"+ - "02cafecafe"+ - "01"+ - "00"+ - "00"+ - "0000"+ - "00000000"+ - "0000000000000000"+ - "ff"+ - "ffff"+ - "ffffffff"+ - "ffffffffffffffff"+ - "00ff000000000000000000000000000000000000000000000000000000000000"+ - "0774657374696e670774657374696e67"+ - "020102"+ - "020774657374696e670774657374696e67"+ - "0b68656c6c6f207468657265"+ - "00000001", - hex.EncodeToString(buf.Bytes()), - ) - - buf.Reset() - err := EncodeFields(&buf, uint8(1), struct{}{}) - require.Error(t, err) - require.Contains(t, err.Error(), "cannot be encoded") -} - -func TestEncode_Errors(t *testing.T) { - rw := new(NopReadWriter) - err := EncodeField(rw, &struct{}{}) - require.Error(t, err) - require.Contains(t, err.Error(), "cannot be encoded") - - customEncoder := &ConfiguredEncoder{ - MaxVariableArrayLen: 5, - MaxByteFieldLen: 5, - } - - err = customEncoder.EncodeField(rw, make([]byte, customEncoder.MaxByteFieldLen+1)) - require.Error(t, err) - require.Contains(t, err.Error(), "byte-assignable field length too large to encode") - - // zero out err since the message is the same - err = nil - err = customEncoder.EncodeField(rw, "123456") - require.Error(t, err) - require.Contains(t, err.Error(), "byte-assignable field length too large to encode") - - err = customEncoder.EncodeField(rw, make([]string, customEncoder.MaxVariableArrayLen+1)) - require.Error(t, err) - require.Contains(t, err.Error(), "variable array field length too large to encode") -} diff --git a/dwire/encoder.go b/dwire/encoder.go deleted file mode 100644 index 2800098..0000000 --- a/dwire/encoder.go +++ /dev/null @@ -1,42 +0,0 @@ -package dwire - -import "io" - -const ( - DefaultMaxVariableArrayLen = 4096 - DefaultMaxByteFieldLen = 8 * 256 * 4096 -) - -// Encoder is an interface that allows arbitrary types to be -// encoded. Types implementing the Encoder interface can be -// encoded using EncodeField or EncodeFields. -type Encoder interface { - Encode(w io.Writer) error -} - -// Decoder is an interface that allows arbitrary types to be -// decoded. Types implementing the Decoder interface can be -// decoded using DecodeField or DecodeFields. -type Decoder interface { - Decode(r io.Reader) error -} - -type EncodeDecoder interface { - Encoder - Decoder -} - -type ConfiguredEncoder struct { - // MaxVariableArrayLen is the maximum length of a variable-length array dwire - // will decode before stopping early. - MaxVariableArrayLen int - - // MaxByteFieldLen is the maximum length of a variable-length byte array field - // dwire will decode before stopping early. - MaxByteFieldLen uint64 -} - -var defaultEncoder = &ConfiguredEncoder{ - MaxVariableArrayLen: DefaultMaxVariableArrayLen, - MaxByteFieldLen: DefaultMaxByteFieldLen, -} diff --git a/dwire/encoding_bench_test.go b/dwire/encoding_bench_test.go deleted file mode 100644 index 948457e..0000000 --- a/dwire/encoding_bench_test.go +++ /dev/null @@ -1,107 +0,0 @@ -package dwire - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -type NopReadWriter struct{} - -func (n *NopReadWriter) Read(p []byte) (int, error) { - return len(p), nil -} - -func (n *NopReadWriter) Write(p []byte) (int, error) { - return len(p), nil -} - -func BenchmarkUint8Encoding(b *testing.B) { - var i uint8 - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, i)) - } -} - -func BenchmarkUint16Encoding(b *testing.B) { - var i uint16 - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, i)) - } -} - -func BenchmarkUint32Encoding(b *testing.B) { - var i uint32 - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, i)) - } -} - -func BenchmarkUint64Encoding(b *testing.B) { - var i uint64 - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, i)) - } -} - -func BenchmarkByteSliceEncoding1024(b *testing.B) { - bytes := make([]byte, 1024, 1024) - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, bytes)) - } -} - -func BenchmarkStringEncoding1024(b *testing.B) { - bytes := make([]byte, 1024, 1024) - str := string(bytes) - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, str)) - } -} - -func BenchmarkByteArrayEncoding32(b *testing.B) { - bytes := make([]byte, 32, 32) - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, bytes)) - } -} - -func BenchmarkByteArrayEncodingReflect(b *testing.B) { - var bytes [1024]byte - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, bytes)) - } -} - -func BenchmarkUint16ArrayEncodingReflect(b *testing.B) { - var uints [1024]uint16 - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, uints)) - } -} - -func BenchmarkStringArrayEncodingReflect(b *testing.B) { - var strings [1024]string - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, strings)) - } -} - -func BenchmarkWellKnownTimeEncoding(b *testing.B) { - ts := time.Now() - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, ts)) - } -} diff --git a/dwire/well_known.go b/dwire/well_known.go deleted file mode 100644 index 24ee9ea..0000000 --- a/dwire/well_known.go +++ /dev/null @@ -1,62 +0,0 @@ -package dwire - -import ( - "fmt" - "io" - "reflect" - "time" - - "github.com/pkg/errors" -) - -type encoderFunc func(w io.Writer, val interface{}) error -type decoderFunc func(r io.Reader, val interface{}) error - -var ( - wellKnownEncoders = make(map[string]encoderFunc) - wellKnownDecoders = make(map[string]decoderFunc) -) - -// Encodes a time.Time value into the Writer. Since time.Time is a -// well-known type, you likely do not need to call this method directly. -// Instead, provide the time value to EncodeField or EncodeFields. -func EncodeTime(w io.Writer, val interface{}) error { - cast, ok := val.(time.Time) - if !ok { - return errors.New("value is not a time.Time") - } - - unix := cast.Unix() - if unix < 0 { - return errors.New("negative UNIX time") - } - return EncodeField(w, uint32(unix)) -} - -// Decodes a time.Time value from the Reader. Since time.Time is a -// well-known type, you likely do not need to call this method directly. -// Instead, call EncodeField or EncodeFields with a &time.Time item. -func DecodeTime(r io.Reader, val interface{}) error { - cast, ok := val.(*time.Time) - if !ok { - return errors.New("value is not a *time.Time") - } - - var unixTs uint32 - if err := DecodeField(r, &unixTs); err != nil { - return errors.Wrap(err, "failed to decode timestamp") - } - - *cast = time.Unix(int64(unixTs), 0) - return nil -} - -func canonicalizeWellKnown(t reflect.Type) string { - return fmt.Sprintf("%s/%s", t.PkgPath(), t.Name()) -} - -func init() { - timeTypeKey := canonicalizeWellKnown(reflect.TypeOf(time.Time{})) - wellKnownEncoders[timeTypeKey] = EncodeTime - wellKnownDecoders[timeTypeKey] = DecodeTime -} diff --git a/dwire/well_known_test.go b/dwire/well_known_test.go deleted file mode 100644 index 181d285..0000000 --- a/dwire/well_known_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package dwire - -import ( - "bytes" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestEncodeTime(t *testing.T) { - var buf bytes.Buffer - require.NoError(t, EncodeTime(&buf, time.Unix(12345, 0))) - require.EqualValues(t, []byte{0x00, 0x00, 0x30, 0x39}, buf.Bytes()) - - rw := new(NopReadWriter) - err := EncodeTime(rw, 9001) - require.Error(t, err) - require.Contains(t, err.Error(), "value is not a time.Time") - - err = EncodeTime(rw, time.Time{}) - require.Error(t, err) - require.Contains(t, err.Error(), "negative UNIX time") -} - -func TestDecodeTime(t *testing.T) { - input := []byte{0x00, 0x00, 0x30, 0x39} - rd := bytes.NewReader(input) - var output time.Time - require.NoError(t, DecodeTime(rd, &output)) - require.True(t, output.Equal(time.Unix(12345, 0))) - - rd = bytes.NewReader(input) - err := DecodeTime(rd, output) - require.Error(t, err) - require.Contains(t, err.Error(), "value is not a *time.Time") -} diff --git a/go.mod b/go.mod index 6f7e536..73b1a69 100644 --- a/go.mod +++ b/go.mod @@ -2,17 +2,23 @@ module fnd go 1.12 +replace fnd.localhost/dwire => ./vendor/fnd.localhost/dwire + +replace fnd.localhost/mstream => ./vendor/fnd.localhost/mstream + +replace fnd.localhost/handshake => ./vendor/fnd.localhost/handshake + require ( + fnd.localhost/dwire v1.0.1 + fnd.localhost/handshake v0.0.0-20200428084808-2c986090302e github.com/btcsuite/btcd v0.20.1-beta - github.com/golang/protobuf v1.4.0-rc.3 + github.com/golang/protobuf v1.4.2 github.com/golang/snappy v0.0.1 // indirect - github.com/google/go-cmp v0.5.0 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/kr/pretty v0.1.0 // indirect github.com/mattn/go-isatty v0.0.11 github.com/mattn/go-runewidth v0.0.4 // indirect github.com/mitchellh/go-homedir v1.1.0 - github.com/mslipper/handshake v0.0.0-20200428084808-2c986090302e github.com/olekukonko/tablewriter v0.0.1 github.com/onsi/ginkgo v1.8.0 // indirect github.com/onsi/gomega v1.5.0 // indirect @@ -24,12 +30,13 @@ require ( github.com/stretchr/testify v1.5.1 github.com/syndtr/goleveldb v1.0.0 golang.org/x/crypto v0.0.0-20200422194213-44a606286825 + golang.org/x/net v0.0.0-20190923162816-aa69164e4478 golang.org/x/sync v0.0.0-20190423024810-112230192c58 golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 // indirect golang.org/x/text v0.3.2 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 google.golang.org/grpc v1.27.0 - google.golang.org/protobuf v1.20.0 + google.golang.org/protobuf v1.25.0 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.2.8 // indirect ) diff --git a/go.sum b/go.sum index 5d6ca22..77e6f54 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +fnd.localhost/dwire v1.0.1 h1:OD5D5aRahOuy0QGCHxXrZf5ZJlX0IBcT/3P0k97elpQ= +fnd.localhost/dwire v1.0.1/go.mod h1:BkHitp5E9PSDVLq5nPLXWzQFEwFSR5aNhTL7M9xeC7I= +fnd.localhost/handshake v0.0.0-20200428084808-2c986090302e h1:MgJUOlZMg4aEHfxoH7DrrOZxuP7XkHQUTZ6WHfMhaXM= +fnd.localhost/handshake v0.0.0-20200428084808-2c986090302e/go.mod h1:YVUlfqY28yFbCM7y59cmL92/VfM0EDBXKrhjgmo2OAg= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -24,10 +28,6 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 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= -fnd v0.2.3 h1:sDSD+Pu4c5KJlHj8Q/PYWu6tqzLyXHOGclVro089rQs= -fnd v0.2.3/go.mod h1:6/1wpeEE7b1oWDZXEj6l3dB34ofQMT5X3CU0vAkE65c= -github.com/ddrp-org/dwire v1.0.1 h1:OD5D5aRahOuy0QGCHxXrZf5ZJlX0IBcT/3P0k97elpQ= -github.com/ddrp-org/dwire v1.0.1/go.mod h1:BkHitp5E9PSDVLq5nPLXWzQFEwFSR5aNhTL7M9xeC7I= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= @@ -41,8 +41,12 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.3 h1:OzhhLcnXjTNb98owNUFibnt+cUqC2RSAGyFqxU4x3ok= -github.com/golang/protobuf v1.4.0-rc.3/go.mod h1:57iy8tErfL8eYKb9AjvkwLdYn7fzOM4yLPLUGc/0Cew= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -50,7 +54,6 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= @@ -80,8 +83,6 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mslipper/handshake v0.0.0-20200428084808-2c986090302e h1:MgJUOlZMg4aEHfxoH7DrrOZxuP7XkHQUTZ6WHfMhaXM= -github.com/mslipper/handshake v0.0.0-20200428084808-2c986090302e/go.mod h1:YVUlfqY28yFbCM7y59cmL92/VfM0EDBXKrhjgmo2OAg= github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -118,6 +119,7 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH 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= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -173,15 +175,17 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610 h1:Ygq9/SRJX9+dU0WCIICM8RkWvDw03lvB77hrhJnpxfU= google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw= google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= @@ -189,8 +193,13 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.0 h1:SsQNHvKpk2VTiWoQ5Pqkt3Go/c2ly77C+v2Lggu5Qek= -google.golang.org/protobuf v1.20.0/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= diff --git a/p2p/counting_reader_test.go b/p2p/counting_reader_test.go index 7900e92..b80bad8 100644 --- a/p2p/counting_reader_test.go +++ b/p2p/counting_reader_test.go @@ -3,10 +3,9 @@ package p2p import ( "bytes" "fnd/crypto" - "testing" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "testing" ) func TestCountingReader(t *testing.T) { diff --git a/p2p/incoming_handshake.go b/p2p/incoming_handshake.go index 62ba806..90de2ca 100644 --- a/p2p/incoming_handshake.go +++ b/p2p/incoming_handshake.go @@ -4,7 +4,6 @@ import ( "context" "fnd/crypto" "fnd/wire" - "github.com/pkg/errors" ) diff --git a/p2p/incoming_handshake_test.go b/p2p/incoming_handshake_test.go index 7288d64..7031320 100644 --- a/p2p/incoming_handshake_test.go +++ b/p2p/incoming_handshake_test.go @@ -3,13 +3,12 @@ package p2p import ( "context" "errors" - "testing" - "time" - "fnd/crypto" + "fnd/testutil/testcrypto" "fnd/wire" - "github.com/stretchr/testify/require" + "testing" + "time" ) func TestHandleIncomingHandshake(t *testing.T) { @@ -41,6 +40,35 @@ func TestHandleIncomingHandshake(t *testing.T) { setup.Close(t) } +func TestHandleIncomingHandshake_InvalidHelloSig(t *testing.T) { + ctx := context.Background() + setup := initializeHandshakes(t) + doneCh := make(chan struct{}, 2) + go func() { + _, err := HandleIncomingHandshake(ctx, &HandshakeConfig{ + Magic: 12345, + ProtocolVersion: 1, + Peer: setup.inPeer, + Signer: setup.inSigner, + }) + require.True(t, errors.Is(err, ErrInvalidEnvelopeSignature)) + doneCh <- struct{}{} + }() + go func() { + _, err := HandleOutgoingHandshake(ctx, &HandshakeConfig{ + Magic: 12345, + ProtocolVersion: 1, + Peer: setup.outPeer, + Signer: testcrypto.NewRandomSigner(), + }) + require.True(t, errors.Is(err, ErrPeerClosed)) + doneCh <- struct{}{} + }() + <-doneCh + setup.Close(t) + <-doneCh +} + func TestHandleIncomingHandshake_InvalidHelloAckNonce(t *testing.T) { ctx := context.Background() setup := initializeHandshakes(t) diff --git a/p2p/listener.go b/p2p/listener.go index ee5edde..b56a2ea 100644 --- a/p2p/listener.go +++ b/p2p/listener.go @@ -4,10 +4,9 @@ import ( "fmt" "fnd/log" "fnd/service" + "github.com/pkg/errors" "net" "sync" - - "github.com/pkg/errors" ) type Listener struct { diff --git a/p2p/outgoing_handshake.go b/p2p/outgoing_handshake.go index 5502193..789eeb4 100644 --- a/p2p/outgoing_handshake.go +++ b/p2p/outgoing_handshake.go @@ -5,9 +5,8 @@ import ( "fnd/crypto" "fnd/version" "fnd/wire" - "time" - "github.com/pkg/errors" + "time" ) var ( diff --git a/p2p/outgoing_handshake_test.go b/p2p/outgoing_handshake_test.go index 7377509..bca4a4a 100644 --- a/p2p/outgoing_handshake_test.go +++ b/p2p/outgoing_handshake_test.go @@ -8,12 +8,11 @@ import ( "fnd/testutil" "fnd/testutil/testcrypto" "fnd/wire" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "net" "testing" "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) type handshakeSetup struct { diff --git a/p2p/peer.go b/p2p/peer.go index 51ddf2b..4c4cabb 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -6,13 +6,12 @@ import ( "errors" "fnd/log" "fnd/wire" + "golang.org/x/time/rate" "io" "math" "net" "sync" "time" - - "golang.org/x/time/rate" ) var ( diff --git a/p2p/peer_manager.go b/p2p/peer_manager.go index 7119a28..2782340 100644 --- a/p2p/peer_manager.go +++ b/p2p/peer_manager.go @@ -8,13 +8,12 @@ import ( "fnd/service" "fnd/store" "fnd/util" - "net" - "sync" - "time" - "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" "golang.org/x/sync/semaphore" + "net" + "sync" + "time" ) const ( diff --git a/p2p/peer_muxer.go b/p2p/peer_muxer.go index d5ac4bb..77d33a4 100644 --- a/p2p/peer_muxer.go +++ b/p2p/peer_muxer.go @@ -6,10 +6,9 @@ import ( "fnd/log" "fnd/util" "fnd/wire" + "github.com/pkg/errors" "sync" "sync/atomic" - - "github.com/pkg/errors" ) const ( diff --git a/p2p/peer_test.go b/p2p/peer_test.go index 2730a02..fe944ad 100644 --- a/p2p/peer_test.go +++ b/p2p/peer_test.go @@ -6,12 +6,11 @@ import ( "errors" "fnd/testutil/testcrypto" "fnd/wire" + "github.com/stretchr/testify/require" "io" "sync" "testing" "time" - - "github.com/stretchr/testify/require" ) type blockingReadWriter struct { diff --git a/p2p/seed_test.go b/p2p/seed_test.go index cbcc430..945f743 100644 --- a/p2p/seed_test.go +++ b/p2p/seed_test.go @@ -1,15 +1,15 @@ package p2p import ( - "testing" - "github.com/stretchr/testify/require" + "testing" ) func TestLookupDNSSeeds(t *testing.T) { - seeds, err := ResolveDNSSeeds("seeds-test.merkleblock.com") + seeds, err := ResolveDNSSeeds("seeds-test.fnd.network") require.NoError(t, err) - require.Equal(t, 1, len(seeds)) - require.Contains(t, seeds, "78.46.17.17") + require.Equal(t, 2, len(seeds)) + require.Contains(t, seeds, "10.1.0.1") + require.Contains(t, seeds, "10.1.0.2") } diff --git a/p2p/seeds.go b/p2p/seeds.go index 1f897b7..1b97e5c 100644 --- a/p2p/seeds.go +++ b/p2p/seeds.go @@ -2,10 +2,9 @@ package p2p import ( "fnd/crypto" + "github.com/pkg/errors" "net" "strings" - - "github.com/pkg/errors" ) type SeedPeer struct { diff --git a/protocol/ban_list.go b/protocol/ban_list.go index 63fe2a9..d18cf87 100644 --- a/protocol/ban_list.go +++ b/protocol/ban_list.go @@ -2,7 +2,7 @@ package protocol import ( "bufio" - "github.com/mslipper/handshake/primitives" + "fnd.localhost/handshake/primitives" "github.com/pkg/errors" "io" "net/http" @@ -22,8 +22,8 @@ func ParseBanListVersion(line string) (int, error) { if len(splits) != 2 { return 0, errors.New("ban list version must consist of two colon-separated components") } - if splits[0] != "DDRPBAN" { - return 0, errors.New("ban list version must start with DDRPBAN") + if splits[0] != "FNBAN" { + return 0, errors.New("ban list version must start with FNBAN") } if !verRegex.MatchString(splits[1]) { return 0, errors.New("ban list version must end with v followed by a digit") diff --git a/protocol/ban_list_test.go b/protocol/ban_list_test.go index b074118..fe4a865 100644 --- a/protocol/ban_list_test.go +++ b/protocol/ban_list_test.go @@ -13,11 +13,11 @@ func TestParseBanListVersion(t *testing.T) { }{ {"", "colon-separated components"}, {"whatever", "colon-separated components"}, - {":", "start with DDRPBAN"}, - {"DDRPBAN", "colon-separated components"}, - {"DDRPBAN:", "end with v followed by a digit"}, - {"DDRPBAN:beep", "end with v followed by a digit"}, - {"DDRPBAN:1", "end with v followed by a digit"}, + {":", "start with FNBAN"}, + {"FNBAN", "colon-separated components"}, + {"FNBAN:", "end with v followed by a digit"}, + {"FNBAN:beep", "end with v followed by a digit"}, + {"FNBAN:1", "end with v followed by a digit"}, } for _, test := range invalidTests { @@ -31,9 +31,9 @@ func TestParseBanListVersion(t *testing.T) { in string ver int }{ - {"DDRPBAN:v0", 0}, - {"DDRPBAN:v1", 1}, - {"DDRPBAN:v10", 10}, + {"FNBAN:v0", 0}, + {"FNBAN:v1", 1}, + {"FNBAN:v10", 10}, } for _, test := range validTests { @@ -53,15 +53,15 @@ func TestReadBanList(t *testing.T) { "must start with version line", }, { - "DDRPBAN:", + "FNBAN:", "v followed by a digit", }, { - "DDRPBAN:v1\n-------.", + "FNBAN:v1\n-------.", "start with a hyphen", }, { - "DDRPBAN:v0\nhonk", + "FNBAN:v0\nhonk", "unsupported ban list version", }, } @@ -78,7 +78,7 @@ func TestReadBanList(t *testing.T) { out []string }{ { - "DDRPBAN:v1\nwar\nis\npeace", + "FNBAN:v1\nwar\nis\npeace", []string{ "war", "is", @@ -86,27 +86,27 @@ func TestReadBanList(t *testing.T) { }, }, { - "DDRPBAN:v1", + "FNBAN:v1", []string{}, }, { - "DDRPBAN:v1\n", + "FNBAN:v1\n", []string{}, }, { - "DDRPBAN:v1\n test2 \n", + "FNBAN:v1\n test2 \n", []string{ "test2", }, }, { - "DDRPBAN:v1\ntest2 \n", + "FNBAN:v1\ntest2 \n", []string{ "test2", }, }, { - "DDRPBAN:v1\n\ttest2 \nhello", + "FNBAN:v1\n\ttest2 \nhello", []string{ "test2", "hello", @@ -125,7 +125,7 @@ func TestReadBanList(t *testing.T) { } func TestFetchListFile(t *testing.T) { - names, err := FetchListFile("https://gist.githubusercontent.com/mslipper/fd68d2eea1fbb0c435924d71c3152f19/raw/ccfa9fff79ce805c149ebdfff0dfa938f408fa52/banlist") + names, err := FetchListFile("") require.NoError(t, err) require.Equal(t, 3, len(names)) require.Equal(t, names[0], "testname") diff --git a/protocol/epoch.go b/protocol/epoch.go index b5e5b8b..c1e2956 100644 --- a/protocol/epoch.go +++ b/protocol/epoch.go @@ -3,7 +3,7 @@ package protocol import ( "time" - "github.com/mslipper/handshake/primitives" + "fnd.localhost/handshake/primitives" ) // 2020 Jan 1 00:00 UTC diff --git a/protocol/heartbeater.go b/protocol/heartbeater.go index 169e438..1b86d65 100644 --- a/protocol/heartbeater.go +++ b/protocol/heartbeater.go @@ -7,11 +7,10 @@ import ( "fnd/log" "fnd/service" "fnd/version" + "github.com/pkg/errors" "net/http" "sync" "time" - - "github.com/pkg/errors" ) const ( diff --git a/protocol/heartbeater_test.go b/protocol/heartbeater_test.go index 388697d..8fc3c1e 100644 --- a/protocol/heartbeater_test.go +++ b/protocol/heartbeater_test.go @@ -4,14 +4,13 @@ import ( "encoding/json" "fnd/crypto" "fnd/testutil/testcrypto" + "github.com/stretchr/testify/require" "io/ioutil" "net/http" "net/http/httptest" "sync" "testing" "time" - - "github.com/stretchr/testify/require" ) func TestHeartbeater_SendHeartbeats(t *testing.T) { diff --git a/protocol/moderation.go b/protocol/moderation.go index 4f4210b..2bb9c42 100644 --- a/protocol/moderation.go +++ b/protocol/moderation.go @@ -4,10 +4,9 @@ import ( "fnd/blob" "fnd/log" "fnd/store" - "time" - "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" + "time" ) const ( diff --git a/protocol/moderation_test.go b/protocol/moderation_test.go index 7dbfa63..21e875a 100644 --- a/protocol/moderation_test.go +++ b/protocol/moderation_test.go @@ -4,9 +4,8 @@ import ( "fnd/blob" "fnd/store" "fnd/testutil/testfs" - "testing" - "github.com/stretchr/testify/require" + "testing" ) // TODO: refactor to use the httptest server @@ -23,8 +22,8 @@ func TestIngestBanLists(t *testing.T) { require.NoError(t, bl.Close()) err = IngestBanLists(db, bs, []string{ - "https://gist.githubusercontent.com/mslipper/b5d28fe54850be8b879b4064abcacddf/raw/6c412b8bc02a3765b49acf455b6ce32c7a5a4ddd/banlist-test-1", - "https://gist.githubusercontent.com/mslipper/cc32c19da426622e156cf771aafa58da/raw/07210f958c01737a139d916c5082dd1bc7724955/banlist-test-2", + "", + "", }) require.NoError(t, err) diff --git a/protocol/name_importer.go b/protocol/name_importer.go index 0f601a7..4b45227 100644 --- a/protocol/name_importer.go +++ b/protocol/name_importer.go @@ -3,21 +3,20 @@ package protocol import ( "bytes" "encoding/hex" + "encoding/base64" "fmt" + "github.com/btcsuite/btcd/btcec" "fnd/config" "fnd/log" "fnd/store" - "strings" + "fnd.localhost/handshake/client" + "fnd.localhost/handshake/dns" + "fnd.localhost/handshake/primitives" + "github.com/pkg/errors" + "github.com/syndtr/goleveldb/leveldb" "sync" "sync/atomic" "time" - - "github.com/btcsuite/btcd/btcec" - "github.com/mslipper/handshake/client" - "github.com/mslipper/handshake/dns" - "github.com/mslipper/handshake/primitives" - "github.com/pkg/errors" - "github.com/syndtr/goleveldb/leveldb" ) type NameImporter struct { @@ -197,13 +196,13 @@ func (n *NameImporter) fetchBlocks(start int, count int) ([]*primitives.Block, e return partition, nil } -type DDRPKeyRecord struct { +type FNRecord struct { NameHash string PublicKey *btcec.PublicKey } -func ExtractTXTRecordsBlock(block *primitives.Block) []*DDRPKeyRecord { - uniqRecords := make(map[string]*DDRPKeyRecord) +func ExtractTXTRecordsBlock(block *primitives.Block) []*FNRecord { + uniqRecords := make(map[string]*FNRecord) var order []string for _, tx := range block.Transactions { records := ExtractTXTRecordsTx(tx) @@ -214,15 +213,15 @@ func ExtractTXTRecordsBlock(block *primitives.Block) []*DDRPKeyRecord { uniqRecords[rec.NameHash] = rec } } - out := make([]*DDRPKeyRecord, len(uniqRecords)) + out := make([]*FNRecord, len(uniqRecords)) for i := 0; i < len(order); i++ { out[i] = uniqRecords[order[i]] } return out } -func ExtractTXTRecordsTx(tx *primitives.Transaction) []*DDRPKeyRecord { - var out []*DDRPKeyRecord +func ExtractTXTRecordsTx(tx *primitives.Transaction) []*FNRecord { + var out []*FNRecord for _, vOut := range tx.Outputs { covenant := vOut.Covenant var resource *dns.Resource @@ -247,13 +246,16 @@ func ExtractTXTRecordsTx(tx *primitives.Transaction) []*DDRPKeyRecord { } var pub *btcec.PublicKey + if resource == nil { + continue + } for _, record := range resource.Records { txt, ok := record.(*dns.TXTRecord) if !ok { continue } for _, entry := range txt.Entries { - p, err := ParseDDRPKeyRecord(entry) + p, err := ParseFNRecord(entry) if err != nil { continue } @@ -265,7 +267,7 @@ func ExtractTXTRecordsTx(tx *primitives.Transaction) []*DDRPKeyRecord { continue } - out = append(out, &DDRPKeyRecord{ + out = append(out, &FNRecord{ NameHash: hex.EncodeToString(nh), PublicKey: pub, }) @@ -273,18 +275,19 @@ func ExtractTXTRecordsTx(tx *primitives.Transaction) []*DDRPKeyRecord { return out } -func ParseDDRPKeyRecord(record string) (*btcec.PublicKey, error) { - splits := strings.Split(record, ":") - if len(splits) != 2 { +func ParseFNRecord(record string) (*btcec.PublicKey, error) { + if len(record) != 45 { return nil, errors.New("mal-formed txt record") } - if splits[0] != "DDRPKEY" { + prefix := record[0:1] + pubkeyb64 := record[1:] + if prefix != "f" { return nil, errors.New("mal-formed record sigil") } - if len(splits[1]) != 66 { + if len(pubkeyb64) != 44 { return nil, errors.New("invalid public key length") } - keyBytes, err := hex.DecodeString(splits[1]) + keyBytes, err := base64.StdEncoding.DecodeString(pubkeyb64) if err != nil { return nil, errors.New("mal-formed public key") } diff --git a/protocol/name_importer_test.go b/protocol/name_importer_test.go index ac43f63..9d4b3e0 100644 --- a/protocol/name_importer_test.go +++ b/protocol/name_importer_test.go @@ -3,30 +3,29 @@ package protocol import ( "fmt" "fnd/testutil/testcrypto" - "testing" - "github.com/stretchr/testify/require" + "testing" ) -func TestParseDDRPKeyRecord(t *testing.T) { +func TestParseFNRecord(t *testing.T) { invalid := []string{ - "DDRPKEY:000000000000000000000000000000000000000000000000000000000000000000", - "DDRPKEY:whateverwhateverwhateverwhateverwhateverwhateverwhateverwhateverwh", - "DDRPKEY", - "DDRPKEY:", - "DDRPKEY:whatever", - "DDRPKEY", + "f000000000000000000000000000000000000000000000000000000000000000000", + "fwhateverwhateverwhateverwhateverwhateverwhateverwhateverwhateverwh", + "f", + "f", + "fwhatever", + "f", "", "wibble", } for _, rec := range invalid { - _, err := ParseDDRPKeyRecord(rec) + _, err := ParseFNRecord(rec) require.Error(t, err) } _, expPub := testcrypto.RandKey() - rec := fmt.Sprintf("DDRPKEY:%x", expPub.SerializeCompressed()) - actPub, err := ParseDDRPKeyRecord(rec) + rec := fmt.Sprintf("f%x", expPub.SerializeCompressed()) + actPub, err := ParseFNRecord(rec) require.NoError(t, err) require.True(t, expPub.IsEqual(actPub)) } diff --git a/protocol/name_syncer.go b/protocol/name_syncer.go index e1c2e55..614e1bb 100644 --- a/protocol/name_syncer.go +++ b/protocol/name_syncer.go @@ -1,10 +1,6 @@ package protocol import ( - "sync" - "sync/atomic" - "time" - "fnd/config" "fnd/crypto" "fnd/log" @@ -12,9 +8,11 @@ import ( "fnd/store" "fnd/util" "fnd/wire" - "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" + "sync" + "sync/atomic" + "time" ) var ( @@ -174,7 +172,7 @@ func (ns *NameSyncer) OnSyncError(cb func(name string, err error)) util.Unsubscr func (ns *NameSyncer) syncName(info *store.NameInfo) { name := info.Name - ownEpoch := uint16(0) + var epochHeight, sectorSize uint16 header, err := store.GetHeader(ns.db, info.Name) if err != nil && !errors.Is(err, leveldb.ErrNotFound) { ns.lgr.Error( @@ -184,7 +182,8 @@ func (ns *NameSyncer) syncName(info *store.NameInfo) { return } if err == nil { - ownEpoch = header.EpochHeight + epochHeight = header.EpochHeight + sectorSize = header.SectorSize } isEnvelopeCh := make(chan bool) @@ -198,9 +197,9 @@ func (ns *NameSyncer) syncName(info *store.NameInfo) { }) recips, _ := p2p.BroadcastRandom(ns.mux, ns.SampleSize, &wire.UpdateReq{ - Name: name, - EpochHeight: ownEpoch, - SectorSize: uint16(0), // FIXME + Name: name, + EpochHeight: epochHeight, + SectorSize: sectorSize, }) sampleSize := len(recips) diff --git a/protocol/peer_exchanger.go b/protocol/peer_exchanger.go index 9a1cdf1..7696b14 100644 --- a/protocol/peer_exchanger.go +++ b/protocol/peer_exchanger.go @@ -8,13 +8,12 @@ import ( "fnd/store" "fnd/util" "fnd/wire" + "github.com/syndtr/goleveldb/leveldb" "math" "math/rand" "net" "sync" "time" - - "github.com/syndtr/goleveldb/leveldb" ) const ( diff --git a/protocol/peer_set_test.go b/protocol/peer_set_test.go index 1b4e0b7..b5cdabe 100644 --- a/protocol/peer_set_test.go +++ b/protocol/peer_set_test.go @@ -2,9 +2,8 @@ package protocol import ( "fnd/crypto" - "testing" - "github.com/stretchr/testify/require" + "testing" ) func TestPeerSet(t *testing.T) { diff --git a/protocol/pinger_test.go b/protocol/pinger_test.go index bf9ea25..3bbc3d7 100644 --- a/protocol/pinger_test.go +++ b/protocol/pinger_test.go @@ -7,12 +7,11 @@ import ( "fnd/testutil" "fnd/testutil/testcrypto" "fnd/wire" + "github.com/stretchr/testify/require" "io" "io/ioutil" "testing" "time" - - "github.com/stretchr/testify/require" ) func TestPinger_SendsPingsOnInterval(t *testing.T) { diff --git a/protocol/sector_server.go b/protocol/sector_server.go index e8c0a94..30a62b1 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -2,8 +2,6 @@ package protocol import ( "fmt" - "time" - "fnd/blob" "fnd/config" "fnd/crypto" @@ -12,8 +10,8 @@ import ( "fnd/store" "fnd/util" "fnd/wire" - "github.com/syndtr/goleveldb/leveldb" + "time" ) type SectorServer struct { diff --git a/protocol/syncer.go b/protocol/syncer.go index 71ee893..3ffa730 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -1,15 +1,13 @@ package protocol import ( - "time" - "fnd/blob" "fnd/crypto" "fnd/log" "fnd/p2p" "fnd/wire" - "github.com/pkg/errors" + "time" ) const ( @@ -40,7 +38,6 @@ type payloadRes struct { func SyncSectors(opts *SyncSectorsOpts) error { lgr := log.WithModule("payload-syncer").Sub("name", opts.Name) - // Implement payload hash based sync payloadResCh := make(chan *payloadRes) payloadProcessedCh := make(chan struct{}, 1) doneCh := make(chan struct{}) diff --git a/protocol/syncer_test.go b/protocol/syncer_test.go deleted file mode 100644 index 76dda72..0000000 --- a/protocol/syncer_test.go +++ /dev/null @@ -1,209 +0,0 @@ -package protocol - -import ( - "bytes" - "crypto/rand" - "errors" - "testing" - "time" - - "fnd/blob" - "fnd/crypto" - "fnd/testutil/mockapp" - "fnd/util" - - "github.com/stretchr/testify/require" -) - -type syncTreeBasesSetup struct { - tp *mockapp.TestPeers - ls *mockapp.TestStorage - rs *mockapp.TestStorage -} - -func TestSyncTreeBases(t *testing.T) { - name := "foobar" - tests := []struct { - name string - run func(t *testing.T, setup *syncTreeBasesSetup) - }{ - { - "syncs tree bases with one valid peer", - func(t *testing.T, setup *syncTreeBasesSetup) { - ts := time.Now() - - var randSector blob.Sector - _, err := rand.Read(randSector[:]) - require.NoError(t, err) - sectorHash := blob.HashSector(randSector) - buf := new(bytes.Buffer) - buf.Write(blob.ZeroSector[:]) - buf.Write(randSector[:]) - update := mockapp.FillBlobReader( - t, - setup.rs.DB, - setup.rs.BlobStore, - setup.tp.RemoteSigner, - name, - ts, - ts, - bytes.NewReader(buf.Bytes()), - ) - - merkleBase, err := SyncTreeBases(&SyncTreeBasesOpts{ - Mux: setup.tp.LocalMux, - Peers: NewPeerSet([]crypto.Hash{ - crypto.HashPub(setup.tp.RemoteSigner.Pub()), - }), - MerkleRoot: update.MerkleRoot, - Name: name, - }) - - require.NoError(t, err) - for i, hash := range merkleBase { - if i == 1 { - require.Equal(t, sectorHash, hash) - continue - } - require.Equal(t, blob.EmptyBlobBaseHash, hash) - } - }, - }, - { - "aborts sync if all peers return invalid merkle bases", - func(t *testing.T, setup *syncTreeBasesSetup) { - ts := time.Now() - addlPeer, addlPeerDone := mockapp.ConnectAdditionalPeer(t, setup.tp.LocalSigner, setup.tp.LocalMux) - defer addlPeerDone() - addlStorage, addlStorageDone := mockapp.CreateStorage(t) - defer addlStorageDone() - addlSS := NewSectorServer(addlPeer.Mux, addlStorage.DB, addlStorage.BlobStore, util.NewMultiLocker()) - require.NoError(t, addlSS.Start()) - defer require.NoError(t, addlSS.Stop()) - // each blob will contain different data, thus yielding a - // different merkle root - mockapp.FillBlobRandom( - t, - setup.rs.DB, - setup.rs.BlobStore, - setup.tp.RemoteSigner, - name, - ts, - ts, - ) - mockapp.FillBlobRandom( - t, - addlStorage.DB, - addlStorage.BlobStore, - setup.tp.RemoteSigner, - name, - ts, - ts, - ) - - merkleBase, err := SyncTreeBases(&SyncTreeBasesOpts{ - Mux: setup.tp.LocalMux, - Peers: NewPeerSet([]crypto.Hash{ - crypto.HashPub(setup.tp.RemoteSigner.Pub()), - crypto.HashPub(addlPeer.Signer.Pub()), - }), - MerkleRoot: crypto.Rand32(), - Name: name, - }) - require.Equal(t, blob.ZeroMerkleBase, merkleBase) - require.Error(t, err) - require.True(t, errors.Is(err, ErrNoTreeBaseCandidates)) - }, - }, - { - "handles peers that time out", - func(t *testing.T, setup *syncTreeBasesSetup) { - ts := time.Now() - addlPeer, addlPeerDone := mockapp.ConnectAdditionalPeer(t, setup.tp.LocalSigner, setup.tp.LocalMux) - defer addlPeerDone() - - // trigger timeout by not configuring a sector server for the - // additional peer - - mockapp.FillBlobRandom( - t, - setup.rs.DB, - setup.rs.BlobStore, - setup.tp.RemoteSigner, - name, - ts, - ts, - ) - - merkleBase, err := SyncTreeBases(&SyncTreeBasesOpts{ - Timeout: 250 * time.Millisecond, - Mux: setup.tp.LocalMux, - Peers: NewPeerSet([]crypto.Hash{ - crypto.HashPub(addlPeer.Signer.Pub()), - crypto.HashPub(setup.tp.RemoteSigner.Pub()), - }), - MerkleRoot: crypto.Rand32(), - Name: name, - }) - require.Equal(t, blob.ZeroMerkleBase, merkleBase) - require.Error(t, err) - require.True(t, errors.Is(err, ErrNoTreeBaseCandidates)) - }, - }, - { - "handles peer send errors", - func(t *testing.T, setup *syncTreeBasesSetup) { - ts := time.Now() - addlPeer, addlPeerDone := mockapp.ConnectAdditionalPeer(t, setup.tp.LocalSigner, setup.tp.LocalMux) - defer addlPeerDone() - - // trigger a peer send error by closing the additional peer - // before starting tree base sync - require.NoError(t, addlPeer.RemotePeer.Close()) - - mockapp.FillBlobRandom( - t, - setup.rs.DB, - setup.rs.BlobStore, - setup.tp.RemoteSigner, - name, - ts, - ts, - ) - - merkleBase, err := SyncTreeBases(&SyncTreeBasesOpts{ - Timeout: 250 * time.Millisecond, - Mux: setup.tp.LocalMux, - Peers: NewPeerSet([]crypto.Hash{ - crypto.HashPub(addlPeer.Signer.Pub()), - crypto.HashPub(setup.tp.RemoteSigner.Pub()), - }), - MerkleRoot: crypto.Rand32(), - Name: name, - }) - require.Equal(t, blob.ZeroMerkleBase, merkleBase) - require.Error(t, err) - require.True(t, errors.Is(err, ErrNoTreeBaseCandidates)) - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - testPeers, peersDone := mockapp.ConnectTestPeers(t) - defer peersDone() - remoteStorage, remoteStorageDone := mockapp.CreateStorage(t) - defer remoteStorageDone() - localStorage, localStorageDone := mockapp.CreateStorage(t) - defer localStorageDone() - remoteSS := NewSectorServer(testPeers.RemoteMux, remoteStorage.DB, remoteStorage.BlobStore, util.NewMultiLocker()) - require.NoError(t, remoteSS.Start()) - defer require.NoError(t, remoteSS.Stop()) - - tt.run(t, &syncTreeBasesSetup{ - tp: testPeers, - ls: localStorage, - rs: remoteStorage, - }) - }) - } -} diff --git a/protocol/testdata/blob b/protocol/testdata/blob index f8f241094699f689470613d9f00dca2107b0876f..d7776fec633737d6f8542c54d7cbda2eae8a2ca9 100644 GIT binary patch delta 521 zcmWN=1Jo7<006+3Z7Ro%AxuD3i>x z_)}Kd{N-=i<&aY@x#f{pKKT_;P$7jCQB*O-l~7VCrIk@uIptMQQ6-gCQB^h7)lgF{ zwbfBqJ@qxv&_5daS7S{y)l75$X`!W7T5F@NcG~NpqfR>OqN{GY>!GJ!dh4UFfFS+! z#{dHjGT0D94Kv&bBaJfJ7-Nky-UJg(GT9VUO*7pLGtDyF9COVx-vSFQve*(!EwkJT zE3LBH8f&ey-Ub_Ove_0}ZL{4DJMFUD9((<7pZyLv=#ayXIO>?=PB`h5)6O{SobxWY z=#tB>xaykgZn)`|+wQpQp8Fnn=#j^scuNHPlo~ZGWoc zFLl*ZUjq#_(pVEsHPc)REw$2G8*R1IUI!g@(peW>b<Mn?|&O?w8>^$Y_-jHJM6T}ZhP#t&wd9SbjV>x9CgfbC!BQ3X=j{u&UqJH zbjf8`Ty@QLH{5i~ZFk&t&wUR(^vGjRJoU_TFTC{1Yj3>u&U+tx^vP#meD%$DKm7a! Djz0#S diff --git a/protocol/testdata/block8506.json b/protocol/testdata/block8506.json index afc09fa..f5fadd4 100644 --- a/protocol/testdata/block8506.json +++ b/protocol/testdata/block8506.json @@ -2161,4 +2161,4 @@ "chainwork": "00000000000000000000000000000000000000000000000809f33fddea3f8819", "previousblockhash": "00000000000002b49847e9773fc340310c2eec966a43b0a75ab4f1660eae5a37", "nextblockhash": "00000000000002ebf504119f370ae4cd9ff6769a70647fc9a2eefa51e3c98c7f" -} \ No newline at end of file +} diff --git a/protocol/timebank.go b/protocol/timebank.go deleted file mode 100644 index a245273..0000000 --- a/protocol/timebank.go +++ /dev/null @@ -1,39 +0,0 @@ -package protocol - -import ( - "time" -) - -type TimebankParams struct { - TimebankDuration time.Duration - MinUpdateInterval time.Duration - FullUpdatesPerPeriod int -} - -func CheckTimebank(params *TimebankParams, prevUpdateTime time.Time, prevTimebank int, sectorsNeeded int) int { - if sectorsNeeded == 0 { - return -1 - } - if sectorsNeeded > 256 { - return -1 - } - - now := time.Now() - if prevUpdateTime.After(now.Add(-1 * params.MinUpdateInterval)) { - return -1 - } - - sectorUpdatesPerPeriod := params.FullUpdatesPerPeriod * 256 - secondsSince := int(time.Since(prevUpdateTime) / time.Second) - secondsPerSector := int(params.TimebankDuration/time.Second) / sectorUpdatesPerPeriod - sectorsAvailable := prevTimebank + (secondsSince / secondsPerSector) - if sectorsAvailable > sectorUpdatesPerPeriod { - sectorsAvailable = sectorUpdatesPerPeriod - } - - if sectorsNeeded > sectorsAvailable { - return -1 - } - - return sectorsAvailable - sectorsNeeded -} diff --git a/protocol/timebank_test.go b/protocol/timebank_test.go deleted file mode 100644 index d17c820..0000000 --- a/protocol/timebank_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package protocol - -import ( - "github.com/stretchr/testify/require" - "testing" - "time" -) - -func TestCheckTimebank(t *testing.T) { - params := &TimebankParams{ - TimebankDuration: 48 * time.Hour, - MinUpdateInterval: 2 * time.Minute, - FullUpdatesPerPeriod: 2, - } - - now := time.Now() - tests := []struct { - name string - prevUpdateTime time.Time - prevTimebank int - sectorsUpdated int - newTimebank int - }{ - { - "zero bytes updated", - now, - 0, - 0, - -1, - }, - { - "more than sector count updated", - now, - 0, - 256, - -1, - }, - { - "update is within min update frequency", - now, - 0, - 1, - -1, - }, - { - "not enough time bank - one sector interval", - now.Add(-1 * 10 * time.Minute), - 0, - 3, - -1, - }, - { - "not enough time bank - multiple sector intervals", - now.Add(-1 * 24 * time.Hour), - 0, - 257, - -1, - }, - { - "enough time bank - one sector interval", - now.Add(-1 * 10 * time.Minute), - 2, - 1, - 2, - }, - { - "enough time bank - multiple sector intervals", - now.Add(-1 * 24 * time.Hour), - 0, - 100, - 156, - }, - { - "enough time bank - multiple sector intervals with high initial bank", - now.Add(-1 * 24 * time.Hour), - 512, - 100, - 412, - }, - { - "enough time bank - multiple sector intervals zero bank", - now.Add(-1 * params.TimebankDuration), - 0, - 100, - 412, - }, - { - "enough time bank - no previous update time", - time.Time{}, - 0, - 32, - 480, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require.Equal(t, tt.newTimebank, CheckTimebank(params, tt.prevUpdateTime, tt.prevTimebank, tt.sectorsUpdated)) - }) - } -} diff --git a/protocol/transaction_mock_test.go b/protocol/transaction_mock_test.go index 1f13c49..7edc919 100644 --- a/protocol/transaction_mock_test.go +++ b/protocol/transaction_mock_test.go @@ -2,7 +2,6 @@ package protocol import ( "fnd/blob" - "github.com/stretchr/testify/mock" ) diff --git a/protocol/update_queue.go b/protocol/update_queue.go index e2bf695..5478ed9 100644 --- a/protocol/update_queue.go +++ b/protocol/update_queue.go @@ -1,10 +1,7 @@ package protocol import ( - "sync" - "sync/atomic" - "time" - + "github.com/btcsuite/btcd/btcec" "fnd/blob" "fnd/config" "fnd/crypto" @@ -12,11 +9,12 @@ import ( "fnd/p2p" "fnd/store" "fnd/wire" - - "github.com/btcsuite/btcd/btcec" - "github.com/mslipper/handshake/primitives" + "fnd.localhost/handshake/primitives" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" + "sync" + "sync/atomic" + "time" ) var ( diff --git a/protocol/update_queue_test.go b/protocol/update_queue_test.go index f3a6e42..0b7f52a 100644 --- a/protocol/update_queue_test.go +++ b/protocol/update_queue_test.go @@ -1,9 +1,6 @@ package protocol import ( - "testing" - "time" - "fnd/blob" "fnd/crypto" "fnd/p2p" @@ -11,9 +8,10 @@ import ( "fnd/testutil" "fnd/testutil/testcrypto" "fnd/wire" - "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" + "testing" + "time" ) func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { diff --git a/protocol/update_server_test.go b/protocol/update_server_test.go index 955069e..37385e8 100644 --- a/protocol/update_server_test.go +++ b/protocol/update_server_test.go @@ -1,9 +1,6 @@ package protocol import ( - "io" - "testing" - "fnd/blob" "fnd/crypto" "fnd/p2p" @@ -12,9 +9,10 @@ import ( "fnd/testutil/testcrypto" "fnd/util" "fnd/wire" - "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" + "io" + "testing" ) func TestUpdateServer(t *testing.T) { @@ -114,15 +112,15 @@ func TestUpdateServer(t *testing.T) { func(t *testing.T) { epochHeight := uint16(0) sectorSize := uint16(10) - tree := blob.MakeTreeFromBase(blob.ZeroMerkleBase) - sig, err := blob.SignSeal(signer, "valid", epochHeight, sectorSize, tree.Root(), crypto.ZeroHash) + sectorHashTip := blob.ZeroHash + sig, err := blob.SignSeal(signer, "valid", epochHeight, sectorSize, sectorHashTip, crypto.ZeroHash) require.NoError(t, err) require.NoError(t, store.WithTx(db, func(tx *leveldb.Transaction) error { return store.SetHeaderTx(tx, &store.Header{ Name: "valid", EpochHeight: epochHeight, SectorSize: sectorSize, - SectorTipHash: tree.Root(), + SectorTipHash: sectorHashTip, Signature: sig, }, blob.ZeroSectorHashes) })) diff --git a/protocol/updater.go b/protocol/updater.go index c375a03..38bdc9f 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -1,9 +1,6 @@ package protocol import ( - "sync" - "time" - "fnd/blob" "fnd/config" "fnd/crypto" @@ -12,9 +9,10 @@ import ( "fnd/store" "fnd/util" "fnd/wire" - "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" + "sync" + "time" ) var ( diff --git a/protocol/updater_test.go b/protocol/updater_test.go index c3196b1..a668b2e 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -3,9 +3,6 @@ package protocol import ( "crypto/rand" "errors" - "testing" - "time" - "fnd/blob" "fnd/crypto" "fnd/p2p" @@ -13,9 +10,10 @@ import ( "fnd/testutil/mockapp" "fnd/util" "fnd/wire" - "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" + "testing" + "time" ) type updaterTestSetup struct { diff --git a/protocol/util_test.go b/protocol/util_test.go index e201ffa..5416c99 100644 --- a/protocol/util_test.go +++ b/protocol/util_test.go @@ -3,12 +3,11 @@ package protocol import ( "fmt" "fnd/store" + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" "io/ioutil" "os" "testing" - - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" ) func setupDB(t *testing.T) (*leveldb.DB, func()) { diff --git a/rpc/blob.go b/rpc/blob.go index 8723d01..6e579d0 100644 --- a/rpc/blob.go +++ b/rpc/blob.go @@ -2,15 +2,13 @@ package rpc import ( "context" - "io" - "time" - + "github.com/btcsuite/btcd/btcec" "fnd/crypto" apiv1 "fnd/rpc/v1" "fnd/store" - - "github.com/btcsuite/btcd/btcec" "github.com/pkg/errors" + "io" + "time" ) func GetBlobInfo(client apiv1.Footnotev1Client, name string) (*store.BlobInfo, error) { diff --git a/rpc/blob_writer.go b/rpc/blob_writer.go index 938bc86..3ac4e81 100644 --- a/rpc/blob_writer.go +++ b/rpc/blob_writer.go @@ -2,13 +2,11 @@ package rpc import ( "context" - "time" - "fnd/blob" "fnd/crypto" apiv1 "fnd/rpc/v1" - "github.com/pkg/errors" + "time" ) type BlobWriter struct { diff --git a/rpc/server.go b/rpc/server.go index 2dcfbac..9ab94e3 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -2,11 +2,6 @@ package rpc import ( "context" - "net" - "strconv" - "sync/atomic" - "time" - "fnd/blob" "fnd/crypto" "fnd/log" @@ -16,10 +11,13 @@ import ( "fnd/store" "fnd/util" "fnd/wire" - "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" "google.golang.org/grpc" + "net" + "strconv" + "sync/atomic" + "time" ) const ( diff --git a/rpc/v1/api.pb.go b/rpc/v1/api.pb.go index e9b5f6d..1b49210 100644 --- a/rpc/v1/api.pb.go +++ b/rpc/v1/api.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0-devel -// protoc v3.12.4 +// protoc-gen-go v1.23.0 +// protoc v3.6.1 // source: api.proto package v1 diff --git a/scripts/gen-node-bindings.sh b/scripts/gen-node-bindings.sh index 3bcafc4..17baf5b 100755 --- a/scripts/gen-node-bindings.sh +++ b/scripts/gen-node-bindings.sh @@ -20,4 +20,4 @@ protoc \ --ts_out="service=grpc-node:${OUT_DIR}" \ --grpc_out="${OUT_DIR}" \ -I "$DIR/../rpc/v1/" \ - "$DIR/../rpc/v1/api.proto" \ No newline at end of file + "$DIR/../rpc/v1/api.proto" diff --git a/scripts/release-public.sh b/scripts/release-public.sh index ec69060..a4929f3 100755 --- a/scripts/release-public.sh +++ b/scripts/release-public.sh @@ -8,16 +8,16 @@ tag="$(git describe --tags --abbrev=0)" version="${tag:1}" create_tarball() { - mv -f "$build_dir/fnd-$1-amd64" "$build_dir/ddrpd" + mv -f "$build_dir/fnd-$1-amd64" "$build_dir/fnd" mv -f "$build_dir/fnd-cli-$1-amd64" "$build_dir/fnd-cli" - tar -czvf "$build_dir/ddrp-$version-$1-amd64.tgz" -C "$build_dir" "fnd" "fnd-cli" - gpg2 --detach-sig --default-key D4B604F1 --output "$build_dir/ddrp-$version-$1-amd64.tgz.sig" "$build_dir/ddrp-$version-$1-amd64.tgz" + tar -czvf "$build_dir/fnd-$version-$1-amd64.tgz" -C "$build_dir" "fnd" "fnd-cli" + gpg2 --detach-sig --default-key D4B604F1 --output "$build_dir/fnd-$version-$1-amd64.tgz.sig" "$build_dir/fnd-$version-$1-amd64.tgz" } upload_binary() { echo "Uploading $1 binary..." - gothub upload --user ddrp-org --repo ddrp --tag "$tag" --file "$build_dir/ddrp-$version-$1-amd64.tgz" --name "ddrp-$version-$1-amd64.tgz" - gothub upload --user ddrp-org --repo ddrp --tag "$tag" --file "$build_dir/ddrp-$version-$1-amd64.tgz.sig" --name "ddrp-$version-$1-amd64.tgz.sig" + gothub upload --user fnd-org --repo fnd --tag "$tag" --file "$build_dir/fnd-$version-$1-amd64.tgz" --name "fnd-$version-$1-amd64.tgz" + gothub upload --user fnd-org --repo fnd --tag "$tag" --file "$build_dir/fnd-$version-$1-amd64.tgz.sig" --name "fnd-$version-$1-amd64.tgz.sig" } make clean @@ -26,22 +26,22 @@ make package-deb version="$version" create_tarball "linux" create_tarball "darwin" -gpg2 --detach-sig --default-key D4B604F1 --output "$build_dir/ddrp-$version-amd64.deb.sig" "$build_dir/ddrp-$version-amd64.deb" +gpg2 --detach-sig --default-key D4B604F1 --output "$build_dir/fnd-$version-amd64.deb.sig" "$build_dir/fnd-$version-amd64.deb" -gothub release --user ddrp-org --repo ddrp --tag "$tag" --name "$tag" --description "" +gothub release --user fnd-org --repo fnd --tag "$tag" --name "$tag" --description "" upload_binary "linux" upload_binary "darwin" echo "Uploading .deb..." -gothub upload --user ddrp-org --repo ddrp --tag "$tag" --file "$build_dir/ddrp-$version-amd64.deb" --name "ddrp-$version-amd64.deb" -gothub upload --user ddrp-org --repo ddrp --tag "$tag" --file "$build_dir/ddrp-$version-amd64.deb.sig" --name "ddrp-$version-amd64.deb.sig" +gothub upload --user fnd-org --repo fnd --tag "$tag" --file "$build_dir/fnd-$version-amd64.deb" --name "fnd-$version-amd64.deb" +gothub upload --user fnd-org --repo fnd --tag "$tag" --file "$build_dir/fnd-$version-amd64.deb.sig" --name "fnd-$version-amd64.deb.sig" # for seed node deployments -s3cmd put "$build_dir/ddrp-$version-linux-amd64.tgz" s3://ddrp-releases/ddrp-linux-amd64.tgz -s3cmd setacl s3://ddrp-releases/ddrp-linux-amd64.tgz --acl-public -s3cmd put "$build_dir/ddrp-$version-linux-amd64.tgz.sig" s3://ddrp-releases/ddrp-linux-amd64.tgz.sig -s3cmd setacl s3://ddrp-releases/ddrp-linux-amd64.tgz.sig --acl-public -cp "$build_dir/ddrp-$version-linux-amd64.tgz" "$build_dir/ddrp-linux-amd64.tgz" -cd "$build_dir" && shasum -a 256 "ddrp-linux-amd64.tgz" > /tmp/ddrp-linux-amd64.tgz.sum.txt && cd "$DIR" -s3cmd put /tmp/ddrp-linux-amd64.tgz.sum.txt s3://ddrp-releases/ddrp-linux-amd64.tgz.sum.txt -s3cmd setacl s3://ddrp-releases/ddrp-linux-amd64.tgz.sum.txt --acl-public +s3cmd put "$build_dir/fnd-$version-linux-amd64.tgz" s3://fnd-releases/fnd-linux-amd64.tgz +s3cmd setacl s3://fnd-releases/fnd-linux-amd64.tgz --acl-public +s3cmd put "$build_dir/fnd-$version-linux-amd64.tgz.sig" s3://fnd-releases/fnd-linux-amd64.tgz.sig +s3cmd setacl s3://fnd-releases/fnd-linux-amd64.tgz.sig --acl-public +cp "$build_dir/fnd-$version-linux-amd64.tgz" "$build_dir/fnd-linux-amd64.tgz" +cd "$build_dir" && shasum -a 256 "fnd-linux-amd64.tgz" > /tmp/fnd-linux-amd64.tgz.sum.txt && cd "$DIR" +s3cmd put /tmp/fnd-linux-amd64.tgz.sum.txt s3://fnd-releases/fnd-linux-amd64.tgz.sum.txt +s3cmd setacl s3://fnd-releases/fnd-linux-amd64.tgz.sum.txt --acl-public diff --git a/store/headers.go b/store/headers.go index 4e02d81..e9978d3 100644 --- a/store/headers.go +++ b/store/headers.go @@ -4,17 +4,15 @@ import ( "bytes" "encoding/hex" "encoding/json" - "sync" - "time" - + "github.com/btcsuite/btcd/btcec" "fnd/blob" "fnd/crypto" - - "github.com/btcsuite/btcd/btcec" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/iterator" "github.com/syndtr/goleveldb/leveldb/util" + "sync" + "time" ) type Header struct { diff --git a/store/headers_test.go b/store/headers_test.go index d366617..7eb7271 100644 --- a/store/headers_test.go +++ b/store/headers_test.go @@ -2,14 +2,12 @@ package store import ( "crypto/rand" - "testing" - "time" - "fnd/blob" "fnd/crypto" - "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" + "testing" + "time" ) func TestHeaders_GetSet(t *testing.T) { diff --git a/store/naming_test.go b/store/naming_test.go index 9ef0907..d8b8f23 100644 --- a/store/naming_test.go +++ b/store/naming_test.go @@ -2,10 +2,9 @@ package store import ( "fnd/testutil/testcrypto" - "testing" - "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" + "testing" ) func TestNaming_Meta(t *testing.T) { diff --git a/store/peers.go b/store/peers.go index 2f17cf5..9c508dd 100644 --- a/store/peers.go +++ b/store/peers.go @@ -5,13 +5,12 @@ import ( "encoding/hex" "encoding/json" "fnd/crypto" - "math" - "time" - "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/iterator" "github.com/syndtr/goleveldb/leveldb/util" + "math" + "time" ) type Peer struct { diff --git a/store/peers_test.go b/store/peers_test.go index 6c3141e..ccec6ba 100644 --- a/store/peers_test.go +++ b/store/peers_test.go @@ -2,11 +2,10 @@ package store import ( "fnd/crypto" - "testing" - "time" - "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" + "testing" + "time" ) func TestPeers(t *testing.T) { diff --git a/store/store.go b/store/store.go index 0b7e566..05fd052 100644 --- a/store/store.go +++ b/store/store.go @@ -2,7 +2,6 @@ package store import ( "fnd/log" - "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" ) diff --git a/testutil/mockapp/peer.go b/testutil/mockapp/peer.go index a9c25e2..4af6a01 100644 --- a/testutil/mockapp/peer.go +++ b/testutil/mockapp/peer.go @@ -5,9 +5,8 @@ import ( "fnd/p2p" "fnd/testutil" "fnd/testutil/testcrypto" - "testing" - "github.com/stretchr/testify/require" + "testing" ) type TestPeers struct { diff --git a/testutil/mockapp/storage.go b/testutil/mockapp/storage.go index 4edc7b6..ab61b36 100644 --- a/testutil/mockapp/storage.go +++ b/testutil/mockapp/storage.go @@ -2,18 +2,16 @@ package mockapp import ( "crypto/rand" - "io" - "testing" - "time" - "fnd/blob" "fnd/crypto" "fnd/store" "fnd/testutil/testfs" "fnd/wire" - "github.com/stretchr/testify/require" "github.com/syndtr/goleveldb/leveldb" + "io" + "testing" + "time" ) type TestStorage struct { diff --git a/testutil/net.go b/testutil/net.go index 6e551db..467ad18 100644 --- a/testutil/net.go +++ b/testutil/net.go @@ -3,11 +3,10 @@ package testutil import ( "fnd/testutil/testcrypto" "fnd/wire" + "github.com/stretchr/testify/require" "io" "net" "testing" - - "github.com/stretchr/testify/require" ) const ( diff --git a/testutil/testcrypto/crypto.go b/testutil/testcrypto/crypto.go index 9cab2e4..34eef5a 100644 --- a/testutil/testcrypto/crypto.go +++ b/testutil/testcrypto/crypto.go @@ -3,11 +3,10 @@ package testcrypto import ( "crypto/rand" "encoding/hex" - "fnd/crypto" - "testing" - "github.com/btcsuite/btcd/btcec" + "fnd/crypto" "github.com/stretchr/testify/require" + "testing" ) func RandKey() (*btcec.PrivateKey, *btcec.PublicKey) { diff --git a/wire/blob_req.go b/wire/blob_req.go index 2c545af..c2709bd 100644 --- a/wire/blob_req.go +++ b/wire/blob_req.go @@ -4,7 +4,7 @@ import ( "io" "fnd/crypto" - "fnd/dwire" + "fnd.localhost/dwire" ) type BlobReq struct { diff --git a/wire/blob_res.go b/wire/blob_res.go index b4d48bb..eaa0258 100644 --- a/wire/blob_res.go +++ b/wire/blob_res.go @@ -5,7 +5,7 @@ import ( "fnd/blob" "fnd/crypto" - "fnd/dwire" + "fnd.localhost/dwire" ) type BlobRes struct { diff --git a/wire/envelope.go b/wire/envelope.go index 6ffba2a..a11a58b 100644 --- a/wire/envelope.go +++ b/wire/envelope.go @@ -3,11 +3,10 @@ package wire import ( "bytes" "fmt" + "fnd/crypto" + "fnd.localhost/dwire" "io" "time" - - "fnd/crypto" - "fnd/dwire" ) type Envelope struct { diff --git a/wire/hash_cacher.go b/wire/hash_cacher.go index 2007e40..3d99c0e 100644 --- a/wire/hash_cacher.go +++ b/wire/hash_cacher.go @@ -2,10 +2,9 @@ package wire import ( "bytes" - "sync" - "fnd/crypto" - "fnd/dwire" + "fnd.localhost/dwire" + "sync" ) var hashCacherBufPool = sync.Pool{ diff --git a/wire/hash_cacher_test.go b/wire/hash_cacher_test.go index 2566daa..c6e3e36 100644 --- a/wire/hash_cacher_test.go +++ b/wire/hash_cacher_test.go @@ -2,14 +2,12 @@ package wire import ( "encoding/hex" + "fnd/crypto" + "fnd.localhost/dwire" + "github.com/stretchr/testify/require" "io" "sync" "testing" - - "fnd/crypto" - "fnd/dwire" - - "github.com/stretchr/testify/require" ) type input struct { diff --git a/wire/hello.go b/wire/hello.go index e5f4fe0..e09d614 100644 --- a/wire/hello.go +++ b/wire/hello.go @@ -1,12 +1,10 @@ package wire import ( - "io" - - "fnd/crypto" - "fnd/dwire" - "github.com/btcsuite/btcd/btcec" + "fnd/crypto" + "fnd.localhost/dwire" + "io" ) type Hello struct { diff --git a/wire/hello_ack.go b/wire/hello_ack.go index 3fff7b0..2363e95 100644 --- a/wire/hello_ack.go +++ b/wire/hello_ack.go @@ -1,10 +1,9 @@ package wire import ( - "io" - "fnd/crypto" - "fnd/dwire" + "fnd.localhost/dwire" + "io" ) type HelloAck struct { diff --git a/wire/message.go b/wire/message.go index 32914f6..e55dd1b 100644 --- a/wire/message.go +++ b/wire/message.go @@ -1,10 +1,9 @@ package wire import ( - "io" - "fnd/crypto" - "fnd/dwire" + "fnd.localhost/dwire" + "io" ) type Message interface { diff --git a/wire/nil_update.go b/wire/nil_update.go index 702c2e8..312151c 100644 --- a/wire/nil_update.go +++ b/wire/nil_update.go @@ -1,10 +1,9 @@ package wire import ( - "io" - "fnd/crypto" - "fnd/dwire" + "fnd.localhost/dwire" + "io" ) type NilUpdate struct { diff --git a/wire/peer_res.go b/wire/peer_res.go index 994fbc9..b3cbe53 100644 --- a/wire/peer_res.go +++ b/wire/peer_res.go @@ -2,11 +2,10 @@ package wire import ( "bytes" + "fnd/crypto" + "fnd.localhost/dwire" "io" "net" - - "fnd/crypto" - "fnd/dwire" ) type Peer struct { diff --git a/wire/testdata/hello b/wire/testdata/hello index a6e5d4ff8ed3a565bdbacf249a3b1f04c699d1ef..a238b5509dada53ce6b11c8ef12d589127bf09b3 100644 GIT binary patch delta 6 Ncmd1Fosh%G1po*?0pS1u delta 4 Lcmd1JnUDhj1c(9F diff --git a/wire/testdata/hello_ack b/wire/testdata/hello_ack index ed43e9374f30c2c714540587cf9ea9f685fd2d95..c952a9f99ee80bd421805a9c40d77674698832b9 100644 GIT binary patch literal 33 NcmZSh&wv+j0RSKi0SW*B delta 4 LcmY#Xn4kav0w@6T diff --git a/wire/testdata/nil_update b/wire/testdata/nil_update index 197ca51..8554269 100644 --- a/wire/testdata/nil_update +++ b/wire/testdata/nil_update @@ -1 +1 @@ - testname. \ No newline at end of file + testname. diff --git a/wire/testdata/peer_res b/wire/testdata/peer_res index 20d344a80de5c7e74aebb8167f6c1c78101faefc..6a5836c372da911004de62752126aea68ccb6b0c 100644 GIT binary patch delta 6 NcmYdHnvlrI1po)70l)wN delta 4 LcmYdFoRA0r1TX=$ diff --git a/wire/update.go b/wire/update.go index bb8960c..9f01281 100644 --- a/wire/update.go +++ b/wire/update.go @@ -1,10 +1,9 @@ package wire import ( - "io" - "fnd/crypto" - "fnd/dwire" + "fnd.localhost/dwire" + "io" ) type Update struct { diff --git a/wire/update_req.go b/wire/update_req.go index fa13aaf..2ffbdb5 100644 --- a/wire/update_req.go +++ b/wire/update_req.go @@ -1,10 +1,9 @@ package wire import ( - "io" - "fnd/crypto" - "fnd/dwire" + "fnd.localhost/dwire" + "io" ) type UpdateReq struct { diff --git a/wire/util_test.go b/wire/util_test.go index 70f3288..40150d9 100644 --- a/wire/util_test.go +++ b/wire/util_test.go @@ -3,19 +3,15 @@ package wire import ( "bytes" "fmt" - "io/ioutil" - "testing" - - "fnd/blob" "fnd/crypto" - "github.com/stretchr/testify/require" + "io/ioutil" + "testing" ) var ( fixedSig crypto.Signature fixedHash crypto.Hash - fixedMerkleProof blob.MerkleProof fixedEpochHeight = uint16(0) fixedSectorSize = uint16(0) ) @@ -49,5 +45,4 @@ func testMessageEncoding(t *testing.T, fixtureName string, input Message, proto func init() { fixedSig[1] = 0xff fixedHash[1] = 0xff - fixedMerkleProof[1] = 0xff } From 040e1daa9d5e939503831433a1d57958b90438d1 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 18 Jan 2021 20:26:33 +0530 Subject: [PATCH 05/71] blob: fix seal prefix --- blob/seal.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blob/seal.go b/blob/seal.go index c75f2ef..e18110c 100644 --- a/blob/seal.go +++ b/blob/seal.go @@ -8,7 +8,7 @@ import ( func SealHash(name string, epochHeight, sectorSize uint16, sectorTipHash crypto.Hash, reservedRoot crypto.Hash) crypto.Hash { h, _ := blake2b.New256(nil) - if _, err := h.Write([]byte("DDRPBLOB")); err != nil { + if _, err := h.Write([]byte("FNBLOB")); err != nil { panic(err) } if err := dwire.EncodeField(h, name); err != nil { From 71b469ed7e45f2eca4c67449bb6e9bac9a857f9e Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 18 Jan 2021 20:44:20 +0530 Subject: [PATCH 06/71] testutil: rename test prefix --- testutil/testfs/fs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testutil/testfs/fs.go b/testutil/testfs/fs.go index fef13a3..ef36d6d 100644 --- a/testutil/testfs/fs.go +++ b/testutil/testfs/fs.go @@ -8,7 +8,7 @@ import ( ) func NewTempDir(t *testing.T) (string, func()) { - dir, err := ioutil.TempDir("", "ddrptest_") + dir, err := ioutil.TempDir("", "fndtest_") require.NoError(t, err) return dir, func() { require.NoError(t, os.RemoveAll(dir)) @@ -16,7 +16,7 @@ func NewTempDir(t *testing.T) (string, func()) { } func NewTempFile(t *testing.T) (*os.File, func()) { - f, err := ioutil.TempFile("", "ddrptest_") + f, err := ioutil.TempFile("", "fndtest_") require.NoError(t, err) return f, func() { require.NoError(t, f.Close()) From d06f231e2df6f2eb4647d833ae2d0f384d7319d2 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 18 Jan 2021 21:13:22 +0530 Subject: [PATCH 07/71] testutil: revert flags --- testutil/testflags/flags.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testutil/testflags/flags.go b/testutil/testflags/flags.go index d584c97..22b119d 100644 --- a/testutil/testflags/flags.go +++ b/testutil/testflags/flags.go @@ -6,7 +6,7 @@ import ( ) func IntegrationTest(t *testing.T) { - _, ok := os.LookupEnv("DDRP_ENABLE_INTEGRATION_TESTS") + _, ok := os.LookupEnv("Footnote_ENABLE_INTEGRATION_TESTS") if !ok { t.SkipNow() } @@ -14,7 +14,7 @@ func IntegrationTest(t *testing.T) { } func HandshakeTest(t *testing.T) { - _, ok := os.LookupEnv("DDRP_ENABLE_HANDSHAKE_TESTS") + _, ok := os.LookupEnv("Footnote_ENABLE_HANDSHAKE_TESTS") if !ok { t.SkipNow() } From 79023fe800bb991e897e792720a0f489c9eff1a9 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 18 Jan 2021 21:34:48 +0530 Subject: [PATCH 08/71] dwire: bump MaxByteFieldLen --- vendor/fnd.localhost/dwire/encoder.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/fnd.localhost/dwire/encoder.go b/vendor/fnd.localhost/dwire/encoder.go index 3b358f8..da93123 100644 --- a/vendor/fnd.localhost/dwire/encoder.go +++ b/vendor/fnd.localhost/dwire/encoder.go @@ -4,7 +4,7 @@ import "io" const ( DefaultMaxVariableArrayLen = 1024 - DefaultMaxByteFieldLen = 256 * 1024 + DefaultMaxByteFieldLen = 8 * 256 * 1024 ) // Encoder is an interface that allows arbitrary types to be @@ -33,7 +33,7 @@ type ConfiguredEncoder struct { // MaxByteFieldLen is the maximum length of a variable-length byte array field // dwire will decode before stopping early. - MaxByteFieldLen uint64 + MaxByteFieldLen uint64 } var defaultEncoder = &ConfiguredEncoder{ From fcd9877e32bf3af198306d7e6d4eb275045dcbd2 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 18 Jan 2021 22:13:24 +0530 Subject: [PATCH 09/71] protocol: update test urls; fix parse name record --- protocol/ban_list_test.go | 2 +- protocol/moderation_test.go | 4 ++-- protocol/name_importer_test.go | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/protocol/ban_list_test.go b/protocol/ban_list_test.go index fe4a865..8e4a04f 100644 --- a/protocol/ban_list_test.go +++ b/protocol/ban_list_test.go @@ -125,7 +125,7 @@ func TestReadBanList(t *testing.T) { } func TestFetchListFile(t *testing.T) { - names, err := FetchListFile("") + names, err := FetchListFile("http://sprunge.us/GgRLMw") require.NoError(t, err) require.Equal(t, 3, len(names)) require.Equal(t, names[0], "testname") diff --git a/protocol/moderation_test.go b/protocol/moderation_test.go index 21e875a..08596bf 100644 --- a/protocol/moderation_test.go +++ b/protocol/moderation_test.go @@ -22,8 +22,8 @@ func TestIngestBanLists(t *testing.T) { require.NoError(t, bl.Close()) err = IngestBanLists(db, bs, []string{ - "", - "", + "http://sprunge.us/fKKV87", + "http://sprunge.us/Ot8MYp", }) require.NoError(t, err) diff --git a/protocol/name_importer_test.go b/protocol/name_importer_test.go index 9d4b3e0..51456ad 100644 --- a/protocol/name_importer_test.go +++ b/protocol/name_importer_test.go @@ -1,6 +1,7 @@ package protocol import ( + "encoding/base64" "fmt" "fnd/testutil/testcrypto" "github.com/stretchr/testify/require" @@ -24,7 +25,7 @@ func TestParseFNRecord(t *testing.T) { } _, expPub := testcrypto.RandKey() - rec := fmt.Sprintf("f%x", expPub.SerializeCompressed()) + rec := fmt.Sprintf("f%v", base64.StdEncoding.EncodeToString(expPub.SerializeCompressed())) actPub, err := ParseFNRecord(rec) require.NoError(t, err) require.True(t, expPub.IsEqual(actPub)) From d6ee38efac3db8ac1d88601589db4a60b3d53e37 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 18 Jan 2021 22:31:07 +0530 Subject: [PATCH 10/71] blob, p2p: update and fix tests --- blob/blob_test.go | 4 ++-- blob/io_test.go | 4 ++-- blob/seal_test.go | 4 ++-- p2p/seed_test.go | 7 +++---- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/blob/blob_test.go b/blob/blob_test.go index e5e430e..3e26eb0 100644 --- a/blob/blob_test.go +++ b/blob/blob_test.go @@ -18,13 +18,13 @@ func TestBlob_Reading(t *testing.T) { require.Equal(t, "foobar", bl.Name()) var expSector Sector - _, err = f.ReadAt(expSector[:], 65536) + _, err = f.ReadAt(expSector[:], 4096) require.NoError(t, err) actSector, err := bl.ReadSector(1) require.NoError(t, err) require.Equal(t, expSector, actSector) actData := make([]byte, 10, 10) - _, err = bl.ReadAt(actData, 65536) + _, err = bl.ReadAt(actData, 4096) require.NoError(t, err) require.EqualValues(t, expSector[:10], actData) } diff --git a/blob/io_test.go b/blob/io_test.go index b266c47..e851319 100644 --- a/blob/io_test.go +++ b/blob/io_test.go @@ -110,7 +110,7 @@ func TestReadSector(t *testing.T) { }, { 255, - 16711680, + 1044480, }, } r := &readerWrapper{ @@ -189,7 +189,7 @@ func TestWriteSector(t *testing.T) { }, { 255, - 16711680, + 1044480, }, } w := &writerWrapper{ diff --git a/blob/seal_test.go b/blob/seal_test.go index 30f75ca..66fd3cf 100644 --- a/blob/seal_test.go +++ b/blob/seal_test.go @@ -13,7 +13,7 @@ func TestSealHash(t *testing.T) { epochZero := uint16(0) sectorSize := uint16(0) h := SealHash("testname", epochZero, sectorSize, crypto.ZeroHash, crypto.ZeroHash) - assert.Equal(t, "694802db0f9b9b72725cf9c108b7a496bf20e1bdcc4d7feb9c42b8df1a08823b", hex.EncodeToString(h[:])) + assert.Equal(t, "ec3f68febf79bfe9439b37c9ae707a7e16abf02e67d1ee29fd530598571e16de", hex.EncodeToString(h[:])) } func TestSignSeal(t *testing.T) { @@ -22,5 +22,5 @@ func TestSignSeal(t *testing.T) { priv, _ := testcrypto.FixedKey(t) sig, err := SignSeal(crypto.NewSECP256k1Signer(priv), "testname", epochZero, sectorSize, crypto.ZeroHash, crypto.ZeroHash) require.NoError(t, err) - assert.Equal(t, "1cdb0e3aa14a5489cc1bfcf25843d6747cb9412d6200c35b69dd5fb9cb133ebc7c339ea9d5bb0cce8a9b20e84642757d9a2bc82e9e0a777a9641dd05fb9e5e4836", sig.String()) + assert.Equal(t, "1c3f284e48f72666b5631c707f53c81cc6ba79f3b92d0ae7785189f1ebf43a8174572d16e6ef38de65eb918f6468d7c0bcc04a269fc7346b9da2f29c4b3a08a695", sig.String()) } diff --git a/p2p/seed_test.go b/p2p/seed_test.go index 945f743..069ff66 100644 --- a/p2p/seed_test.go +++ b/p2p/seed_test.go @@ -6,10 +6,9 @@ import ( ) func TestLookupDNSSeeds(t *testing.T) { - seeds, err := ResolveDNSSeeds("seeds-test.fnd.network") + seeds, err := ResolveDNSSeeds("seeds-test.merkleblock.com") require.NoError(t, err) - require.Equal(t, 2, len(seeds)) - require.Contains(t, seeds, "10.1.0.1") - require.Contains(t, seeds, "10.1.0.2") + require.Equal(t, 1, len(seeds)) + require.Contains(t, seeds, "78.46.17.17") } From 0a54dba9278e91cc4fb8a7f16f6a0ac975596cba Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 18 Jan 2021 22:48:34 +0530 Subject: [PATCH 11/71] p2p, wire: update test fixtures; fix handshake test --- p2p/incoming_handshake_test.go | 2 +- wire/testdata/hello | Bin 109 -> 108 bytes wire/testdata/hello_ack | Bin 33 -> 32 bytes wire/testdata/nil_update | 2 +- wire/testdata/peer_res | Bin 98 -> 97 bytes 5 files changed, 2 insertions(+), 2 deletions(-) diff --git a/p2p/incoming_handshake_test.go b/p2p/incoming_handshake_test.go index 7031320..6b8735b 100644 --- a/p2p/incoming_handshake_test.go +++ b/p2p/incoming_handshake_test.go @@ -61,7 +61,7 @@ func TestHandleIncomingHandshake_InvalidHelloSig(t *testing.T) { Peer: setup.outPeer, Signer: testcrypto.NewRandomSigner(), }) - require.True(t, errors.Is(err, ErrPeerClosed)) + require.True(t, errors.Is(err, ErrPeerHangup)) doneCh <- struct{}{} }() <-doneCh diff --git a/wire/testdata/hello b/wire/testdata/hello index a238b5509dada53ce6b11c8ef12d589127bf09b3..a6e5d4ff8ed3a565bdbacf249a3b1f04c699d1ef 100644 GIT binary patch delta 4 Lcmd1JnUDhj1c(9F delta 6 Ncmd1Fosh%G1po*?0pS1u diff --git a/wire/testdata/hello_ack b/wire/testdata/hello_ack index c952a9f99ee80bd421805a9c40d77674698832b9..ed43e9374f30c2c714540587cf9ea9f685fd2d95 100644 GIT binary patch delta 4 LcmY#Xn4kav0w@6T literal 33 NcmZSh&wv+j0RSKi0SW*B diff --git a/wire/testdata/nil_update b/wire/testdata/nil_update index 8554269..197ca51 100644 --- a/wire/testdata/nil_update +++ b/wire/testdata/nil_update @@ -1 +1 @@ - testname. + testname. \ No newline at end of file diff --git a/wire/testdata/peer_res b/wire/testdata/peer_res index 6a5836c372da911004de62752126aea68ccb6b0c..20d344a80de5c7e74aebb8167f6c1c78101faefc 100644 GIT binary patch delta 4 LcmYdFoRA0r1TX=$ delta 6 NcmYdHnvlrI1po)70l)wN From 6afcfbfc460272d14bc5d283c8a45f31e260eb11 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 18 Jan 2021 22:51:46 +0530 Subject: [PATCH 12/71] syncer: reuse timeout --- protocol/syncer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index 3ffa730..cfb5e1b 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -124,6 +124,7 @@ func SyncSectors(opts *SyncSectorsOpts) error { } }() + timeout := time.NewTimer(opts.Timeout) payloadLoop: for { lgr.Debug("requesting payload") @@ -131,7 +132,7 @@ payloadLoop: case <-payloadProcessedCh: lgr.Debug("payload processed") break payloadLoop - case <-time.NewTimer(opts.Timeout).C: + case <-timeout.C: lgr.Warn("payload request timed out") break payloadLoop } From 5ab78256a38023ae46cd869ff844621e1bf2fde7 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 18 Jan 2021 23:00:37 +0530 Subject: [PATCH 13/71] protocol: refactor and separate epoch/updater tests --- protocol/epoch_test.go | 276 +-------------------------------------- protocol/updater_test.go | 258 ++++++++++++++++++++++++++++++++++++ 2 files changed, 262 insertions(+), 272 deletions(-) diff --git a/protocol/epoch_test.go b/protocol/epoch_test.go index 4ed07a1..b5600dd 100644 --- a/protocol/epoch_test.go +++ b/protocol/epoch_test.go @@ -1,280 +1,12 @@ package protocol import ( - "errors" "testing" - "time" - "fnd/blob" - "fnd/crypto" - "fnd/store" - "fnd/testutil/mockapp" - "fnd/util" - - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" + "github.com/stretchr/testify/assert" ) -type epochTestSetup struct { - tp *mockapp.TestPeers - ls *mockapp.TestStorage - rs *mockapp.TestStorage -} - -func TestEpoch(t *testing.T) { - name := "foobar" - tests := []struct { - name string - run func(t *testing.T, setup *epochTestSetup) - }{ - { - "syncs sectors when the local node has never seen the name before", - func(t *testing.T, setup *epochTestSetup) { - ts := time.Now() - update := mockapp.FillBlobRandom( - t, - setup.rs.DB, - setup.rs.BlobStore, - setup.tp.RemoteSigner, - name, - 0, - blob.SectorCount, - ts, - ) - cfg := &UpdateConfig{ - Mux: setup.tp.LocalMux, - DB: setup.ls.DB, - NameLocker: util.NewMultiLocker(), - BlobStore: setup.ls.BlobStore, - Item: &UpdateQueueItem{ - PeerIDs: NewPeerSet([]crypto.Hash{ - crypto.HashPub(setup.tp.RemoteSigner.Pub()), - }), - Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), - }, - } - require.NoError(t, UpdateBlob(cfg)) - mockapp.RequireBlobsEqual(t, setup.ls.BlobStore, setup.rs.BlobStore, name) - }, - }, - { - "aborts sync if the name is banned", - func(t *testing.T, setup *epochTestSetup) { - cfg := &UpdateConfig{ - Mux: setup.tp.LocalMux, - DB: setup.ls.DB, - BlobStore: setup.ls.BlobStore, - Item: &UpdateQueueItem{ - PeerIDs: NewPeerSet([]crypto.Hash{ - crypto.HashPub(setup.tp.RemoteSigner.Pub()), - }), - Name: name, - EpochHeight: CurrentEpoch(name) + 1, - }, - } - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - return store.SetHeaderTx(tx, &store.Header{ - Name: name, - EpochHeight: 0, - SectorSize: 10, - Banned: true, - BannedAt: time.Now().Add(-1 * 24 * time.Duration(time.Hour)), - }, blob.ZeroSectorHashes) - })) - err := UpdateBlob(cfg) - require.NotNil(t, err) - require.True(t, errors.Is(err, ErrNameBanned)) - }, - }, - { - "syncs sectors when the name ban has passed", - func(t *testing.T, setup *epochTestSetup) { - ts := time.Now() - update := mockapp.FillBlobRandom( - t, - setup.rs.DB, - setup.rs.BlobStore, - setup.tp.RemoteSigner, - name, - 0, - blob.SectorCount, - ts, - ) - cfg := &UpdateConfig{ - Mux: setup.tp.LocalMux, - DB: setup.ls.DB, - NameLocker: util.NewMultiLocker(), - BlobStore: setup.ls.BlobStore, - Item: &UpdateQueueItem{ - PeerIDs: NewPeerSet([]crypto.Hash{ - crypto.HashPub(setup.tp.RemoteSigner.Pub()), - }), - Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), - }, - } - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - return store.SetHeaderTx(tx, &store.Header{ - Name: name, - EpochHeight: 0, - SectorSize: 0, - Banned: true, - BannedAt: time.Now().Add(-8 * 24 * time.Duration(time.Hour)), - }, blob.ZeroSectorHashes) - })) - require.NoError(t, UpdateBlob(cfg)) - mockapp.RequireBlobsEqual(t, setup.ls.BlobStore, setup.rs.BlobStore, name) - }, - }, - { - "aborts sync if the epoch is throttled", - func(t *testing.T, setup *epochTestSetup) { - cfg := &UpdateConfig{ - Mux: setup.tp.LocalMux, - DB: setup.ls.DB, - BlobStore: setup.ls.BlobStore, - Item: &UpdateQueueItem{ - PeerIDs: NewPeerSet([]crypto.Hash{ - crypto.HashPub(setup.tp.RemoteSigner.Pub()), - }), - Name: name, - EpochHeight: CurrentEpoch(name) + 1, - }, - } - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - return store.SetHeaderTx(tx, &store.Header{ - Name: name, - EpochHeight: 0, - SectorSize: 10, - EpochStartAt: time.Now(), - }, blob.ZeroSectorHashes) - })) - err := UpdateBlob(cfg) - require.NotNil(t, err) - require.True(t, errors.Is(err, ErrInvalidEpochThrottled)) - }, - }, - { - "aborts sync if the epoch is backdated", - func(t *testing.T, setup *epochTestSetup) { - cfg := &UpdateConfig{ - Mux: setup.tp.LocalMux, - DB: setup.ls.DB, - BlobStore: setup.ls.BlobStore, - Item: &UpdateQueueItem{ - PeerIDs: NewPeerSet([]crypto.Hash{ - crypto.HashPub(setup.tp.RemoteSigner.Pub()), - }), - Name: name, - EpochHeight: 0, - }, - } - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - return store.SetHeaderTx(tx, &store.Header{ - Name: name, - EpochHeight: CurrentEpoch(name), - SectorSize: 10, - Banned: true, - BannedAt: time.Now().Add(-1 * 24 * time.Duration(time.Hour)), - }, blob.ZeroSectorHashes) - })) - err := UpdateBlob(cfg) - require.NotNil(t, err) - require.True(t, errors.Is(err, ErrInvalidEpochBackdated)) - }, - }, - { - "aborts sync if the epoch is futuredated", - func(t *testing.T, setup *epochTestSetup) { - cfg := &UpdateConfig{ - Mux: setup.tp.LocalMux, - DB: setup.ls.DB, - BlobStore: setup.ls.BlobStore, - Item: &UpdateQueueItem{ - PeerIDs: NewPeerSet([]crypto.Hash{ - crypto.HashPub(setup.tp.RemoteSigner.Pub()), - }), - Name: name, - EpochHeight: CurrentEpoch(name) + 1, - }, - } - err := UpdateBlob(cfg) - require.NotNil(t, err) - require.True(t, errors.Is(err, ErrInvalidEpochFuturedated)) - }, - }, - { - "rewrites partial blob with new blob on epoch rollover", - func(t *testing.T, setup *epochTestSetup) { - ts := time.Now() - update := mockapp.FillBlobRandom( - t, - setup.rs.DB, - setup.rs.BlobStore, - setup.tp.RemoteSigner, - name, - CurrentEpoch(name), - blob.SectorCount, - ts, - ) - cfg := &UpdateConfig{ - Mux: setup.tp.LocalMux, - DB: setup.ls.DB, - NameLocker: util.NewMultiLocker(), - BlobStore: setup.ls.BlobStore, - Item: &UpdateQueueItem{ - PeerIDs: NewPeerSet([]crypto.Hash{ - crypto.HashPub(setup.tp.RemoteSigner.Pub()), - }), - Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), - }, - } - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - return store.SetHeaderTx(tx, &store.Header{ - Name: name, - EpochHeight: CurrentEpoch(name) - 1, - SectorSize: 10, - }, blob.ZeroSectorHashes) - })) - require.NoError(t, UpdateBlob(cfg)) - mockapp.RequireBlobsEqual(t, setup.ls.BlobStore, setup.rs.BlobStore, name) - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - testPeers, peersDone := mockapp.ConnectTestPeers(t) - defer peersDone() - remoteStorage, remoteStorageDone := mockapp.CreateStorage(t) - defer remoteStorageDone() - localStorage, localStorageDone := mockapp.CreateStorage(t) - defer localStorageDone() - remoteSS := NewSectorServer(testPeers.RemoteMux, remoteStorage.DB, remoteStorage.BlobStore, util.NewMultiLocker()) - require.NoError(t, remoteSS.Start()) - defer require.NoError(t, remoteSS.Stop()) - - tt.run(t, &epochTestSetup{ - tp: testPeers, - ls: localStorage, - rs: remoteStorage, - }) - }) - } +func TestCurrentEpoch(t *testing.T) { + epoch := CurrentEpoch("bazinga") + assert.Equal(t, uint16(54), epoch) } diff --git a/protocol/updater_test.go b/protocol/updater_test.go index a668b2e..b3068c7 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -367,3 +367,261 @@ func TestUpdater(t *testing.T) { }) } } + +func TestEpoch(t *testing.T) { + name := "foobar" + tests := []struct { + name string + run func(t *testing.T, setup *updaterTestSetup) + }{ + { + "syncs sectors when the local node has never seen the name before", + func(t *testing.T, setup *updaterTestSetup) { + ts := time.Now() + update := mockapp.FillBlobRandom( + t, + setup.rs.DB, + setup.rs.BlobStore, + setup.tp.RemoteSigner, + name, + 0, + blob.SectorCount, + ts, + ) + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + NameLocker: util.NewMultiLocker(), + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: setup.tp.RemoteSigner.Pub(), + }, + } + require.NoError(t, UpdateBlob(cfg)) + mockapp.RequireBlobsEqual(t, setup.ls.BlobStore, setup.rs.BlobStore, name) + }, + }, + { + "aborts sync if the name is banned", + func(t *testing.T, setup *updaterTestSetup) { + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: CurrentEpoch(name) + 1, + }, + } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: 0, + SectorSize: 10, + Banned: true, + BannedAt: time.Now().Add(-1 * 24 * time.Duration(time.Hour)), + }, blob.ZeroSectorHashes) + })) + err := UpdateBlob(cfg) + require.NotNil(t, err) + require.True(t, errors.Is(err, ErrNameBanned)) + }, + }, + { + "syncs sectors when the name ban has passed", + func(t *testing.T, setup *updaterTestSetup) { + ts := time.Now() + update := mockapp.FillBlobRandom( + t, + setup.rs.DB, + setup.rs.BlobStore, + setup.tp.RemoteSigner, + name, + 0, + blob.SectorCount, + ts, + ) + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + NameLocker: util.NewMultiLocker(), + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: setup.tp.RemoteSigner.Pub(), + }, + } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: 0, + SectorSize: 0, + Banned: true, + BannedAt: time.Now().Add(-8 * 24 * time.Duration(time.Hour)), + }, blob.ZeroSectorHashes) + })) + require.NoError(t, UpdateBlob(cfg)) + mockapp.RequireBlobsEqual(t, setup.ls.BlobStore, setup.rs.BlobStore, name) + }, + }, + { + "aborts sync if the epoch is throttled", + func(t *testing.T, setup *updaterTestSetup) { + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: CurrentEpoch(name) + 1, + }, + } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: 0, + SectorSize: 10, + EpochStartAt: time.Now(), + }, blob.ZeroSectorHashes) + })) + err := UpdateBlob(cfg) + require.NotNil(t, err) + require.True(t, errors.Is(err, ErrInvalidEpochThrottled)) + }, + }, + { + "aborts sync if the epoch is backdated", + func(t *testing.T, setup *updaterTestSetup) { + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: 0, + }, + } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: CurrentEpoch(name), + SectorSize: 10, + Banned: true, + BannedAt: time.Now().Add(-1 * 24 * time.Duration(time.Hour)), + }, blob.ZeroSectorHashes) + })) + err := UpdateBlob(cfg) + require.NotNil(t, err) + require.True(t, errors.Is(err, ErrInvalidEpochBackdated)) + }, + }, + { + "aborts sync if the epoch is futuredated", + func(t *testing.T, setup *updaterTestSetup) { + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: CurrentEpoch(name) + 1, + }, + } + err := UpdateBlob(cfg) + require.NotNil(t, err) + require.True(t, errors.Is(err, ErrInvalidEpochFuturedated)) + }, + }, + { + "rewrites partial blob with new blob on epoch rollover", + func(t *testing.T, setup *updaterTestSetup) { + ts := time.Now() + update := mockapp.FillBlobRandom( + t, + setup.rs.DB, + setup.rs.BlobStore, + setup.tp.RemoteSigner, + name, + CurrentEpoch(name), + blob.SectorCount, + ts, + ) + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + NameLocker: util.NewMultiLocker(), + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + SectorTipHash: update.SectorTipHash, + ReservedRoot: update.ReservedRoot, + Signature: update.Signature, + Pub: setup.tp.RemoteSigner.Pub(), + }, + } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: CurrentEpoch(name) - 1, + SectorSize: 10, + }, blob.ZeroSectorHashes) + })) + require.NoError(t, UpdateBlob(cfg)) + mockapp.RequireBlobsEqual(t, setup.ls.BlobStore, setup.rs.BlobStore, name) + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + testPeers, peersDone := mockapp.ConnectTestPeers(t) + defer peersDone() + remoteStorage, remoteStorageDone := mockapp.CreateStorage(t) + defer remoteStorageDone() + localStorage, localStorageDone := mockapp.CreateStorage(t) + defer localStorageDone() + remoteSS := NewSectorServer(testPeers.RemoteMux, remoteStorage.DB, remoteStorage.BlobStore, util.NewMultiLocker()) + require.NoError(t, remoteSS.Start()) + defer require.NoError(t, remoteSS.Stop()) + + tt.run(t, &updaterTestSetup{ + tp: testPeers, + ls: localStorage, + rs: remoteStorage, + }) + }) + } +} From 558d08662841320f8f0fa7df069f50b920c4a4ea Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Tue, 19 Jan 2021 20:38:58 +0530 Subject: [PATCH 14/71] blob: switch sectorlen, sectorcount consts --- blob/blob_test.go | 4 ++-- blob/consts.go | 4 ++-- blob/io_test.go | 4 ++-- protocol/updater_test.go | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/blob/blob_test.go b/blob/blob_test.go index 3e26eb0..f769d45 100644 --- a/blob/blob_test.go +++ b/blob/blob_test.go @@ -18,13 +18,13 @@ func TestBlob_Reading(t *testing.T) { require.Equal(t, "foobar", bl.Name()) var expSector Sector - _, err = f.ReadAt(expSector[:], 4096) + _, err = f.ReadAt(expSector[:], SectorLen) require.NoError(t, err) actSector, err := bl.ReadSector(1) require.NoError(t, err) require.Equal(t, expSector, actSector) actData := make([]byte, 10, 10) - _, err = bl.ReadAt(actData, 4096) + _, err = bl.ReadAt(actData, SectorLen) require.NoError(t, err) require.EqualValues(t, expSector[:10], actData) } diff --git a/blob/consts.go b/blob/consts.go index 43e0668..e406d6a 100644 --- a/blob/consts.go +++ b/blob/consts.go @@ -2,8 +2,8 @@ package blob const ( HeaderLen = 1 + 1 + 63 + 8 + 32 + 65 - SectorLen = 4096 - SectorCount = 256 + SectorLen = 256 + SectorCount = 4096 Size = SectorLen * SectorCount CurrentVersion = 1 ) diff --git a/blob/io_test.go b/blob/io_test.go index e851319..58ce9f0 100644 --- a/blob/io_test.go +++ b/blob/io_test.go @@ -110,7 +110,7 @@ func TestReadSector(t *testing.T) { }, { 255, - 1044480, + 65280, }, } r := &readerWrapper{ @@ -189,7 +189,7 @@ func TestWriteSector(t *testing.T) { }, { 255, - 1044480, + 65280, }, } w := &writerWrapper{ diff --git a/protocol/updater_test.go b/protocol/updater_test.go index b3068c7..038739c 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -39,7 +39,7 @@ func TestUpdater(t *testing.T) { setup.tp.RemoteSigner, name, CurrentEpoch(name), - blob.SectorCount, + blob.SectorLen, ts, ) cfg := &UpdateConfig{ @@ -385,7 +385,7 @@ func TestEpoch(t *testing.T) { setup.tp.RemoteSigner, name, 0, - blob.SectorCount, + blob.SectorLen, ts, ) cfg := &UpdateConfig{ @@ -450,7 +450,7 @@ func TestEpoch(t *testing.T) { setup.tp.RemoteSigner, name, 0, - blob.SectorCount, + blob.SectorLen, ts, ) cfg := &UpdateConfig{ @@ -572,7 +572,7 @@ func TestEpoch(t *testing.T) { setup.tp.RemoteSigner, name, CurrentEpoch(name), - blob.SectorCount, + blob.SectorLen, ts, ) cfg := &UpdateConfig{ From 29881c5fcb6cd6605607b8a5f750202ab2a9f70e Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Tue, 19 Jan 2021 21:11:59 +0530 Subject: [PATCH 15/71] blob: use io.Seeker interface in Transaction --- blob/blob.go | 29 +++++++++-------------------- blob/store.go | 8 -------- blob/transaction.go | 22 +++++++++++++++++++--- protocol/updater.go | 13 +++++++++---- rpc/server.go | 15 ++++++++++----- 5 files changed, 47 insertions(+), 40 deletions(-) diff --git a/blob/blob.go b/blob/blob.go index 73884c2..8a6410f 100644 --- a/blob/blob.go +++ b/blob/blob.go @@ -1,11 +1,12 @@ package blob import ( - "github.com/pkg/errors" "io" "io/ioutil" "os" "sync" + + "github.com/pkg/errors" ) type SectorReader interface { @@ -22,15 +23,12 @@ type Blob interface { io.Closer Readable Transaction() (Transaction, error) - Seek(uint16) - At() uint16 } type blobImpl struct { - f *os.File - sectorSize uint16 - name string - mu sync.Mutex + f *os.File + name string + mu sync.Mutex } func newFromFile(name string, f *os.File) Blob { @@ -44,14 +42,6 @@ func (b *blobImpl) Name() string { return b.name } -func (b *blobImpl) Seek(sectorSize uint16) { - b.sectorSize = sectorSize -} - -func (b *blobImpl) At() uint16 { - return b.sectorSize -} - func (b *blobImpl) ReadSector(id uint8) (Sector, error) { b.mu.Lock() defer b.mu.Unlock() @@ -66,11 +56,10 @@ func (b *blobImpl) ReadAt(p []byte, off int64) (int, error) { func (b *blobImpl) Transaction() (Transaction, error) { return &txImpl{ - name: b.name, - sectorSize: b.sectorSize, - cloner: b.txCloner, - committer: b.txCommitter, - remover: b.txRemover, + name: b.name, + cloner: b.txCloner, + committer: b.txCommitter, + remover: b.txRemover, }, nil } diff --git a/blob/store.go b/blob/store.go index 7195c2c..cf609f9 100644 --- a/blob/store.go +++ b/blob/store.go @@ -92,14 +92,6 @@ func (w *wrappedBlob) Name() string { return w.blob.Name() } -func (w *wrappedBlob) Seek(sectorSize uint16) { - w.blob.Seek(sectorSize) -} - -func (w *wrappedBlob) At() uint16 { - return w.blob.At() -} - func (w *wrappedBlob) ReadAt(p []byte, off int64) (n int, err error) { return w.blob.ReadAt(p, off) } diff --git a/blob/transaction.go b/blob/transaction.go index 73d7f85..4e875b4 100644 --- a/blob/transaction.go +++ b/blob/transaction.go @@ -1,11 +1,12 @@ package blob import ( - "github.com/pkg/errors" "io" "io/ioutil" "os" "sync" + + "github.com/pkg/errors" ) var ( @@ -15,6 +16,7 @@ var ( type Transaction interface { Readable + io.Seeker io.WriterAt WriteSector(sector Sector) error Truncate() error @@ -40,8 +42,22 @@ func (t *txImpl) Name() string { return t.name } -func (t *txImpl) SectorSize() uint16 { - return t.sectorSize +func (t *txImpl) Seek(off int64, whence int) (int64, error) { + if off%SectorLen != 0 { + return 0, errors.New("seek not a multiple of sector len") + } + switch whence { + case io.SeekStart: + if off > Size { + return 0, errors.New("seek beyond blob bounds") + } + t.sectorSize = uint16(off) / SectorLen + case io.SeekCurrent: + case io.SeekEnd: + default: + panic("invalid whence") + } + return off, nil } func (t *txImpl) ReadSector(id uint8) (Sector, error) { diff --git a/protocol/updater.go b/protocol/updater.go index 38bdc9f..1e69c71 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -9,10 +9,12 @@ import ( "fnd/store" "fnd/util" "fnd/wire" - "github.com/pkg/errors" - "github.com/syndtr/goleveldb/leveldb" + "io" "sync" "time" + + "github.com/pkg/errors" + "github.com/syndtr/goleveldb/leveldb" ) var ( @@ -181,13 +183,16 @@ func UpdateBlob(cfg *UpdateConfig) error { } }() - bl.Seek(sectorSize) - tx, err := bl.Transaction() if err != nil { return errors.Wrap(err, "error starting transaction") } + _, err = tx.Seek(int64(sectorSize*blob.SectorLen), io.SeekStart) + if err != nil { + return errors.Wrap(err, "error seeking transaction") + } + err = SyncSectors(&SyncSectorsOpts{ Timeout: DefaultSyncerBlobResTimeout, Mux: cfg.Mux, diff --git a/rpc/server.go b/rpc/server.go index 9ab94e3..e7a51f9 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -11,13 +11,15 @@ import ( "fnd/store" "fnd/util" "fnd/wire" - "github.com/pkg/errors" - "github.com/syndtr/goleveldb/leveldb" - "google.golang.org/grpc" + "io" "net" "strconv" "sync/atomic" "time" + + "github.com/pkg/errors" + "github.com/syndtr/goleveldb/leveldb" + "google.golang.org/grpc" ) const ( @@ -233,13 +235,16 @@ func (s *Server) Checkout(ctx context.Context, req *apiv1.CheckoutReq) (*apiv1.C sectorTipHash = header.SectorTipHash } - bl.Seek(sectorSize) - tx, err := bl.Transaction() if err != nil { return nil, err } + _, err = tx.Seek(int64(sectorSize*blob.SectorLen), io.SeekStart) + if err != nil { + return nil, err + } + s.txStore.Set(strconv.FormatUint(uint64(txID), 32), &awaitingTx{ blob: bl, tx: tx, From 94f96ee1ab2869e40041290b51f49ce78646ca9d Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Tue, 19 Jan 2021 21:41:13 +0530 Subject: [PATCH 16/71] blob: seeker - additional checks --- blob/transaction.go | 3 +++ protocol/updater.go | 2 +- rpc/server.go | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/blob/transaction.go b/blob/transaction.go index 4e875b4..65a5c8e 100644 --- a/blob/transaction.go +++ b/blob/transaction.go @@ -46,6 +46,9 @@ func (t *txImpl) Seek(off int64, whence int) (int64, error) { if off%SectorLen != 0 { return 0, errors.New("seek not a multiple of sector len") } + if off < int64(t.sectorSize)*int64(SectorLen) { + return 0, errors.New("seek before already written sector") + } switch whence { case io.SeekStart: if off > Size { diff --git a/protocol/updater.go b/protocol/updater.go index 1e69c71..1d7d22b 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -188,7 +188,7 @@ func UpdateBlob(cfg *UpdateConfig) error { return errors.Wrap(err, "error starting transaction") } - _, err = tx.Seek(int64(sectorSize*blob.SectorLen), io.SeekStart) + _, err = tx.Seek(int64(sectorSize)*int64(blob.SectorLen), io.SeekStart) if err != nil { return errors.Wrap(err, "error seeking transaction") } diff --git a/rpc/server.go b/rpc/server.go index e7a51f9..49aef7b 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -240,7 +240,7 @@ func (s *Server) Checkout(ctx context.Context, req *apiv1.CheckoutReq) (*apiv1.C return nil, err } - _, err = tx.Seek(int64(sectorSize*blob.SectorLen), io.SeekStart) + _, err = tx.Seek(int64(sectorSize)*int64(blob.SectorLen), io.SeekStart) if err != nil { return nil, err } From eca1a1b888b2aa901064b278f158f6aac2686cee Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Tue, 19 Jan 2021 21:48:23 +0530 Subject: [PATCH 17/71] blob: cleanup --- blob/blob.go | 3 +-- blob/blob_mock_test.go | 7 ------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/blob/blob.go b/blob/blob.go index 8a6410f..e7433e3 100644 --- a/blob/blob.go +++ b/blob/blob.go @@ -1,12 +1,11 @@ package blob import ( + "github.com/pkg/errors" "io" "io/ioutil" "os" "sync" - - "github.com/pkg/errors" ) type SectorReader interface { diff --git a/blob/blob_mock_test.go b/blob/blob_mock_test.go index 11762fe..1b49adb 100644 --- a/blob/blob_mock_test.go +++ b/blob/blob_mock_test.go @@ -26,13 +26,6 @@ func (b BlobMock) Name() string { return args.String(0) } -func (b BlobMock) Seek(sectorSize uint16) { -} - -func (b BlobMock) At() uint16 { - return 0 -} - func (b BlobMock) Transaction() (Transaction, error) { args := b.Called() return args.Get(0).(Transaction), args.Error(1) From c44e96ab9f95c5f9c3f37b5ac770b3103efb68c5 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Tue, 19 Jan 2021 21:57:59 +0530 Subject: [PATCH 18/71] all: rename merkle root -> sector tip hash --- cmd/fnd-cli/cmd/blob/info.go | 2 +- rpc/blob.go | 4 +- rpc/server.go | 4 +- rpc/v1/api.pb.go | 122 +++++++++++++++++------------------ rpc/v1/api.proto | 2 +- store/headers.go | 14 ++-- 6 files changed, 74 insertions(+), 74 deletions(-) diff --git a/cmd/fnd-cli/cmd/blob/info.go b/cmd/fnd-cli/cmd/blob/info.go index ec1bd9c..215d7f2 100644 --- a/cmd/fnd-cli/cmd/blob/info.go +++ b/cmd/fnd-cli/cmd/blob/info.go @@ -55,7 +55,7 @@ var infoCmd = &cobra.Command{ hex.EncodeToString(res.PublicKey.SerializeCompressed()), strconv.Itoa(int(res.EpochHeight)), strconv.Itoa(int(res.SectorSize)), - res.MerkleRoot.String(), + res.SectorTipHash.String(), res.ReservedRoot.String(), res.ReceivedAt.String(), res.Signature.String(), diff --git a/rpc/blob.go b/rpc/blob.go index 6e579d0..5f86378 100644 --- a/rpc/blob.go +++ b/rpc/blob.go @@ -61,7 +61,7 @@ func parseBlobInfoRes(res *apiv1.BlobInfoRes) (*store.BlobInfo, error) { if err != nil { return nil, errors.Wrap(err, "error parsing public key") } - merkleRoot, err := crypto.NewHashFromBytes(res.MerkleRoot) + merkleRoot, err := crypto.NewHashFromBytes(res.SectorTipHash) if err != nil { return nil, errors.Wrap(err, "error parsing merkle root") } @@ -80,7 +80,7 @@ func parseBlobInfoRes(res *apiv1.BlobInfoRes) (*store.BlobInfo, error) { ImportHeight: int(res.ImportHeight), EpochHeight: uint16(res.EpochHeight), SectorSize: uint16(res.SectorSize), - MerkleRoot: merkleRoot, + SectorTipHash: merkleRoot, ReservedRoot: reservedRoot, ReceivedAt: time.Unix(int64(res.ReceivedAt), 0), Signature: sig, diff --git a/rpc/server.go b/rpc/server.go index 49aef7b..feaa1eb 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -405,7 +405,7 @@ func (s *Server) GetBlobInfo(_ context.Context, req *apiv1.BlobInfoReq) (*apiv1. ImportHeight: uint32(info.ImportHeight), EpochHeight: uint32(header.EpochHeight), SectorSize: uint32(header.SectorSize), - MerkleRoot: header.SectorTipHash[:], + SectorTipHash: header.SectorTipHash[:], ReservedRoot: header.ReservedRoot[:], ReceivedAt: uint64(header.EpochStartAt.Unix()), Signature: header.Signature[:], @@ -433,7 +433,7 @@ func (s *Server) ListBlobInfo(req *apiv1.ListBlobInfoReq, srv apiv1.Footnotev1_L ImportHeight: uint32(info.ImportHeight), EpochHeight: uint32(info.EpochHeight), SectorSize: uint32(info.SectorSize), - MerkleRoot: info.MerkleRoot[:], + SectorTipHash: info.SectorTipHash[:], ReservedRoot: info.ReservedRoot[:], ReceivedAt: uint64(info.ReceivedAt.Unix()), Signature: info.Signature[:], diff --git a/rpc/v1/api.pb.go b/rpc/v1/api.pb.go index 1b49210..5d73afb 100644 --- a/rpc/v1/api.pb.go +++ b/rpc/v1/api.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.23.0 -// protoc v3.6.1 +// protoc-gen-go v1.25.0-devel +// protoc v3.12.4 // source: api.proto package v1 @@ -1124,15 +1124,15 @@ type BlobInfoRes struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - PublicKey []byte `protobuf:"bytes,2,opt,name=publicKey,proto3" json:"publicKey,omitempty"` - ImportHeight uint32 `protobuf:"varint,3,opt,name=importHeight,proto3" json:"importHeight,omitempty"` - EpochHeight uint32 `protobuf:"varint,4,opt,name=epochHeight,proto3" json:"epochHeight,omitempty"` // protobuf doesn't have uint16 - SectorSize uint32 `protobuf:"varint,5,opt,name=sectorSize,proto3" json:"sectorSize,omitempty"` // ditto ^ - MerkleRoot []byte `protobuf:"bytes,6,opt,name=merkleRoot,proto3" json:"merkleRoot,omitempty"` - ReservedRoot []byte `protobuf:"bytes,7,opt,name=reservedRoot,proto3" json:"reservedRoot,omitempty"` - ReceivedAt uint64 `protobuf:"varint,8,opt,name=receivedAt,proto3" json:"receivedAt,omitempty"` - Signature []byte `protobuf:"bytes,9,opt,name=signature,proto3" json:"signature,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + PublicKey []byte `protobuf:"bytes,2,opt,name=publicKey,proto3" json:"publicKey,omitempty"` + ImportHeight uint32 `protobuf:"varint,3,opt,name=importHeight,proto3" json:"importHeight,omitempty"` + EpochHeight uint32 `protobuf:"varint,4,opt,name=epochHeight,proto3" json:"epochHeight,omitempty"` // protobuf doesn't have uint16 + SectorSize uint32 `protobuf:"varint,5,opt,name=sectorSize,proto3" json:"sectorSize,omitempty"` // ditto ^ + SectorTipHash []byte `protobuf:"bytes,6,opt,name=sectorTipHash,proto3" json:"sectorTipHash,omitempty"` + ReservedRoot []byte `protobuf:"bytes,7,opt,name=reservedRoot,proto3" json:"reservedRoot,omitempty"` + ReceivedAt uint64 `protobuf:"varint,8,opt,name=receivedAt,proto3" json:"receivedAt,omitempty"` + Signature []byte `protobuf:"bytes,9,opt,name=signature,proto3" json:"signature,omitempty"` } func (x *BlobInfoRes) Reset() { @@ -1202,9 +1202,9 @@ func (x *BlobInfoRes) GetSectorSize() uint32 { return 0 } -func (x *BlobInfoRes) GetMerkleRoot() []byte { +func (x *BlobInfoRes) GetSectorTipHash() []byte { if x != nil { - return x.MerkleRoot + return x.SectorTipHash } return nil } @@ -1416,7 +1416,7 @@ var file_api_proto_rawDesc = []byte{ 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x27, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x22, 0xa7, 0x02, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x72, 0x74, 0x22, 0xad, 0x02, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, @@ -1426,53 +1426,53 @@ var file_api_proto_rawDesc = []byte{ 0x68, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, - 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, - 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, - 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1e, - 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, - 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x23, 0x0a, 0x0d, - 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x22, 0x37, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x69, - 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0xe9, 0x03, 0x0a, 0x0a, 0x46, - 0x6f, 0x6f, 0x74, 0x6e, 0x6f, 0x74, 0x65, 0x76, 0x31, 0x12, 0x22, 0x0a, 0x09, 0x47, 0x65, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, - 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, - 0x07, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x1e, 0x0a, - 0x07, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x42, 0x61, 0x6e, 0x50, 0x65, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x22, 0x0a, - 0x09, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x55, 0x6e, 0x62, - 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x12, 0x2b, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x0d, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x26, - 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x0c, 0x2e, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x0b, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x0f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x12, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x52, 0x65, 0x61, - 0x64, 0x41, 0x74, 0x12, 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x71, 0x1a, - 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x0b, 0x47, - 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, - 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, - 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, - 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x2c, 0x0a, 0x0a, 0x53, 0x65, 0x6e, 0x64, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x42, 0x04, 0x5a, 0x02, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, 0x70, 0x48, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0d, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, 0x70, 0x48, 0x61, 0x73, 0x68, + 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x6f, 0x74, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, + 0x41, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, + 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x22, 0x23, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x37, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x69, + 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0e, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x32, 0xe9, 0x03, 0x0a, 0x0a, 0x46, 0x6f, 0x6f, 0x74, 0x6e, 0x6f, 0x74, 0x65, 0x76, 0x31, 0x12, + 0x22, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, + 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x07, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, + 0x2e, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x22, 0x0a, 0x09, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, + 0x12, 0x0d, 0x2e, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, + 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2b, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, + 0x65, 0x65, 0x72, 0x73, 0x12, 0x0d, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x73, 0x30, 0x01, 0x12, 0x26, 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, + 0x12, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, + 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x0b, + 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x0f, 0x2e, 0x57, 0x72, + 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x57, + 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, + 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x12, + 0x20, 0x0a, 0x06, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x12, 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, + 0x41, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, + 0x73, 0x12, 0x29, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, + 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x0c, + 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, + 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x2c, + 0x0a, 0x0a, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x2e, 0x53, + 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x53, + 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x42, 0x04, 0x5a, 0x02, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/rpc/v1/api.proto b/rpc/v1/api.proto index f84062d..522f4bf 100644 --- a/rpc/v1/api.proto +++ b/rpc/v1/api.proto @@ -128,7 +128,7 @@ message BlobInfoRes { uint32 importHeight = 3; uint32 epochHeight = 4; // protobuf doesn't have uint16 uint32 sectorSize = 5; // ditto ^ - bytes merkleRoot = 6; + bytes sectorTipHash = 6; bytes reservedRoot = 7; uint64 receivedAt = 8; bytes signature = 9; diff --git a/store/headers.go b/store/headers.go index e9978d3..dab814a 100644 --- a/store/headers.go +++ b/store/headers.go @@ -32,7 +32,7 @@ func (h *Header) MarshalJSON() ([]byte, error) { Name string `json:"name"` EpochHeight uint16 `json:"epoch_height"` SectorSize uint16 `json:"sector_size"` - MerkleRoot string `json:"merkle_root"` + SectorTipHash string `json:"sector_tip_hash"` Signature string `json:"signature"` ReservedRoot string `json:"reserved_root"` EpochStartAt time.Time `json:"epoch_start_at"` @@ -58,7 +58,7 @@ func (h *Header) UnmarshalJSON(b []byte) error { Name string `json:"name"` EpochHeight uint16 `json:"epoch_height"` SectorSize uint16 `json:"sector_size"` - MerkleRoot string `json:"merkle_root"` + SectorTipHash string `json:"sector_tip_hash"` Signature string `json:"signature"` ReservedRoot string `json:"reserved_root"` EpochStartAt time.Time `json:"epoch_start_at"` @@ -68,7 +68,7 @@ func (h *Header) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(b, in); err != nil { return err } - mrB, err := hex.DecodeString(in.MerkleRoot) + mrB, err := hex.DecodeString(in.SectorTipHash) if err != nil { return err } @@ -200,7 +200,7 @@ type BlobInfo struct { ImportHeight int `json:"import_height"` EpochHeight uint16 `json:"epoch_height"` SectorSize uint16 `json:"sector_size"` - MerkleRoot crypto.Hash `json:"merkle_root"` + SectorTipHash crypto.Hash `json:"sector_tip_hash"` Signature crypto.Signature `json:"signature"` ReservedRoot crypto.Hash `json:"reserved_root"` ReceivedAt time.Time `json:"received_at"` @@ -213,7 +213,7 @@ func (b *BlobInfo) MarshalJSON() ([]byte, error) { ImportHeight int `json:"import_height"` EpochHeight uint16 `json:"epoch_height"` SectorSize uint16 `json:"sector_size"` - MerkleRoot string `json:"merkle_root"` + SectorTipHash string `json:"sector_tip_hash"` Signature string `json:"signature"` ReservedRoot string `json:"reserved_root"` ReceivedAt time.Time `json:"received_at"` @@ -223,7 +223,7 @@ func (b *BlobInfo) MarshalJSON() ([]byte, error) { b.ImportHeight, b.EpochHeight, b.SectorSize, - hex.EncodeToString(b.MerkleRoot[:]), + hex.EncodeToString(b.SectorTipHash[:]), hex.EncodeToString(b.Signature[:]), hex.EncodeToString(b.ReservedRoot[:]), b.ReceivedAt, @@ -254,7 +254,7 @@ func (bis *BlobInfoStream) Next() (*BlobInfo, error) { ImportHeight: nameInfo.ImportHeight, EpochHeight: header.EpochHeight, SectorSize: header.SectorSize, - MerkleRoot: header.SectorTipHash, + SectorTipHash: header.SectorTipHash, Signature: header.Signature, ReservedRoot: header.ReservedRoot, ReceivedAt: header.EpochStartAt, From 7c8209fef85800bb07b7c603cbfd2e500d69fd55 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Fri, 22 Jan 2021 16:27:18 +0530 Subject: [PATCH 19/71] epoch: fix test --- protocol/epoch_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/epoch_test.go b/protocol/epoch_test.go index b5600dd..fff78cd 100644 --- a/protocol/epoch_test.go +++ b/protocol/epoch_test.go @@ -8,5 +8,5 @@ import ( func TestCurrentEpoch(t *testing.T) { epoch := CurrentEpoch("bazinga") - assert.Equal(t, uint16(54), epoch) + assert.Equal(t, uint16(55), epoch) } From 9459c18b7c8a912d834df611c130d8f929fb024e Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Tue, 26 Jan 2021 19:00:30 +0530 Subject: [PATCH 20/71] blob: fix uint16 overflow in tx.Seek --- blob/transaction.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blob/transaction.go b/blob/transaction.go index 65a5c8e..ab7ccd1 100644 --- a/blob/transaction.go +++ b/blob/transaction.go @@ -54,7 +54,7 @@ func (t *txImpl) Seek(off int64, whence int) (int64, error) { if off > Size { return 0, errors.New("seek beyond blob bounds") } - t.sectorSize = uint16(off) / SectorLen + t.sectorSize = uint16(off / SectorLen) case io.SeekCurrent: case io.SeekEnd: default: From 52b16e31d81a455fc723416d9a43f9ef6dbbb944 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 28 Jan 2021 19:46:19 +0530 Subject: [PATCH 21/71] protocol: fix issue with dequeue --- protocol/update_queue.go | 1 + 1 file changed, 1 insertion(+) diff --git a/protocol/update_queue.go b/protocol/update_queue.go index 5478ed9..bd69347 100644 --- a/protocol/update_queue.go +++ b/protocol/update_queue.go @@ -167,6 +167,7 @@ func (u *UpdateQueue) Dequeue() *UpdateQueueItem { ret := u.entries[name] u.queue = u.queue[1:] atomic.AddInt32(&u.queueLen, -1) + delete(u.entries, name) return ret } From 54a57a83f796980007dcf2aab617f3a822c751c9 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 11 Feb 2021 15:12:42 +0530 Subject: [PATCH 22/71] epoch: update test --- protocol/epoch_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/epoch_test.go b/protocol/epoch_test.go index fff78cd..ff5ef82 100644 --- a/protocol/epoch_test.go +++ b/protocol/epoch_test.go @@ -8,5 +8,5 @@ import ( func TestCurrentEpoch(t *testing.T) { epoch := CurrentEpoch("bazinga") - assert.Equal(t, uint16(55), epoch) + assert.Equal(t, uint16(56), epoch) } From fbdb21e3fe4ce99fc886032fbd7c8bc32c5b0128 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 11 Feb 2021 15:15:11 +0530 Subject: [PATCH 23/71] vendor: use float64 for ChainInfo.progress instead of int --- vendor/fnd.localhost/handshake/client/rest_types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/fnd.localhost/handshake/client/rest_types.go b/vendor/fnd.localhost/handshake/client/rest_types.go index 95dc63e..1ac2e53 100644 --- a/vendor/fnd.localhost/handshake/client/rest_types.go +++ b/vendor/fnd.localhost/handshake/client/rest_types.go @@ -21,7 +21,7 @@ type ChainInfo struct { Height int `json:"height"` Tip string `json:"tip"` TreeRoot string `json:"treeRoot"` - Progress int `json:"progress"` + Progress float64 `json:"progress"` State StateInfo `json:"state"` } From a61f3748330551ef1b540b504a82df1d3daaa075 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 11 Feb 2021 15:34:09 +0530 Subject: [PATCH 24/71] epoch: update test to use mock time --- protocol/epoch.go | 4 +++- protocol/epoch_test.go | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/protocol/epoch.go b/protocol/epoch.go index c1e2956..bc6c1be 100644 --- a/protocol/epoch.go +++ b/protocol/epoch.go @@ -9,6 +9,8 @@ import ( // 2020 Jan 1 00:00 UTC var epochDate = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC) +var now = time.Now + const ( secondsPerHour = 60 * 60 hoursPerWeek = 7 * 24 @@ -30,5 +32,5 @@ func CurrentEpoch(name string) uint16 { mod := modBuffer(hash, hoursPerWeek) offset := mod * secondsPerHour startDate := epochDate.Add(time.Duration(offset) * time.Second) - return uint16(int(time.Now().Sub(startDate).Seconds()) / int(weekDuration.Seconds())) + return uint16(int(now().Sub(startDate).Seconds()) / int(weekDuration.Seconds())) } diff --git a/protocol/epoch_test.go b/protocol/epoch_test.go index ff5ef82..0172d51 100644 --- a/protocol/epoch_test.go +++ b/protocol/epoch_test.go @@ -2,11 +2,13 @@ package protocol import ( "testing" + "time" "github.com/stretchr/testify/assert" ) func TestCurrentEpoch(t *testing.T) { + now = func() time.Time { return time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC) } epoch := CurrentEpoch("bazinga") - assert.Equal(t, uint16(56), epoch) + assert.Equal(t, uint16(52), epoch) } From 367ee6faa470435410d8964bea3893d69176f49d Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 11 Feb 2021 16:24:34 +0530 Subject: [PATCH 25/71] updater: update epoch checks --- protocol/updater.go | 35 ++++++++++++++++++++++++++++------- protocol/updater_test.go | 23 ++++++++++++++++------- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/protocol/updater.go b/protocol/updater.go index 1d7d22b..9df955b 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -126,7 +126,10 @@ func UpdateBlob(cfg *UpdateConfig) error { if err != nil && !errors.Is(err, leveldb.ErrNotFound) { return errors.Wrap(err, "error getting header") } - if header != nil && header.EpochHeight == item.EpochHeight && header.SectorSize == item.SectorSize { + + // If the new update and is the same size or fewer reject if it is in the + // same epoch. In the future, this may be an equivocation condition + if header != nil && header.EpochHeight == item.EpochHeight && header.SectorSize >= item.SectorSize { return ErrUpdaterAlreadySynchronized } @@ -139,27 +142,45 @@ func UpdateBlob(cfg *UpdateConfig) error { prevHash = header.SectorTipHash } + // header is the existing header/data in the db + // item is the new incoming update + + // The new header should have a higher or equal epoch if item.EpochHeight < epochHeight { return ErrInvalidEpochBackdated } - if item.EpochHeight > epochHeight { - if header != nil && header.Banned { + // If it is higher (skip if it's appending data to the same epoch) + if header != nil && item.EpochHeight > epochHeight { + // Recovery from banning must increment the epoch by at least 2 and one + // real week since the local node banned + if header.Banned { + // Banned for at least a week if header.BannedAt.Add(7 * 24 * time.Duration(time.Hour)).After(time.Now()) { return ErrNameBanned } - if item.EpochHeight >= CurrentEpoch(item.Name) { + // Publisher is banned for the equivocating epoch and the next epoch + // The faulty epoch may be old or backdated, so the penalty may not be + // as large as it seems + if item.EpochHeight <= epochHeight+1 { return ErrInvalidEpochCurrent } } - if header != nil && time.Now().Before(header.EpochStartAt.Add(7*24*time.Duration(time.Hour))) { - if item.EpochHeight != CurrentEpoch(item.Name) { + // If the epoch is updated less than a week ago BUT NOT the current + // epoch or the next one. The node can bank up one extra epoch just in + // case (or periodically burst and do two epochs in a week). This + // conditions is only valid if the last local epoch increment is less + // than a week old. + if time.Now().Before(header.EpochStartAt.Add(7 * 24 * time.Duration(time.Hour))) { + if item.EpochHeight < CurrentEpoch(item.Name)+1 { return ErrInvalidEpochThrottled } } - if item.EpochHeight > CurrentEpoch(item.Name) { + + // Reject any epochs more than one in the future + if item.EpochHeight > CurrentEpoch(item.Name)+1 { return ErrInvalidEpochFuturedated } diff --git a/protocol/updater_test.go b/protocol/updater_test.go index 038739c..4cf3844 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -10,10 +10,11 @@ import ( "fnd/testutil/mockapp" "fnd/util" "fnd/wire" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" "testing" "time" + + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" ) type updaterTestSetup struct { @@ -488,15 +489,16 @@ func TestEpoch(t *testing.T) { "aborts sync if the epoch is throttled", func(t *testing.T, setup *updaterTestSetup) { cfg := &UpdateConfig{ - Mux: setup.tp.LocalMux, - DB: setup.ls.DB, - BlobStore: setup.ls.BlobStore, + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + NameLocker: util.NewMultiLocker(), + BlobStore: setup.ls.BlobStore, Item: &UpdateQueueItem{ PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), Name: name, - EpochHeight: CurrentEpoch(name) + 1, + EpochHeight: CurrentEpoch(name) - 1, }, } require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { @@ -553,9 +555,16 @@ func TestEpoch(t *testing.T) { crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), Name: name, - EpochHeight: CurrentEpoch(name) + 1, + EpochHeight: CurrentEpoch(name) + 2, }, } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: CurrentEpoch(name), + SectorSize: 10, + }, blob.ZeroSectorHashes) + })) err := UpdateBlob(cfg) require.NotNil(t, err) require.True(t, errors.Is(err, ErrInvalidEpochFuturedated)) From fdf1462b4f62310d9e0d0fb86945c485ce0a1c0a Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 15 Feb 2021 16:17:17 +0530 Subject: [PATCH 26/71] deps: rm mstream --- go.mod | 3 - go.sum | 10 +- vendor/fnd.localhost/mstream/.gitignore | 18 -- vendor/fnd.localhost/mstream/Makefile | 8 - vendor/fnd.localhost/mstream/decode.go | 219 ------------------ vendor/fnd.localhost/mstream/decode_test.go | 166 ------------- vendor/fnd.localhost/mstream/encode.go | 128 ---------- vendor/fnd.localhost/mstream/encode_test.go | 105 --------- vendor/fnd.localhost/mstream/encoder.go | 31 --- .../mstream/encoding_bench_test.go | 107 --------- vendor/fnd.localhost/mstream/go.mod | 8 - vendor/fnd.localhost/mstream/go.sum | 13 -- vendor/fnd.localhost/mstream/well_known.go | 52 ----- .../fnd.localhost/mstream/well_known_test.go | 33 --- 14 files changed, 2 insertions(+), 899 deletions(-) delete mode 100644 vendor/fnd.localhost/mstream/.gitignore delete mode 100644 vendor/fnd.localhost/mstream/Makefile delete mode 100644 vendor/fnd.localhost/mstream/decode.go delete mode 100644 vendor/fnd.localhost/mstream/decode_test.go delete mode 100644 vendor/fnd.localhost/mstream/encode.go delete mode 100644 vendor/fnd.localhost/mstream/encode_test.go delete mode 100644 vendor/fnd.localhost/mstream/encoder.go delete mode 100644 vendor/fnd.localhost/mstream/encoding_bench_test.go delete mode 100644 vendor/fnd.localhost/mstream/go.mod delete mode 100644 vendor/fnd.localhost/mstream/go.sum delete mode 100644 vendor/fnd.localhost/mstream/well_known.go delete mode 100644 vendor/fnd.localhost/mstream/well_known_test.go diff --git a/go.mod b/go.mod index 73b1a69..0b92a92 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,6 @@ go 1.12 replace fnd.localhost/dwire => ./vendor/fnd.localhost/dwire -replace fnd.localhost/mstream => ./vendor/fnd.localhost/mstream - replace fnd.localhost/handshake => ./vendor/fnd.localhost/handshake require ( @@ -30,7 +28,6 @@ require ( github.com/stretchr/testify v1.5.1 github.com/syndtr/goleveldb v1.0.0 golang.org/x/crypto v0.0.0-20200422194213-44a606286825 - golang.org/x/net v0.0.0-20190923162816-aa69164e4478 golang.org/x/sync v0.0.0-20190423024810-112230192c58 golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 // indirect golang.org/x/text v0.3.2 // indirect diff --git a/go.sum b/go.sum index 77e6f54..840e420 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,4 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -fnd.localhost/dwire v1.0.1 h1:OD5D5aRahOuy0QGCHxXrZf5ZJlX0IBcT/3P0k97elpQ= -fnd.localhost/dwire v1.0.1/go.mod h1:BkHitp5E9PSDVLq5nPLXWzQFEwFSR5aNhTL7M9xeC7I= -fnd.localhost/handshake v0.0.0-20200428084808-2c986090302e h1:MgJUOlZMg4aEHfxoH7DrrOZxuP7XkHQUTZ6WHfMhaXM= -fnd.localhost/handshake v0.0.0-20200428084808-2c986090302e/go.mod h1:YVUlfqY28yFbCM7y59cmL92/VfM0EDBXKrhjgmo2OAg= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -54,6 +50,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= @@ -175,18 +172,15 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610 h1:Ygq9/SRJX9+dU0WCIICM8RkWvDw03lvB77hrhJnpxfU= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw= -google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= diff --git a/vendor/fnd.localhost/mstream/.gitignore b/vendor/fnd.localhost/mstream/.gitignore deleted file mode 100644 index ea34f98..0000000 --- a/vendor/fnd.localhost/mstream/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# Created by .ignore support plugin (hsz.mobi) -### Go template -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - diff --git a/vendor/fnd.localhost/mstream/Makefile b/vendor/fnd.localhost/mstream/Makefile deleted file mode 100644 index 98eb341..0000000 --- a/vendor/fnd.localhost/mstream/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -test: - go test ./... --race - -fmt: - goimports -w . - gofmt -s -w . - -.PHONY: test fmt diff --git a/vendor/fnd.localhost/mstream/decode.go b/vendor/fnd.localhost/mstream/decode.go deleted file mode 100644 index 9349e43..0000000 --- a/vendor/fnd.localhost/mstream/decode.go +++ /dev/null @@ -1,219 +0,0 @@ -package mstream - -import ( - "encoding/binary" - "fmt" - "io" - "reflect" - - "github.com/pkg/errors" -) - -type byteReader struct { - r io.Reader - buf []byte -} - -func newByteReader(r io.Reader) *byteReader { - return &byteReader{ - r: r, - buf: make([]byte, 1, 1), - } -} - -func (r *byteReader) Read(p []byte) (int, error) { - return r.r.Read(p) -} - -func (r *byteReader) ReadByte() (byte, error) { - _, err := io.ReadFull(r.r, r.buf) - if err != nil { - return 0, err - } - return r.buf[0], nil -} - -func DecodeFields(r io.Reader, items ...interface{}) error { - return defaultEncoder.DecodeFields(r, items...) -} - -func DecodeField(r io.Reader, item interface{}) error { - return defaultEncoder.DecodeField(r, item) -} - -func (c *ConfiguredEncoder) DecodeFields(r io.Reader, items ...interface{}) error { - for _, item := range items { - if err := c.DecodeField(r, item); err != nil { - return err - } - } - - return nil -} - -func (c *ConfiguredEncoder) DecodeField(r io.Reader, item interface{}) error { - var err error - switch it := item.(type) { - case Decoder: - err = it.Decode(r) - case *bool: - b := make([]byte, 1, 1) - if _, err := io.ReadFull(r, b); err != nil { - return err - } - if b[0] == 0x00 { - *it = false - } else if b[0] == 0x01 { - *it = true - } else { - return errors.Errorf("invalid boolean value: %x", b[0]) - } - case *uint8: - b := make([]byte, 1, 1) - if _, err := io.ReadFull(r, b); err != nil { - return err - } - *it = b[0] - case *uint16: - b := make([]byte, 2, 2) - if _, err := io.ReadFull(r, b); err != nil { - return err - } - *it = binary.BigEndian.Uint16(b) - case *uint32: - b := make([]byte, 4, 4) - if _, err := io.ReadFull(r, b); err != nil { - return err - } - *it = binary.BigEndian.Uint32(b) - case *uint64: - b := make([]byte, 8, 8) - if _, err := io.ReadFull(r, b); err != nil { - return err - } - *it = binary.BigEndian.Uint64(b) - case *[]byte: - br := newByteReader(r) - l, err := binary.ReadUvarint(br) - if err != nil { - return err - } - if l > c.MaxByteFieldLen { - return errors.New("byte-assignable field length too large to decode") - } - buf := make([]byte, l, l) - if _, err := io.ReadFull(r, buf); err != nil { - return err - } - *it = buf - case *string: - var buf []byte - if err := c.DecodeField(r, &buf); err != nil { - return err - } - *it = string(buf) - case *[32]byte: - var buf [32]byte - if _, err := io.ReadFull(r, buf[:]); err != nil { - return err - } - *it = buf - default: - err = c.decodeReflect(r, item) - } - - return err -} - -func (c *ConfiguredEncoder) decodeReflect(r io.Reader, item interface{}) error { - itemT := reflect.TypeOf(item) - if itemT.Kind() != reflect.Ptr { - return errors.New("can only decode into pointer types") - } - - canonicalized := canonicalizeWellKnown(itemT.Elem()) - if wellKnownDecoders[canonicalized] != nil { - return wellKnownDecoders[canonicalized](r, item) - } - - elemKind := itemT.Elem().Kind() - if itemT.Elem().Kind() == reflect.Array { - return c.decodeArray(r, item) - } - - if elemKind == reflect.Slice { - return c.decodeSlice(r, item) - } - - return errors.New(fmt.Sprintf("type %s cannot be decoded", itemT.String())) -} - -func (c *ConfiguredEncoder) decodeArray(r io.Reader, item interface{}) error { - itemVal := reflect.ValueOf(item) - indirectVal := reflect.Indirect(itemVal) - indirectT := indirectVal.Type() - - l := indirectT.Len() - tmp := reflect.Zero(reflect.ArrayOf(l, indirectT.Elem())) - tmpPtr := reflect.New(indirectT) - tmpPtr.Elem().Set(tmp) - if indirectT.Elem().Kind() == reflect.Uint8 { - buf := make([]byte, l, l) - if _, err := io.ReadFull(r, buf); err != nil { - return err - } - reflect.Copy(tmpPtr.Elem().Slice(0, l), reflect.ValueOf(buf)) - } else { - for i := 0; i < indirectVal.Len(); i++ { - if err := c.DecodeField(r, tmpPtr.Elem().Index(i).Addr().Interface()); err != nil { - return err - } - } - } - itemVal.Elem().Set(tmpPtr.Elem()) - return nil -} - -func (c *ConfiguredEncoder) decodeSlice(r io.Reader, item interface{}) error { - itemVal := reflect.ValueOf(item) - indirectVal := reflect.Indirect(itemVal) - indirectT := indirectVal.Type() - - tmp := reflect.Zero(reflect.SliceOf(indirectT.Elem())) - tmpPtr := reflect.New(indirectT) - tmpPtr.Elem().Set(tmp) - - br := newByteReader(r) - l, err := binary.ReadUvarint(br) - if err != nil { - return err - } - if l > uint64(c.MaxVariableArrayLen) { - return errors.New("variable array field length too large to decode") - } - - if indirectT.Elem().Kind() == reflect.Ptr { - for i := 0; i < int(l); i++ { - sliceItem := reflect.Zero(indirectT.Elem().Elem()) - sliceItemPtr := reflect.New(sliceItem.Type()) - sliceItemPtr.Elem().Set(sliceItem) - if err := c.DecodeField(r, sliceItemPtr.Interface()); err != nil { - return err - } - tmpPtr.Elem().Set(reflect.Append(tmpPtr.Elem(), sliceItemPtr)) - } - } else { - for i := 0; i < int(l); i++ { - sliceItem := reflect.Zero(indirectT.Elem()) - sliceItemPtr := reflect.New(indirectT.Elem()) - sliceItemPtr.Elem().Set(sliceItem) - if err := c.DecodeField(r, sliceItemPtr.Interface()); err != nil { - return err - } - tmpPtr.Elem().Set(reflect.Append(tmpPtr.Elem(), sliceItemPtr.Elem())) - } - } - - itemVal.Elem().Set(tmpPtr.Elem()) - return nil -} diff --git a/vendor/fnd.localhost/mstream/decode_test.go b/vendor/fnd.localhost/mstream/decode_test.go deleted file mode 100644 index 74e3d81..0000000 --- a/vendor/fnd.localhost/mstream/decode_test.go +++ /dev/null @@ -1,166 +0,0 @@ -package mstream - -import ( - "bytes" - "encoding/hex" - "errors" - "io" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -type cafeEncodeDecoder struct { - data []byte -} - -func (c *cafeEncodeDecoder) Decode(r io.Reader) error { - buf := make([]byte, 2, 2) - if _, err := io.ReadFull(r, buf); err != nil { - return err - } - if !bytes.Equal(buf, []byte{0xca, 0xfe}) { - return errors.New("invalid cafe decode") - } - c.data = buf - return nil -} - -func (c *cafeEncodeDecoder) Encode(w io.Writer) error { - _, err := w.Write([]byte{0xca, 0xfe}) - return err -} - -func TestDecodeFields(t *testing.T) { - var cafe cafeEncodeDecoder - - type testStruct struct { - f0 cafeEncodeDecoder - f1 uint8 - f2 uint16 - f3 uint32 - f4 uint64 - f5 []byte - f6 string - f7 [32]byte - f8 [2]uint8 - f9 []uint8 - f10 []string - f11 time.Time - f12 [2]string - f13 []*cafeEncodeDecoder - } - exp := &testStruct{ - f0: cafe, - f1: 1, - f2: 2, - f3: 3, - f4: 4, - f5: []byte{0xff, 0x00}, - f6: "testing", - f7: [32]byte{}, - f8: [2]uint8{ - 1, - 2, - }, - f9: []uint8{ - 3, - 4, - }, - f10: []string{ - "testing", - "testing", - }, - f11: time.Unix(1, 0), - f12: [2]string{ - "testing", - "testing", - }, - f13: []*cafeEncodeDecoder{ - &cafe, - &cafe, - }, - } - exp.f7[0] = 0x11 - - var actual testStruct - inputBytes, err := hex.DecodeString( - "cafe" + - "01" + - "0002" + - "00000003" + - "0000000000000004" + - "02ff00" + - "0774657374696e67" + - "1100000000000000000000000000000000000000000000000000000000000000" + - "0102" + - "020304" + - "020774657374696e670774657374696e67" + - "0000000000000001" + - "0774657374696e670774657374696e67" + - "02cafecafe", - ) - require.NoError(t, err) - require.NoError(t, DecodeFields( - bytes.NewReader(inputBytes), - &actual.f0, - &actual.f1, - &actual.f2, - &actual.f3, - &actual.f4, - &actual.f5, - &actual.f6, - &actual.f7, - &actual.f8, - &actual.f9, - &actual.f10, - &actual.f11, - &actual.f12, - &actual.f13, - )) - require.EqualValues(t, exp.f0.data, exp.f0.data) - require.EqualValues(t, exp.f1, actual.f1) - require.EqualValues(t, exp.f2, actual.f2) - require.EqualValues(t, exp.f3, actual.f3) - require.EqualValues(t, exp.f4, actual.f4) - require.EqualValues(t, exp.f5, actual.f5) - require.EqualValues(t, exp.f6, actual.f6) - require.EqualValues(t, exp.f7, actual.f7) - require.EqualValues(t, exp.f8, actual.f8) - require.EqualValues(t, exp.f9, actual.f9) - require.EqualValues(t, exp.f10, actual.f10) - require.EqualValues(t, exp.f11, actual.f11) - require.EqualValues(t, exp.f12, actual.f12) - require.Equal(t, len(exp.f13), len(actual.f13)) -} - -func TestDecode_Errors(t *testing.T) { - var boolVal bool - err := DecodeField(bytes.NewReader([]byte{0x02}), &boolVal) - require.Error(t, err) - require.Contains(t, err.Error(), "invalid boolean value") - - err = DecodeField(bytes.NewReader([]byte{}), uint64(0)) - require.Error(t, err) - require.Contains(t, err.Error(), "can only decode into pointer types") - - var buf bytes.Buffer - require.NoError(t, writeUvarint(&buf, DefaultMaxByteFieldLen+DefaultMaxVariableArrayLen+1)) - var byteArrVal []byte - err = DecodeField(bytes.NewReader(buf.Bytes()), &byteArrVal) - require.Error(t, err) - require.Contains(t, err.Error(), "byte-assignable field length too large to decode") - - var strVal string - // zero out err since the err message is the same - err = nil - err = DecodeField(bytes.NewReader(buf.Bytes()), &strVal) - require.Error(t, err) - require.Contains(t, err.Error(), "byte-assignable field length too large to decode") - - var strArrVal []string - err = DecodeField(bytes.NewReader(buf.Bytes()), &strArrVal) - require.Error(t, err) - require.Contains(t, err.Error(), "variable array field length too large to decode") -} diff --git a/vendor/fnd.localhost/mstream/encode.go b/vendor/fnd.localhost/mstream/encode.go deleted file mode 100644 index 89c443e..0000000 --- a/vendor/fnd.localhost/mstream/encode.go +++ /dev/null @@ -1,128 +0,0 @@ -package mstream - -import ( - "encoding/binary" - "errors" - "fmt" - "io" - "reflect" -) - -var ( - trueWire = []byte{0x01} - falseWire = []byte{0x00} -) - -func EncodeFields(w io.Writer, items ...interface{}) error { - return defaultEncoder.EncodeFields(w, items...) -} - -func EncodeField(w io.Writer, item interface{}) error { - return defaultEncoder.EncodeField(w, item) -} - -func (c *ConfiguredEncoder) EncodeFields(w io.Writer, items ...interface{}) error { - for _, item := range items { - if err := c.EncodeField(w, item); err != nil { - return err - } - } - - return nil -} - -func (c *ConfiguredEncoder) EncodeField(w io.Writer, item interface{}) error { - var err error - switch it := item.(type) { - case Encoder: - err = it.Encode(w) - case bool: - val := falseWire - if it { - val = trueWire - } - _, err = w.Write(val) - case uint8: - _, err = w.Write([]byte{it}) - case uint16: - b := make([]byte, 2, 2) - binary.BigEndian.PutUint16(b, it) - _, err = w.Write(b) - case uint32: - b := make([]byte, 4, 4) - binary.BigEndian.PutUint32(b, it) - _, err = w.Write(b) - case uint64: - b := make([]byte, 8, 8) - binary.BigEndian.PutUint64(b, it) - _, err = w.Write(b) - case []byte: - if uint64(len(it)) > c.MaxByteFieldLen { - return errors.New("byte-assignable field length too large to encode") - } - if err := writeUvarint(w, len(it)); err != nil { - return err - } - _, err = w.Write(it) - case string: - err = c.EncodeField(w, []byte(item.(string))) - case [32]byte: - _, err = w.Write(it[:]) - default: - err = c.encodeReflect(w, item) - } - - return err -} - -func (c *ConfiguredEncoder) encodeReflect(w io.Writer, item interface{}) error { - t := reflect.TypeOf(item) - - canonicalized := canonicalizeWellKnown(t) - if wellKnownEncoders[canonicalized] != nil { - return wellKnownEncoders[canonicalized](w, item) - } - - if t.Kind() == reflect.Array { - itemVal := reflect.ValueOf(item) - if t.Elem().Kind() == reflect.Uint8 { - itemPtr := reflect.New(t) - itemPtr.Elem().Set(itemVal) - _, err := w.Write(itemPtr.Elem().Slice(0, itemVal.Len()).Bytes()) - return err - } - - for i := 0; i < itemVal.Len(); i++ { - if err := c.EncodeField(w, itemVal.Index(i).Interface()); err != nil { - return err - } - } - return nil - } - - if t.Kind() == reflect.Slice { - val := reflect.ValueOf(item) - if val.Len() > c.MaxVariableArrayLen { - return errors.New("variable array field length too large to encode") - } - - if err := writeUvarint(w, val.Len()); err != nil { - return err - } - for i := 0; i < val.Len(); i++ { - if err := c.EncodeField(w, val.Index(i).Interface()); err != nil { - return err - } - } - return nil - } - - return errors.New(fmt.Sprintf("type %s cannot be encoded", t.String())) -} - -func writeUvarint(w io.Writer, n int) error { - lenBuf := make([]byte, binary.MaxVarintLen64, binary.MaxVarintLen64) - bytesWritten := binary.PutUvarint(lenBuf, uint64(n)) - _, err := w.Write(lenBuf[:bytesWritten]) - return err -} diff --git a/vendor/fnd.localhost/mstream/encode_test.go b/vendor/fnd.localhost/mstream/encode_test.go deleted file mode 100644 index bdcee68..0000000 --- a/vendor/fnd.localhost/mstream/encode_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package mstream - -import ( - "bytes" - "encoding/hex" - "math" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestEncodeFields(t *testing.T) { - cafe := new(cafeEncodeDecoder) - - var threeTwoByte [32]byte - threeTwoByte[1] = 0xff - - var buf bytes.Buffer - require.NoError(t, EncodeFields( - &buf, - cafe, - []*cafeEncodeDecoder{ - cafe, - cafe, - }, - true, - false, - uint8(0), - uint16(0), - uint32(0), - uint64(0), - uint8(math.MaxUint8), - uint16(math.MaxUint16), - uint32(math.MaxUint32), - uint64(math.MaxUint64), - threeTwoByte, - [2]string{ - "testing", - "testing", - }, - []byte{ - 0x01, 0x02, - }, - []string{ - "testing", - "testing", - }, - "hello there", - time.Unix(1, 0), - )) - require.Equal( - t, - "cafe"+ - "02cafecafe"+ - "01"+ - "00"+ - "00"+ - "0000"+ - "00000000"+ - "0000000000000000"+ - "ff"+ - "ffff"+ - "ffffffff"+ - "ffffffffffffffff"+ - "00ff000000000000000000000000000000000000000000000000000000000000"+ - "0774657374696e670774657374696e67"+ - "020102"+ - "020774657374696e670774657374696e67"+ - "0b68656c6c6f207468657265"+ - "0000000000000001", - hex.EncodeToString(buf.Bytes()), - ) - - buf.Reset() - err := EncodeFields(&buf, uint8(1), struct{}{}) - require.Error(t, err) - require.Contains(t, err.Error(), "cannot be encoded") -} - -func TestEncode_Errors(t *testing.T) { - rw := new(NopReadWriter) - err := EncodeField(rw, &struct{}{}) - require.Error(t, err) - require.Contains(t, err.Error(), "cannot be encoded") - - customEncoder := &ConfiguredEncoder{ - MaxVariableArrayLen: 5, - MaxByteFieldLen: 5, - } - - err = customEncoder.EncodeField(rw, make([]byte, customEncoder.MaxByteFieldLen+1)) - require.Error(t, err) - require.Contains(t, err.Error(), "byte-assignable field length too large to encode") - - // zero out err since the message is the same - err = nil - err = customEncoder.EncodeField(rw, "123456") - require.Error(t, err) - require.Contains(t, err.Error(), "byte-assignable field length too large to encode") - - err = customEncoder.EncodeField(rw, make([]string, customEncoder.MaxVariableArrayLen+1)) - require.Error(t, err) - require.Contains(t, err.Error(), "variable array field length too large to encode") -} diff --git a/vendor/fnd.localhost/mstream/encoder.go b/vendor/fnd.localhost/mstream/encoder.go deleted file mode 100644 index d1884aa..0000000 --- a/vendor/fnd.localhost/mstream/encoder.go +++ /dev/null @@ -1,31 +0,0 @@ -package mstream - -import "io" - -const ( - DefaultMaxVariableArrayLen = 1024 - DefaultMaxByteFieldLen = 256 * 1024 -) - -type Encoder interface { - Encode(w io.Writer) error -} - -type Decoder interface { - Decode(r io.Reader) error -} - -type EncodeDecoder interface { - Encoder - Decoder -} - -type ConfiguredEncoder struct { - MaxVariableArrayLen int - MaxByteFieldLen uint64 -} - -var defaultEncoder = &ConfiguredEncoder{ - MaxVariableArrayLen: DefaultMaxVariableArrayLen, - MaxByteFieldLen: DefaultMaxByteFieldLen, -} diff --git a/vendor/fnd.localhost/mstream/encoding_bench_test.go b/vendor/fnd.localhost/mstream/encoding_bench_test.go deleted file mode 100644 index 473f428..0000000 --- a/vendor/fnd.localhost/mstream/encoding_bench_test.go +++ /dev/null @@ -1,107 +0,0 @@ -package mstream - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -type NopReadWriter struct{} - -func (n *NopReadWriter) Read(p []byte) (int, error) { - return len(p), nil -} - -func (n *NopReadWriter) Write(p []byte) (int, error) { - return len(p), nil -} - -func BenchmarkUint8Encoding(b *testing.B) { - var i uint8 - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, i)) - } -} - -func BenchmarkUint16Encoding(b *testing.B) { - var i uint16 - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, i)) - } -} - -func BenchmarkUint32Encoding(b *testing.B) { - var i uint32 - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, i)) - } -} - -func BenchmarkUint64Encoding(b *testing.B) { - var i uint64 - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, i)) - } -} - -func BenchmarkByteSliceEncoding1024(b *testing.B) { - bytes := make([]byte, 1024, 1024) - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, bytes)) - } -} - -func BenchmarkStringEncoding1024(b *testing.B) { - bytes := make([]byte, 1024, 1024) - str := string(bytes) - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, str)) - } -} - -func BenchmarkByteArrayEncoding32(b *testing.B) { - bytes := make([]byte, 32, 32) - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, bytes)) - } -} - -func BenchmarkByteArrayEncodingReflect(b *testing.B) { - var bytes [1024]byte - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, bytes)) - } -} - -func BenchmarkUint16ArrayEncodingReflect(b *testing.B) { - var uints [1024]uint16 - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, uints)) - } -} - -func BenchmarkStringArrayEncodingReflect(b *testing.B) { - var strings [1024]string - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, strings)) - } -} - -func BenchmarkWellKnownTimeEncoding(b *testing.B) { - ts := time.Now() - rw := new(NopReadWriter) - for n := 0; n < b.N; n++ { - require.NoError(b, EncodeField(rw, ts)) - } -} diff --git a/vendor/fnd.localhost/mstream/go.mod b/vendor/fnd.localhost/mstream/go.mod deleted file mode 100644 index df8267d..0000000 --- a/vendor/fnd.localhost/mstream/go.mod +++ /dev/null @@ -1,8 +0,0 @@ -module fnd.localhost/mstream - -go 1.12 - -require ( - github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.4.0 -) diff --git a/vendor/fnd.localhost/mstream/go.sum b/vendor/fnd.localhost/mstream/go.sum deleted file mode 100644 index 1552a1a..0000000 --- a/vendor/fnd.localhost/mstream/go.sum +++ /dev/null @@ -1,13 +0,0 @@ -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/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.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 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/fnd.localhost/mstream/well_known.go b/vendor/fnd.localhost/mstream/well_known.go deleted file mode 100644 index b6969f7..0000000 --- a/vendor/fnd.localhost/mstream/well_known.go +++ /dev/null @@ -1,52 +0,0 @@ -package mstream - -import ( - "fmt" - "io" - "reflect" - "time" - - "github.com/pkg/errors" -) - -type encoderFunc func(w io.Writer, val interface{}) error -type decoderFunc func(r io.Reader, val interface{}) error - -var ( - wellKnownEncoders = make(map[string]encoderFunc) - wellKnownDecoders = make(map[string]decoderFunc) -) - -func EncodeTime(w io.Writer, val interface{}) error { - cast, ok := val.(time.Time) - if !ok { - return errors.New("value is not a time.Time") - } - - return EncodeField(w, uint64(cast.Unix())) -} - -func DecodeTime(r io.Reader, val interface{}) error { - cast, ok := val.(*time.Time) - if !ok { - return errors.New("value is not a *time.Time") - } - - var unixTs uint64 - if err := DecodeField(r, &unixTs); err != nil { - return errors.Wrap(err, "failed to decode timestamp") - } - - *cast = time.Unix(int64(unixTs), 0) - return nil -} - -func canonicalizeWellKnown(t reflect.Type) string { - return fmt.Sprintf("%s/%s", t.PkgPath(), t.Name()) -} - -func init() { - timeTypeKey := canonicalizeWellKnown(reflect.TypeOf(time.Time{})) - wellKnownEncoders[timeTypeKey] = EncodeTime - wellKnownDecoders[timeTypeKey] = DecodeTime -} diff --git a/vendor/fnd.localhost/mstream/well_known_test.go b/vendor/fnd.localhost/mstream/well_known_test.go deleted file mode 100644 index c64993d..0000000 --- a/vendor/fnd.localhost/mstream/well_known_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package mstream - -import ( - "bytes" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestEncodeTime(t *testing.T) { - var buf bytes.Buffer - require.NoError(t, EncodeTime(&buf, time.Unix(12345, 0))) - require.EqualValues(t, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39}, buf.Bytes()) - - rw := new(NopReadWriter) - err := EncodeTime(rw, 9001) - require.Error(t, err) - require.Contains(t, err.Error(), "value is not a time.Time") -} - -func TestDecodeTime(t *testing.T) { - input := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39} - rd := bytes.NewReader(input) - var output time.Time - require.NoError(t, DecodeTime(rd, &output)) - require.True(t, output.Equal(time.Unix(12345, 0))) - - rd = bytes.NewReader(input) - err := DecodeTime(rd, output) - require.Error(t, err) - require.Contains(t, err.Error(), "value is not a *time.Time") -} From de0996d7b5094e4f38c42226667d2a94af2626cd Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 15 Feb 2021 16:17:36 +0530 Subject: [PATCH 27/71] dwire: bump max var array len --- vendor/fnd.localhost/dwire/encoder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/fnd.localhost/dwire/encoder.go b/vendor/fnd.localhost/dwire/encoder.go index da93123..a259f8a 100644 --- a/vendor/fnd.localhost/dwire/encoder.go +++ b/vendor/fnd.localhost/dwire/encoder.go @@ -3,7 +3,7 @@ package dwire import "io" const ( - DefaultMaxVariableArrayLen = 1024 + DefaultMaxVariableArrayLen = 4 * 1024 DefaultMaxByteFieldLen = 8 * 256 * 1024 ) From 19eb25da14cd51de673614110e1069b7d10e91e3 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Mon, 15 Feb 2021 17:52:33 +0530 Subject: [PATCH 28/71] protocol: rename errors to match sector instead of timestamp --- protocol/update_queue.go | 27 ++++++++++++++------------- protocol/update_queue_test.go | 6 +++--- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/protocol/update_queue.go b/protocol/update_queue.go index bd69347..02074ce 100644 --- a/protocol/update_queue.go +++ b/protocol/update_queue.go @@ -1,7 +1,6 @@ package protocol import ( - "github.com/btcsuite/btcd/btcec" "fnd/blob" "fnd/config" "fnd/crypto" @@ -9,21 +8,23 @@ import ( "fnd/p2p" "fnd/store" "fnd/wire" - "fnd.localhost/handshake/primitives" - "github.com/pkg/errors" - "github.com/syndtr/goleveldb/leveldb" "sync" "sync/atomic" "time" + + "fnd.localhost/handshake/primitives" + "github.com/btcsuite/btcd/btcec" + "github.com/pkg/errors" + "github.com/syndtr/goleveldb/leveldb" ) var ( - ErrUpdateQueueMaxLen = errors.New("update queue is at max length") - ErrUpdateQueueIdenticalTimestamp = errors.New("timestamp is identical to stored") - ErrUpdateQueueThrottled = errors.New("update is throttled") - ErrUpdateQueueStaleTimestamp = errors.New("update is stale") - ErrUpdateQueueSpltBrain = errors.New("split brain") - ErrInitialImportIncomplete = errors.New("initial import incomplete") + ErrUpdateQueueMaxLen = errors.New("update queue is at max length") + ErrUpdateQueueSectorUpdated = errors.New("sector already updated") + ErrUpdateQueueThrottled = errors.New("update is throttled") + ErrUpdateQueueStaleSector = errors.New("sector is stale") + ErrUpdateQueueSpltBrain = errors.New("split brain") + ErrInitialImportIncomplete = errors.New("initial import incomplete") ) type UpdateQueue struct { @@ -115,10 +116,10 @@ func (u *UpdateQueue) Enqueue(peerID crypto.Hash, update *wire.Update) error { } if storedSectorSize > update.SectorSize { - return ErrUpdateQueueStaleTimestamp + return ErrUpdateQueueStaleSector } if storedSectorSize == update.SectorSize { - return ErrUpdateQueueIdenticalTimestamp + return ErrUpdateQueueSectorUpdated } u.mu.Lock() defer u.mu.Unlock() @@ -145,7 +146,7 @@ func (u *UpdateQueue) Enqueue(peerID crypto.Hash, update *wire.Update) error { } if entry.SectorSize > update.SectorSize { - return ErrUpdateQueueStaleTimestamp + return ErrUpdateQueueStaleSector } if entry.Signature != update.Signature { return ErrUpdateQueueSpltBrain diff --git a/protocol/update_queue_test.go b/protocol/update_queue_test.go index 0b7f52a..3add1e1 100644 --- a/protocol/update_queue_test.go +++ b/protocol/update_queue_test.go @@ -113,7 +113,7 @@ func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { Signature: identicalHeader.Signature, }, func(t *testing.T, err error) { - require.Equal(t, ErrUpdateQueueIdenticalTimestamp, err) + require.Equal(t, ErrUpdateQueueSectorUpdated, err) }, }, { @@ -126,7 +126,7 @@ func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { ReservedRoot: identicalHeader.ReservedRoot, }), func(t *testing.T, err error) { - require.Equal(t, ErrUpdateQueueStaleTimestamp, err) + require.Equal(t, ErrUpdateQueueStaleSector, err) }, }, } @@ -169,7 +169,7 @@ func TestUpdateQueue_Enqueue_InvalidAfterEnqueue(t *testing.T) { EpochHeight: header.EpochHeight, SectorSize: header.SectorSize + 1, }))) - require.Equal(t, ErrUpdateQueueStaleTimestamp, queue.Enqueue(crypto.Rand32(), signUpdate(t, &wire.Update{ + require.Equal(t, ErrUpdateQueueStaleSector, queue.Enqueue(crypto.Rand32(), signUpdate(t, &wire.Update{ Name: header.Name, EpochHeight: header.EpochHeight, SectorSize: header.SectorSize - 10, From d6feae3a1a7009618282c2c4874ae6f7a1d20754 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 18 Feb 2021 13:32:39 +0530 Subject: [PATCH 29/71] syncer: write equivocation proof to level store --- protocol/syncer.go | 19 ++++++----- protocol/updater.go | 1 + store/equivocation_proof.go | 34 +++++++++++++++++++ wire/envelope.go | 5 ++- wire/equivocation_proof.go | 68 +++++++++++++++++++++++++++++++++++++ wire/message.go | 6 +++- 6 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 store/equivocation_proof.go create mode 100644 wire/equivocation_proof.go diff --git a/protocol/syncer.go b/protocol/syncer.go index cfb5e1b..57a5e90 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -5,9 +5,12 @@ import ( "fnd/crypto" "fnd/log" "fnd/p2p" + "fnd/store" "fnd/wire" - "github.com/pkg/errors" "time" + + "github.com/pkg/errors" + "github.com/syndtr/goleveldb/leveldb" ) const ( @@ -29,6 +32,7 @@ type SyncSectorsOpts struct { PrevHash crypto.Hash SectorTipHash crypto.Hash Name string + DB *leveldb.DB } type payloadRes struct { @@ -99,16 +103,13 @@ func SyncSectors(opts *SyncSectorsOpts) error { } if sectorTipHash != opts.SectorTipHash { lgr.Trace("payload tip hash mismatch", "payload_tip_hash", sectorTipHash, "expected_payload_tip_hash", opts.SectorTipHash) - peer, err := opts.Mux.PeerByID(peerID) + err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { + return store.SetEquivocationProofTx(tx, msg.Name, &wire.EquivocationProof{}) + }) if err != nil { - lgr.Trace("error fetching peer", "peer_id", peerID) + lgr.Error("failed to write equivocation proof", "err", err) } - // TODO: set header.bannedat = time.now for this name - if err := peer.Close(); err != nil { - lgr.Trace("error banning peer", "peer_id", peerID) - } - // TODO: generate equivocation proof - continue + return } for i := 0; int(i) < len(msg.Payload); i++ { if err := opts.Tx.WriteSector(msg.Payload[i]); err != nil { diff --git a/protocol/updater.go b/protocol/updater.go index 9df955b..b82be4f 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -224,6 +224,7 @@ func UpdateBlob(cfg *UpdateConfig) error { SectorTipHash: item.SectorTipHash, PrevHash: prevHash, Name: item.Name, + DB: cfg.DB, }) if err != nil { if err := tx.Rollback(); err != nil { diff --git a/store/equivocation_proof.go b/store/equivocation_proof.go new file mode 100644 index 0000000..421ac6c --- /dev/null +++ b/store/equivocation_proof.go @@ -0,0 +1,34 @@ +package store + +import ( + "bufio" + "bytes" + "fnd/wire" + + "github.com/pkg/errors" + "github.com/syndtr/goleveldb/leveldb" +) + +var ( + equivocationProofsPrefix = Prefixer("equivocationproofs") +) + +func GeEquivocationProof(db *leveldb.DB, name string) (*wire.EquivocationProof, error) { + proof := new(wire.EquivocationProof) + equivocationProofData, err := db.Get(equivocationProofsPrefix(name), nil) + if err != nil { + return nil, errors.Wrap(err, "error getting equivocation proof data") + } + mustUnmarshalJSON(equivocationProofData, proof) + return proof, nil +} + +func SetEquivocationProofTx(tx *leveldb.Transaction, name string, proof *wire.EquivocationProof) error { + var buf bytes.Buffer + wr := bufio.NewWriter(&buf) + proof.Encode(wr) + if err := tx.Put(equivocationProofsPrefix(proof.Name), buf.Bytes(), nil); err != nil { + return errors.Wrap(err, "error writing header tree") + } + return nil +} diff --git a/wire/envelope.go b/wire/envelope.go index a11a58b..c074c4c 100644 --- a/wire/envelope.go +++ b/wire/envelope.go @@ -4,9 +4,10 @@ import ( "bytes" "fmt" "fnd/crypto" - "fnd.localhost/dwire" "io" "time" + + "fnd.localhost/dwire" ) type Envelope struct { @@ -92,6 +93,8 @@ func (e *Envelope) Decode(r io.Reader) error { msg = &PeerRes{} case MessageTypeUpdateReq: msg = &UpdateReq{} + case MessageTypeEquivocationProof: + msg = &EquivocationProof{} default: return fmt.Errorf("invalid message type: %d", e.MessageType) } diff --git a/wire/equivocation_proof.go b/wire/equivocation_proof.go new file mode 100644 index 0000000..09df786 --- /dev/null +++ b/wire/equivocation_proof.go @@ -0,0 +1,68 @@ +package wire + +import ( + "io" + + "fnd/blob" + "fnd/crypto" + + "fnd.localhost/dwire" +) + +type EquivocationProof struct { + HashCacher + + Name string + EpochHeight uint16 + PayloadPosition uint16 + PrevHash crypto.Hash + ReservedRoot crypto.Hash + Payload []blob.Sector +} + +var _ Message = (*EquivocationProof)(nil) + +func (s *EquivocationProof) MsgType() MessageType { + return MessageTypeEquivocationProof +} + +func (s *EquivocationProof) Equals(other Message) bool { + cast, ok := other.(*EquivocationProof) + if !ok { + return false + } + + return s.Name == cast.Name && + s.EpochHeight == cast.EpochHeight && + s.PayloadPosition == cast.PayloadPosition && + s.PrevHash == cast.PrevHash && + s.ReservedRoot == cast.ReservedRoot +} + +func (s *EquivocationProof) Encode(w io.Writer) error { + return dwire.EncodeFields( + w, + s.Name, + s.EpochHeight, + s.PayloadPosition, + s.PrevHash, + s.ReservedRoot, + s.Payload, + ) +} + +func (s *EquivocationProof) Decode(r io.Reader) error { + return dwire.DecodeFields( + r, + &s.Name, + &s.EpochHeight, + &s.PayloadPosition, + &s.PrevHash, + &s.ReservedRoot, + &s.Payload, + ) +} + +func (s *EquivocationProof) Hash() (crypto.Hash, error) { + return s.HashCacher.Hash(s) +} diff --git a/wire/message.go b/wire/message.go index e55dd1b..52d4c6f 100644 --- a/wire/message.go +++ b/wire/message.go @@ -2,8 +2,9 @@ package wire import ( "fnd/crypto" - "fnd.localhost/dwire" "io" + + "fnd.localhost/dwire" ) type Message interface { @@ -27,6 +28,7 @@ const ( MessageTypePeerRes MessageTypeUpdateReq MessageTypeNameRes + MessageTypeEquivocationProof ) func (t MessageType) String() string { @@ -53,6 +55,8 @@ func (t MessageType) String() string { return "UpdateReq" case MessageTypeNameRes: return "NameRes" + case MessageTypeEquivocationProof: + return "EquivocationProof" default: return "unknown" } From ecaefeeafdd168017d681ab1ee36ea4d272165d0 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 18 Feb 2021 14:59:09 +0530 Subject: [PATCH 30/71] cli: blob write - add flag to reset epoch --- cmd/fnd-cli/cmd/blob/write.go | 53 ++++++++++++++-- store/headers.go | 110 +++++++++++++++++++--------------- 2 files changed, 110 insertions(+), 53 deletions(-) diff --git a/cmd/fnd-cli/cmd/blob/write.go b/cmd/fnd-cli/cmd/blob/write.go index 3d0e4ee..22e67bb 100644 --- a/cmd/fnd-cli/cmd/blob/write.go +++ b/cmd/fnd-cli/cmd/blob/write.go @@ -6,20 +6,29 @@ import ( "fmt" "fnd/blob" "fnd/cli" + "fnd/config" + "fnd/protocol" "fnd/rpc" apiv1 "fnd/rpc/v1" - "github.com/mattn/go-isatty" - "github.com/spf13/cobra" + "fnd/store" "io" "os" + "path" + + "github.com/mattn/go-isatty" + "github.com/pkg/errors" + "github.com/spf13/cobra" ) const ( - BroadcastFlag = "broadcast" + BroadcastFlag = "broadcast" + ResetEpochFlag = "reset-epoch" ) var ( - broadcast bool + fndHome string + broadcast bool + resetEpoch bool ) var writeCmd = &cobra.Command{ @@ -27,17 +36,49 @@ var writeCmd = &cobra.Command{ Short: "Write data to the specified blob.", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { + name := args[0] + conn, err := cli.DialRPC(cmd) if err != nil { return err } + + if resetEpoch { + res, err := rpc.GetBlobInfo(apiv1.NewFootnotev1Client(conn), name) + if err != nil { + return err + } + + if res.EpochHeight >= protocol.CurrentEpoch(name) { + return errors.New("cannot reset epoch ahead of schedule") + } + + homePath := config.ExpandHomePath(fndHome) + db, err := store.Open(config.ExpandDBPath(homePath)) + if err != nil { + return errors.Wrap(err, "error opening store") + } + + blobsPath := config.ExpandBlobsPath(homePath) + blobSubpath := blob.PathifyName(name) + blobFile := path.Join(blobsPath, blobSubpath) + if err := os.RemoveAll(blobFile); err != nil { + return errors.Wrap(err, "error erasing blob data") + } + if err := store.TruncateHeaderName(db, name); err != nil { + return errors.Wrap(err, "error truncating header store") + } + if err := db.Close(); err != nil { + return errors.Wrap(err, "error closing DB") + } + } + homeDir := cli.GetHomeDir(cmd) signer, err := cli.GetSigner(homeDir) if err != nil { return err } - name := args[0] wr := rpc.NewBlobWriter(apiv1.NewFootnotev1Client(conn), signer, name) if err := wr.Open(); err != nil { @@ -90,5 +131,7 @@ func readDataTTY() []byte { func init() { writeCmd.Flags().BoolVar(&broadcast, BroadcastFlag, true, "Broadcast data to the network upon completion") + writeCmd.Flags().BoolVar(&resetEpoch, ResetEpochFlag, false, "Increment the epoch and reset the blob before write.") + writeCmd.Flags().StringVar(&fndHome, "fnd-home", "~/.fnd", "Path to FootnoteD's home directory.") cmd.AddCommand(writeCmd) } diff --git a/store/headers.go b/store/headers.go index dab814a..f7aa18e 100644 --- a/store/headers.go +++ b/store/headers.go @@ -4,15 +4,16 @@ import ( "bytes" "encoding/hex" "encoding/json" - "github.com/btcsuite/btcd/btcec" "fnd/blob" "fnd/crypto" + "sync" + "time" + + "github.com/btcsuite/btcd/btcec" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/iterator" "github.com/syndtr/goleveldb/leveldb/util" - "sync" - "time" ) type Header struct { @@ -29,15 +30,15 @@ type Header struct { func (h *Header) MarshalJSON() ([]byte, error) { out := &struct { - Name string `json:"name"` - EpochHeight uint16 `json:"epoch_height"` - SectorSize uint16 `json:"sector_size"` - SectorTipHash string `json:"sector_tip_hash"` - Signature string `json:"signature"` - ReservedRoot string `json:"reserved_root"` - EpochStartAt time.Time `json:"epoch_start_at"` - Banned bool `json:"banned"` - BannedAt time.Time `json:"banned_at"` + Name string `json:"name"` + EpochHeight uint16 `json:"epoch_height"` + SectorSize uint16 `json:"sector_size"` + SectorTipHash string `json:"sector_tip_hash"` + Signature string `json:"signature"` + ReservedRoot string `json:"reserved_root"` + EpochStartAt time.Time `json:"epoch_start_at"` + Banned bool `json:"banned"` + BannedAt time.Time `json:"banned_at"` }{ h.Name, h.EpochHeight, @@ -55,15 +56,15 @@ func (h *Header) MarshalJSON() ([]byte, error) { func (h *Header) UnmarshalJSON(b []byte) error { in := &struct { - Name string `json:"name"` - EpochHeight uint16 `json:"epoch_height"` - SectorSize uint16 `json:"sector_size"` - SectorTipHash string `json:"sector_tip_hash"` - Signature string `json:"signature"` - ReservedRoot string `json:"reserved_root"` - EpochStartAt time.Time `json:"epoch_start_at"` - Banned bool `json:"banned"` - BannedAt time.Time `json:"banned_at"` + Name string `json:"name"` + EpochHeight uint16 `json:"epoch_height"` + SectorSize uint16 `json:"sector_size"` + SectorTipHash string `json:"sector_tip_hash"` + Signature string `json:"signature"` + ReservedRoot string `json:"reserved_root"` + EpochStartAt time.Time `json:"epoch_start_at"` + Banned bool `json:"banned"` + BannedAt time.Time `json:"banned_at"` }{} if err := json.Unmarshal(b, in); err != nil { return err @@ -195,28 +196,28 @@ func SetHeaderTx(tx *leveldb.Transaction, header *Header, sectorHashes blob.Sect } type BlobInfo struct { - Name string `json:"name"` - PublicKey *btcec.PublicKey `json:"public_key"` - ImportHeight int `json:"import_height"` - EpochHeight uint16 `json:"epoch_height"` - SectorSize uint16 `json:"sector_size"` - SectorTipHash crypto.Hash `json:"sector_tip_hash"` - Signature crypto.Signature `json:"signature"` - ReservedRoot crypto.Hash `json:"reserved_root"` - ReceivedAt time.Time `json:"received_at"` + Name string `json:"name"` + PublicKey *btcec.PublicKey `json:"public_key"` + ImportHeight int `json:"import_height"` + EpochHeight uint16 `json:"epoch_height"` + SectorSize uint16 `json:"sector_size"` + SectorTipHash crypto.Hash `json:"sector_tip_hash"` + Signature crypto.Signature `json:"signature"` + ReservedRoot crypto.Hash `json:"reserved_root"` + ReceivedAt time.Time `json:"received_at"` } func (b *BlobInfo) MarshalJSON() ([]byte, error) { jsonInfo := struct { - Name string `json:"name"` - PublicKey string `json:"public_key"` - ImportHeight int `json:"import_height"` - EpochHeight uint16 `json:"epoch_height"` - SectorSize uint16 `json:"sector_size"` - SectorTipHash string `json:"sector_tip_hash"` - Signature string `json:"signature"` - ReservedRoot string `json:"reserved_root"` - ReceivedAt time.Time `json:"received_at"` + Name string `json:"name"` + PublicKey string `json:"public_key"` + ImportHeight int `json:"import_height"` + EpochHeight uint16 `json:"epoch_height"` + SectorSize uint16 `json:"sector_size"` + SectorTipHash string `json:"sector_tip_hash"` + Signature string `json:"signature"` + ReservedRoot string `json:"reserved_root"` + ReceivedAt time.Time `json:"received_at"` }{ b.Name, hex.EncodeToString(b.PublicKey.SerializeCompressed()), @@ -249,15 +250,15 @@ func (bis *BlobInfoStream) Next() (*BlobInfo, error) { return nil, errors.Wrap(err, "error getting name info") } return &BlobInfo{ - Name: header.Name, - PublicKey: nameInfo.PublicKey, - ImportHeight: nameInfo.ImportHeight, - EpochHeight: header.EpochHeight, - SectorSize: header.SectorSize, - SectorTipHash: header.SectorTipHash, - Signature: header.Signature, - ReservedRoot: header.ReservedRoot, - ReceivedAt: header.EpochStartAt, + Name: header.Name, + PublicKey: nameInfo.PublicKey, + ImportHeight: nameInfo.ImportHeight, + EpochHeight: header.EpochHeight, + SectorSize: header.SectorSize, + SectorTipHash: header.SectorTipHash, + Signature: header.Signature, + ReservedRoot: header.ReservedRoot, + ReceivedAt: header.EpochStartAt, }, nil } @@ -287,6 +288,19 @@ func StreamBlobInfo(db *leveldb.DB, start string) (*BlobInfoStream, error) { }, nil } +func TruncateHeaderName(db *leveldb.DB, name string) error { + err := WithTx(db, func(tx *leveldb.Transaction) error { + if err := tx.Delete(headerDataPrefix(name), nil); err != nil { + return errors.Wrap(err, "error deleting header store key") + } + return nil + }) + if err != nil { + return errors.Wrap(err, "error truncating header store") + } + return nil +} + func TruncateHeaderStore(db *leveldb.DB) error { err := WithTx(db, func(tx *leveldb.Transaction) error { iter := tx.NewIterator(util.BytesPrefix(headersPrefix()), nil) From 4f794ff9cd8ed15ec337e7abe14e77acf4ad9117 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 18 Feb 2021 15:25:07 +0530 Subject: [PATCH 31/71] rpc: add reset epoch method placeholder --- cmd/fnd-cli/cmd/blob/write.go | 42 +--- rpc/blob.go | 23 ++- rpc/blob_writer.go | 7 +- rpc/server.go | 41 ++-- rpc/v1/api.pb.go | 371 ++++++++++++++++++++++++---------- rpc/v1/api.proto | 9 + 6 files changed, 320 insertions(+), 173 deletions(-) diff --git a/cmd/fnd-cli/cmd/blob/write.go b/cmd/fnd-cli/cmd/blob/write.go index 22e67bb..6505de7 100644 --- a/cmd/fnd-cli/cmd/blob/write.go +++ b/cmd/fnd-cli/cmd/blob/write.go @@ -6,17 +6,12 @@ import ( "fmt" "fnd/blob" "fnd/cli" - "fnd/config" - "fnd/protocol" "fnd/rpc" apiv1 "fnd/rpc/v1" - "fnd/store" "io" "os" - "path" "github.com/mattn/go-isatty" - "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -43,36 +38,6 @@ var writeCmd = &cobra.Command{ return err } - if resetEpoch { - res, err := rpc.GetBlobInfo(apiv1.NewFootnotev1Client(conn), name) - if err != nil { - return err - } - - if res.EpochHeight >= protocol.CurrentEpoch(name) { - return errors.New("cannot reset epoch ahead of schedule") - } - - homePath := config.ExpandHomePath(fndHome) - db, err := store.Open(config.ExpandDBPath(homePath)) - if err != nil { - return errors.Wrap(err, "error opening store") - } - - blobsPath := config.ExpandBlobsPath(homePath) - blobSubpath := blob.PathifyName(name) - blobFile := path.Join(blobsPath, blobSubpath) - if err := os.RemoveAll(blobFile); err != nil { - return errors.Wrap(err, "error erasing blob data") - } - if err := store.TruncateHeaderName(db, name); err != nil { - return errors.Wrap(err, "error truncating header store") - } - if err := db.Close(); err != nil { - return errors.Wrap(err, "error closing DB") - } - } - homeDir := cli.GetHomeDir(cmd) signer, err := cli.GetSigner(homeDir) if err != nil { @@ -84,6 +49,13 @@ var writeCmd = &cobra.Command{ if err := wr.Open(); err != nil { return err } + + if resetEpoch { + if err := wr.Reset(); err != nil { + return err + } + } + var rd io.Reader if len(args) < 2 { if isatty.IsTerminal(os.Stdin.Fd()) { diff --git a/rpc/blob.go b/rpc/blob.go index 5f86378..4f3a37e 100644 --- a/rpc/blob.go +++ b/rpc/blob.go @@ -2,13 +2,14 @@ package rpc import ( "context" - "github.com/btcsuite/btcd/btcec" "fnd/crypto" apiv1 "fnd/rpc/v1" "fnd/store" - "github.com/pkg/errors" "io" "time" + + "github.com/btcsuite/btcd/btcec" + "github.com/pkg/errors" ) func GetBlobInfo(client apiv1.Footnotev1Client, name string) (*store.BlobInfo, error) { @@ -75,14 +76,14 @@ func parseBlobInfoRes(res *apiv1.BlobInfoRes) (*store.BlobInfo, error) { } return &store.BlobInfo{ - Name: res.Name, - PublicKey: pub, - ImportHeight: int(res.ImportHeight), - EpochHeight: uint16(res.EpochHeight), - SectorSize: uint16(res.SectorSize), - SectorTipHash: merkleRoot, - ReservedRoot: reservedRoot, - ReceivedAt: time.Unix(int64(res.ReceivedAt), 0), - Signature: sig, + Name: res.Name, + PublicKey: pub, + ImportHeight: int(res.ImportHeight), + EpochHeight: uint16(res.EpochHeight), + SectorSize: uint16(res.SectorSize), + SectorTipHash: merkleRoot, + ReservedRoot: reservedRoot, + ReceivedAt: time.Unix(int64(res.ReceivedAt), 0), + Signature: sig, }, nil } diff --git a/rpc/blob_writer.go b/rpc/blob_writer.go index 3ac4e81..e79161d 100644 --- a/rpc/blob_writer.go +++ b/rpc/blob_writer.go @@ -5,8 +5,9 @@ import ( "fnd/blob" "fnd/crypto" apiv1 "fnd/rpc/v1" - "github.com/pkg/errors" "time" + + "github.com/pkg/errors" ) type BlobWriter struct { @@ -81,6 +82,10 @@ func (b *BlobWriter) WriteSector(p []byte) (crypto.Hash, error) { return b.sectorTipHash, nil } +func (b *BlobWriter) Reset() error { + return nil +} + func (b *BlobWriter) Commit(broadcast bool) (crypto.Hash, error) { if !b.opened { panic("writer not open") diff --git a/rpc/server.go b/rpc/server.go index feaa1eb..214624e 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -355,6 +355,11 @@ func (s *Server) Commit(ctx context.Context, req *apiv1.CommitReq) (*apiv1.Commi return &apiv1.CommitRes{}, nil } +func (s *Server) ResetEpoch(ctx context.Context, req *apiv1.ResetEpochReq) (*apiv1.ResetEpochRes, error) { + // TODO: implement epoch reset + return &apiv1.ResetEpochRes{}, nil +} + func (s *Server) ReadAt(_ context.Context, req *apiv1.ReadAtReq) (*apiv1.ReadAtRes, error) { if req.Offset > blob.Size { return nil, errors.New("offset is beyond blob bounds") @@ -400,15 +405,15 @@ func (s *Server) GetBlobInfo(_ context.Context, req *apiv1.BlobInfoReq) (*apiv1. } return &apiv1.BlobInfoRes{ - Name: name, - PublicKey: info.PublicKey.SerializeCompressed(), - ImportHeight: uint32(info.ImportHeight), - EpochHeight: uint32(header.EpochHeight), - SectorSize: uint32(header.SectorSize), - SectorTipHash: header.SectorTipHash[:], - ReservedRoot: header.ReservedRoot[:], - ReceivedAt: uint64(header.EpochStartAt.Unix()), - Signature: header.Signature[:], + Name: name, + PublicKey: info.PublicKey.SerializeCompressed(), + ImportHeight: uint32(info.ImportHeight), + EpochHeight: uint32(header.EpochHeight), + SectorSize: uint32(header.SectorSize), + SectorTipHash: header.SectorTipHash[:], + ReservedRoot: header.ReservedRoot[:], + ReceivedAt: uint64(header.EpochStartAt.Unix()), + Signature: header.Signature[:], }, nil } @@ -428,15 +433,15 @@ func (s *Server) ListBlobInfo(req *apiv1.ListBlobInfoReq, srv apiv1.Footnotev1_L return nil } res := &apiv1.BlobInfoRes{ - Name: info.Name, - PublicKey: info.PublicKey.SerializeCompressed(), - ImportHeight: uint32(info.ImportHeight), - EpochHeight: uint32(info.EpochHeight), - SectorSize: uint32(info.SectorSize), - SectorTipHash: info.SectorTipHash[:], - ReservedRoot: info.ReservedRoot[:], - ReceivedAt: uint64(info.ReceivedAt.Unix()), - Signature: info.Signature[:], + Name: info.Name, + PublicKey: info.PublicKey.SerializeCompressed(), + ImportHeight: uint32(info.ImportHeight), + EpochHeight: uint32(info.EpochHeight), + SectorSize: uint32(info.SectorSize), + SectorTipHash: info.SectorTipHash[:], + ReservedRoot: info.ReservedRoot[:], + ReceivedAt: uint64(info.ReceivedAt.Unix()), + Signature: info.Signature[:], } if err = srv.Send(res); err != nil { return errors.Wrap(err, "error sending info") diff --git a/rpc/v1/api.pb.go b/rpc/v1/api.pb.go index 5d73afb..adce7af 100644 --- a/rpc/v1/api.pb.go +++ b/rpc/v1/api.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0-devel -// protoc v3.12.4 +// protoc-gen-go v1.25.0 +// protoc v3.6.1 // source: api.proto package v1 @@ -1025,6 +1025,91 @@ func (x *ReadAtRes) GetData() []byte { return nil } +type ResetEpochReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *ResetEpochReq) Reset() { + *x = ResetEpochReq{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResetEpochReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResetEpochReq) ProtoMessage() {} + +func (x *ResetEpochReq) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResetEpochReq.ProtoReflect.Descriptor instead. +func (*ResetEpochReq) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{17} +} + +func (x *ResetEpochReq) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type ResetEpochRes struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ResetEpochRes) Reset() { + *x = ResetEpochRes{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResetEpochRes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResetEpochRes) ProtoMessage() {} + +func (x *ResetEpochRes) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResetEpochRes.ProtoReflect.Descriptor instead. +func (*ResetEpochRes) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{18} +} + type BlobInfoReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1036,7 +1121,7 @@ type BlobInfoReq struct { func (x *BlobInfoReq) Reset() { *x = BlobInfoReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[17] + mi := &file_api_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1049,7 +1134,7 @@ func (x *BlobInfoReq) String() string { func (*BlobInfoReq) ProtoMessage() {} func (x *BlobInfoReq) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[17] + mi := &file_api_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1062,7 +1147,7 @@ func (x *BlobInfoReq) ProtoReflect() protoreflect.Message { // Deprecated: Use BlobInfoReq.ProtoReflect.Descriptor instead. func (*BlobInfoReq) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{17} + return file_api_proto_rawDescGZIP(), []int{19} } func (x *BlobInfoReq) GetName() string { @@ -1083,7 +1168,7 @@ type ListBlobInfoReq struct { func (x *ListBlobInfoReq) Reset() { *x = ListBlobInfoReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[18] + mi := &file_api_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1096,7 +1181,7 @@ func (x *ListBlobInfoReq) String() string { func (*ListBlobInfoReq) ProtoMessage() {} func (x *ListBlobInfoReq) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[18] + mi := &file_api_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1109,7 +1194,7 @@ func (x *ListBlobInfoReq) ProtoReflect() protoreflect.Message { // Deprecated: Use ListBlobInfoReq.ProtoReflect.Descriptor instead. func (*ListBlobInfoReq) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{18} + return file_api_proto_rawDescGZIP(), []int{20} } func (x *ListBlobInfoReq) GetStart() string { @@ -1138,7 +1223,7 @@ type BlobInfoRes struct { func (x *BlobInfoRes) Reset() { *x = BlobInfoRes{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[19] + mi := &file_api_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1151,7 +1236,7 @@ func (x *BlobInfoRes) String() string { func (*BlobInfoRes) ProtoMessage() {} func (x *BlobInfoRes) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[19] + mi := &file_api_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1164,7 +1249,7 @@ func (x *BlobInfoRes) ProtoReflect() protoreflect.Message { // Deprecated: Use BlobInfoRes.ProtoReflect.Descriptor instead. func (*BlobInfoRes) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{19} + return file_api_proto_rawDescGZIP(), []int{21} } func (x *BlobInfoRes) GetName() string { @@ -1241,7 +1326,7 @@ type SendUpdateReq struct { func (x *SendUpdateReq) Reset() { *x = SendUpdateReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[20] + mi := &file_api_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1254,7 +1339,7 @@ func (x *SendUpdateReq) String() string { func (*SendUpdateReq) ProtoMessage() {} func (x *SendUpdateReq) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[20] + mi := &file_api_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1267,7 +1352,7 @@ func (x *SendUpdateReq) ProtoReflect() protoreflect.Message { // Deprecated: Use SendUpdateReq.ProtoReflect.Descriptor instead. func (*SendUpdateReq) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{20} + return file_api_proto_rawDescGZIP(), []int{22} } func (x *SendUpdateReq) GetName() string { @@ -1288,7 +1373,7 @@ type SendUpdateRes struct { func (x *SendUpdateRes) Reset() { *x = SendUpdateRes{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[21] + mi := &file_api_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1301,7 +1386,7 @@ func (x *SendUpdateRes) String() string { func (*SendUpdateRes) ProtoMessage() {} func (x *SendUpdateRes) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[21] + mi := &file_api_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1314,7 +1399,7 @@ func (x *SendUpdateRes) ProtoReflect() protoreflect.Message { // Deprecated: Use SendUpdateRes.ProtoReflect.Descriptor instead. func (*SendUpdateRes) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{21} + return file_api_proto_rawDescGZIP(), []int{23} } func (x *SendUpdateRes) GetRecipientCount() uint32 { @@ -1411,68 +1496,74 @@ var file_api_proto_rawDesc = []byte{ 0x09, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x21, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x27, 0x0a, 0x0f, 0x4c, 0x69, 0x73, - 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x22, 0xad, 0x02, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x69, 0x6d, 0x70, 0x6f, - 0x72, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x70, 0x6f, 0x63, - 0x68, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, - 0x70, 0x6f, 0x63, 0x68, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, - 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, 0x70, 0x48, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0d, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, 0x70, 0x48, 0x61, 0x73, 0x68, - 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x6f, 0x74, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, - 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, - 0x41, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, - 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x22, 0x23, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x37, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x69, - 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x0e, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x32, 0xe9, 0x03, 0x0a, 0x0a, 0x46, 0x6f, 0x6f, 0x74, 0x6e, 0x6f, 0x74, 0x65, 0x76, 0x31, 0x12, - 0x22, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, - 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x07, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, - 0x2e, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x12, 0x22, 0x0a, 0x09, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, - 0x12, 0x0d, 0x2e, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, - 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2b, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, - 0x65, 0x65, 0x72, 0x73, 0x12, 0x0d, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, - 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, - 0x65, 0x73, 0x30, 0x01, 0x12, 0x26, 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, - 0x12, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, - 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x0b, - 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x0f, 0x2e, 0x57, 0x72, - 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x57, - 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, - 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x12, - 0x20, 0x0a, 0x06, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x12, 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, - 0x41, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, - 0x73, 0x12, 0x29, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, - 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x0c, - 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, - 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x2c, - 0x0a, 0x0a, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x2e, 0x53, - 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x53, - 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x42, 0x04, 0x5a, 0x02, - 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x23, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x65, 0x74, 0x45, + 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x52, + 0x65, 0x73, 0x65, 0x74, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x73, 0x22, 0x21, 0x0a, 0x0b, + 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x27, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0xad, 0x02, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, + 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0c, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x20, + 0x0a, 0x0b, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x69, 0x7a, 0x65, + 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, 0x70, 0x48, 0x61, 0x73, + 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, + 0x69, 0x70, 0x48, 0x61, 0x73, 0x68, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x72, 0x65, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, + 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, + 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x23, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x37, 0x0a, + 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x12, 0x26, + 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0x97, 0x04, 0x0a, 0x0a, 0x46, 0x6f, 0x6f, 0x74, 0x6e, + 0x6f, 0x74, 0x65, 0x76, 0x31, 0x12, 0x22, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x47, 0x65, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x07, 0x41, 0x64, 0x64, + 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x07, 0x42, 0x61, 0x6e, + 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x22, 0x0a, 0x09, 0x55, 0x6e, 0x62, + 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2b, 0x0a, + 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x0d, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x26, 0x0a, 0x08, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, + 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, + 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x0b, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x12, 0x0f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, + 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x0a, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x52, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x65, 0x74, 0x45, 0x70, + 0x6f, 0x63, 0x68, 0x12, 0x0e, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x45, 0x70, 0x6f, 0x63, 0x68, + 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x45, 0x70, 0x6f, 0x63, 0x68, + 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x12, 0x0a, 0x2e, + 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, + 0x41, 0x74, 0x52, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, + 0x12, 0x30, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x10, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, + 0x30, 0x01, 0x12, 0x2c, 0x0a, 0x0a, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x12, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x1a, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x42, 0x04, 0x5a, 0x02, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1487,7 +1578,7 @@ func file_api_proto_rawDescGZIP() []byte { return file_api_proto_rawDescData } -var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 22) +var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 24) var file_api_proto_goTypes = []interface{}{ (*Empty)(nil), // 0: Empty (*GetStatusRes)(nil), // 1: GetStatusRes @@ -1506,11 +1597,13 @@ var file_api_proto_goTypes = []interface{}{ (*CommitRes)(nil), // 14: CommitRes (*ReadAtReq)(nil), // 15: ReadAtReq (*ReadAtRes)(nil), // 16: ReadAtRes - (*BlobInfoReq)(nil), // 17: BlobInfoReq - (*ListBlobInfoReq)(nil), // 18: ListBlobInfoReq - (*BlobInfoRes)(nil), // 19: BlobInfoRes - (*SendUpdateReq)(nil), // 20: SendUpdateReq - (*SendUpdateRes)(nil), // 21: SendUpdateRes + (*ResetEpochReq)(nil), // 17: ResetEpochReq + (*ResetEpochRes)(nil), // 18: ResetEpochRes + (*BlobInfoReq)(nil), // 19: BlobInfoReq + (*ListBlobInfoReq)(nil), // 20: ListBlobInfoReq + (*BlobInfoRes)(nil), // 21: BlobInfoRes + (*SendUpdateReq)(nil), // 22: SendUpdateReq + (*SendUpdateRes)(nil), // 23: SendUpdateRes } var file_api_proto_depIdxs = []int32{ 0, // 0: Footnotev1.GetStatus:input_type -> Empty @@ -1521,24 +1614,26 @@ var file_api_proto_depIdxs = []int32{ 9, // 5: Footnotev1.Checkout:input_type -> CheckoutReq 11, // 6: Footnotev1.WriteSector:input_type -> WriteSectorReq 13, // 7: Footnotev1.Commit:input_type -> CommitReq - 15, // 8: Footnotev1.ReadAt:input_type -> ReadAtReq - 17, // 9: Footnotev1.GetBlobInfo:input_type -> BlobInfoReq - 18, // 10: Footnotev1.ListBlobInfo:input_type -> ListBlobInfoReq - 20, // 11: Footnotev1.SendUpdate:input_type -> SendUpdateReq - 1, // 12: Footnotev1.GetStatus:output_type -> GetStatusRes - 0, // 13: Footnotev1.AddPeer:output_type -> Empty - 0, // 14: Footnotev1.BanPeer:output_type -> Empty - 0, // 15: Footnotev1.UnbanPeer:output_type -> Empty - 8, // 16: Footnotev1.ListPeers:output_type -> ListPeersRes - 10, // 17: Footnotev1.Checkout:output_type -> CheckoutRes - 12, // 18: Footnotev1.WriteSector:output_type -> WriteSectorRes - 14, // 19: Footnotev1.Commit:output_type -> CommitRes - 16, // 20: Footnotev1.ReadAt:output_type -> ReadAtRes - 19, // 21: Footnotev1.GetBlobInfo:output_type -> BlobInfoRes - 19, // 22: Footnotev1.ListBlobInfo:output_type -> BlobInfoRes - 21, // 23: Footnotev1.SendUpdate:output_type -> SendUpdateRes - 12, // [12:24] is the sub-list for method output_type - 0, // [0:12] is the sub-list for method input_type + 17, // 8: Footnotev1.ResetEpoch:input_type -> ResetEpochReq + 15, // 9: Footnotev1.ReadAt:input_type -> ReadAtReq + 19, // 10: Footnotev1.GetBlobInfo:input_type -> BlobInfoReq + 20, // 11: Footnotev1.ListBlobInfo:input_type -> ListBlobInfoReq + 22, // 12: Footnotev1.SendUpdate:input_type -> SendUpdateReq + 1, // 13: Footnotev1.GetStatus:output_type -> GetStatusRes + 0, // 14: Footnotev1.AddPeer:output_type -> Empty + 0, // 15: Footnotev1.BanPeer:output_type -> Empty + 0, // 16: Footnotev1.UnbanPeer:output_type -> Empty + 8, // 17: Footnotev1.ListPeers:output_type -> ListPeersRes + 10, // 18: Footnotev1.Checkout:output_type -> CheckoutRes + 12, // 19: Footnotev1.WriteSector:output_type -> WriteSectorRes + 14, // 20: Footnotev1.Commit:output_type -> CommitRes + 18, // 21: Footnotev1.ResetEpoch:output_type -> ResetEpochRes + 16, // 22: Footnotev1.ReadAt:output_type -> ReadAtRes + 21, // 23: Footnotev1.GetBlobInfo:output_type -> BlobInfoRes + 21, // 24: Footnotev1.ListBlobInfo:output_type -> BlobInfoRes + 23, // 25: Footnotev1.SendUpdate:output_type -> SendUpdateRes + 13, // [13:26] is the sub-list for method output_type + 0, // [0:13] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name @@ -1755,7 +1850,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BlobInfoReq); i { + switch v := v.(*ResetEpochReq); i { case 0: return &v.state case 1: @@ -1767,7 +1862,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListBlobInfoReq); i { + switch v := v.(*ResetEpochRes); i { case 0: return &v.state case 1: @@ -1779,7 +1874,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BlobInfoRes); i { + switch v := v.(*BlobInfoReq); i { case 0: return &v.state case 1: @@ -1791,7 +1886,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendUpdateReq); i { + switch v := v.(*ListBlobInfoReq); i { case 0: return &v.state case 1: @@ -1803,6 +1898,30 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BlobInfoRes); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendUpdateReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SendUpdateRes); i { case 0: return &v.state @@ -1821,7 +1940,7 @@ func file_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_proto_rawDesc, NumEnums: 0, - NumMessages: 22, + NumMessages: 24, NumExtensions: 0, NumServices: 1, }, @@ -1855,6 +1974,7 @@ type Footnotev1Client interface { Checkout(ctx context.Context, in *CheckoutReq, opts ...grpc.CallOption) (*CheckoutRes, error) WriteSector(ctx context.Context, in *WriteSectorReq, opts ...grpc.CallOption) (*WriteSectorRes, error) Commit(ctx context.Context, in *CommitReq, opts ...grpc.CallOption) (*CommitRes, error) + ResetEpoch(ctx context.Context, in *ResetEpochReq, opts ...grpc.CallOption) (*ResetEpochRes, error) ReadAt(ctx context.Context, in *ReadAtReq, opts ...grpc.CallOption) (*ReadAtRes, error) GetBlobInfo(ctx context.Context, in *BlobInfoReq, opts ...grpc.CallOption) (*BlobInfoRes, error) ListBlobInfo(ctx context.Context, in *ListBlobInfoReq, opts ...grpc.CallOption) (Footnotev1_ListBlobInfoClient, error) @@ -1964,6 +2084,15 @@ func (c *footnotev1Client) Commit(ctx context.Context, in *CommitReq, opts ...gr return out, nil } +func (c *footnotev1Client) ResetEpoch(ctx context.Context, in *ResetEpochReq, opts ...grpc.CallOption) (*ResetEpochRes, error) { + out := new(ResetEpochRes) + err := c.cc.Invoke(ctx, "/Footnotev1/ResetEpoch", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *footnotev1Client) ReadAt(ctx context.Context, in *ReadAtReq, opts ...grpc.CallOption) (*ReadAtRes, error) { out := new(ReadAtRes) err := c.cc.Invoke(ctx, "/Footnotev1/ReadAt", in, out, opts...) @@ -2033,6 +2162,7 @@ type Footnotev1Server interface { Checkout(context.Context, *CheckoutReq) (*CheckoutRes, error) WriteSector(context.Context, *WriteSectorReq) (*WriteSectorRes, error) Commit(context.Context, *CommitReq) (*CommitRes, error) + ResetEpoch(context.Context, *ResetEpochReq) (*ResetEpochRes, error) ReadAt(context.Context, *ReadAtReq) (*ReadAtRes, error) GetBlobInfo(context.Context, *BlobInfoReq) (*BlobInfoRes, error) ListBlobInfo(*ListBlobInfoReq, Footnotev1_ListBlobInfoServer) error @@ -2067,6 +2197,9 @@ func (*UnimplementedFootnotev1Server) WriteSector(context.Context, *WriteSectorR func (*UnimplementedFootnotev1Server) Commit(context.Context, *CommitReq) (*CommitRes, error) { return nil, status.Errorf(codes.Unimplemented, "method Commit not implemented") } +func (*UnimplementedFootnotev1Server) ResetEpoch(context.Context, *ResetEpochReq) (*ResetEpochRes, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResetEpoch not implemented") +} func (*UnimplementedFootnotev1Server) ReadAt(context.Context, *ReadAtReq) (*ReadAtRes, error) { return nil, status.Errorf(codes.Unimplemented, "method ReadAt not implemented") } @@ -2231,6 +2364,24 @@ func _Footnotev1_Commit_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Footnotev1_ResetEpoch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResetEpochReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(Footnotev1Server).ResetEpoch(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Footnotev1/ResetEpoch", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(Footnotev1Server).ResetEpoch(ctx, req.(*ResetEpochReq)) + } + return interceptor(ctx, in, info, handler) +} + func _Footnotev1_ReadAt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ReadAtReq) if err := dec(in); err != nil { @@ -2338,6 +2489,10 @@ var _Footnotev1_serviceDesc = grpc.ServiceDesc{ MethodName: "Commit", Handler: _Footnotev1_Commit_Handler, }, + { + MethodName: "ResetEpoch", + Handler: _Footnotev1_ResetEpoch_Handler, + }, { MethodName: "ReadAt", Handler: _Footnotev1_ReadAt_Handler, diff --git a/rpc/v1/api.proto b/rpc/v1/api.proto index 522f4bf..fab0d4d 100644 --- a/rpc/v1/api.proto +++ b/rpc/v1/api.proto @@ -12,9 +12,11 @@ service Footnotev1 { rpc Checkout (CheckoutReq) returns (CheckoutRes); rpc WriteSector (WriteSectorReq) returns (WriteSectorRes); rpc Commit (CommitReq) returns (CommitRes); + rpc ResetEpoch(ResetEpochReq) returns (ResetEpochRes); rpc ReadAt (ReadAtReq) returns (ReadAtRes); + rpc GetBlobInfo (BlobInfoReq) returns (BlobInfoRes); rpc ListBlobInfo (ListBlobInfoReq) returns (stream BlobInfoRes); @@ -114,6 +116,13 @@ message ReadAtRes { bytes data = 2; } +message ResetEpochReq { + string name = 1; +} + +message ResetEpochRes { +} + message BlobInfoReq { string name = 1; } From 408b867be22aa7ca32719c5716ef3de3adf58f9e Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Fri, 19 Feb 2021 12:13:08 +0530 Subject: [PATCH 32/71] rpc: implement reset epoch; reset blob --- blob/store.go | 29 +++++++++++++++++++++++++++++ cmd/fnd-cli/cmd/blob/write.go | 8 ++++---- rpc/server.go | 25 +++++++++++++++++++++++++ rpc/v1/api.pb.go | 16 ++++++++-------- rpc/v1/api.proto | 2 +- 5 files changed, 67 insertions(+), 13 deletions(-) diff --git a/blob/store.go b/blob/store.go index cf609f9..5ac1ed7 100644 --- a/blob/store.go +++ b/blob/store.go @@ -10,6 +10,7 @@ import ( type Store interface { Open(name string) (Blob, error) Exists(name string) (bool, error) + Reset(name string) error } type storeImpl struct { @@ -42,6 +43,34 @@ func (s *storeImpl) Exists(name string) (bool, error) { return fileExists(path.Join(s.blobsPath, PathifyName(name))) } +func (s *storeImpl) Reset(name string) error { + blobSubpath := PathifyName(name) + blobFile := path.Join(s.blobsPath, blobSubpath) + exists, err := fileExists(blobFile) + var f *os.File + if err != nil { + return err + } + if !exists { + return nil + } + err = os.Remove(path.Join(s.blobsPath, PathifyName(name))) + if err != nil { + return err + } + if err := os.MkdirAll(filepath.Dir(blobFile), 0700); err != nil { + return err + } + f, err = os.OpenFile(blobFile, os.O_RDWR|os.O_CREATE, 0666) + if err != nil { + return err + } + if err := f.Truncate(Size); err != nil { + return err + } + return nil +} + func NewInStorePath(blobsPath string, name string) (Blob, error) { blobSubpath := PathifyName(name) blobFile := path.Join(blobsPath, blobSubpath) diff --git a/cmd/fnd-cli/cmd/blob/write.go b/cmd/fnd-cli/cmd/blob/write.go index 6505de7..62fed7b 100644 --- a/cmd/fnd-cli/cmd/blob/write.go +++ b/cmd/fnd-cli/cmd/blob/write.go @@ -46,16 +46,16 @@ var writeCmd = &cobra.Command{ wr := rpc.NewBlobWriter(apiv1.NewFootnotev1Client(conn), signer, name) - if err := wr.Open(); err != nil { - return err - } - if resetEpoch { if err := wr.Reset(); err != nil { return err } } + if err := wr.Open(); err != nil { + return err + } + var rd io.Reader if len(args) < 2 { if isatty.IsTerminal(os.Stdin.Fd()) { diff --git a/rpc/server.go b/rpc/server.go index 214624e..a7e7161 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -357,6 +357,31 @@ func (s *Server) Commit(ctx context.Context, req *apiv1.CommitReq) (*apiv1.Commi func (s *Server) ResetEpoch(ctx context.Context, req *apiv1.ResetEpochReq) (*apiv1.ResetEpochRes, error) { // TODO: implement epoch reset + id := strconv.FormatUint(uint64(req.TxID), 32) + awaiting := s.txStore.Get(id).(*awaitingTx) + if awaiting == nil { + return nil, errors.New("transaction ID not found") + } + + tx := awaiting.tx + name := tx.Name() + header, err := store.GetHeader(s.db, name) + if err != nil { + return nil, err + } + + if header.EpochHeight >= protocol.CurrentEpoch(name) { + return nil, errors.New("cannot reset epoch ahead of schedule") + } + + if err := s.bs.Reset(name); err != nil { + return nil, err + } + + if err := store.TruncateHeaderName(s.db, name); err != nil { + return nil, err + } + return &apiv1.ResetEpochRes{}, nil } diff --git a/rpc/v1/api.pb.go b/rpc/v1/api.pb.go index adce7af..400a323 100644 --- a/rpc/v1/api.pb.go +++ b/rpc/v1/api.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.6.1 +// protoc-gen-go v1.25.0-devel +// protoc v3.12.4 // source: api.proto package v1 @@ -1030,7 +1030,7 @@ type ResetEpochReq struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + TxID uint32 `protobuf:"varint,1,opt,name=txID,proto3" json:"txID,omitempty"` } func (x *ResetEpochReq) Reset() { @@ -1065,11 +1065,11 @@ func (*ResetEpochReq) Descriptor() ([]byte, []int) { return file_api_proto_rawDescGZIP(), []int{17} } -func (x *ResetEpochReq) GetName() string { +func (x *ResetEpochReq) GetTxID() uint32 { if x != nil { - return x.Name + return x.TxID } - return "" + return 0 } type ResetEpochRes struct { @@ -1497,8 +1497,8 @@ var file_api_proto_rawDesc = []byte{ 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x23, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x65, 0x74, 0x45, - 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x52, + 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x49, 0x44, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x78, 0x49, 0x44, 0x22, 0x0f, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x65, 0x74, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x73, 0x22, 0x21, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, diff --git a/rpc/v1/api.proto b/rpc/v1/api.proto index fab0d4d..acba295 100644 --- a/rpc/v1/api.proto +++ b/rpc/v1/api.proto @@ -117,7 +117,7 @@ message ReadAtRes { } message ResetEpochReq { - string name = 1; + uint32 txID = 1; } message ResetEpochRes { From 30021f526c3e7d8e666e3ca2d95774283a605a69 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Fri, 19 Feb 2021 12:18:31 +0530 Subject: [PATCH 33/71] rpc: blob writer - use reset epoch --- rpc/blob_writer.go | 5 ++++- rpc/server.go | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/rpc/blob_writer.go b/rpc/blob_writer.go index e79161d..8fbd59e 100644 --- a/rpc/blob_writer.go +++ b/rpc/blob_writer.go @@ -83,7 +83,10 @@ func (b *BlobWriter) WriteSector(p []byte) (crypto.Hash, error) { } func (b *BlobWriter) Reset() error { - return nil + _, err := b.client.ResetEpoch(context.Background(), &apiv1.ResetEpochReq{ + TxID: b.txID, + }) + return err } func (b *BlobWriter) Commit(broadcast bool) (crypto.Hash, error) { diff --git a/rpc/server.go b/rpc/server.go index a7e7161..8d17895 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -356,7 +356,6 @@ func (s *Server) Commit(ctx context.Context, req *apiv1.CommitReq) (*apiv1.Commi } func (s *Server) ResetEpoch(ctx context.Context, req *apiv1.ResetEpochReq) (*apiv1.ResetEpochRes, error) { - // TODO: implement epoch reset id := strconv.FormatUint(uint64(req.TxID), 32) awaiting := s.txStore.Get(id).(*awaitingTx) if awaiting == nil { From d2039fe2ae6e2b6b4f5f70a79187c8df2e721dcc Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Fri, 19 Feb 2021 12:47:26 +0530 Subject: [PATCH 34/71] WIP: move signature from update to blob_res --- protocol/syncer.go | 28 ++++++++++++++++++++++++ protocol/update_queue.go | 46 +++++++-------------------------------- protocol/update_server.go | 8 +++---- protocol/updater.go | 7 +++--- rpc/server.go | 16 +++++--------- wire/blob_res.go | 7 +++++- wire/update.go | 23 +++++--------------- 7 files changed, 60 insertions(+), 75 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index 57a5e90..c665d57 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -9,6 +9,7 @@ import ( "fnd/wire" "time" + "fnd.localhost/handshake/primitives" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" ) @@ -40,6 +41,28 @@ type payloadRes struct { msg *wire.BlobRes } +func validateBlobRes(opts *SyncSectorsOpts, name string, epochHeight, sectorSize uint16, mr crypto.Hash, rr crypto.Hash, sig crypto.Signature) (*store.NameInfo, error) { + if err := primitives.ValidateName(name); err != nil { + return nil, errors.Wrap(err, "update name is invalid") + } + banned, err := store.NameIsBanned(opts.DB, name) + if err != nil { + return nil, errors.Wrap(err, "error reading name ban state") + } + if banned { + return nil, errors.New("name is banned") + } + info, err := store.GetNameInfo(opts.DB, name) + if err != nil { + return nil, errors.Wrap(err, "error reading name info") + } + h := blob.SealHash(name, epochHeight, sectorSize, mr, rr) + if !crypto.VerifySigPub(info.PublicKey, sig, h) { + return nil, errors.New("update signature is invalid") + } + return info, nil +} + func SyncSectors(opts *SyncSectorsOpts) error { lgr := log.WithModule("payload-syncer").Sub("name", opts.Name) payloadResCh := make(chan *payloadRes) @@ -101,6 +124,11 @@ func SyncSectors(opts *SyncSectorsOpts) error { for i := 0; int(i) < len(msg.Payload); i++ { sectorTipHash = blob.SerialHashSector(msg.Payload[i], sectorTipHash) } + if err := validateBlobRes(opts, msg.Name, opts.EpochHeight, opts.SectorSize, sectorTipHash, msg.ReservedRoot, msg.Signature); err != nil { + lgr.Trace("blob res validation failed", err) + continue + } + // FIXME: opts.SectorTipHash was being set from update.SectorTipHash, now that it's removed, the condition on the next line always fails if sectorTipHash != opts.SectorTipHash { lgr.Trace("payload tip hash mismatch", "payload_tip_hash", sectorTipHash, "expected_payload_tip_hash", opts.SectorTipHash) err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { diff --git a/protocol/update_queue.go b/protocol/update_queue.go index 02074ce..7fd95aa 100644 --- a/protocol/update_queue.go +++ b/protocol/update_queue.go @@ -1,7 +1,6 @@ package protocol import ( - "fnd/blob" "fnd/config" "fnd/crypto" "fnd/log" @@ -12,7 +11,6 @@ import ( "sync/atomic" "time" - "fnd.localhost/handshake/primitives" "github.com/btcsuite/btcd/btcec" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" @@ -101,9 +99,9 @@ func (u *UpdateQueue) Enqueue(peerID crypto.Hash, update *wire.Update) error { return ErrInitialImportIncomplete } - nameInfo, err := u.validateUpdate(update.Name, update.EpochHeight, update.SectorSize, update.SectorTipHash, update.ReservedRoot, update.Signature) + nameInfo, err := store.GetNameInfo(u.db, update.Name) if err != nil { - return errors.Wrap(err, "name failed validation") + return errors.Wrap(err, "error getting name info") } // FIXME: epochHeight? @@ -126,15 +124,12 @@ func (u *UpdateQueue) Enqueue(peerID crypto.Hash, update *wire.Update) error { entry := u.entries[update.Name] if entry == nil || entry.SectorSize < update.SectorSize { u.entries[update.Name] = &UpdateQueueItem{ - PeerIDs: NewPeerSet([]crypto.Hash{peerID}), - Name: update.Name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: nameInfo.PublicKey, - Height: nameInfo.ImportHeight, + PeerIDs: NewPeerSet([]crypto.Hash{peerID}), + Name: update.Name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + Pub: nameInfo.PublicKey, + Height: nameInfo.ImportHeight, } if entry == nil { @@ -148,9 +143,6 @@ func (u *UpdateQueue) Enqueue(peerID crypto.Hash, update *wire.Update) error { if entry.SectorSize > update.SectorSize { return ErrUpdateQueueStaleSector } - if entry.Signature != update.Signature { - return ErrUpdateQueueSpltBrain - } u.lgr.Info("enqueued update", "name", update.Name, "epoch", update.EpochHeight, "sector", update.SectorSize) entry.PeerIDs.Add(peerID) @@ -172,28 +164,6 @@ func (u *UpdateQueue) Dequeue() *UpdateQueueItem { return ret } -func (u *UpdateQueue) validateUpdate(name string, epochHeight, sectorSize uint16, mr crypto.Hash, rr crypto.Hash, sig crypto.Signature) (*store.NameInfo, error) { - if err := primitives.ValidateName(name); err != nil { - return nil, errors.Wrap(err, "update name is invalid") - } - banned, err := store.NameIsBanned(u.db, name) - if err != nil { - return nil, errors.Wrap(err, "error reading name ban state") - } - if banned { - return nil, errors.New("name is banned") - } - info, err := store.GetNameInfo(u.db, name) - if err != nil { - return nil, errors.Wrap(err, "error reading name info") - } - h := blob.SealHash(name, epochHeight, sectorSize, mr, rr) - if !crypto.VerifySigPub(info.PublicKey, sig, h) { - return nil, errors.New("update signature is invalid") - } - return info, nil -} - func (u *UpdateQueue) onUpdate(peerID crypto.Hash, envelope *wire.Envelope) { update := envelope.Message.(*wire.Update) if err := u.Enqueue(peerID, update); err != nil { diff --git a/protocol/update_server.go b/protocol/update_server.go index 4f22df4..9178480 100644 --- a/protocol/update_server.go +++ b/protocol/update_server.go @@ -80,11 +80,9 @@ func (u *UpdateServer) UpdateReqHandler(peerID crypto.Hash, envelope *wire.Envel } err = u.mux.Send(peerID, &wire.Update{ - Name: msg.Name, - EpochHeight: header.EpochHeight, - SectorSize: header.SectorSize, - SectorTipHash: header.SectorTipHash, - Signature: header.Signature, + Name: msg.Name, + EpochHeight: header.EpochHeight, + SectorSize: header.SectorSize, }) if err != nil { u.lgr.Error("error serving update", "name", msg.Name, "err", err) diff --git a/protocol/updater.go b/protocol/updater.go index b82be4f..db3c038 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -305,10 +305,9 @@ func UpdateBlob(cfg *UpdateConfig) error { } update := &wire.Update{ - Name: item.Name, - EpochHeight: item.EpochHeight, - SectorSize: item.SectorSize, - SectorTipHash: item.SectorTipHash, + Name: item.Name, + EpochHeight: item.EpochHeight, + SectorSize: item.SectorSize, } p2p.GossipAll(cfg.Mux, update) return nil diff --git a/rpc/server.go b/rpc/server.go index 8d17895..32bfe20 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -343,11 +343,9 @@ func (s *Server) Commit(ctx context.Context, req *apiv1.CommitReq) (*apiv1.Commi var recips []crypto.Hash if req.Broadcast { recips, _ = p2p.GossipAll(s.mux, &wire.Update{ - Name: name, - EpochHeight: epochHeight, - SectorSize: sectorSize, - SectorTipHash: sectorTipHash, - Signature: sig, + Name: name, + EpochHeight: epochHeight, + SectorSize: sectorSize, }) } s.lgr.Info("committed blob", "name", name, "recipient_count", len(recips)) @@ -480,11 +478,9 @@ func (s *Server) SendUpdate(_ context.Context, req *apiv1.SendUpdateReq) (*apiv1 } recips, _ := p2p.GossipAll(s.mux, &wire.Update{ - Name: req.Name, - EpochHeight: header.EpochHeight, - SectorSize: header.SectorSize, - SectorTipHash: header.SectorTipHash, - Signature: header.Signature, + Name: req.Name, + EpochHeight: header.EpochHeight, + SectorSize: header.SectorSize, }) return &apiv1.SendUpdateRes{ diff --git a/wire/blob_res.go b/wire/blob_res.go index eaa0258..16371bc 100644 --- a/wire/blob_res.go +++ b/wire/blob_res.go @@ -5,6 +5,7 @@ import ( "fnd/blob" "fnd/crypto" + "fnd.localhost/dwire" ) @@ -17,6 +18,7 @@ type BlobRes struct { PrevHash crypto.Hash ReservedRoot crypto.Hash Payload []blob.Sector + Signature crypto.Signature } var _ Message = (*BlobRes)(nil) @@ -35,7 +37,8 @@ func (s *BlobRes) Equals(other Message) bool { s.EpochHeight == cast.EpochHeight && s.PayloadPosition == cast.PayloadPosition && s.PrevHash == cast.PrevHash && - s.ReservedRoot == cast.ReservedRoot + s.ReservedRoot == cast.ReservedRoot && + s.Signature == cast.Signature } func (s *BlobRes) Encode(w io.Writer) error { @@ -47,6 +50,7 @@ func (s *BlobRes) Encode(w io.Writer) error { s.PrevHash, s.ReservedRoot, s.Payload, + s.Signature, ) } @@ -59,6 +63,7 @@ func (s *BlobRes) Decode(r io.Reader) error { &s.PrevHash, &s.ReservedRoot, &s.Payload, + &s.Signature, ) } diff --git a/wire/update.go b/wire/update.go index 9f01281..2cf670e 100644 --- a/wire/update.go +++ b/wire/update.go @@ -2,19 +2,17 @@ package wire import ( "fnd/crypto" - "fnd.localhost/dwire" "io" + + "fnd.localhost/dwire" ) type Update struct { HashCacher - Name string - EpochHeight uint16 - SectorSize uint16 - SectorTipHash crypto.Hash - ReservedRoot crypto.Hash - Signature crypto.Signature + Name string + EpochHeight uint16 + SectorSize uint16 } var _ Message = (*Update)(nil) @@ -31,10 +29,7 @@ func (u *Update) Equals(other Message) bool { return u.Name == cast.Name && u.EpochHeight == cast.EpochHeight && - u.SectorSize == cast.SectorSize && - u.SectorTipHash == cast.SectorTipHash && - u.ReservedRoot == cast.ReservedRoot && - u.Signature == cast.Signature + u.SectorSize == cast.SectorSize } func (u *Update) Encode(w io.Writer) error { @@ -43,9 +38,6 @@ func (u *Update) Encode(w io.Writer) error { u.Name, u.EpochHeight, u.SectorSize, - u.SectorTipHash, - u.ReservedRoot, - u.Signature, ) } @@ -55,9 +47,6 @@ func (u *Update) Decode(r io.Reader) error { &u.Name, &u.EpochHeight, &u.SectorSize, - &u.SectorTipHash, - &u.ReservedRoot, - &u.Signature, ) } From 4199a91a30a67960a9f617957d871cc7e53c6188 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Fri, 19 Feb 2021 16:59:49 +0530 Subject: [PATCH 35/71] WIP: validate blob res signature - TODO fix tests signature validation was moved from update to blob res signature covers all the update item like sector tip hash, sector size, epoch height, reserved root. With the new approach, the sector tip hash is recomputed, then signature is validated. Same with sector size, it's recomputed as payload position + len(payload). Ideally, all information in the blob res is enough to validate itself. i.e. prev hash, payload pos, payload. tests are failing because updater does not expect to sign over all the data in blob res. sector server needs to be updated to serve a valid signature. --- protocol/sector_server.go | 10 +-- protocol/syncer.go | 57 ++++++++--------- protocol/update_queue.go | 19 ++++++ protocol/update_queue_test.go | 69 ++++---------------- protocol/update_server_test.go | 13 ++-- protocol/updater.go | 40 ++++-------- protocol/updater_test.go | 112 ++++++++++++++------------------- testutil/mockapp/storage.go | 14 ++--- wire/blob_res_test.go | 1 + wire/testdata/blob_res | Bin 79 -> 144 bytes wire/testdata/update | Bin 142 -> 13 bytes wire/update_test.go | 9 +-- 12 files changed, 137 insertions(+), 207 deletions(-) diff --git a/protocol/sector_server.go b/protocol/sector_server.go index 30a62b1..062041b 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -10,8 +10,9 @@ import ( "fnd/store" "fnd/util" "fnd/wire" - "github.com/syndtr/goleveldb/leveldb" "time" + + "github.com/syndtr/goleveldb/leveldb" ) type SectorServer struct { @@ -81,7 +82,7 @@ func (s *SectorServer) onBlobReq(peerID crypto.Hash, envelope *wire.Envelope) { cached := s.cache.Get(cacheKey) if cached != nil { s.nameLocker.RUnlock(reqMsg.Name) - s.sendResponse(peerID, reqMsg.Name, prevHash, cached.([]blob.Sector), reqMsg.EpochHeight, reqMsg.SectorSize) + s.sendResponse(peerID, reqMsg.Name, prevHash, cached.([]blob.Sector), header.EpochHeight, reqMsg.SectorSize, header.Signature) return } @@ -115,16 +116,17 @@ func (s *SectorServer) onBlobReq(peerID crypto.Hash, envelope *wire.Envelope) { } s.cache.Set(cacheKey, sectors, int64(s.CacheExpiry/time.Millisecond)) s.nameLocker.RUnlock(reqMsg.Name) - s.sendResponse(peerID, reqMsg.Name, prevHash, sectors, reqMsg.EpochHeight, reqMsg.SectorSize) + s.sendResponse(peerID, reqMsg.Name, prevHash, sectors, header.EpochHeight, reqMsg.SectorSize, header.Signature) } -func (s *SectorServer) sendResponse(peerID crypto.Hash, name string, prevHash crypto.Hash, sectors []blob.Sector, epochHeight, sectorSize uint16) { +func (s *SectorServer) sendResponse(peerID crypto.Hash, name string, prevHash crypto.Hash, sectors []blob.Sector, epochHeight, sectorSize uint16, signature crypto.Signature) { resMsg := &wire.BlobRes{ Name: name, EpochHeight: epochHeight, PayloadPosition: sectorSize, PrevHash: prevHash, Payload: sectors, + Signature: signature, } if err := s.mux.Send(peerID, resMsg); err != nil { s.lgr.Error("error serving sector response", "err", err) diff --git a/protocol/syncer.go b/protocol/syncer.go index c665d57..062b79c 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -24,16 +24,15 @@ var ( ) type SyncSectorsOpts struct { - Timeout time.Duration - Mux *p2p.PeerMuxer - Tx blob.Transaction - Peers *PeerSet - EpochHeight uint16 - SectorSize uint16 - PrevHash crypto.Hash - SectorTipHash crypto.Hash - Name string - DB *leveldb.DB + Timeout time.Duration + Mux *p2p.PeerMuxer + Tx blob.Transaction + Peers *PeerSet + EpochHeight uint16 + SectorSize uint16 + PrevHash crypto.Hash + Name string + DB *leveldb.DB } type payloadRes struct { @@ -41,26 +40,26 @@ type payloadRes struct { msg *wire.BlobRes } -func validateBlobRes(opts *SyncSectorsOpts, name string, epochHeight, sectorSize uint16, mr crypto.Hash, rr crypto.Hash, sig crypto.Signature) (*store.NameInfo, error) { +func validateBlobRes(opts *SyncSectorsOpts, name string, epochHeight, sectorSize uint16, mr crypto.Hash, rr crypto.Hash, sig crypto.Signature) error { if err := primitives.ValidateName(name); err != nil { - return nil, errors.Wrap(err, "update name is invalid") + return errors.Wrap(err, "update name is invalid") } banned, err := store.NameIsBanned(opts.DB, name) if err != nil { - return nil, errors.Wrap(err, "error reading name ban state") + return errors.Wrap(err, "error reading name ban state") } if banned { - return nil, errors.New("name is banned") + return errors.New("name is banned") } info, err := store.GetNameInfo(opts.DB, name) if err != nil { - return nil, errors.Wrap(err, "error reading name info") + return errors.Wrap(err, "error reading name info") } h := blob.SealHash(name, epochHeight, sectorSize, mr, rr) if !crypto.VerifySigPub(info.PublicKey, sig, h) { - return nil, errors.New("update signature is invalid") + return errors.New("update signature is invalid") } - return info, nil + return nil } func SyncSectors(opts *SyncSectorsOpts) error { @@ -115,30 +114,24 @@ func SyncSectors(opts *SyncSectorsOpts) error { lgr.Trace("already processed this payload", "payload_position", msg.PayloadPosition, "peer_id", peerID) continue } - // TODO: if payloadposition = 0xff, handle equivocation proof if opts.SectorSize != msg.PayloadPosition { - lgr.Trace("received unexpected payload position", "payload_size", opts.SectorSize, "payload_position", msg.PayloadPosition) + lgr.Trace("received unexpected payload position", "sector_size", opts.SectorSize, "payload_position", msg.PayloadPosition) + continue + } + sectorSize := msg.PayloadPosition + uint16(len(msg.Payload)) + if int(sectorSize) > blob.Size { + lgr.Trace("received unexpected payload size", "sector_size", sectorSize) continue } var sectorTipHash crypto.Hash = opts.PrevHash for i := 0; int(i) < len(msg.Payload); i++ { sectorTipHash = blob.SerialHashSector(msg.Payload[i], sectorTipHash) } - if err := validateBlobRes(opts, msg.Name, opts.EpochHeight, opts.SectorSize, sectorTipHash, msg.ReservedRoot, msg.Signature); err != nil { - lgr.Trace("blob res validation failed", err) + if err := validateBlobRes(opts, msg.Name, msg.EpochHeight, sectorSize, sectorTipHash, msg.ReservedRoot, msg.Signature); err != nil { + lgr.Trace("blob res validation failed", "err", err) + // TODO: probably drop this peer, it's sending clearly invalid data continue } - // FIXME: opts.SectorTipHash was being set from update.SectorTipHash, now that it's removed, the condition on the next line always fails - if sectorTipHash != opts.SectorTipHash { - lgr.Trace("payload tip hash mismatch", "payload_tip_hash", sectorTipHash, "expected_payload_tip_hash", opts.SectorTipHash) - err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { - return store.SetEquivocationProofTx(tx, msg.Name, &wire.EquivocationProof{}) - }) - if err != nil { - lgr.Error("failed to write equivocation proof", "err", err) - } - return - } for i := 0; int(i) < len(msg.Payload); i++ { if err := opts.Tx.WriteSector(msg.Payload[i]); err != nil { lgr.Error("failed to write payload", "payload_id", i, "err", err) diff --git a/protocol/update_queue.go b/protocol/update_queue.go index 7fd95aa..dcdb573 100644 --- a/protocol/update_queue.go +++ b/protocol/update_queue.go @@ -11,6 +11,7 @@ import ( "sync/atomic" "time" + "fnd.localhost/handshake/primitives" "github.com/btcsuite/btcd/btcec" "github.com/pkg/errors" "github.com/syndtr/goleveldb/leveldb" @@ -99,6 +100,10 @@ func (u *UpdateQueue) Enqueue(peerID crypto.Hash, update *wire.Update) error { return ErrInitialImportIncomplete } + if err := u.validateUpdate(update.Name); err != nil { + return err + } + nameInfo, err := store.GetNameInfo(u.db, update.Name) if err != nil { return errors.Wrap(err, "error getting name info") @@ -171,6 +176,20 @@ func (u *UpdateQueue) onUpdate(peerID crypto.Hash, envelope *wire.Envelope) { } } +func (u *UpdateQueue) validateUpdate(name string) error { + if err := primitives.ValidateName(name); err != nil { + return errors.Wrap(err, "update name is invalid") + } + banned, err := store.NameIsBanned(u.db, name) + if err != nil { + return errors.Wrap(err, "error reading name ban state") + } + if banned { + return errors.New("name is banned") + } + return nil +} + func (u *UpdateQueue) reapDequeuedUpdates() { u.mu.Lock() defer u.mu.Unlock() diff --git a/protocol/update_queue_test.go b/protocol/update_queue_test.go index 3add1e1..bb87fe8 100644 --- a/protocol/update_queue_test.go +++ b/protocol/update_queue_test.go @@ -8,10 +8,11 @@ import ( "fnd/testutil" "fnd/testutil/testcrypto" "fnd/wire" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" "testing" "time" + + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" ) func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { @@ -88,47 +89,17 @@ func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { require.Contains(t, err.Error(), "name is banned") }, }, - { - "bad signature", - &wire.Update{ - Name: identicalHeader.Name, - EpochHeight: identicalHeader.EpochHeight, - SectorSize: identicalHeader.SectorSize + 10, - SectorTipHash: identicalHeader.SectorTipHash, - ReservedRoot: identicalHeader.ReservedRoot, - Signature: identicalHeader.Signature, - }, - func(t *testing.T, err error) { - require.Contains(t, err.Error(), "signature is invalid") - }, - }, { "identical", &wire.Update{ - Name: identicalHeader.Name, - EpochHeight: identicalHeader.EpochHeight, - SectorSize: identicalHeader.SectorSize, - SectorTipHash: identicalHeader.SectorTipHash, - ReservedRoot: identicalHeader.ReservedRoot, - Signature: identicalHeader.Signature, + Name: identicalHeader.Name, + EpochHeight: identicalHeader.EpochHeight, + SectorSize: identicalHeader.SectorSize, }, func(t *testing.T, err error) { require.Equal(t, ErrUpdateQueueSectorUpdated, err) }, }, - { - "stale", - signUpdate(t, &wire.Update{ - Name: staleHeader.Name, - EpochHeight: staleHeader.EpochHeight, - SectorSize: staleHeader.SectorSize - 10, - SectorTipHash: throttledHeader.SectorTipHash, - ReservedRoot: identicalHeader.ReservedRoot, - }), - func(t *testing.T, err error) { - require.Equal(t, ErrUpdateQueueStaleSector, err) - }, - }, } queue := NewUpdateQueue(p2p.NewPeerMuxer(testutil.TestMagic, testcrypto.FixedSigner(t)), db) for _, inv := range invalid { @@ -164,22 +135,16 @@ func TestUpdateQueue_Enqueue_InvalidAfterEnqueue(t *testing.T) { })) queue := NewUpdateQueue(p2p.NewPeerMuxer(testutil.TestMagic, testcrypto.FixedSigner(t)), db) - require.NoError(t, queue.Enqueue(crypto.Rand32(), signUpdate(t, &wire.Update{ + require.NoError(t, queue.Enqueue(crypto.Rand32(), &wire.Update{ Name: header.Name, EpochHeight: header.EpochHeight, SectorSize: header.SectorSize + 1, - }))) - require.Equal(t, ErrUpdateQueueStaleSector, queue.Enqueue(crypto.Rand32(), signUpdate(t, &wire.Update{ + })) + require.Equal(t, ErrUpdateQueueStaleSector, queue.Enqueue(crypto.Rand32(), &wire.Update{ Name: header.Name, EpochHeight: header.EpochHeight, SectorSize: header.SectorSize - 10, - }))) - require.Equal(t, ErrUpdateQueueSpltBrain, queue.Enqueue(crypto.Rand32(), signUpdate(t, &wire.Update{ - Name: header.Name, - EpochHeight: header.EpochHeight, - SectorSize: header.SectorSize + 1, - SectorTipHash: crypto.Rand32(), - }))) + })) } func TestUpdateQueue_EnqueueDequeue(t *testing.T) { @@ -212,11 +177,11 @@ func TestUpdateQueue_EnqueueDequeue(t *testing.T) { crypto.Rand32(), } queue := NewUpdateQueue(p2p.NewPeerMuxer(testutil.TestMagic, testcrypto.FixedSigner(t)), db) - update := signUpdate(t, &wire.Update{ + update := &wire.Update{ Name: header.Name, EpochHeight: header.EpochHeight, SectorSize: header.SectorSize + 1, - }) + } for _, pid := range pids { require.NoError(t, queue.Enqueue(pid, update)) } @@ -228,9 +193,6 @@ func TestUpdateQueue_EnqueueDequeue(t *testing.T) { require.Equal(t, update.Name, item.Name) require.Equal(t, update.EpochHeight, item.EpochHeight) require.Equal(t, update.SectorSize, item.SectorSize) - require.Equal(t, update.SectorTipHash, item.SectorTipHash) - require.Equal(t, update.ReservedRoot, item.ReservedRoot) - require.Equal(t, update.Signature, item.Signature) require.True(t, pub.IsEqual(item.Pub)) require.Equal(t, 10, item.Height) } @@ -241,10 +203,3 @@ func signHeader(t *testing.T, header *store.Header) *store.Header { header.Signature = sig return header } - -func signUpdate(t *testing.T, update *wire.Update) *wire.Update { - sig, err := blob.SignSeal(testcrypto.FixedSigner(t), update.Name, update.EpochHeight, update.SectorSize, update.SectorTipHash, update.ReservedRoot) - require.NoError(t, err) - update.Signature = sig - return update -} diff --git a/protocol/update_server_test.go b/protocol/update_server_test.go index 37385e8..3a00131 100644 --- a/protocol/update_server_test.go +++ b/protocol/update_server_test.go @@ -9,10 +9,11 @@ import ( "fnd/testutil/testcrypto" "fnd/util" "fnd/wire" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" "io" "testing" + + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" ) func TestUpdateServer(t *testing.T) { @@ -130,11 +131,9 @@ func TestUpdateServer(t *testing.T) { require.NoError(t, err) envelope := testutil.ReceiveEnvelope(t, clientConn) require.EqualValues(t, &wire.Update{ - Name: header.Name, - EpochHeight: header.EpochHeight, - SectorSize: header.SectorSize, - SectorTipHash: header.SectorTipHash, - Signature: header.Signature, + Name: header.Name, + EpochHeight: header.EpochHeight, + SectorSize: header.SectorSize, }, envelope.Message) }, }, diff --git a/protocol/updater.go b/protocol/updater.go index db3c038..753925c 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -129,6 +129,7 @@ func UpdateBlob(cfg *UpdateConfig) error { // If the new update and is the same size or fewer reject if it is in the // same epoch. In the future, this may be an equivocation condition + // may not be eq if header != nil && header.EpochHeight == item.EpochHeight && header.SectorSize >= item.SectorSize { return ErrUpdaterAlreadySynchronized } @@ -189,6 +190,8 @@ func UpdateBlob(cfg *UpdateConfig) error { sectorSize = 0 } + // check blob res prev hash and equivocate + if !cfg.NameLocker.TryLock(item.Name) { return ErrNameLocked } @@ -215,16 +218,15 @@ func UpdateBlob(cfg *UpdateConfig) error { } err = SyncSectors(&SyncSectorsOpts{ - Timeout: DefaultSyncerBlobResTimeout, - Mux: cfg.Mux, - Tx: tx, - Peers: item.PeerIDs, - EpochHeight: epochHeight, - SectorSize: sectorSize, - SectorTipHash: item.SectorTipHash, - PrevHash: prevHash, - Name: item.Name, - DB: cfg.DB, + Timeout: DefaultSyncerBlobResTimeout, + Mux: cfg.Mux, + Tx: tx, + Peers: item.PeerIDs, + EpochHeight: epochHeight, + SectorSize: sectorSize, + PrevHash: prevHash, + Name: item.Name, + DB: cfg.DB, }) if err != nil { if err := tx.Rollback(); err != nil { @@ -239,24 +241,6 @@ func UpdateBlob(cfg *UpdateConfig) error { } return errors.Wrap(err, "error calculating new blob sector tip hash") } - if tree.Tip() != item.SectorTipHash { - if err := tx.Rollback(); err != nil { - updaterLogger.Error("error rolling back blob transaction", "err", err) - } - err = store.WithTx(cfg.DB, func(tx *leveldb.Transaction) error { - return store.SetHeaderTx(tx, &store.Header{ - Name: item.Name, - EpochHeight: item.EpochHeight, - SectorSize: item.SectorSize, - SectorTipHash: item.SectorTipHash, - Signature: item.Signature, - ReservedRoot: item.ReservedRoot, - Banned: true, - BannedAt: time.Now(), - }, blob.ZeroSectorHashes) - }) - return ErrUpdaterSectorTipHashMismatch - } var sectorsNeeded uint16 diff --git a/protocol/updater_test.go b/protocol/updater_test.go index 4cf3844..8a42026 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -32,6 +32,15 @@ func TestUpdater(t *testing.T) { { "syncs sectors when the local node has never seen the blob", func(t *testing.T, setup *updaterTestSetup) { + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { + return err + } + return nil + })) ts := time.Now() update := mockapp.FillBlobRandom( t, @@ -52,13 +61,10 @@ func TestUpdater(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + Pub: setup.tp.RemoteSigner.Pub(), }, } require.NoError(t, UpdateBlob(cfg)) @@ -103,13 +109,10 @@ func TestUpdater(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + Pub: setup.tp.RemoteSigner.Pub(), }, } require.NoError(t, UpdateBlob(cfg)) @@ -154,13 +157,10 @@ func TestUpdater(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + Pub: setup.tp.RemoteSigner.Pub(), }, } err := UpdateBlob(cfg) @@ -195,13 +195,10 @@ func TestUpdater(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + Pub: setup.tp.RemoteSigner.Pub(), }, } require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { @@ -272,14 +269,11 @@ func TestUpdater(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), - Height: 101, + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + Pub: setup.tp.RemoteSigner.Pub(), + Height: 101, }, } require.NoError(t, UpdateBlob(cfg)) @@ -325,14 +319,11 @@ func TestUpdater(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), - Height: 80, + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + Pub: setup.tp.RemoteSigner.Pub(), + Height: 80, }, } require.NoError(t, UpdateBlob(cfg)) @@ -398,13 +389,10 @@ func TestEpoch(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + Pub: setup.tp.RemoteSigner.Pub(), }, } require.NoError(t, UpdateBlob(cfg)) @@ -463,13 +451,10 @@ func TestEpoch(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + Pub: setup.tp.RemoteSigner.Pub(), }, } require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { @@ -593,13 +578,10 @@ func TestEpoch(t *testing.T) { PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), - Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - SectorTipHash: update.SectorTipHash, - ReservedRoot: update.ReservedRoot, - Signature: update.Signature, - Pub: setup.tp.RemoteSigner.Pub(), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + Pub: setup.tp.RemoteSigner.Pub(), }, } require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { diff --git a/testutil/mockapp/storage.go b/testutil/mockapp/storage.go index ab61b36..b158410 100644 --- a/testutil/mockapp/storage.go +++ b/testutil/mockapp/storage.go @@ -7,11 +7,12 @@ import ( "fnd/store" "fnd/testutil/testfs" "fnd/wire" - "github.com/stretchr/testify/require" - "github.com/syndtr/goleveldb/leveldb" "io" "testing" "time" + + "github.com/stretchr/testify/require" + "github.com/syndtr/goleveldb/leveldb" ) type TestStorage struct { @@ -69,12 +70,9 @@ func FillBlobReader(t *testing.T, db *leveldb.DB, bs blob.Store, signer crypto.S })) require.NoError(t, tx.Commit()) return &wire.Update{ - Name: name, - EpochHeight: epochHeight, - SectorSize: sectorSize, - SectorTipHash: tree.Tip(), - ReservedRoot: crypto.ZeroHash, - Signature: sig, + Name: name, + EpochHeight: epochHeight, + SectorSize: sectorSize, } } diff --git a/wire/blob_res_test.go b/wire/blob_res_test.go index 83163c1..3b1ae78 100644 --- a/wire/blob_res_test.go +++ b/wire/blob_res_test.go @@ -12,6 +12,7 @@ func TestBlobRes_Encoding(t *testing.T) { PrevHash: fixedHash, ReservedRoot: fixedHash, Payload: nil, + Signature: fixedSig, } testMessageEncoding(t, "blob_res", blobRes, &BlobRes{}) diff --git a/wire/testdata/blob_res b/wire/testdata/blob_res index c8bec84beaea98fcc983bb6914a6d62183bfccfb..1726ca6bac176e45b3723b6ce84d3a3a5551f4fc 100644 GIT binary patch delta 17 XcmeaDz&OEwqMqVJ1%4o6VqgFOFB}9S delta 5 McmbQh=s&?900lJxzyJUM diff --git a/wire/testdata/update b/wire/testdata/update index e528fbeefc51a0b8acabd93b8be82f7024f607b1..ba2bf1290b1ee6418ee43a99aebc7cc5c11b6ad9 100755 GIT binary patch literal 13 Scmd-mNi8nPOUzAW00ICVYy)Zl literal 142 dcmd-mNi8nPOUzAW0D=Et5;sAqJZ_UAG63|{24?^O diff --git a/wire/update_test.go b/wire/update_test.go index 2e4c5d0..5b49bff 100644 --- a/wire/update_test.go +++ b/wire/update_test.go @@ -6,12 +6,9 @@ import ( func TestUpdate_Encoding(t *testing.T) { update := &Update{ - Name: "testname", - EpochHeight: fixedEpochHeight, - SectorSize: fixedSectorSize, - SectorTipHash: fixedHash, - ReservedRoot: fixedHash, - Signature: fixedSig, + Name: "testname", + EpochHeight: fixedEpochHeight, + SectorSize: fixedSectorSize, } testMessageEncoding(t, "update", update, &Update{}) From 023de5e45b6838680e9cdf4d13e48781af4bf7ab Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sat, 20 Feb 2021 14:18:07 +0530 Subject: [PATCH 36/71] protocol: update tests to validate blob res since signature is now verified on blob res rather than update, the tests needed to be updated to handle this. Mostly this is just a matter of setting up the header for the name, so that the syncer can use it to fetch the pubkey and match the signature for the payload. If anything breaks in sync, the most likely culprit is the last couple of commits that rework the syncing mechanism to switch validating updates to validating blob res. --- protocol/syncer.go | 17 +++-- protocol/updater_test.go | 159 ++++++++++++++++++++++++--------------- 2 files changed, 111 insertions(+), 65 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index 062b79c..40f25f9 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -19,8 +19,9 @@ const ( ) var ( - ErrSyncerNoProgress = errors.New("sync not progressing") - ErrSyncerMaxAttempts = errors.New("reached max sync attempts") + ErrInvalidPayloadSignature = errors.New("update signature is invalid") + ErrSyncerNoProgress = errors.New("sync not progressing") + ErrSyncerMaxAttempts = errors.New("reached max sync attempts") ) type SyncSectorsOpts struct { @@ -57,13 +58,14 @@ func validateBlobRes(opts *SyncSectorsOpts, name string, epochHeight, sectorSize } h := blob.SealHash(name, epochHeight, sectorSize, mr, rr) if !crypto.VerifySigPub(info.PublicKey, sig, h) { - return errors.New("update signature is invalid") + return ErrInvalidPayloadSignature } return nil } func SyncSectors(opts *SyncSectorsOpts) error { lgr := log.WithModule("payload-syncer").Sub("name", opts.Name) + errs := make(chan error) payloadResCh := make(chan *payloadRes) payloadProcessedCh := make(chan struct{}, 1) doneCh := make(chan struct{}) @@ -129,8 +131,7 @@ func SyncSectors(opts *SyncSectorsOpts) error { } if err := validateBlobRes(opts, msg.Name, msg.EpochHeight, sectorSize, sectorTipHash, msg.ReservedRoot, msg.Signature); err != nil { lgr.Trace("blob res validation failed", "err", err) - // TODO: probably drop this peer, it's sending clearly invalid data - continue + errs <- err } for i := 0; int(i) < len(msg.Payload); i++ { if err := opts.Tx.WriteSector(msg.Payload[i]); err != nil { @@ -146,6 +147,7 @@ func SyncSectors(opts *SyncSectorsOpts) error { } }() + var err error timeout := time.NewTimer(opts.Timeout) payloadLoop: for { @@ -157,10 +159,13 @@ payloadLoop: case <-timeout.C: lgr.Warn("payload request timed out") break payloadLoop + case err = <-errs: + lgr.Warn("payload syncing failed") + break payloadLoop } } unsubRes() close(doneCh) - return nil + return err } diff --git a/protocol/updater_test.go b/protocol/updater_test.go index 8a42026..fe8a899 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -5,11 +5,9 @@ import ( "errors" "fnd/blob" "fnd/crypto" - "fnd/p2p" "fnd/store" "fnd/testutil/mockapp" "fnd/util" - "fnd/wire" "testing" "time" @@ -74,6 +72,15 @@ func TestUpdater(t *testing.T) { { "syncs sectors when the local node has an older blob", func(t *testing.T, setup *updaterTestSetup) { + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { + return err + } + return nil + })) ts := time.Now() epochHeight := CurrentEpoch(name) sectorSize := uint16(10) @@ -120,8 +127,17 @@ func TestUpdater(t *testing.T) { }, }, { - "aborts sync when there is a sector tip hash mismatch", + "aborts sync when there is a invalid payload signature", func(t *testing.T, setup *updaterTestSetup) { + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { + return err + } + return nil + })) ts := time.Now() epochHeight := CurrentEpoch(name) sectorSize := uint16(10) @@ -165,14 +181,21 @@ func TestUpdater(t *testing.T) { } err := UpdateBlob(cfg) require.NotNil(t, err) - require.True(t, errors.Is(err, ErrUpdaterSectorTipHashMismatch)) - header, err := store.GetHeader(setup.ls.DB, name) - require.True(t, header.Banned) + require.True(t, errors.Is(err, ErrInvalidPayloadSignature)) }, }, { "aborts sync if the new sector size is equal to the stored sector size", func(t *testing.T, setup *updaterTestSetup) { + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { + return err + } + return nil + })) ts := time.Now() epochHeight := CurrentEpoch(name) sectorSize := uint16(0) @@ -216,6 +239,15 @@ func TestUpdater(t *testing.T) { { "aborts sync if the name is locked", func(t *testing.T, setup *updaterTestSetup) { + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { + return err + } + return nil + })) locker := util.NewMultiLocker() require.True(t, locker.TryLock(name)) cfg := &UpdateConfig{ @@ -237,23 +269,24 @@ func TestUpdater(t *testing.T) { }, }, { - "does not gossip if the name has fewer than 10 confirmations", + "aborts sync if the new sector size is equal to the stored sector size", func(t *testing.T, setup *updaterTestSetup) { require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - return store.SetLastNameImportHeightTx(tx, 100) + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { + return err + } + return nil })) ts := time.Now() epochHeight := CurrentEpoch(name) sectorSize := uint16(0) - updateCh := make(chan struct{}) - unsub := setup.tp.RemoteMux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeUpdate, func(id crypto.Hash, envelope *wire.Envelope) { - updateCh <- struct{}{} - })) - defer unsub() update := mockapp.FillBlobRandom( t, - setup.rs.DB, - setup.rs.BlobStore, + setup.ls.DB, + setup.ls.BlobStore, setup.tp.RemoteSigner, name, epochHeight, @@ -273,69 +306,50 @@ func TestUpdater(t *testing.T) { EpochHeight: update.EpochHeight, SectorSize: update.SectorSize, Pub: setup.tp.RemoteSigner.Pub(), - Height: 101, }, } - require.NoError(t, UpdateBlob(cfg)) - - timeout := time.NewTimer(100 * time.Millisecond) - select { - case <-updateCh: - t.FailNow() - case <-timeout.C: - } + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderTx(tx, &store.Header{ + Name: name, + EpochHeight: epochHeight, + SectorSize: sectorSize, + }, blob.ZeroSectorHashes) + })) + err := UpdateBlob(cfg) + require.NotNil(t, err) + require.True(t, errors.Is(err, ErrUpdaterAlreadySynchronized)) }, }, { - "gossips if the name has more than 10 confirmations", + "aborts sync if the name is locked", func(t *testing.T, setup *updaterTestSetup) { require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - return store.SetLastNameImportHeightTx(tx, 100) - })) - ts := time.Now() - epochHeight := CurrentEpoch(name) - sectorSize := uint16(0) - updateCh := make(chan *wire.Envelope, 1) - unsub := setup.tp.RemoteMux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeUpdate, func(id crypto.Hash, envelope *wire.Envelope) { - updateCh <- envelope + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { + return err + } + return nil })) - defer unsub() - update := mockapp.FillBlobRandom( - t, - setup.rs.DB, - setup.rs.BlobStore, - setup.tp.RemoteSigner, - name, - epochHeight, - sectorSize, - ts, - ) + locker := util.NewMultiLocker() + require.True(t, locker.TryLock(name)) cfg := &UpdateConfig{ Mux: setup.tp.LocalMux, DB: setup.ls.DB, - NameLocker: util.NewMultiLocker(), + NameLocker: locker, BlobStore: setup.ls.BlobStore, Item: &UpdateQueueItem{ PeerIDs: NewPeerSet([]crypto.Hash{ crypto.HashPub(setup.tp.RemoteSigner.Pub()), }), Name: name, - EpochHeight: update.EpochHeight, - SectorSize: update.SectorSize, - Pub: setup.tp.RemoteSigner.Pub(), - Height: 80, + EpochHeight: CurrentEpoch(name), }, } - require.NoError(t, UpdateBlob(cfg)) - - timeout := time.NewTimer(250 * time.Millisecond) - select { - case envelope := <-updateCh: - msg := envelope.Message.(*wire.Update) - require.Equal(t, name, msg.Name) - case <-timeout.C: - t.Fail() - } + err := UpdateBlob(cfg) + require.NotNil(t, err) + require.True(t, errors.Is(err, ErrNameLocked)) }, }, } @@ -369,6 +383,15 @@ func TestEpoch(t *testing.T) { { "syncs sectors when the local node has never seen the name before", func(t *testing.T, setup *updaterTestSetup) { + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { + return err + } + return nil + })) ts := time.Now() update := mockapp.FillBlobRandom( t, @@ -431,6 +454,15 @@ func TestEpoch(t *testing.T) { { "syncs sectors when the name ban has passed", func(t *testing.T, setup *updaterTestSetup) { + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { + return err + } + return nil + })) ts := time.Now() update := mockapp.FillBlobRandom( t, @@ -558,6 +590,15 @@ func TestEpoch(t *testing.T) { { "rewrites partial blob with new blob on epoch rollover", func(t *testing.T, setup *updaterTestSetup) { + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { + return err + } + return nil + })) ts := time.Now() update := mockapp.FillBlobRandom( t, From 929f6831a45466b72c5be1dd6bdc655eaab0a070 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Tue, 23 Feb 2021 13:09:35 +0530 Subject: [PATCH 37/71] syncer: verify update prev hash --- protocol/syncer.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/protocol/syncer.go b/protocol/syncer.go index 40f25f9..632f9b8 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -20,6 +20,7 @@ const ( var ( ErrInvalidPayloadSignature = errors.New("update signature is invalid") + ErrInvalidPrevHash = errors.New("update prev hash is invalid") ErrSyncerNoProgress = errors.New("sync not progressing") ErrSyncerMaxAttempts = errors.New("reached max sync attempts") ) @@ -125,13 +126,21 @@ func SyncSectors(opts *SyncSectorsOpts) error { lgr.Trace("received unexpected payload size", "sector_size", sectorSize) continue } + if opts.PrevHash != msg.PrevHash { + lgr.Trace("received unexpected prev hash", "sector_size", sectorSize) + errs <- ErrInvalidPrevHash + break + } var sectorTipHash crypto.Hash = opts.PrevHash for i := 0; int(i) < len(msg.Payload); i++ { sectorTipHash = blob.SerialHashSector(msg.Payload[i], sectorTipHash) } + // prev hash - store it in struct if err := validateBlobRes(opts, msg.Name, msg.EpochHeight, sectorSize, sectorTipHash, msg.ReservedRoot, msg.Signature); err != nil { + // faulty message lgr.Trace("blob res validation failed", "err", err) errs <- err + break } for i := 0; int(i) < len(msg.Payload); i++ { if err := opts.Tx.WriteSector(msg.Payload[i]); err != nil { From 4ccfc336a0419555ebfd9f53752a9c8fd563fc22 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Tue, 23 Feb 2021 13:38:16 +0530 Subject: [PATCH 38/71] protocol: handle prev hash mismatch --- protocol/syncer.go | 24 +++++++++++++++++++----- protocol/updater_test.go | 7 +++++-- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index 632f9b8..d842994 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -117,27 +117,41 @@ func SyncSectors(opts *SyncSectorsOpts) error { lgr.Trace("already processed this payload", "payload_position", msg.PayloadPosition, "peer_id", peerID) continue } + // Verify that we received the payload starting from the sector + // we requested in blob request. opts.SectorSize contains our + // current known sector size, which is what we send in blob + // request. if opts.SectorSize != msg.PayloadPosition { + // TODO: Check for race condition when sector is + // being updated and is written _after_ our request... because + // then this check will fail. lgr.Trace("received unexpected payload position", "sector_size", opts.SectorSize, "payload_position", msg.PayloadPosition) continue } sectorSize := msg.PayloadPosition + uint16(len(msg.Payload)) - if int(sectorSize) > blob.Size { - lgr.Trace("received unexpected payload size", "sector_size", sectorSize) + // Additional sanity check: make sure that update does not overflow max sectors. + if int(sectorSize) > blob.SectorCount { + lgr.Trace("received unexpected sector size", "sector_size", sectorSize, "max", blob.SectorCount) continue } + // Verify that the prev hash from the remote matches our + // current tip hash i.e. the update starts _after_ our latest + // sector and both the sector hashes match. if opts.PrevHash != msg.PrevHash { - lgr.Trace("received unexpected prev hash", "sector_size", sectorSize) + lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) errs <- ErrInvalidPrevHash break } + // Generate the current tip hash from prev hash and the payload sectors var sectorTipHash crypto.Hash = opts.PrevHash for i := 0; int(i) < len(msg.Payload); i++ { sectorTipHash = blob.SerialHashSector(msg.Payload[i], sectorTipHash) } - // prev hash - store it in struct + // Verify that the update is valid by using the recomputed + // sector size, sector tip hash etc and validate the signature + // over the hash of the metadata. + // TODO: store the latest tip hash if err := validateBlobRes(opts, msg.Name, msg.EpochHeight, sectorSize, sectorTipHash, msg.ReservedRoot, msg.Signature); err != nil { - // faulty message lgr.Trace("blob res validation failed", "err", err) errs <- err break diff --git a/protocol/updater_test.go b/protocol/updater_test.go index fe8a899..359595d 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -127,7 +127,7 @@ func TestUpdater(t *testing.T) { }, }, { - "aborts sync when there is a invalid payload signature", + "aborts sync when there is a prev hash mismatch", func(t *testing.T, setup *updaterTestSetup) { require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { if err := store.SetInitialImportCompleteTx(tx); err != nil { @@ -153,6 +153,9 @@ func TestUpdater(t *testing.T) { rand.Reader, ) // create the new blob remotely + // this forces an equivocation because local has 10 random sectors + // and remote as 20 _different_ random sectors. Prev Hash at 10 will + // mismatch, leading to ErrInvalidPrevHash update := mockapp.FillBlobReader( t, setup.rs.DB, @@ -181,7 +184,7 @@ func TestUpdater(t *testing.T) { } err := UpdateBlob(cfg) require.NotNil(t, err) - require.True(t, errors.Is(err, ErrInvalidPayloadSignature)) + require.True(t, errors.Is(err, ErrInvalidPrevHash)) }, }, { From 82cb7791311963d7ef8dc12c8fdae20d9e0caac6 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Tue, 23 Feb 2021 14:31:39 +0530 Subject: [PATCH 39/71] test: restore invalid payload signature test --- protocol/updater_test.go | 61 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/protocol/updater_test.go b/protocol/updater_test.go index 359595d..7c36c26 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -187,6 +187,67 @@ func TestUpdater(t *testing.T) { require.True(t, errors.Is(err, ErrInvalidPrevHash)) }, }, + { + "aborts sync when there is a invalid payload signature", + func(t *testing.T, setup *updaterTestSetup) { + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, setup.tp.LocalSigner.Pub(), 10); err != nil { + return err + } + return nil + })) + ts := time.Now() + epochHeight := CurrentEpoch(name) + sectorSize := uint16(10) + mockapp.FillBlobReader( + t, + setup.ls.DB, + setup.ls.BlobStore, + setup.tp.RemoteSigner, + name, + epochHeight, + sectorSize, + ts.Add(-48*time.Hour), + mockapp.NullReader, + ) + // create the new blob remotely + // this forces an equivocation because local has 10 random sectors + // and remote as 20 _different_ random sectors. Prev Hash at 10 will + // mismatch, leading to ErrInvalidPrevHash + update := mockapp.FillBlobReader( + t, + setup.rs.DB, + setup.rs.BlobStore, + setup.tp.RemoteSigner, + name, + epochHeight, + sectorSize+10, + ts, + mockapp.NullReader, + ) + cfg := &UpdateConfig{ + Mux: setup.tp.LocalMux, + DB: setup.ls.DB, + NameLocker: util.NewMultiLocker(), + BlobStore: setup.ls.BlobStore, + Item: &UpdateQueueItem{ + PeerIDs: NewPeerSet([]crypto.Hash{ + crypto.HashPub(setup.tp.RemoteSigner.Pub()), + }), + Name: name, + EpochHeight: update.EpochHeight, + SectorSize: update.SectorSize, + Pub: setup.tp.RemoteSigner.Pub(), + }, + } + err := UpdateBlob(cfg) + require.NotNil(t, err) + require.True(t, errors.Is(err, ErrInvalidPayloadSignature)) + }, + }, { "aborts sync if the new sector size is equal to the stored sector size", func(t *testing.T, setup *updaterTestSetup) { From c94dccb817a047eaabd54932dfc3714b88dce560 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Tue, 23 Feb 2021 14:46:59 +0530 Subject: [PATCH 40/71] SectorLen->SectorBytes; SectorCount->MaxSectors --- blob/blob_test.go | 4 ++-- blob/consts.go | 6 +++--- blob/hash.go | 4 ++-- blob/io.go | 4 ++-- blob/sector.go | 2 +- blob/transaction.go | 6 +++--- cmd/fnd-cli/cmd/blob/write.go | 2 +- protocol/sector_server.go | 2 +- protocol/syncer.go | 4 ++-- protocol/updater.go | 2 +- protocol/updater_test.go | 8 ++++---- rpc/server.go | 2 +- testutil/mockapp/storage.go | 2 +- 13 files changed, 24 insertions(+), 24 deletions(-) diff --git a/blob/blob_test.go b/blob/blob_test.go index f769d45..cf12948 100644 --- a/blob/blob_test.go +++ b/blob/blob_test.go @@ -18,13 +18,13 @@ func TestBlob_Reading(t *testing.T) { require.Equal(t, "foobar", bl.Name()) var expSector Sector - _, err = f.ReadAt(expSector[:], SectorLen) + _, err = f.ReadAt(expSector[:], SectorBytes) require.NoError(t, err) actSector, err := bl.ReadSector(1) require.NoError(t, err) require.Equal(t, expSector, actSector) actData := make([]byte, 10, 10) - _, err = bl.ReadAt(actData, SectorLen) + _, err = bl.ReadAt(actData, SectorBytes) require.NoError(t, err) require.EqualValues(t, expSector[:10], actData) } diff --git a/blob/consts.go b/blob/consts.go index e406d6a..33babbd 100644 --- a/blob/consts.go +++ b/blob/consts.go @@ -2,8 +2,8 @@ package blob const ( HeaderLen = 1 + 1 + 63 + 8 + 32 + 65 - SectorLen = 256 - SectorCount = 4096 - Size = SectorLen * SectorCount + SectorBytes = 256 + MaxSectors = 4096 + Size = SectorBytes * MaxSectors CurrentVersion = 1 ) diff --git a/blob/hash.go b/blob/hash.go index 3b196ae..7c70759 100644 --- a/blob/hash.go +++ b/blob/hash.go @@ -13,7 +13,7 @@ var ( ZeroSectorHashes SectorHashes ) -type SectorHashes [SectorCount]crypto.Hash +type SectorHashes [MaxSectors]crypto.Hash func (s SectorHashes) Encode(w io.Writer) error { for _, h := range s { @@ -54,7 +54,7 @@ func (s SectorHashes) DiffWith(other SectorHashes) int { func (s SectorHashes) Tip() crypto.Hash { var i int - for i = 0; i < SectorCount; i++ { + for i = 0; i < MaxSectors; i++ { if s[i] == ZeroHash { break } diff --git a/blob/io.go b/blob/io.go index 8272ec1..4f966d4 100644 --- a/blob/io.go +++ b/blob/io.go @@ -27,7 +27,7 @@ func ReadBlobAt(r io.ReaderAt, b []byte, off int64) (int, error) { func ReadSector(r io.ReaderAt, id uint8) (Sector, error) { var sector Sector - _, err := r.ReadAt(sector[:], int64(id)*int64(SectorLen)) + _, err := r.ReadAt(sector[:], int64(id)*int64(SectorBytes)) return sector, err } @@ -48,7 +48,7 @@ func WriteBlobAt(w io.WriterAt, b []byte, off int64) (int, error) { } func WriteSector(w io.WriterAt, id uint16, sector Sector) error { - _, err := w.WriteAt(sector[:], int64(id)*int64(SectorLen)) + _, err := w.WriteAt(sector[:], int64(id)*int64(SectorBytes)) return err } diff --git a/blob/sector.go b/blob/sector.go index 34399cc..6e383d3 100644 --- a/blob/sector.go +++ b/blob/sector.go @@ -2,7 +2,7 @@ package blob import "io" -type Sector [SectorLen]byte +type Sector [SectorBytes]byte var ZeroSector Sector diff --git a/blob/transaction.go b/blob/transaction.go index ab7ccd1..73a9341 100644 --- a/blob/transaction.go +++ b/blob/transaction.go @@ -43,10 +43,10 @@ func (t *txImpl) Name() string { } func (t *txImpl) Seek(off int64, whence int) (int64, error) { - if off%SectorLen != 0 { + if off%SectorBytes != 0 { return 0, errors.New("seek not a multiple of sector len") } - if off < int64(t.sectorSize)*int64(SectorLen) { + if off < int64(t.sectorSize)*int64(SectorBytes) { return 0, errors.New("seek before already written sector") } switch whence { @@ -54,7 +54,7 @@ func (t *txImpl) Seek(off int64, whence int) (int64, error) { if off > Size { return 0, errors.New("seek beyond blob bounds") } - t.sectorSize = uint16(off / SectorLen) + t.sectorSize = uint16(off / SectorBytes) case io.SeekCurrent: case io.SeekEnd: default: diff --git a/cmd/fnd-cli/cmd/blob/write.go b/cmd/fnd-cli/cmd/blob/write.go index 62fed7b..f7ffe99 100644 --- a/cmd/fnd-cli/cmd/blob/write.go +++ b/cmd/fnd-cli/cmd/blob/write.go @@ -67,7 +67,7 @@ var writeCmd = &cobra.Command{ rd = bufio.NewReader(bytes.NewReader([]byte(args[1]))) } var sector blob.Sector - for i := 0; i < blob.SectorCount; i++ { + for i := 0; i < blob.MaxSectors; i++ { if _, err := rd.Read(sector[:]); err != nil { if err == io.EOF { break diff --git a/protocol/sector_server.go b/protocol/sector_server.go index 062041b..37c921e 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -103,7 +103,7 @@ func (s *SectorServer) onBlobReq(peerID crypto.Hash, envelope *wire.Envelope) { var sectors []blob.Sector for i := reqMsg.SectorSize; i < header.SectorSize; i++ { sector := &blob.Sector{} - _, err = bl.ReadAt(sector[:], int64(i)*blob.SectorLen) + _, err = bl.ReadAt(sector[:], int64(i)*blob.SectorBytes) if err != nil { s.nameLocker.RUnlock(reqMsg.Name) lgr.Error( diff --git a/protocol/syncer.go b/protocol/syncer.go index d842994..1f240cb 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -130,8 +130,8 @@ func SyncSectors(opts *SyncSectorsOpts) error { } sectorSize := msg.PayloadPosition + uint16(len(msg.Payload)) // Additional sanity check: make sure that update does not overflow max sectors. - if int(sectorSize) > blob.SectorCount { - lgr.Trace("received unexpected sector size", "sector_size", sectorSize, "max", blob.SectorCount) + if int(sectorSize) > blob.MaxSectors { + lgr.Trace("received unexpected sector size", "sector_size", sectorSize, "max", blob.MaxSectors) continue } // Verify that the prev hash from the remote matches our diff --git a/protocol/updater.go b/protocol/updater.go index 753925c..38cdcad 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -212,7 +212,7 @@ func UpdateBlob(cfg *UpdateConfig) error { return errors.Wrap(err, "error starting transaction") } - _, err = tx.Seek(int64(sectorSize)*int64(blob.SectorLen), io.SeekStart) + _, err = tx.Seek(int64(sectorSize)*int64(blob.SectorBytes), io.SeekStart) if err != nil { return errors.Wrap(err, "error seeking transaction") } diff --git a/protocol/updater_test.go b/protocol/updater_test.go index 7c36c26..d1c446e 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -47,7 +47,7 @@ func TestUpdater(t *testing.T) { setup.tp.RemoteSigner, name, CurrentEpoch(name), - blob.SectorLen, + blob.SectorBytes, ts, ) cfg := &UpdateConfig{ @@ -464,7 +464,7 @@ func TestEpoch(t *testing.T) { setup.tp.RemoteSigner, name, 0, - blob.SectorLen, + blob.SectorBytes, ts, ) cfg := &UpdateConfig{ @@ -535,7 +535,7 @@ func TestEpoch(t *testing.T) { setup.tp.RemoteSigner, name, 0, - blob.SectorLen, + blob.SectorBytes, ts, ) cfg := &UpdateConfig{ @@ -671,7 +671,7 @@ func TestEpoch(t *testing.T) { setup.tp.RemoteSigner, name, CurrentEpoch(name), - blob.SectorLen, + blob.SectorBytes, ts, ) cfg := &UpdateConfig{ diff --git a/rpc/server.go b/rpc/server.go index 32bfe20..354d0af 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -240,7 +240,7 @@ func (s *Server) Checkout(ctx context.Context, req *apiv1.CheckoutReq) (*apiv1.C return nil, err } - _, err = tx.Seek(int64(sectorSize)*int64(blob.SectorLen), io.SeekStart) + _, err = tx.Seek(int64(sectorSize)*int64(blob.SectorBytes), io.SeekStart) if err != nil { return nil, err } diff --git a/testutil/mockapp/storage.go b/testutil/mockapp/storage.go index b158410..4367908 100644 --- a/testutil/mockapp/storage.go +++ b/testutil/mockapp/storage.go @@ -95,7 +95,7 @@ func RequireBlobsEqual(t *testing.T, localBS blob.Store, remoteBS blob.Store, na require.NoError(t, err) remoteBl, err := remoteBS.Open(name) require.NoError(t, err) - for i := 0; i < blob.SectorCount; i++ { + for i := 0; i < blob.MaxSectors; i++ { localSector, err := localBl.ReadSector(uint8(i)) require.NoError(t, err) remoteSector, err := remoteBl.ReadSector(uint8(i)) From 14e97009bc53a5796c1f61e5c5cd6af310466535 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Tue, 23 Feb 2021 18:08:50 +0530 Subject: [PATCH 41/71] test: add docs --- protocol/updater_test.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/protocol/updater_test.go b/protocol/updater_test.go index d1c446e..4cf2245 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -194,6 +194,7 @@ func TestUpdater(t *testing.T) { if err := store.SetInitialImportCompleteTx(tx); err != nil { return err } + // TODO: ideally setup a fake signer if err := store.SetNameInfoTx(tx, name, setup.tp.LocalSigner.Pub(), 10); err != nil { return err } @@ -213,10 +214,10 @@ func TestUpdater(t *testing.T) { ts.Add(-48*time.Hour), mockapp.NullReader, ) - // create the new blob remotely - // this forces an equivocation because local has 10 random sectors - // and remote as 20 _different_ random sectors. Prev Hash at 10 will - // mismatch, leading to ErrInvalidPrevHash + // The sectors are generated from null reader, so there won't + // be an equivocation, however we used local signer on the + // remote (instead of remote signer like other test cases + // above), so it generates an invalid signature. update := mockapp.FillBlobReader( t, setup.rs.DB, From 16bfa17434f9809e13d225e177496de4942cc2df Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Tue, 23 Feb 2021 20:06:04 +0530 Subject: [PATCH 42/71] syncer: verify epoch height, prev hash after sig --- protocol/syncer.go | 47 +++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index 1f240cb..d9739f1 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -117,14 +117,16 @@ func SyncSectors(opts *SyncSectorsOpts) error { lgr.Trace("already processed this payload", "payload_position", msg.PayloadPosition, "peer_id", peerID) continue } + // Verify that the remote is at the same epoch height or lower + if opts.EpochHeight > msg.EpochHeight { + lgr.Trace("received unexpected epoch height", "expected_epoch_height", opts.EpochHeight, "received_epoch_height", msg.EpochHeight) + continue + } // Verify that we received the payload starting from the sector // we requested in blob request. opts.SectorSize contains our // current known sector size, which is what we send in blob // request. if opts.SectorSize != msg.PayloadPosition { - // TODO: Check for race condition when sector is - // being updated and is written _after_ our request... because - // then this check will fail. lgr.Trace("received unexpected payload position", "sector_size", opts.SectorSize, "payload_position", msg.PayloadPosition) continue } @@ -134,26 +136,41 @@ func SyncSectors(opts *SyncSectorsOpts) error { lgr.Trace("received unexpected sector size", "sector_size", sectorSize, "max", blob.MaxSectors) continue } - // Verify that the prev hash from the remote matches our - // current tip hash i.e. the update starts _after_ our latest - // sector and both the sector hashes match. - if opts.PrevHash != msg.PrevHash { - lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) - errs <- ErrInvalidPrevHash - break - } - // Generate the current tip hash from prev hash and the payload sectors + // Generate the current tip hash from prev hash and the payload + // sectors. var sectorTipHash crypto.Hash = opts.PrevHash for i := 0; int(i) < len(msg.Payload); i++ { sectorTipHash = blob.SerialHashSector(msg.Payload[i], sectorTipHash) } // Verify that the update is valid by using the recomputed - // sector size, sector tip hash etc and validate the signature - // over the hash of the metadata. + // sector size, sector tip hash and other metadata. This data + // is first hashed and the signature is validated against the + // name's pubkey. See validateBlobRes. // TODO: store the latest tip hash if err := validateBlobRes(opts, msg.Name, msg.EpochHeight, sectorSize, sectorTipHash, msg.ReservedRoot, msg.Signature); err != nil { lgr.Trace("blob res validation failed", "err", err) - errs <- err + // Verify that the prev hash from the remote matches our + // current tip hash i.e. the update starts _after_ our + // latest sector and both the sector hashes match. A + // mismatch indicates a proof of equivocation. + if opts.PrevHash != msg.PrevHash { + lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) + errs <- ErrInvalidPrevHash + break + // TODO: generate eq proof if epoch height eq msg + // broadcast update msg sector size zero + // payload size 0xff + // blob req sector size 0xff + // -> eq proof + // <- handle eq + // eq epoch height must be same, same reserved root + // -> log time, ban name + // if already has eq proof dont write to disk + } + // If prev hash matches, we have an invalid signature, + // which cannot be used as a proof of equivocation. + // TODO: ban the peer as it is clearly sending invalid data + errs <- errors.Wrap(ErrInvalidPayloadSignature, "signature validation failed") break } for i := 0; int(i) < len(msg.Payload); i++ { From d54475f43a965ccfad1741bb90da36958dacd46d Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Wed, 24 Feb 2021 15:19:48 +0530 Subject: [PATCH 43/71] syncer: verify prev hash and check for equivocation --- protocol/syncer.go | 7 ++++--- protocol/updater_test.go | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index d9739f1..b7feaf1 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -20,7 +20,7 @@ const ( var ( ErrInvalidPayloadSignature = errors.New("update signature is invalid") - ErrInvalidPrevHash = errors.New("update prev hash is invalid") + ErrPayloadEquivocation = errors.New("update payload is equivocated") ErrSyncerNoProgress = errors.New("sync not progressing") ErrSyncerMaxAttempts = errors.New("reached max sync attempts") ) @@ -155,8 +155,9 @@ func SyncSectors(opts *SyncSectorsOpts) error { // mismatch indicates a proof of equivocation. if opts.PrevHash != msg.PrevHash { lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) - errs <- ErrInvalidPrevHash - break + if err := validateBlobRes(opts, msg.Name, msg.EpochHeight, sectorSize, msg.PrevHash, msg.ReservedRoot, msg.Signature); err != nil { + errs <- ErrPayloadEquivocation + } // TODO: generate eq proof if epoch height eq msg // broadcast update msg sector size zero // payload size 0xff diff --git a/protocol/updater_test.go b/protocol/updater_test.go index 4cf2245..2153f89 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -127,7 +127,7 @@ func TestUpdater(t *testing.T) { }, }, { - "aborts sync when there is a prev hash mismatch", + "aborts sync when there is an equivocation", func(t *testing.T, setup *updaterTestSetup) { require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { if err := store.SetInitialImportCompleteTx(tx); err != nil { @@ -184,7 +184,7 @@ func TestUpdater(t *testing.T) { } err := UpdateBlob(cfg) require.NotNil(t, err) - require.True(t, errors.Is(err, ErrInvalidPrevHash)) + require.True(t, errors.Is(err, ErrPayloadEquivocation)) }, }, { From 96ba0a07f22456fa3de3fdfbd6c701c194cd99a6 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Wed, 24 Feb 2021 15:22:03 +0530 Subject: [PATCH 44/71] syncer: minor - break after err equivocation --- protocol/syncer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/protocol/syncer.go b/protocol/syncer.go index b7feaf1..583a386 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -157,6 +157,7 @@ func SyncSectors(opts *SyncSectorsOpts) error { lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) if err := validateBlobRes(opts, msg.Name, msg.EpochHeight, sectorSize, msg.PrevHash, msg.ReservedRoot, msg.Signature); err != nil { errs <- ErrPayloadEquivocation + break } // TODO: generate eq proof if epoch height eq msg // broadcast update msg sector size zero From 3733047adf69c968bee73709400563b2d834dba1 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Wed, 24 Feb 2021 15:40:22 +0530 Subject: [PATCH 45/71] all: generate equivocation proof --- protocol/syncer.go | 26 +++++++++++++++++--------- store/equivocation_proof.go | 11 ++++++----- wire/equivocation_proof.go | 6 +++++- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index 583a386..da8ae63 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -156,18 +156,26 @@ func SyncSectors(opts *SyncSectorsOpts) error { if opts.PrevHash != msg.PrevHash { lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) if err := validateBlobRes(opts, msg.Name, msg.EpochHeight, sectorSize, msg.PrevHash, msg.ReservedRoot, msg.Signature); err != nil { + if opts.EpochHeight == msg.EpochHeight { + if err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { + return store.SetEquivocationProofTx(tx, msg.Name, msg) + }); err != nil { + lgr.Trace("error writing equivocation proof", "err", err) + } + // TODO: handle equivocation proof + // -> update { sectorSize: 0 } + // <- BlobReq { sectorSize 0xff } + // -> BlobRes { equivocation proof } + update := &wire.Update{ + Name: msg.Name, + EpochHeight: msg.EpochHeight, + SectorSize: 0, + } + p2p.GossipAll(opts.Mux, update) + } errs <- ErrPayloadEquivocation break } - // TODO: generate eq proof if epoch height eq msg - // broadcast update msg sector size zero - // payload size 0xff - // blob req sector size 0xff - // -> eq proof - // <- handle eq - // eq epoch height must be same, same reserved root - // -> log time, ban name - // if already has eq proof dont write to disk } // If prev hash matches, we have an invalid signature, // which cannot be used as a proof of equivocation. diff --git a/store/equivocation_proof.go b/store/equivocation_proof.go index 421ac6c..ece91a1 100644 --- a/store/equivocation_proof.go +++ b/store/equivocation_proof.go @@ -13,22 +13,23 @@ var ( equivocationProofsPrefix = Prefixer("equivocationproofs") ) -func GeEquivocationProof(db *leveldb.DB, name string) (*wire.EquivocationProof, error) { - proof := new(wire.EquivocationProof) +func GeEquivocationProof(db *leveldb.DB, name string) (*wire.BlobRes, error) { + proof := new(wire.BlobRes) equivocationProofData, err := db.Get(equivocationProofsPrefix(name), nil) if err != nil { return nil, errors.Wrap(err, "error getting equivocation proof data") } - mustUnmarshalJSON(equivocationProofData, proof) + wr := bytes.NewReader(equivocationProofData) + proof.Decode(wr) return proof, nil } -func SetEquivocationProofTx(tx *leveldb.Transaction, name string, proof *wire.EquivocationProof) error { +func SetEquivocationProofTx(tx *leveldb.Transaction, name string, proof *wire.BlobRes) error { var buf bytes.Buffer wr := bufio.NewWriter(&buf) proof.Encode(wr) if err := tx.Put(equivocationProofsPrefix(proof.Name), buf.Bytes(), nil); err != nil { - return errors.Wrap(err, "error writing header tree") + return errors.Wrap(err, "error writing equivocation proof") } return nil } diff --git a/wire/equivocation_proof.go b/wire/equivocation_proof.go index 09df786..5f040db 100644 --- a/wire/equivocation_proof.go +++ b/wire/equivocation_proof.go @@ -18,6 +18,7 @@ type EquivocationProof struct { PrevHash crypto.Hash ReservedRoot crypto.Hash Payload []blob.Sector + Signature crypto.Signature } var _ Message = (*EquivocationProof)(nil) @@ -36,7 +37,8 @@ func (s *EquivocationProof) Equals(other Message) bool { s.EpochHeight == cast.EpochHeight && s.PayloadPosition == cast.PayloadPosition && s.PrevHash == cast.PrevHash && - s.ReservedRoot == cast.ReservedRoot + s.ReservedRoot == cast.ReservedRoot && + s.Signature == cast.Signature } func (s *EquivocationProof) Encode(w io.Writer) error { @@ -48,6 +50,7 @@ func (s *EquivocationProof) Encode(w io.Writer) error { s.PrevHash, s.ReservedRoot, s.Payload, + s.Signature, ) } @@ -60,6 +63,7 @@ func (s *EquivocationProof) Decode(r io.Reader) error { &s.PrevHash, &s.ReservedRoot, &s.Payload, + &s.Signature, ) } From 452b0dd07c4a3eecaa7ce040f5935c17f8316e94 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Wed, 24 Feb 2021 15:59:17 +0530 Subject: [PATCH 46/71] protocol: handle equivocation proof request --- protocol/sector_server.go | 16 ++++++++++++++++ protocol/syncer.go | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/protocol/sector_server.go b/protocol/sector_server.go index 37c921e..ac69bf7 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -53,6 +53,22 @@ func (s *SectorServer) onBlobReq(peerID crypto.Hash, envelope *wire.Envelope) { "peer_id", peerID, ) + if reqMsg.SectorSize == blob.MaxSectors { + // handle equivocation proof + blobRes, err := store.GeEquivocationProof(s.db, reqMsg.Name) + if err != nil { + lgr.Error( + "failed to fetch equivocation proof", + "err", err) + return + } + if err := s.mux.Send(peerID, blobRes); err != nil { + s.lgr.Error("error serving equivocation proof", "err", err) + return + } + return + } + if !s.nameLocker.TryRLock(reqMsg.Name) { lgr.Info("dropping sector req for busy name") return diff --git a/protocol/syncer.go b/protocol/syncer.go index da8ae63..1fc4ee3 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -163,9 +163,14 @@ func SyncSectors(opts *SyncSectorsOpts) error { lgr.Trace("error writing equivocation proof", "err", err) } // TODO: handle equivocation proof + // local // -> update { sectorSize: 0 } // <- BlobReq { sectorSize 0xff } // -> BlobRes { equivocation proof } + // remote + // <- update { sectorSize: 0 } + // -> BlobReq { sectorSize 0xff } + // <- BlobRes { equivocation proof } update := &wire.Update{ Name: msg.Name, EpochHeight: msg.EpochHeight, From e1f60ea0b52dcbc7723b8f9bc255f8c153544e67 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Wed, 24 Feb 2021 16:06:53 +0530 Subject: [PATCH 47/71] protocol: handle equivocation update --- protocol/update_queue.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/protocol/update_queue.go b/protocol/update_queue.go index dcdb573..5d6bf53 100644 --- a/protocol/update_queue.go +++ b/protocol/update_queue.go @@ -1,6 +1,7 @@ package protocol import ( + "fnd/blob" "fnd/config" "fnd/crypto" "fnd/log" @@ -100,6 +101,15 @@ func (u *UpdateQueue) Enqueue(peerID crypto.Hash, update *wire.Update) error { return ErrInitialImportIncomplete } + if update.SectorSize == 0 { + err := u.mux.Send(peerID, &wire.BlobReq{ + Name: update.Name, + EpochHeight: update.EpochHeight, + SectorSize: blob.MaxSectors, + }) + return err + } + if err := u.validateUpdate(update.Name); err != nil { return err } From b050535d8ca09bc1676c272a3603a4d217adf463 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Wed, 24 Feb 2021 16:11:52 +0530 Subject: [PATCH 48/71] protocol: handle equivocation response --- protocol/sector_server.go | 13 +++++++++++++ protocol/syncer.go | 1 + 2 files changed, 14 insertions(+) diff --git a/protocol/sector_server.go b/protocol/sector_server.go index ac69bf7..20015be 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -39,6 +39,7 @@ func NewSectorServer(mux *p2p.PeerMuxer, db *leveldb.DB, bs blob.Store, nameLock func (s *SectorServer) Start() error { s.mux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeBlobReq, s.onBlobReq)) + s.mux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeBlobRes, s.onBlobRes)) return nil } @@ -154,3 +155,15 @@ func (s *SectorServer) sendResponse(peerID crypto.Hash, name string, prevHash cr "sector_size", sectorSize, ) } + +func (s *SectorServer) onBlobRes(peerID crypto.Hash, envelope *wire.Envelope) { + reqMsg := envelope.Message.(*wire.BlobRes) + lgr := s.lgr.Sub( + "name", reqMsg.Name, + "peer_id", peerID, + ) + if reqMsg.PayloadPosition == blob.MaxSectors { + lgr.Trace("handling equivocation response") + } + return +} diff --git a/protocol/syncer.go b/protocol/syncer.go index 1fc4ee3..f08b15d 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -158,6 +158,7 @@ func SyncSectors(opts *SyncSectorsOpts) error { if err := validateBlobRes(opts, msg.Name, msg.EpochHeight, sectorSize, msg.PrevHash, msg.ReservedRoot, msg.Signature); err != nil { if opts.EpochHeight == msg.EpochHeight { if err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { + msg.PayloadPosition = blob.MaxSectors return store.SetEquivocationProofTx(tx, msg.Name, msg) }); err != nil { lgr.Trace("error writing equivocation proof", "err", err) From a434eeb7ce302ceb0d6a7dc39eff1a4acd316f99 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Wed, 24 Feb 2021 16:27:43 +0530 Subject: [PATCH 49/71] protocol: validateBlobRes - pass db instead of opts --- protocol/syncer.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index f08b15d..2ddd7cb 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -42,18 +42,18 @@ type payloadRes struct { msg *wire.BlobRes } -func validateBlobRes(opts *SyncSectorsOpts, name string, epochHeight, sectorSize uint16, mr crypto.Hash, rr crypto.Hash, sig crypto.Signature) error { +func validateBlobRes(db *leveldb.DB, name string, epochHeight, sectorSize uint16, mr crypto.Hash, rr crypto.Hash, sig crypto.Signature) error { if err := primitives.ValidateName(name); err != nil { return errors.Wrap(err, "update name is invalid") } - banned, err := store.NameIsBanned(opts.DB, name) + banned, err := store.NameIsBanned(db, name) if err != nil { return errors.Wrap(err, "error reading name ban state") } if banned { return errors.New("name is banned") } - info, err := store.GetNameInfo(opts.DB, name) + info, err := store.GetNameInfo(db, name) if err != nil { return errors.Wrap(err, "error reading name info") } @@ -147,7 +147,7 @@ func SyncSectors(opts *SyncSectorsOpts) error { // is first hashed and the signature is validated against the // name's pubkey. See validateBlobRes. // TODO: store the latest tip hash - if err := validateBlobRes(opts, msg.Name, msg.EpochHeight, sectorSize, sectorTipHash, msg.ReservedRoot, msg.Signature); err != nil { + if err := validateBlobRes(opts.DB, msg.Name, msg.EpochHeight, sectorSize, sectorTipHash, msg.ReservedRoot, msg.Signature); err != nil { lgr.Trace("blob res validation failed", "err", err) // Verify that the prev hash from the remote matches our // current tip hash i.e. the update starts _after_ our @@ -155,7 +155,7 @@ func SyncSectors(opts *SyncSectorsOpts) error { // mismatch indicates a proof of equivocation. if opts.PrevHash != msg.PrevHash { lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) - if err := validateBlobRes(opts, msg.Name, msg.EpochHeight, sectorSize, msg.PrevHash, msg.ReservedRoot, msg.Signature); err != nil { + if err := validateBlobRes(opts.DB, msg.Name, msg.EpochHeight, sectorSize, msg.PrevHash, msg.ReservedRoot, msg.Signature); err != nil { if opts.EpochHeight == msg.EpochHeight { if err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { msg.PayloadPosition = blob.MaxSectors @@ -166,12 +166,12 @@ func SyncSectors(opts *SyncSectorsOpts) error { // TODO: handle equivocation proof // local // -> update { sectorSize: 0 } - // <- BlobReq { sectorSize 0xff } - // -> BlobRes { equivocation proof } + // <- BlobReq { sectorSize: 0xff } + // -> BlobRes { payloadPosition: 0xff } // remote // <- update { sectorSize: 0 } - // -> BlobReq { sectorSize 0xff } - // <- BlobRes { equivocation proof } + // -> BlobReq { sectorSize: 0xff } + // <- BlobRes { payloadPosition: 0xff } update := &wire.Update{ Name: msg.Name, EpochHeight: msg.EpochHeight, From 97587dd7309c60e6df51ef333e1226d5cae93bf3 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Wed, 24 Feb 2021 16:34:08 +0530 Subject: [PATCH 50/71] protocol: fix update queue tests --- protocol/update_queue_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/protocol/update_queue_test.go b/protocol/update_queue_test.go index bb87fe8..594a539 100644 --- a/protocol/update_queue_test.go +++ b/protocol/update_queue_test.go @@ -74,7 +74,9 @@ func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { { "invalid name", &wire.Update{ - Name: "--not-a-good-name--", + Name: "--not-a-good-name--", + EpochHeight: 52, + SectorSize: 10, }, func(t *testing.T, err error) { require.Contains(t, err.Error(), "name is invalid") @@ -83,7 +85,9 @@ func TestUpdateQueue_Enqueue_InvalidBeforeEnqueue(t *testing.T) { { "banned name", &wire.Update{ - Name: "banned", + Name: "banned", + EpochHeight: 52, + SectorSize: 10, }, func(t *testing.T, err error) { require.Contains(t, err.Error(), "name is banned") From 1ed3657500351b266e3e5917887c5eb2b289e329 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Wed, 24 Feb 2021 17:27:47 +0530 Subject: [PATCH 51/71] protocol: simplify validation --- protocol/syncer.go | 69 +++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index 2ddd7cb..c93c80d 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -138,7 +138,7 @@ func SyncSectors(opts *SyncSectorsOpts) error { } // Generate the current tip hash from prev hash and the payload // sectors. - var sectorTipHash crypto.Hash = opts.PrevHash + var sectorTipHash crypto.Hash = msg.PrevHash for i := 0; int(i) < len(msg.Payload); i++ { sectorTipHash = blob.SerialHashSector(msg.Payload[i], sectorTipHash) } @@ -149,46 +149,45 @@ func SyncSectors(opts *SyncSectorsOpts) error { // TODO: store the latest tip hash if err := validateBlobRes(opts.DB, msg.Name, msg.EpochHeight, sectorSize, sectorTipHash, msg.ReservedRoot, msg.Signature); err != nil { lgr.Trace("blob res validation failed", "err", err) - // Verify that the prev hash from the remote matches our - // current tip hash i.e. the update starts _after_ our - // latest sector and both the sector hashes match. A - // mismatch indicates a proof of equivocation. - if opts.PrevHash != msg.PrevHash { - lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) - if err := validateBlobRes(opts.DB, msg.Name, msg.EpochHeight, sectorSize, msg.PrevHash, msg.ReservedRoot, msg.Signature); err != nil { - if opts.EpochHeight == msg.EpochHeight { - if err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { - msg.PayloadPosition = blob.MaxSectors - return store.SetEquivocationProofTx(tx, msg.Name, msg) - }); err != nil { - lgr.Trace("error writing equivocation proof", "err", err) - } - // TODO: handle equivocation proof - // local - // -> update { sectorSize: 0 } - // <- BlobReq { sectorSize: 0xff } - // -> BlobRes { payloadPosition: 0xff } - // remote - // <- update { sectorSize: 0 } - // -> BlobReq { sectorSize: 0xff } - // <- BlobRes { payloadPosition: 0xff } - update := &wire.Update{ - Name: msg.Name, - EpochHeight: msg.EpochHeight, - SectorSize: 0, - } - p2p.GossipAll(opts.Mux, update) - } - errs <- ErrPayloadEquivocation - break - } - } // If prev hash matches, we have an invalid signature, // which cannot be used as a proof of equivocation. // TODO: ban the peer as it is clearly sending invalid data errs <- errors.Wrap(ErrInvalidPayloadSignature, "signature validation failed") break } + // Verify that the prev hash from the remote matches our + // current tip hash i.e. the update starts _after_ our + // latest sector and both the sector hashes match. A + // mismatch indicates a proof of equivocation. + if opts.PrevHash != msg.PrevHash { + lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) + if opts.EpochHeight == msg.EpochHeight { + // TODO: check if eq exists + if err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { + msg.PayloadPosition = blob.MaxSectors + return store.SetEquivocationProofTx(tx, msg.Name, msg) + }); err != nil { + lgr.Trace("error writing equivocation proof", "err", err) + } + // TODO: handle equivocation proof + // local + // -> update { sectorSize: 0 } + // <- BlobReq { sectorSize: 0xff } + // -> BlobRes { payloadPosition: 0xff } + // remote + // <- update { sectorSize: 0 } + // -> BlobReq { sectorSize: 0xff } + // <- BlobRes { payloadPosition: 0xff } + update := &wire.Update{ + Name: msg.Name, + EpochHeight: msg.EpochHeight, + SectorSize: 0, + } + p2p.GossipAll(opts.Mux, update) + } + errs <- ErrPayloadEquivocation + break + } for i := 0; int(i) < len(msg.Payload); i++ { if err := opts.Tx.WriteSector(msg.Payload[i]); err != nil { lgr.Error("failed to write payload", "payload_id", i, "err", err) From ab9c70dceab7745e484f3d560a9ebbea41e510fc Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Wed, 24 Feb 2021 17:48:41 +0530 Subject: [PATCH 52/71] protocol: add TODOs --- protocol/syncer.go | 6 +++++- protocol/update_queue.go | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index c93c80d..b045b64 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -162,7 +162,11 @@ func SyncSectors(opts *SyncSectorsOpts) error { if opts.PrevHash != msg.PrevHash { lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) if opts.EpochHeight == msg.EpochHeight { - // TODO: check if eq exists + // TODO: check and skip if equivocation already exists + // TODO: rewrite to use EquivocationProof wire message: + // version A -> [header, sig] version B -> [payload pos, prev hash, payload, sign] + // remote reconstructs tip hash, sector size and matches versions A and B + // and if both are valid, handles equivocation condition if err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { msg.PayloadPosition = blob.MaxSectors return store.SetEquivocationProofTx(tx, msg.Name, msg) diff --git a/protocol/update_queue.go b/protocol/update_queue.go index 5d6bf53..fc50259 100644 --- a/protocol/update_queue.go +++ b/protocol/update_queue.go @@ -85,6 +85,7 @@ func (u *UpdateQueue) Stop() error { return nil } +// TODO: prioritize higher epochs, sector sizes func (u *UpdateQueue) Enqueue(peerID crypto.Hash, update *wire.Update) error { // use atomic below to prevent having to lock mu // during expensive name validation calls when From 91dc4707e544fc880f6dce1405923295fd54ee3b Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Wed, 24 Feb 2021 18:17:07 +0530 Subject: [PATCH 53/71] wire: update equivocation proof message --- protocol/syncer.go | 21 +++++++++-- store/equivocation_proof.go | 6 ++-- wire/equivocation_proof.go | 70 ++++++++++++++++++++++++------------- 3 files changed, 68 insertions(+), 29 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index b045b64..7093f2d 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -167,9 +167,26 @@ func SyncSectors(opts *SyncSectorsOpts) error { // version A -> [header, sig] version B -> [payload pos, prev hash, payload, sign] // remote reconstructs tip hash, sector size and matches versions A and B // and if both are valid, handles equivocation condition + header, err := store.GetHeader(opts.DB, msg.Name) + if err != nil { + lgr.Trace("error getting headers", "err", err) + break + } if err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { - msg.PayloadPosition = blob.MaxSectors - return store.SetEquivocationProofTx(tx, msg.Name, msg) + proof := &wire.EquivocationProof{ + OurEpochHeight: msg.EpochHeight, + OurPayloadPosition: msg.PayloadPosition, + OurPrevHash: msg.PrevHash, + OurReservedRoot: msg.ReservedRoot, + OurPayload: msg.Payload, + OurSignature: msg.Signature, + TheirEpochHeight: header.EpochHeight, + TheirSectorSize: header.SectorSize, + TheirSectorTipHash: header.SectorTipHash, + TheirReservedRoot: header.ReservedRoot, + TheirSignature: header.Signature, + } + return store.SetEquivocationProofTx(tx, msg.Name, proof) }); err != nil { lgr.Trace("error writing equivocation proof", "err", err) } diff --git a/store/equivocation_proof.go b/store/equivocation_proof.go index ece91a1..14f0e23 100644 --- a/store/equivocation_proof.go +++ b/store/equivocation_proof.go @@ -13,8 +13,8 @@ var ( equivocationProofsPrefix = Prefixer("equivocationproofs") ) -func GeEquivocationProof(db *leveldb.DB, name string) (*wire.BlobRes, error) { - proof := new(wire.BlobRes) +func GeEquivocationProof(db *leveldb.DB, name string) (*wire.EquivocationProof, error) { + proof := new(wire.EquivocationProof) equivocationProofData, err := db.Get(equivocationProofsPrefix(name), nil) if err != nil { return nil, errors.Wrap(err, "error getting equivocation proof data") @@ -24,7 +24,7 @@ func GeEquivocationProof(db *leveldb.DB, name string) (*wire.BlobRes, error) { return proof, nil } -func SetEquivocationProofTx(tx *leveldb.Transaction, name string, proof *wire.BlobRes) error { +func SetEquivocationProofTx(tx *leveldb.Transaction, name string, proof *wire.EquivocationProof) error { var buf bytes.Buffer wr := bufio.NewWriter(&buf) proof.Encode(wr) diff --git a/wire/equivocation_proof.go b/wire/equivocation_proof.go index 5f040db..2c0a11f 100644 --- a/wire/equivocation_proof.go +++ b/wire/equivocation_proof.go @@ -12,13 +12,20 @@ import ( type EquivocationProof struct { HashCacher - Name string - EpochHeight uint16 - PayloadPosition uint16 - PrevHash crypto.Hash - ReservedRoot crypto.Hash - Payload []blob.Sector - Signature crypto.Signature + Name string + + OurEpochHeight uint16 + OurPayloadPosition uint16 + OurPrevHash crypto.Hash + OurReservedRoot crypto.Hash + OurPayload []blob.Sector + OurSignature crypto.Signature + + TheirEpochHeight uint16 + TheirSectorSize uint16 + TheirSectorTipHash crypto.Hash + TheirReservedRoot crypto.Hash + TheirSignature crypto.Signature } var _ Message = (*EquivocationProof)(nil) @@ -34,23 +41,33 @@ func (s *EquivocationProof) Equals(other Message) bool { } return s.Name == cast.Name && - s.EpochHeight == cast.EpochHeight && - s.PayloadPosition == cast.PayloadPosition && - s.PrevHash == cast.PrevHash && - s.ReservedRoot == cast.ReservedRoot && - s.Signature == cast.Signature + s.OurEpochHeight == cast.OurEpochHeight && + s.OurPayloadPosition == cast.OurPayloadPosition && + s.OurPrevHash == cast.OurPrevHash && + s.OurReservedRoot == cast.OurReservedRoot && + s.OurSignature == cast.OurSignature && + s.TheirEpochHeight == cast.TheirEpochHeight && + s.TheirSectorSize == cast.TheirSectorSize && + s.TheirSectorTipHash == cast.TheirSectorTipHash && + s.TheirReservedRoot == cast.TheirReservedRoot && + s.TheirSignature == cast.TheirSignature } func (s *EquivocationProof) Encode(w io.Writer) error { return dwire.EncodeFields( w, s.Name, - s.EpochHeight, - s.PayloadPosition, - s.PrevHash, - s.ReservedRoot, - s.Payload, - s.Signature, + s.OurEpochHeight, + s.OurPayloadPosition, + s.OurPrevHash, + s.OurReservedRoot, + s.OurPayload, + s.OurSignature, + s.TheirEpochHeight, + s.TheirSectorSize, + s.TheirSectorTipHash, + s.TheirReservedRoot, + s.TheirSignature, ) } @@ -58,12 +75,17 @@ func (s *EquivocationProof) Decode(r io.Reader) error { return dwire.DecodeFields( r, &s.Name, - &s.EpochHeight, - &s.PayloadPosition, - &s.PrevHash, - &s.ReservedRoot, - &s.Payload, - &s.Signature, + &s.OurEpochHeight, + &s.OurPayloadPosition, + &s.OurPrevHash, + &s.OurReservedRoot, + &s.OurPayload, + &s.OurSignature, + &s.TheirEpochHeight, + &s.TheirSectorSize, + &s.TheirSectorTipHash, + &s.TheirReservedRoot, + &s.TheirSignature, ) } From 2c3ce1c89941c14dcf544a0f8c2e95a726f432ac Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Wed, 24 Feb 2021 18:22:39 +0530 Subject: [PATCH 54/71] protocol: update equivocation proof construction --- protocol/sector_server.go | 10 ++++------ protocol/syncer.go | 10 +++++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/protocol/sector_server.go b/protocol/sector_server.go index 20015be..dbc4320 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -39,7 +39,7 @@ func NewSectorServer(mux *p2p.PeerMuxer, db *leveldb.DB, bs blob.Store, nameLock func (s *SectorServer) Start() error { s.mux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeBlobReq, s.onBlobReq)) - s.mux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeBlobRes, s.onBlobRes)) + s.mux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeEquivocationProof, s.onEquivocationProof)) return nil } @@ -156,14 +156,12 @@ func (s *SectorServer) sendResponse(peerID crypto.Hash, name string, prevHash cr ) } -func (s *SectorServer) onBlobRes(peerID crypto.Hash, envelope *wire.Envelope) { - reqMsg := envelope.Message.(*wire.BlobRes) +func (s *SectorServer) onEquivocationProof(peerID crypto.Hash, envelope *wire.Envelope) { + reqMsg := envelope.Message.(*wire.EquivocationProof) lgr := s.lgr.Sub( "name", reqMsg.Name, "peer_id", peerID, ) - if reqMsg.PayloadPosition == blob.MaxSectors { - lgr.Trace("handling equivocation response") - } + lgr.Trace("handling equivocation response") return } diff --git a/protocol/syncer.go b/protocol/syncer.go index 7093f2d..27137fe 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -162,11 +162,11 @@ func SyncSectors(opts *SyncSectorsOpts) error { if opts.PrevHash != msg.PrevHash { lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) if opts.EpochHeight == msg.EpochHeight { - // TODO: check and skip if equivocation already exists - // TODO: rewrite to use EquivocationProof wire message: - // version A -> [header, sig] version B -> [payload pos, prev hash, payload, sign] - // remote reconstructs tip hash, sector size and matches versions A and B - // and if both are valid, handles equivocation condition + // skip if equivocation already exists + if _, err := store.GeEquivocationProof(opts.DB, msg.Name); err == nil { + lgr.Trace("skipping update, equivocation exists") + break + } header, err := store.GetHeader(opts.DB, msg.Name) if err != nil { lgr.Trace("error getting headers", "err", err) From 50cfe0178e5131774cedd80dc65e4c291125a167 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 25 Feb 2021 12:31:00 +0530 Subject: [PATCH 55/71] protocol: update equivocation proof test --- protocol/updater_test.go | 99 ++++++++++------------------------------ 1 file changed, 25 insertions(+), 74 deletions(-) diff --git a/protocol/updater_test.go b/protocol/updater_test.go index 2153f89..9d86b97 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -30,15 +30,6 @@ func TestUpdater(t *testing.T) { { "syncs sectors when the local node has never seen the blob", func(t *testing.T, setup *updaterTestSetup) { - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - if err := store.SetInitialImportCompleteTx(tx); err != nil { - return err - } - if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { - return err - } - return nil - })) ts := time.Now() update := mockapp.FillBlobRandom( t, @@ -72,15 +63,6 @@ func TestUpdater(t *testing.T) { { "syncs sectors when the local node has an older blob", func(t *testing.T, setup *updaterTestSetup) { - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - if err := store.SetInitialImportCompleteTx(tx); err != nil { - return err - } - if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { - return err - } - return nil - })) ts := time.Now() epochHeight := CurrentEpoch(name) sectorSize := uint16(10) @@ -129,15 +111,6 @@ func TestUpdater(t *testing.T) { { "aborts sync when there is an equivocation", func(t *testing.T, setup *updaterTestSetup) { - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - if err := store.SetInitialImportCompleteTx(tx); err != nil { - return err - } - if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { - return err - } - return nil - })) ts := time.Now() epochHeight := CurrentEpoch(name) sectorSize := uint16(10) @@ -190,16 +163,6 @@ func TestUpdater(t *testing.T) { { "aborts sync when there is a invalid payload signature", func(t *testing.T, setup *updaterTestSetup) { - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - if err := store.SetInitialImportCompleteTx(tx); err != nil { - return err - } - // TODO: ideally setup a fake signer - if err := store.SetNameInfoTx(tx, name, setup.tp.LocalSigner.Pub(), 10); err != nil { - return err - } - return nil - })) ts := time.Now() epochHeight := CurrentEpoch(name) sectorSize := uint16(10) @@ -215,9 +178,16 @@ func TestUpdater(t *testing.T) { mockapp.NullReader, ) // The sectors are generated from null reader, so there won't - // be an equivocation, however we used local signer on the + // be an equivocation, however we use local signer on the // remote (instead of remote signer like other test cases // above), so it generates an invalid signature. + require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + // TODO: ideally setup a fake signer + if err := store.SetNameInfoTx(tx, name, setup.tp.LocalSigner.Pub(), 10); err != nil { + return err + } + return nil + })) update := mockapp.FillBlobReader( t, setup.rs.DB, @@ -252,15 +222,6 @@ func TestUpdater(t *testing.T) { { "aborts sync if the new sector size is equal to the stored sector size", func(t *testing.T, setup *updaterTestSetup) { - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - if err := store.SetInitialImportCompleteTx(tx); err != nil { - return err - } - if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { - return err - } - return nil - })) ts := time.Now() epochHeight := CurrentEpoch(name) sectorSize := uint16(0) @@ -304,15 +265,6 @@ func TestUpdater(t *testing.T) { { "aborts sync if the name is locked", func(t *testing.T, setup *updaterTestSetup) { - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - if err := store.SetInitialImportCompleteTx(tx); err != nil { - return err - } - if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { - return err - } - return nil - })) locker := util.NewMultiLocker() require.True(t, locker.TryLock(name)) cfg := &UpdateConfig{ @@ -336,15 +288,6 @@ func TestUpdater(t *testing.T) { { "aborts sync if the new sector size is equal to the stored sector size", func(t *testing.T, setup *updaterTestSetup) { - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - if err := store.SetInitialImportCompleteTx(tx); err != nil { - return err - } - if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { - return err - } - return nil - })) ts := time.Now() epochHeight := CurrentEpoch(name) sectorSize := uint16(0) @@ -388,15 +331,6 @@ func TestUpdater(t *testing.T) { { "aborts sync if the name is locked", func(t *testing.T, setup *updaterTestSetup) { - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - if err := store.SetInitialImportCompleteTx(tx); err != nil { - return err - } - if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { - return err - } - return nil - })) locker := util.NewMultiLocker() require.True(t, locker.TryLock(name)) cfg := &UpdateConfig{ @@ -429,6 +363,23 @@ func TestUpdater(t *testing.T) { remoteSS := NewSectorServer(testPeers.RemoteMux, remoteStorage.DB, remoteStorage.BlobStore, util.NewMultiLocker()) require.NoError(t, remoteSS.Start()) defer require.NoError(t, remoteSS.Stop()) + localSS := NewSectorServer(testPeers.LocalMux, localStorage.DB, localStorage.BlobStore, util.NewMultiLocker()) + require.NoError(t, localSS.Start()) + defer require.NoError(t, localSS.Stop()) + go func() { + remoteUQ := NewUpdateQueue(testPeers.RemoteMux, localStorage.DB) + require.NoError(t, remoteUQ.Start()) + defer require.NoError(t, remoteUQ.Stop()) + }() + require.NoError(t, store.WithTx(localStorage.DB, func(tx *leveldb.Transaction) error { + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, testPeers.RemoteSigner.Pub(), 10); err != nil { + return err + } + return nil + })) tt.run(t, &updaterTestSetup{ tp: testPeers, From 5b92dabf9df141099be3103a35f2da647484e426 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 25 Feb 2021 15:23:30 +0530 Subject: [PATCH 56/71] protocol: handle equivocation request --- protocol/sector_server.go | 13 +++++++++++-- protocol/syncer.go | 4 ++-- store/equivocation_proof.go | 20 ++++++++------------ 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/protocol/sector_server.go b/protocol/sector_server.go index dbc4320..27b3fe7 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -1,6 +1,7 @@ package protocol import ( + "bytes" "fmt" "fnd/blob" "fnd/config" @@ -56,14 +57,22 @@ func (s *SectorServer) onBlobReq(peerID crypto.Hash, envelope *wire.Envelope) { if reqMsg.SectorSize == blob.MaxSectors { // handle equivocation proof - blobRes, err := store.GeEquivocationProof(s.db, reqMsg.Name) + raw, err := store.GetEquivocationProof(s.db, reqMsg.Name) if err != nil { lgr.Error( "failed to fetch equivocation proof", "err", err) return } - if err := s.mux.Send(peerID, blobRes); err != nil { + proof := &wire.EquivocationProof{} + buf := bytes.NewReader(raw) + if err := proof.Decode(buf); err != nil { + lgr.Error( + "failed to deserialize equivocation proof", + "err", err) + return + } + if err := s.mux.Send(peerID, proof); err != nil { s.lgr.Error("error serving equivocation proof", "err", err) return } diff --git a/protocol/syncer.go b/protocol/syncer.go index 27137fe..5376d40 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -163,13 +163,13 @@ func SyncSectors(opts *SyncSectorsOpts) error { lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) if opts.EpochHeight == msg.EpochHeight { // skip if equivocation already exists - if _, err := store.GeEquivocationProof(opts.DB, msg.Name); err == nil { + if _, err := store.GetEquivocationProof(opts.DB, msg.Name); err == nil { lgr.Trace("skipping update, equivocation exists") break } header, err := store.GetHeader(opts.DB, msg.Name) if err != nil { - lgr.Trace("error getting headers", "err", err) + lgr.Trace("error getting header", "err", err) break } if err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { diff --git a/store/equivocation_proof.go b/store/equivocation_proof.go index 14f0e23..ac43d73 100644 --- a/store/equivocation_proof.go +++ b/store/equivocation_proof.go @@ -1,7 +1,6 @@ package store import ( - "bufio" "bytes" "fnd/wire" @@ -13,23 +12,20 @@ var ( equivocationProofsPrefix = Prefixer("equivocationproofs") ) -func GeEquivocationProof(db *leveldb.DB, name string) (*wire.EquivocationProof, error) { - proof := new(wire.EquivocationProof) - equivocationProofData, err := db.Get(equivocationProofsPrefix(name), nil) +func GetEquivocationProof(db *leveldb.DB, name string) ([]byte, error) { + bytes, err := db.Get(equivocationProofsPrefix(name), nil) if err != nil { - return nil, errors.Wrap(err, "error getting equivocation proof data") + return nil, errors.Wrap(err, "error getting equivocation proof") } - wr := bytes.NewReader(equivocationProofData) - proof.Decode(wr) - return proof, nil + return bytes, nil } func SetEquivocationProofTx(tx *leveldb.Transaction, name string, proof *wire.EquivocationProof) error { var buf bytes.Buffer - wr := bufio.NewWriter(&buf) - proof.Encode(wr) - if err := tx.Put(equivocationProofsPrefix(proof.Name), buf.Bytes(), nil); err != nil { - return errors.Wrap(err, "error writing equivocation proof") + proof.Encode(&buf) + err := tx.Put(equivocationProofsPrefix(name), buf.Bytes(), nil) + if err != nil { + return errors.Wrap(err, "error setting equivocation proof") } return nil } From bbc69cb7dba9362b751fa60fdc2b3327e86ce23f Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 25 Feb 2021 15:26:07 +0530 Subject: [PATCH 57/71] protocol: rename equivocation proof fields --- protocol/syncer.go | 22 +++++----- wire/equivocation_proof.go | 86 +++++++++++++++++++------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index 5376d40..7de2078 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -174,17 +174,17 @@ func SyncSectors(opts *SyncSectorsOpts) error { } if err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { proof := &wire.EquivocationProof{ - OurEpochHeight: msg.EpochHeight, - OurPayloadPosition: msg.PayloadPosition, - OurPrevHash: msg.PrevHash, - OurReservedRoot: msg.ReservedRoot, - OurPayload: msg.Payload, - OurSignature: msg.Signature, - TheirEpochHeight: header.EpochHeight, - TheirSectorSize: header.SectorSize, - TheirSectorTipHash: header.SectorTipHash, - TheirReservedRoot: header.ReservedRoot, - TheirSignature: header.Signature, + RemoteEpochHeight: msg.EpochHeight, + RemotePayloadPosition: msg.PayloadPosition, + RemotePrevHash: msg.PrevHash, + RemoteReservedRoot: msg.ReservedRoot, + RemotePayload: msg.Payload, + RemoteSignature: msg.Signature, + LocalEpochHeight: header.EpochHeight, + LocalSectorSize: header.SectorSize, + LocalSectorTipHash: header.SectorTipHash, + LocalReservedRoot: header.ReservedRoot, + LocalSignature: header.Signature, } return store.SetEquivocationProofTx(tx, msg.Name, proof) }); err != nil { diff --git a/wire/equivocation_proof.go b/wire/equivocation_proof.go index 2c0a11f..2f9f042 100644 --- a/wire/equivocation_proof.go +++ b/wire/equivocation_proof.go @@ -14,18 +14,18 @@ type EquivocationProof struct { Name string - OurEpochHeight uint16 - OurPayloadPosition uint16 - OurPrevHash crypto.Hash - OurReservedRoot crypto.Hash - OurPayload []blob.Sector - OurSignature crypto.Signature + RemoteEpochHeight uint16 + RemotePayloadPosition uint16 + RemotePrevHash crypto.Hash + RemoteReservedRoot crypto.Hash + RemotePayload []blob.Sector + RemoteSignature crypto.Signature - TheirEpochHeight uint16 - TheirSectorSize uint16 - TheirSectorTipHash crypto.Hash - TheirReservedRoot crypto.Hash - TheirSignature crypto.Signature + LocalEpochHeight uint16 + LocalSectorSize uint16 + LocalSectorTipHash crypto.Hash + LocalReservedRoot crypto.Hash + LocalSignature crypto.Signature } var _ Message = (*EquivocationProof)(nil) @@ -41,33 +41,33 @@ func (s *EquivocationProof) Equals(other Message) bool { } return s.Name == cast.Name && - s.OurEpochHeight == cast.OurEpochHeight && - s.OurPayloadPosition == cast.OurPayloadPosition && - s.OurPrevHash == cast.OurPrevHash && - s.OurReservedRoot == cast.OurReservedRoot && - s.OurSignature == cast.OurSignature && - s.TheirEpochHeight == cast.TheirEpochHeight && - s.TheirSectorSize == cast.TheirSectorSize && - s.TheirSectorTipHash == cast.TheirSectorTipHash && - s.TheirReservedRoot == cast.TheirReservedRoot && - s.TheirSignature == cast.TheirSignature + s.RemoteEpochHeight == cast.RemoteEpochHeight && + s.RemotePayloadPosition == cast.RemotePayloadPosition && + s.RemotePrevHash == cast.RemotePrevHash && + s.RemoteReservedRoot == cast.RemoteReservedRoot && + s.RemoteSignature == cast.RemoteSignature && + s.LocalEpochHeight == cast.LocalEpochHeight && + s.LocalSectorSize == cast.LocalSectorSize && + s.LocalSectorTipHash == cast.LocalSectorTipHash && + s.LocalReservedRoot == cast.LocalReservedRoot && + s.LocalSignature == cast.LocalSignature } func (s *EquivocationProof) Encode(w io.Writer) error { return dwire.EncodeFields( w, s.Name, - s.OurEpochHeight, - s.OurPayloadPosition, - s.OurPrevHash, - s.OurReservedRoot, - s.OurPayload, - s.OurSignature, - s.TheirEpochHeight, - s.TheirSectorSize, - s.TheirSectorTipHash, - s.TheirReservedRoot, - s.TheirSignature, + s.RemoteEpochHeight, + s.RemotePayloadPosition, + s.RemotePrevHash, + s.RemoteReservedRoot, + s.RemotePayload, + s.RemoteSignature, + s.LocalEpochHeight, + s.LocalSectorSize, + s.LocalSectorTipHash, + s.LocalReservedRoot, + s.LocalSignature, ) } @@ -75,17 +75,17 @@ func (s *EquivocationProof) Decode(r io.Reader) error { return dwire.DecodeFields( r, &s.Name, - &s.OurEpochHeight, - &s.OurPayloadPosition, - &s.OurPrevHash, - &s.OurReservedRoot, - &s.OurPayload, - &s.OurSignature, - &s.TheirEpochHeight, - &s.TheirSectorSize, - &s.TheirSectorTipHash, - &s.TheirReservedRoot, - &s.TheirSignature, + &s.RemoteEpochHeight, + &s.RemotePayloadPosition, + &s.RemotePrevHash, + &s.RemoteReservedRoot, + &s.RemotePayload, + &s.RemoteSignature, + &s.LocalEpochHeight, + &s.LocalSectorSize, + &s.LocalSectorTipHash, + &s.LocalReservedRoot, + &s.LocalSignature, ) } From 5d5173874b495daaa58d10acd5785b5217fa7e68 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 25 Feb 2021 15:27:30 +0530 Subject: [PATCH 58/71] protocol: update TODO --- protocol/syncer.go | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index 7de2078..d89c44a 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -167,6 +167,7 @@ func SyncSectors(opts *SyncSectorsOpts) error { lgr.Trace("skipping update, equivocation exists") break } + // TODO: record timestamp and ban this name header, err := store.GetHeader(opts.DB, msg.Name) if err != nil { lgr.Trace("error getting header", "err", err) @@ -180,25 +181,16 @@ func SyncSectors(opts *SyncSectorsOpts) error { RemoteReservedRoot: msg.ReservedRoot, RemotePayload: msg.Payload, RemoteSignature: msg.Signature, - LocalEpochHeight: header.EpochHeight, - LocalSectorSize: header.SectorSize, - LocalSectorTipHash: header.SectorTipHash, - LocalReservedRoot: header.ReservedRoot, - LocalSignature: header.Signature, + LocalEpochHeight: header.EpochHeight, + LocalSectorSize: header.SectorSize, + LocalSectorTipHash: header.SectorTipHash, + LocalReservedRoot: header.ReservedRoot, + LocalSignature: header.Signature, } return store.SetEquivocationProofTx(tx, msg.Name, proof) }); err != nil { lgr.Trace("error writing equivocation proof", "err", err) } - // TODO: handle equivocation proof - // local - // -> update { sectorSize: 0 } - // <- BlobReq { sectorSize: 0xff } - // -> BlobRes { payloadPosition: 0xff } - // remote - // <- update { sectorSize: 0 } - // -> BlobReq { sectorSize: 0xff } - // <- BlobRes { payloadPosition: 0xff } update := &wire.Update{ Name: msg.Name, EpochHeight: msg.EpochHeight, From cbedf5faf1df73722de7fbd1e8b450d87af28d7e Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 25 Feb 2021 15:55:57 +0530 Subject: [PATCH 59/71] protocol: validate eq proof --- protocol/sector_server.go | 40 ++++++++++++++++++++++++++++++++++++--- protocol/syncer.go | 1 + protocol/updater_test.go | 10 ++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/protocol/sector_server.go b/protocol/sector_server.go index 27b3fe7..fa5ca6b 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -166,11 +166,45 @@ func (s *SectorServer) sendResponse(peerID crypto.Hash, name string, prevHash cr } func (s *SectorServer) onEquivocationProof(peerID crypto.Hash, envelope *wire.Envelope) { - reqMsg := envelope.Message.(*wire.EquivocationProof) + msg := envelope.Message.(*wire.EquivocationProof) lgr := s.lgr.Sub( - "name", reqMsg.Name, + "name", msg.Name, "peer_id", peerID, ) - lgr.Trace("handling equivocation response") + lgr.Trace("handling equivocation response", "name", msg.Name) + if msg.LocalEpochHeight != msg.RemoteEpochHeight { + s.lgr.Warn("unexpected epoch height", "local_epoch_height", msg.LocalEpochHeight, "remote_epoch_height", msg.RemoteEpochHeight) + return + } + if msg.LocalSectorSize != msg.RemotePayloadPosition { + s.lgr.Warn("unexpected sector size", "local_sector_size", msg.LocalSectorSize, "remote_payload_position", msg.RemotePayloadPosition) + return + } + if err := validateBlobRes(s.db, msg.Name, msg.LocalEpochHeight, msg.LocalSectorSize, msg.LocalSectorTipHash, msg.LocalReservedRoot, msg.LocalSignature); err != nil { + lgr.Warn("local signaure validation failed", "err", err) + return + } + sectorSize := msg.RemotePayloadPosition + uint16(len(msg.RemotePayload)) + // Additional sanity check: make sure that update does not overflow max sectors. + if int(sectorSize) > blob.MaxSectors { + lgr.Warn("received unexpected sector size", "sector_size", sectorSize, "max", blob.MaxSectors) + return + } + // Generate the current tip hash from prev hash and the payload + // sectors. + var sectorTipHash crypto.Hash = msg.RemotePrevHash + for i := 0; int(i) < len(msg.RemotePayload); i++ { + sectorTipHash = blob.SerialHashSector(msg.RemotePayload[i], sectorTipHash) + } + // Verify that the update is valid by using the recomputed + // sector size, sector tip hash and other metadata. This data + // is first hashed and the signature is validated against the + // name's pubkey. See validateBlobRes. + // TODO: store the latest tip hash + if err := validateBlobRes(s.db, msg.Name, msg.RemoteEpochHeight, sectorSize, sectorTipHash, msg.RemoteReservedRoot, msg.RemoteSignature); err != nil { + lgr.Warn("remote signaure validation failed", "err", err) + return + } + // TODO: log timestamp and ban name return } diff --git a/protocol/syncer.go b/protocol/syncer.go index d89c44a..14639c3 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -175,6 +175,7 @@ func SyncSectors(opts *SyncSectorsOpts) error { } if err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { proof := &wire.EquivocationProof{ + Name: msg.Name, RemoteEpochHeight: msg.EpochHeight, RemotePayloadPosition: msg.PayloadPosition, RemotePrevHash: msg.PrevHash, diff --git a/protocol/updater_test.go b/protocol/updater_test.go index 9d86b97..35e0c90 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -111,6 +111,15 @@ func TestUpdater(t *testing.T) { { "aborts sync when there is an equivocation", func(t *testing.T, setup *updaterTestSetup) { + require.NoError(t, store.WithTx(setup.rs.DB, func(tx *leveldb.Transaction) error { + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, setup.tp.LocalSigner.Pub(), 10); err != nil { + return err + } + return nil + })) ts := time.Now() epochHeight := CurrentEpoch(name) sectorSize := uint16(10) @@ -157,6 +166,7 @@ func TestUpdater(t *testing.T) { } err := UpdateBlob(cfg) require.NotNil(t, err) + time.Sleep(time.Second) require.True(t, errors.Is(err, ErrPayloadEquivocation)) }, }, From 12c9316d8c09ff910de16f4ce4cfc2e28c0805be Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 25 Feb 2021 15:57:45 +0530 Subject: [PATCH 60/71] protocol: handle valid equivocation proof --- protocol/sector_server.go | 1 + protocol/updater_test.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/protocol/sector_server.go b/protocol/sector_server.go index fa5ca6b..1b342af 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -205,6 +205,7 @@ func (s *SectorServer) onEquivocationProof(peerID crypto.Hash, envelope *wire.En lgr.Warn("remote signaure validation failed", "err", err) return } + lgr.Trace("equivocation proof valid ", "name", msg.Name) // TODO: log timestamp and ban name return } diff --git a/protocol/updater_test.go b/protocol/updater_test.go index 35e0c90..c1409c5 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -115,7 +115,7 @@ func TestUpdater(t *testing.T) { if err := store.SetInitialImportCompleteTx(tx); err != nil { return err } - if err := store.SetNameInfoTx(tx, name, setup.tp.LocalSigner.Pub(), 10); err != nil { + if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { return err } return nil From 6dc3e1c5a7384abdcabe8d022cc336173ae1b72e Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 25 Feb 2021 17:03:30 +0530 Subject: [PATCH 61/71] protocol: epoch height and equivocation status check --- protocol/sector_server.go | 59 ++++++++++++++++++++++++++++++++------- protocol/syncer.go | 3 +- protocol/update_queue.go | 2 +- rpc/server.go | 1 + 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/protocol/sector_server.go b/protocol/sector_server.go index 1b342af..a43c80f 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -55,8 +55,30 @@ func (s *SectorServer) onBlobReq(peerID crypto.Hash, envelope *wire.Envelope) { "peer_id", peerID, ) + header, err := store.GetHeader(s.db, reqMsg.Name) + if err != nil { + lgr.Error( + "failed to fetch header", + "err", err) + return + } + + if header.EpochHeight < reqMsg.EpochHeight { + lgr.Error( + "request epoch height must be <= header epoch height", + "request_epoch_height", reqMsg.EpochHeight, + "header_epoch_height", header.EpochHeight) + return + } + if reqMsg.SectorSize == blob.MaxSectors { - // handle equivocation proof + if header.EpochHeight != reqMsg.EpochHeight { + lgr.Error( + "request epoch height must be == header epoch height", + "request_epoch_height", reqMsg.EpochHeight, + "header_epoch_height", header.EpochHeight) + return + } raw, err := store.GetEquivocationProof(s.db, reqMsg.Name) if err != nil { lgr.Error( @@ -84,14 +106,6 @@ func (s *SectorServer) onBlobReq(peerID crypto.Hash, envelope *wire.Envelope) { return } - header, err := store.GetHeader(s.db, reqMsg.Name) - if err != nil { - lgr.Error( - "failed to fetch header", - "err", err) - return - } - var prevHash crypto.Hash = blob.ZeroHash if reqMsg.SectorSize != 0 { hash, err := store.GetSectorHash(s.db, reqMsg.Name, reqMsg.SectorSize-1) @@ -171,11 +185,32 @@ func (s *SectorServer) onEquivocationProof(peerID crypto.Hash, envelope *wire.En "name", msg.Name, "peer_id", peerID, ) + lgr.Trace("handling equivocation response", "name", msg.Name) if msg.LocalEpochHeight != msg.RemoteEpochHeight { s.lgr.Warn("unexpected epoch height", "local_epoch_height", msg.LocalEpochHeight, "remote_epoch_height", msg.RemoteEpochHeight) return } + + // Skip if equivocation already exists + if _, err := store.GetEquivocationProof(s.db, msg.Name); err == nil { + lgr.Trace("skipping equivocation proof, equivocation exists") + return + } + + header, err := store.GetHeader(s.db, msg.Name) + if err != nil { + lgr.Error( + "failed to fetch header", + "err", err) + return + } + + if header.EpochHeight > msg.RemoteEpochHeight { + s.lgr.Warn("remote epoch height must be <= header epoch heigth", "header_epoch_height", header.EpochHeight, "remote_epoch_height", msg.RemoteEpochHeight) + return + } + if msg.LocalSectorSize != msg.RemotePayloadPosition { s.lgr.Warn("unexpected sector size", "local_sector_size", msg.LocalSectorSize, "remote_payload_position", msg.RemotePayloadPosition) return @@ -206,6 +241,10 @@ func (s *SectorServer) onEquivocationProof(peerID crypto.Hash, envelope *wire.En return } lgr.Trace("equivocation proof valid ", "name", msg.Name) - // TODO: log timestamp and ban name + if err := store.WithTx(s.db, func(tx *leveldb.Transaction) error { + return store.SetEquivocationProofTx(tx, msg.Name, msg) + }); err != nil { + lgr.Trace("error writing equivocation proof", "err", err) + } return } diff --git a/protocol/syncer.go b/protocol/syncer.go index 14639c3..7e5af19 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -162,7 +162,7 @@ func SyncSectors(opts *SyncSectorsOpts) error { if opts.PrevHash != msg.PrevHash { lgr.Trace("received unexpected prev hash", "expected_prev_hash", opts.PrevHash, "received_prev_hash", msg.PrevHash) if opts.EpochHeight == msg.EpochHeight { - // skip if equivocation already exists + // Skip if equivocation already exists if _, err := store.GetEquivocationProof(opts.DB, msg.Name); err == nil { lgr.Trace("skipping update, equivocation exists") break @@ -173,6 +173,7 @@ func SyncSectors(opts *SyncSectorsOpts) error { lgr.Trace("error getting header", "err", err) break } + // TODO: rename A, B if err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { proof := &wire.EquivocationProof{ Name: msg.Name, diff --git a/protocol/update_queue.go b/protocol/update_queue.go index fc50259..67a890d 100644 --- a/protocol/update_queue.go +++ b/protocol/update_queue.go @@ -85,7 +85,7 @@ func (u *UpdateQueue) Stop() error { return nil } -// TODO: prioritize higher epochs, sector sizes +// TODO: prioritize equivocations first, then higher epochs and sector sizes func (u *UpdateQueue) Enqueue(peerID crypto.Hash, update *wire.Update) error { // use atomic below to prevent having to lock mu // during expensive name validation calls when diff --git a/rpc/server.go b/rpc/server.go index 354d0af..310a952 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -367,6 +367,7 @@ func (s *Server) ResetEpoch(ctx context.Context, req *apiv1.ResetEpochReq) (*api return nil, err } + // double check epoch increment if header.EpochHeight >= protocol.CurrentEpoch(name) { return nil, errors.New("cannot reset epoch ahead of schedule") } From 5d2b2257101e5d18e50b143eb4254fea8eaca813 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Fri, 26 Feb 2021 18:36:06 +0530 Subject: [PATCH 62/71] protocol: set header banned time and skip if so --- protocol/sector_server.go | 41 +++++++++++++++++++---------- protocol/syncer.go | 7 +++++ protocol/updater.go | 9 +++++-- protocol/updater_test.go | 54 +++++++++++++++------------------------ store/headers.go | 37 +++++++++++++++++++-------- 5 files changed, 89 insertions(+), 59 deletions(-) diff --git a/protocol/sector_server.go b/protocol/sector_server.go index a43c80f..881110f 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -71,14 +71,9 @@ func (s *SectorServer) onBlobReq(peerID crypto.Hash, envelope *wire.Envelope) { return } + // Blob request with SectorSize == blob.MaxSectors is an equivocation + // request. Respond with equivocation proof. if reqMsg.SectorSize == blob.MaxSectors { - if header.EpochHeight != reqMsg.EpochHeight { - lgr.Error( - "request epoch height must be == header epoch height", - "request_epoch_height", reqMsg.EpochHeight, - "header_epoch_height", header.EpochHeight) - return - } raw, err := store.GetEquivocationProof(s.db, reqMsg.Name) if err != nil { lgr.Error( @@ -192,20 +187,34 @@ func (s *SectorServer) onEquivocationProof(peerID crypto.Hash, envelope *wire.En return } - // Skip if equivocation already exists - if _, err := store.GetEquivocationProof(s.db, msg.Name); err == nil { - lgr.Trace("skipping equivocation proof, equivocation exists") + header, err := store.GetHeader(s.db, msg.Name) + if err != nil { + lgr.Error( + "failed to fetch header", + "err", err) return } - header, err := store.GetHeader(s.db, msg.Name) + bannedAt, err := store.GetHeaderBan(s.db, msg.Name) if err != nil { lgr.Error( - "failed to fetch header", + "failed to fetch header ban", "err", err) return } + // Skip if name is already in equivocated state. + if !bannedAt.IsZero() && bannedAt.Add(7*24*time.Duration(time.Hour)).After(time.Now()) { + s.lgr.Warn("name banned", "name", msg.Name) + return + } + + // Skip if equivocation proof was already used to ban. + if !bannedAt.IsZero() && header.EpochHeight == msg.RemoteEpochHeight { + s.lgr.Warn("already equivocated", "name", msg.Name) + return + } + if header.EpochHeight > msg.RemoteEpochHeight { s.lgr.Warn("remote epoch height must be <= header epoch heigth", "header_epoch_height", header.EpochHeight, "remote_epoch_height", msg.RemoteEpochHeight) return @@ -235,7 +244,6 @@ func (s *SectorServer) onEquivocationProof(peerID crypto.Hash, envelope *wire.En // sector size, sector tip hash and other metadata. This data // is first hashed and the signature is validated against the // name's pubkey. See validateBlobRes. - // TODO: store the latest tip hash if err := validateBlobRes(s.db, msg.Name, msg.RemoteEpochHeight, sectorSize, sectorTipHash, msg.RemoteReservedRoot, msg.RemoteSignature); err != nil { lgr.Warn("remote signaure validation failed", "err", err) return @@ -246,5 +254,12 @@ func (s *SectorServer) onEquivocationProof(peerID crypto.Hash, envelope *wire.En }); err != nil { lgr.Trace("error writing equivocation proof", "err", err) } + err = store.WithTx(s.db, func(tx *leveldb.Transaction) error { + return store.SetHeaderBan(tx, msg.Name, time.Time{}) + }) + if err != nil { + lgr.Warn("error setting header banned", "err", err) + return + } return } diff --git a/protocol/syncer.go b/protocol/syncer.go index 7e5af19..07a78f5 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -173,6 +173,13 @@ func SyncSectors(opts *SyncSectorsOpts) error { lgr.Trace("error getting header", "err", err) break } + err = store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { + return store.SetHeaderBan(tx, msg.Name, time.Time{}) + }) + if err != nil { + lgr.Trace("error setting header banned", "err", err) + break + } // TODO: rename A, B if err := store.WithTx(opts.DB, func(tx *leveldb.Transaction) error { proof := &wire.EquivocationProof{ diff --git a/protocol/updater.go b/protocol/updater.go index 38cdcad..1828ad7 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -151,13 +151,18 @@ func UpdateBlob(cfg *UpdateConfig) error { return ErrInvalidEpochBackdated } + bannedAt, err := store.GetHeaderBan(cfg.DB, item.Name) + if err != nil { + return err + } + // If it is higher (skip if it's appending data to the same epoch) if header != nil && item.EpochHeight > epochHeight { // Recovery from banning must increment the epoch by at least 2 and one // real week since the local node banned - if header.Banned { + if !bannedAt.IsZero() { // Banned for at least a week - if header.BannedAt.Add(7 * 24 * time.Duration(time.Hour)).After(time.Now()) { + if bannedAt.Add(7 * 24 * time.Duration(time.Hour)).After(time.Now()) { return ErrNameBanned } diff --git a/protocol/updater_test.go b/protocol/updater_test.go index c1409c5..576c0aa 100644 --- a/protocol/updater_test.go +++ b/protocol/updater_test.go @@ -381,6 +381,7 @@ func TestUpdater(t *testing.T) { require.NoError(t, remoteUQ.Start()) defer require.NoError(t, remoteUQ.Stop()) }() + require.NoError(t, store.WithTx(localStorage.DB, func(tx *leveldb.Transaction) error { if err := store.SetInitialImportCompleteTx(tx); err != nil { return err @@ -409,15 +410,6 @@ func TestEpoch(t *testing.T) { { "syncs sectors when the local node has never seen the name before", func(t *testing.T, setup *updaterTestSetup) { - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - if err := store.SetInitialImportCompleteTx(tx); err != nil { - return err - } - if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { - return err - } - return nil - })) ts := time.Now() update := mockapp.FillBlobRandom( t, @@ -464,12 +456,14 @@ func TestEpoch(t *testing.T) { }, } require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + err := store.SetHeaderBan(tx, name, time.Time{}) + if err != nil { + return err + } return store.SetHeaderTx(tx, &store.Header{ Name: name, EpochHeight: 0, SectorSize: 10, - Banned: true, - BannedAt: time.Now().Add(-1 * 24 * time.Duration(time.Hour)), }, blob.ZeroSectorHashes) })) err := UpdateBlob(cfg) @@ -480,15 +474,6 @@ func TestEpoch(t *testing.T) { { "syncs sectors when the name ban has passed", func(t *testing.T, setup *updaterTestSetup) { - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - if err := store.SetInitialImportCompleteTx(tx); err != nil { - return err - } - if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { - return err - } - return nil - })) ts := time.Now() update := mockapp.FillBlobRandom( t, @@ -496,7 +481,7 @@ func TestEpoch(t *testing.T) { setup.rs.BlobStore, setup.tp.RemoteSigner, name, - 0, + CurrentEpoch(name)+1, blob.SectorBytes, ts, ) @@ -516,12 +501,14 @@ func TestEpoch(t *testing.T) { }, } require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { + err := store.SetHeaderBan(tx, name, time.Now().Add(-10*24*time.Duration(time.Hour))) + if err != nil { + return err + } return store.SetHeaderTx(tx, &store.Header{ Name: name, EpochHeight: 0, SectorSize: 0, - Banned: true, - BannedAt: time.Now().Add(-8 * 24 * time.Duration(time.Hour)), }, blob.ZeroSectorHashes) })) require.NoError(t, UpdateBlob(cfg)) @@ -577,8 +564,6 @@ func TestEpoch(t *testing.T) { Name: name, EpochHeight: CurrentEpoch(name), SectorSize: 10, - Banned: true, - BannedAt: time.Now().Add(-1 * 24 * time.Duration(time.Hour)), }, blob.ZeroSectorHashes) })) err := UpdateBlob(cfg) @@ -616,15 +601,6 @@ func TestEpoch(t *testing.T) { { "rewrites partial blob with new blob on epoch rollover", func(t *testing.T, setup *updaterTestSetup) { - require.NoError(t, store.WithTx(setup.ls.DB, func(tx *leveldb.Transaction) error { - if err := store.SetInitialImportCompleteTx(tx); err != nil { - return err - } - if err := store.SetNameInfoTx(tx, name, setup.tp.RemoteSigner.Pub(), 10); err != nil { - return err - } - return nil - })) ts := time.Now() update := mockapp.FillBlobRandom( t, @@ -675,6 +651,16 @@ func TestEpoch(t *testing.T) { require.NoError(t, remoteSS.Start()) defer require.NoError(t, remoteSS.Stop()) + require.NoError(t, store.WithTx(localStorage.DB, func(tx *leveldb.Transaction) error { + if err := store.SetInitialImportCompleteTx(tx); err != nil { + return err + } + if err := store.SetNameInfoTx(tx, name, testPeers.RemoteSigner.Pub(), 10); err != nil { + return err + } + return nil + })) + tt.run(t, &updaterTestSetup{ tp: testPeers, ls: localStorage, diff --git a/store/headers.go b/store/headers.go index f7aa18e..b6db6e4 100644 --- a/store/headers.go +++ b/store/headers.go @@ -24,8 +24,6 @@ type Header struct { Signature crypto.Signature ReservedRoot crypto.Hash EpochStartAt time.Time - Banned bool - BannedAt time.Time } func (h *Header) MarshalJSON() ([]byte, error) { @@ -37,8 +35,6 @@ func (h *Header) MarshalJSON() ([]byte, error) { Signature string `json:"signature"` ReservedRoot string `json:"reserved_root"` EpochStartAt time.Time `json:"epoch_start_at"` - Banned bool `json:"banned"` - BannedAt time.Time `json:"banned_at"` }{ h.Name, h.EpochHeight, @@ -47,8 +43,6 @@ func (h *Header) MarshalJSON() ([]byte, error) { h.Signature.String(), h.ReservedRoot.String(), h.EpochStartAt, - h.Banned, - h.BannedAt, } return json.Marshal(out) @@ -63,8 +57,6 @@ func (h *Header) UnmarshalJSON(b []byte) error { Signature string `json:"signature"` ReservedRoot string `json:"reserved_root"` EpochStartAt time.Time `json:"epoch_start_at"` - Banned bool `json:"banned"` - BannedAt time.Time `json:"banned_at"` }{} if err := json.Unmarshal(b, in); err != nil { return err @@ -101,8 +93,6 @@ func (h *Header) UnmarshalJSON(b []byte) error { h.Signature = sig h.ReservedRoot = rr h.EpochStartAt = in.EpochStartAt - h.Banned = in.Banned - h.BannedAt = in.BannedAt return nil } @@ -110,6 +100,7 @@ var ( headersPrefix = Prefixer("headers") headerCountKey = Prefixer(string(headersPrefix("count")))() headerSectorHashesPrefix = Prefixer(string(headersPrefix("sector-hashes"))) + headerBanPrefix = Prefixer(string(headersPrefix("banned"))) headerDataPrefix = Prefixer(string(headersPrefix("header"))) ) @@ -172,6 +163,32 @@ func GetSectorHashes(db *leveldb.DB, name string) (blob.SectorHashes, error) { return base, nil } +func GetHeaderBan(db *leveldb.DB, name string) (time.Time, error) { + exists, err := db.Has(headerBanPrefix(name), nil) + if err != nil { + return time.Time{}, errors.Wrap(err, "error checking header ban") + } + if !exists { + return time.Time{}, nil + } + bytes, err := db.Get(headerBanPrefix(name), nil) + if err != nil { + return time.Time{}, errors.Wrap(err, "error getting header ban") + } + timestamp := mustDecodeInt(bytes) + return time.Unix(int64(timestamp), 0), nil +} + +func SetHeaderBan(tx *leveldb.Transaction, name string, at time.Time) error { + if at.IsZero() { + at = time.Now() + } + if err := tx.Put(headerBanPrefix(name), mustEncodeInt(int(at.Unix())), nil); err != nil { + return errors.Wrap(err, "error writing header tree") + } + return nil +} + func SetHeaderTx(tx *leveldb.Transaction, header *Header, sectorHashes blob.SectorHashes) error { var buf bytes.Buffer if err := sectorHashes.Encode(&buf); err != nil { From fdfee33001e760d119d2dd7b2db8cc49081888ac Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sat, 27 Feb 2021 11:41:44 +0530 Subject: [PATCH 63/71] updater: set sector tip hash on header --- protocol/updater.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/updater.go b/protocol/updater.go index 1828ad7..5264e2f 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -269,7 +269,7 @@ func UpdateBlob(cfg *UpdateConfig) error { Name: item.Name, EpochHeight: item.EpochHeight, SectorSize: item.SectorSize, - SectorTipHash: item.SectorTipHash, + SectorTipHash: tree.Tip(), Signature: item.Signature, ReservedRoot: item.ReservedRoot, EpochStartAt: epochStart, From 9fa49dc0dfbfff8fbde86104df81aea251dc8c57 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sat, 27 Feb 2021 12:02:12 +0530 Subject: [PATCH 64/71] write: fix reset epoch flag handler --- cmd/fnd-cli/cmd/blob/write.go | 14 ++++++++++---- rpc/blob_writer.go | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/cmd/fnd-cli/cmd/blob/write.go b/cmd/fnd-cli/cmd/blob/write.go index f7ffe99..2234f29 100644 --- a/cmd/fnd-cli/cmd/blob/write.go +++ b/cmd/fnd-cli/cmd/blob/write.go @@ -46,14 +46,20 @@ var writeCmd = &cobra.Command{ wr := rpc.NewBlobWriter(apiv1.NewFootnotev1Client(conn), signer, name) + if err := wr.Open(); err != nil { + return err + } + if resetEpoch { if err := wr.Reset(); err != nil { return err } - } - - if err := wr.Open(); err != nil { - return err + // For technical reasons, Open _must_ be called again after Reset + // This is to reset the initial state on the client and checkout + // the name afresh. + if err := wr.Open(); err != nil { + return err + } } var rd io.Reader diff --git a/rpc/blob_writer.go b/rpc/blob_writer.go index 8fbd59e..bf01721 100644 --- a/rpc/blob_writer.go +++ b/rpc/blob_writer.go @@ -86,6 +86,7 @@ func (b *BlobWriter) Reset() error { _, err := b.client.ResetEpoch(context.Background(), &apiv1.ResetEpochReq{ TxID: b.txID, }) + b.opened = false return err } From 366bad0544ffdcc629422757a6523e049164bdb8 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sat, 27 Feb 2021 12:46:11 +0530 Subject: [PATCH 65/71] protocol: refactor syncsector to return signature --- protocol/update_queue.go | 17 +++++++---------- protocol/updater.go | 2 -- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/protocol/update_queue.go b/protocol/update_queue.go index 67a890d..a673b57 100644 --- a/protocol/update_queue.go +++ b/protocol/update_queue.go @@ -40,16 +40,13 @@ type UpdateQueue struct { } type UpdateQueueItem struct { - PeerIDs *PeerSet - Name string - EpochHeight uint16 - SectorSize uint16 - SectorTipHash crypto.Hash - ReservedRoot crypto.Hash - Signature crypto.Signature - Pub *btcec.PublicKey - Height int - Disposed int32 + PeerIDs *PeerSet + Name string + EpochHeight uint16 + SectorSize uint16 + Pub *btcec.PublicKey + Height int + Disposed int32 } func (u *UpdateQueueItem) Dispose() { diff --git a/protocol/updater.go b/protocol/updater.go index 5264e2f..436e6f7 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -270,8 +270,6 @@ func UpdateBlob(cfg *UpdateConfig) error { EpochHeight: item.EpochHeight, SectorSize: item.SectorSize, SectorTipHash: tree.Tip(), - Signature: item.Signature, - ReservedRoot: item.ReservedRoot, EpochStartAt: epochStart, }, tree) }) From 9a711262ce407e32c11187bd972bb0deb3b5474d Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sat, 27 Feb 2021 12:55:52 +0530 Subject: [PATCH 66/71] protocol: SyncSectors return validated metadata --- protocol/syncer.go | 21 ++++++++++++++++----- protocol/updater.go | 11 ++++++++++- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index 07a78f5..fe6eea9 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -25,6 +25,12 @@ var ( ErrSyncerMaxAttempts = errors.New("reached max sync attempts") ) +type syncUpdate struct { + sectorTipHash crypto.Hash + reservedRoot crypto.Hash + signature crypto.Signature +} + type SyncSectorsOpts struct { Timeout time.Duration Mux *p2p.PeerMuxer @@ -64,11 +70,11 @@ func validateBlobRes(db *leveldb.DB, name string, epochHeight, sectorSize uint16 return nil } -func SyncSectors(opts *SyncSectorsOpts) error { +func SyncSectors(opts *SyncSectorsOpts) (*syncUpdate, error) { lgr := log.WithModule("payload-syncer").Sub("name", opts.Name) errs := make(chan error) payloadResCh := make(chan *payloadRes) - payloadProcessedCh := make(chan struct{}, 1) + payloadProcessedCh := make(chan *syncUpdate, 1) doneCh := make(chan struct{}) unsubRes := opts.Mux.AddMessageHandler(p2p.PeerMessageHandlerForType(wire.MessageTypeBlobRes, func(peerID crypto.Hash, envelope *wire.Envelope) { payloadResCh <- &payloadRes{ @@ -217,7 +223,11 @@ func SyncSectors(opts *SyncSectorsOpts) error { } } receivedPayloads[msg.PayloadPosition] = true - payloadProcessedCh <- struct{}{} + payloadProcessedCh <- &syncUpdate{ + sectorTipHash: sectorTipHash, + reservedRoot: msg.ReservedRoot, + signature: msg.Signature, + } case <-doneCh: return } @@ -225,12 +235,13 @@ func SyncSectors(opts *SyncSectorsOpts) error { }() var err error + var su *syncUpdate timeout := time.NewTimer(opts.Timeout) payloadLoop: for { lgr.Debug("requesting payload") select { - case <-payloadProcessedCh: + case su = <-payloadProcessedCh: lgr.Debug("payload processed") break payloadLoop case <-timeout.C: @@ -244,5 +255,5 @@ payloadLoop: unsubRes() close(doneCh) - return err + return su, err } diff --git a/protocol/updater.go b/protocol/updater.go index 436e6f7..2379043 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -222,7 +222,7 @@ func UpdateBlob(cfg *UpdateConfig) error { return errors.Wrap(err, "error seeking transaction") } - err = SyncSectors(&SyncSectorsOpts{ + sectorMeta, err := SyncSectors(&SyncSectorsOpts{ Timeout: DefaultSyncerBlobResTimeout, Mux: cfg.Mux, Tx: tx, @@ -247,6 +247,13 @@ func UpdateBlob(cfg *UpdateConfig) error { return errors.Wrap(err, "error calculating new blob sector tip hash") } + if sectorMeta.sectorTipHash != tree.Tip() { + if err := tx.Rollback(); err != nil { + updaterLogger.Error("error rolling back blob transaction", "err", err) + } + return errors.Wrap(err, "sector tip hash mismatch") + } + var sectorsNeeded uint16 if header == nil { @@ -270,6 +277,8 @@ func UpdateBlob(cfg *UpdateConfig) error { EpochHeight: item.EpochHeight, SectorSize: item.SectorSize, SectorTipHash: tree.Tip(), + Signature: sectorMeta.signature, + ReservedRoot: sectorMeta.reservedRoot, EpochStartAt: epochStart, }, tree) }) From 246fdf27085e08063beeb83ffe0afa80fbab5532 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sat, 27 Feb 2021 13:27:31 +0530 Subject: [PATCH 67/71] syncer: err if already equivocated --- protocol/syncer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/protocol/syncer.go b/protocol/syncer.go index fe6eea9..1ea7851 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -171,6 +171,7 @@ func SyncSectors(opts *SyncSectorsOpts) (*syncUpdate, error) { // Skip if equivocation already exists if _, err := store.GetEquivocationProof(opts.DB, msg.Name); err == nil { lgr.Trace("skipping update, equivocation exists") + errs <- ErrPayloadEquivocation break } // TODO: record timestamp and ban this name From db8159e170872671fbee3880c0999ec3a81c124c Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sat, 27 Feb 2021 13:31:22 +0530 Subject: [PATCH 68/71] protocol: skip updates if name is equivocated --- protocol/update_queue.go | 11 +++++++++-- rpc/server.go | 3 ++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/protocol/update_queue.go b/protocol/update_queue.go index a673b57..788cc7e 100644 --- a/protocol/update_queue.go +++ b/protocol/update_queue.go @@ -188,13 +188,20 @@ func (u *UpdateQueue) validateUpdate(name string) error { if err := primitives.ValidateName(name); err != nil { return errors.Wrap(err, "update name is invalid") } - banned, err := store.NameIsBanned(u.db, name) + nameBan, err := store.NameIsBanned(u.db, name) if err != nil { return errors.Wrap(err, "error reading name ban state") } - if banned { + if nameBan { return errors.New("name is banned") } + headerBan, err := store.GetHeaderBan(u.db, name) + if err != nil { + return errors.Wrap(err, "error reading header ban state") + } + if !headerBan.IsZero() { + return errors.New("header is banned") + } return nil } diff --git a/rpc/server.go b/rpc/server.go index 310a952..d0e5e6a 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -367,7 +367,8 @@ func (s *Server) ResetEpoch(ctx context.Context, req *apiv1.ResetEpochReq) (*api return nil, err } - // double check epoch increment + // TODO: verify if epoch increments + // verify if header and ban is lifted on reset if header.EpochHeight >= protocol.CurrentEpoch(name) { return nil, errors.New("cannot reset epoch ahead of schedule") } From 0fccc82c4c94aa6cf4d2037d52d8ed6c62043613 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sat, 27 Feb 2021 14:06:51 +0530 Subject: [PATCH 69/71] rpc: return header ban time in blob list cli --- protocol/updater.go | 3 +- rpc/blob.go | 3 +- rpc/server.go | 3 +- rpc/v1/api.pb.go | 114 ++++++++++++++++++++++++-------------------- rpc/v1/api.proto | 5 +- store/headers.go | 8 ++++ 6 files changed, 79 insertions(+), 57 deletions(-) diff --git a/protocol/updater.go b/protocol/updater.go index 2379043..0a82898 100644 --- a/protocol/updater.go +++ b/protocol/updater.go @@ -136,11 +136,12 @@ func UpdateBlob(cfg *UpdateConfig) error { var prevHash crypto.Hash = blob.ZeroHash var epochHeight, sectorSize uint16 - var epochUpdated bool + var epochUpdated bool = true if header != nil { epochHeight = header.EpochHeight sectorSize = header.SectorSize prevHash = header.SectorTipHash + epochUpdated = false } // header is the existing header/data in the db diff --git a/rpc/blob.go b/rpc/blob.go index 4f3a37e..e5f012a 100644 --- a/rpc/blob.go +++ b/rpc/blob.go @@ -83,7 +83,8 @@ func parseBlobInfoRes(res *apiv1.BlobInfoRes) (*store.BlobInfo, error) { SectorSize: uint16(res.SectorSize), SectorTipHash: merkleRoot, ReservedRoot: reservedRoot, - ReceivedAt: time.Unix(int64(res.ReceivedAt), 0), Signature: sig, + ReceivedAt: time.Unix(int64(res.ReceivedAt), 0), + BannedAt: time.Unix(int64(res.BannedAt), 0), }, nil } diff --git a/rpc/server.go b/rpc/server.go index d0e5e6a..d97d1d3 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -464,8 +464,9 @@ func (s *Server) ListBlobInfo(req *apiv1.ListBlobInfoReq, srv apiv1.Footnotev1_L SectorSize: uint32(info.SectorSize), SectorTipHash: info.SectorTipHash[:], ReservedRoot: info.ReservedRoot[:], - ReceivedAt: uint64(info.ReceivedAt.Unix()), Signature: info.Signature[:], + ReceivedAt: uint64(info.ReceivedAt.Unix()), + BannedAt: uint64(info.BannedAt.Unix()), } if err = srv.Send(res); err != nil { return errors.Wrap(err, "error sending info") diff --git a/rpc/v1/api.pb.go b/rpc/v1/api.pb.go index 400a323..2e7fba4 100644 --- a/rpc/v1/api.pb.go +++ b/rpc/v1/api.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0-devel +// protoc-gen-go v1.23.0 // protoc v3.12.4 // source: api.proto @@ -1216,8 +1216,9 @@ type BlobInfoRes struct { SectorSize uint32 `protobuf:"varint,5,opt,name=sectorSize,proto3" json:"sectorSize,omitempty"` // ditto ^ SectorTipHash []byte `protobuf:"bytes,6,opt,name=sectorTipHash,proto3" json:"sectorTipHash,omitempty"` ReservedRoot []byte `protobuf:"bytes,7,opt,name=reservedRoot,proto3" json:"reservedRoot,omitempty"` - ReceivedAt uint64 `protobuf:"varint,8,opt,name=receivedAt,proto3" json:"receivedAt,omitempty"` - Signature []byte `protobuf:"bytes,9,opt,name=signature,proto3" json:"signature,omitempty"` + Signature []byte `protobuf:"bytes,8,opt,name=signature,proto3" json:"signature,omitempty"` + ReceivedAt uint64 `protobuf:"varint,9,opt,name=receivedAt,proto3" json:"receivedAt,omitempty"` + BannedAt uint64 `protobuf:"varint,10,opt,name=bannedAt,proto3" json:"bannedAt,omitempty"` } func (x *BlobInfoRes) Reset() { @@ -1301,6 +1302,13 @@ func (x *BlobInfoRes) GetReservedRoot() []byte { return nil } +func (x *BlobInfoRes) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + func (x *BlobInfoRes) GetReceivedAt() uint64 { if x != nil { return x.ReceivedAt @@ -1308,11 +1316,11 @@ func (x *BlobInfoRes) GetReceivedAt() uint64 { return 0 } -func (x *BlobInfoRes) GetSignature() []byte { +func (x *BlobInfoRes) GetBannedAt() uint64 { if x != nil { - return x.Signature + return x.BannedAt } - return nil + return 0 } type SendUpdateReq struct { @@ -1504,7 +1512,7 @@ var file_api_proto_rawDesc = []byte{ 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x27, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0xad, 0x02, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, + 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0xc9, 0x02, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, @@ -1519,51 +1527,53 @@ var file_api_proto_rawDesc = []byte{ 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, 0x70, 0x48, 0x61, 0x73, 0x68, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x72, 0x65, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, - 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, - 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x23, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x37, 0x0a, - 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x12, 0x26, - 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, - 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0x97, 0x04, 0x0a, 0x0a, 0x46, 0x6f, 0x6f, 0x74, 0x6e, - 0x6f, 0x74, 0x65, 0x76, 0x31, 0x12, 0x22, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x47, 0x65, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x07, 0x41, 0x64, 0x64, - 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x07, 0x42, 0x61, 0x6e, - 0x50, 0x65, 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x22, 0x0a, 0x09, 0x55, 0x6e, 0x62, - 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2b, 0x0a, - 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x0d, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x26, 0x0a, 0x08, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, - 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, - 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x0b, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x12, 0x0f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, - 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x0a, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x52, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x65, 0x74, 0x45, 0x70, - 0x6f, 0x63, 0x68, 0x12, 0x0e, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x45, 0x70, 0x6f, 0x63, 0x68, - 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x45, 0x70, 0x6f, 0x63, 0x68, - 0x52, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x12, 0x0a, 0x2e, - 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, - 0x41, 0x74, 0x52, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, - 0x12, 0x30, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x10, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, - 0x30, 0x01, 0x12, 0x2c, 0x0a, 0x0a, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, - 0x1a, 0x0e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x42, 0x04, 0x5a, 0x02, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x65, + 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x72, 0x65, + 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x61, 0x6e, 0x6e, + 0x65, 0x64, 0x41, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x62, 0x61, 0x6e, 0x6e, + 0x65, 0x64, 0x41, 0x74, 0x22, 0x23, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x37, 0x0a, 0x0d, 0x53, 0x65, 0x6e, + 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, + 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x32, 0x97, 0x04, 0x0a, 0x0a, 0x46, 0x6f, 0x6f, 0x74, 0x6e, 0x6f, 0x74, 0x65, 0x76, + 0x31, 0x12, 0x22, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, + 0x12, 0x0b, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x07, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, + 0x12, 0x0b, 0x2e, 0x42, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x22, 0x0a, 0x09, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, + 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x55, 0x6e, 0x62, 0x61, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2b, 0x0a, 0x09, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x0d, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x26, 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, + 0x75, 0x74, 0x12, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, + 0x1a, 0x0c, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x12, 0x2f, + 0x0a, 0x0b, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x0f, 0x2e, + 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0f, + 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x12, + 0x20, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, + 0x73, 0x12, 0x2c, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x65, 0x74, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, + 0x0e, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, + 0x0e, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x73, 0x12, + 0x20, 0x0a, 0x06, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x12, 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, + 0x41, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x41, 0x74, 0x52, 0x65, + 0x73, 0x12, 0x29, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x0c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, + 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x0c, + 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0c, + 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x30, 0x01, 0x12, 0x2c, + 0x0a, 0x0a, 0x53, 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x2e, 0x53, + 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x53, + 0x65, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x42, 0x04, 0x5a, 0x02, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/rpc/v1/api.proto b/rpc/v1/api.proto index acba295..e400c54 100644 --- a/rpc/v1/api.proto +++ b/rpc/v1/api.proto @@ -139,8 +139,9 @@ message BlobInfoRes { uint32 sectorSize = 5; // ditto ^ bytes sectorTipHash = 6; bytes reservedRoot = 7; - uint64 receivedAt = 8; - bytes signature = 9; + bytes signature = 8; + uint64 receivedAt = 9; + uint64 bannedAt = 10; } message SendUpdateReq { diff --git a/store/headers.go b/store/headers.go index b6db6e4..2771ffd 100644 --- a/store/headers.go +++ b/store/headers.go @@ -222,6 +222,7 @@ type BlobInfo struct { Signature crypto.Signature `json:"signature"` ReservedRoot crypto.Hash `json:"reserved_root"` ReceivedAt time.Time `json:"received_at"` + BannedAt time.Time `json:"banned_at"` } func (b *BlobInfo) MarshalJSON() ([]byte, error) { @@ -235,6 +236,7 @@ func (b *BlobInfo) MarshalJSON() ([]byte, error) { Signature string `json:"signature"` ReservedRoot string `json:"reserved_root"` ReceivedAt time.Time `json:"received_at"` + BannedAt time.Time `json:"banned_at"` }{ b.Name, hex.EncodeToString(b.PublicKey.SerializeCompressed()), @@ -245,6 +247,7 @@ func (b *BlobInfo) MarshalJSON() ([]byte, error) { hex.EncodeToString(b.Signature[:]), hex.EncodeToString(b.ReservedRoot[:]), b.ReceivedAt, + b.BannedAt, } return json.Marshal(jsonInfo) @@ -266,6 +269,10 @@ func (bis *BlobInfoStream) Next() (*BlobInfo, error) { if err != nil { return nil, errors.Wrap(err, "error getting name info") } + bannedAt, err := GetHeaderBan(bis.db, header.Name) + if err != nil { + return nil, errors.Wrap(err, "error getting header ban info") + } return &BlobInfo{ Name: header.Name, PublicKey: nameInfo.PublicKey, @@ -276,6 +283,7 @@ func (bis *BlobInfoStream) Next() (*BlobInfo, error) { Signature: header.Signature, ReservedRoot: header.ReservedRoot, ReceivedAt: header.EpochStartAt, + BannedAt: bannedAt, }, nil } From 83a808d60590afe8ce61c3952252afd8201656f9 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sun, 28 Feb 2021 16:53:36 +0530 Subject: [PATCH 70/71] all: rename vars, add docs --- cmd/fnd-cli/cmd/blob/info.go | 16 +++++++++------- protocol/sector_server.go | 20 ++++++++++++++++++-- protocol/syncer.go | 21 ++++++++++++++++++--- rpc/blob.go | 6 +++--- store/headers.go | 2 +- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/cmd/fnd-cli/cmd/blob/info.go b/cmd/fnd-cli/cmd/blob/info.go index 215d7f2..cc01c33 100644 --- a/cmd/fnd-cli/cmd/blob/info.go +++ b/cmd/fnd-cli/cmd/blob/info.go @@ -6,13 +6,14 @@ import ( "fnd/cli" "fnd/rpc" apiv1 "fnd/rpc/v1" + "os" + "strconv" + "strings" + "fnd.localhost/handshake/primitives" "github.com/olekukonko/tablewriter" "github.com/pkg/errors" "github.com/spf13/cobra" - "os" - "strconv" - "strings" ) var infoCmd = &cobra.Command{ @@ -37,11 +38,11 @@ var infoCmd = &cobra.Command{ "Name", "Public Key", "Timestamp", - "Merkle Root", + "Sector Tip Hash", "Reserved Root", - "Received At", "Signature", - "Time Bank", + "Received At", + "Banned At", }) for _, name := range names { @@ -57,8 +58,9 @@ var infoCmd = &cobra.Command{ strconv.Itoa(int(res.SectorSize)), res.SectorTipHash.String(), res.ReservedRoot.String(), - res.ReceivedAt.String(), res.Signature.String(), + res.ReceivedAt.String(), + res.BannedAt.String(), }) } diff --git a/protocol/sector_server.go b/protocol/sector_server.go index 881110f..cd11571 100644 --- a/protocol/sector_server.go +++ b/protocol/sector_server.go @@ -48,6 +48,22 @@ func (s *SectorServer) Stop() error { return nil } +// onBlobReq handles a BlobReq and responds with a BlobRes +// +// In case the BlobReq contains SectorSize == MaxSectors, it is considered a +// special case, which is a part of the equivocation proof flow. Note that in a +// normal BlobReq/BlobRes flow, SectorSize may never be MaxSectors as it is the +// start for the expected payload. +// +// In the special case where SectorSize = MaxSectors, the BlobReq is considered +// an Equivocation Request. In response, the peer is sent an Equivocation Proof. +// +// Equivocation Proof flow: +// Syncer - sees a conflicting update +// - Writes equivocation proof locally to db +// - Sends an equivocation Update (special case where Update.SectorSize = 0) +// - Expects peers to reply with Equivocation Request i.e. BlobReq where SectorSize = MaxSectors +// - Responds with Equivocation Proof func (s *SectorServer) onBlobReq(peerID crypto.Hash, envelope *wire.Envelope) { reqMsg := envelope.Message.(*wire.BlobReq) lgr := s.lgr.Sub( @@ -224,7 +240,7 @@ func (s *SectorServer) onEquivocationProof(peerID crypto.Hash, envelope *wire.En s.lgr.Warn("unexpected sector size", "local_sector_size", msg.LocalSectorSize, "remote_payload_position", msg.RemotePayloadPosition) return } - if err := validateBlobRes(s.db, msg.Name, msg.LocalEpochHeight, msg.LocalSectorSize, msg.LocalSectorTipHash, msg.LocalReservedRoot, msg.LocalSignature); err != nil { + if err := validateBlobUpdate(s.db, msg.Name, msg.LocalEpochHeight, msg.LocalSectorSize, msg.LocalSectorTipHash, msg.LocalReservedRoot, msg.LocalSignature); err != nil { lgr.Warn("local signaure validation failed", "err", err) return } @@ -244,7 +260,7 @@ func (s *SectorServer) onEquivocationProof(peerID crypto.Hash, envelope *wire.En // sector size, sector tip hash and other metadata. This data // is first hashed and the signature is validated against the // name's pubkey. See validateBlobRes. - if err := validateBlobRes(s.db, msg.Name, msg.RemoteEpochHeight, sectorSize, sectorTipHash, msg.RemoteReservedRoot, msg.RemoteSignature); err != nil { + if err := validateBlobUpdate(s.db, msg.Name, msg.RemoteEpochHeight, sectorSize, sectorTipHash, msg.RemoteReservedRoot, msg.RemoteSignature); err != nil { lgr.Warn("remote signaure validation failed", "err", err) return } diff --git a/protocol/syncer.go b/protocol/syncer.go index 1ea7851..1152e22 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -48,7 +48,12 @@ type payloadRes struct { msg *wire.BlobRes } -func validateBlobRes(db *leveldb.DB, name string, epochHeight, sectorSize uint16, mr crypto.Hash, rr crypto.Hash, sig crypto.Signature) error { +// validateBlobUpdate validates that the provided signature matches the +// expected signature for given update metadata. The metadata commits the +// update to the latest sector size and tip hash, so effectively for a blob of +// known sector size, there exists a _unique_ compact proof of the update in +// the form of the signature. +func validateBlobUpdate(db *leveldb.DB, name string, epochHeight, sectorSize uint16, sectorTipHash crypto.Hash, reservedRoot crypto.Hash, sig crypto.Signature) error { if err := primitives.ValidateName(name); err != nil { return errors.Wrap(err, "update name is invalid") } @@ -59,17 +64,27 @@ func validateBlobRes(db *leveldb.DB, name string, epochHeight, sectorSize uint16 if banned { return errors.New("name is banned") } + // TODO: should we check header ban state here? info, err := store.GetNameInfo(db, name) if err != nil { return errors.Wrap(err, "error reading name info") } - h := blob.SealHash(name, epochHeight, sectorSize, mr, rr) + h := blob.SealHash(name, epochHeight, sectorSize, sectorTipHash, reservedRoot) if !crypto.VerifySigPub(info.PublicKey, sig, h) { return ErrInvalidPayloadSignature } return nil } +// SyncSectors syncs the sectors for the options provided in opts. Syncing +// happens by sending a BlobReq and expecting a BlobRes in return. Multiple +// requests may be send to multiple peers but the first valid response will be +// considered final. +// +// An invalid BlobRes which fails validation may trigger an equivocation proof, +// which is the proof that are two conflicting updates at the same epoch and +// sector size, and this proof will be stored locally and served to peers in +// the equivocation proof flow. See sector_server.go for details. func SyncSectors(opts *SyncSectorsOpts) (*syncUpdate, error) { lgr := log.WithModule("payload-syncer").Sub("name", opts.Name) errs := make(chan error) @@ -153,7 +168,7 @@ func SyncSectors(opts *SyncSectorsOpts) (*syncUpdate, error) { // is first hashed and the signature is validated against the // name's pubkey. See validateBlobRes. // TODO: store the latest tip hash - if err := validateBlobRes(opts.DB, msg.Name, msg.EpochHeight, sectorSize, sectorTipHash, msg.ReservedRoot, msg.Signature); err != nil { + if err := validateBlobUpdate(opts.DB, msg.Name, msg.EpochHeight, sectorSize, sectorTipHash, msg.ReservedRoot, msg.Signature); err != nil { lgr.Trace("blob res validation failed", "err", err) // If prev hash matches, we have an invalid signature, // which cannot be used as a proof of equivocation. diff --git a/rpc/blob.go b/rpc/blob.go index e5f012a..4bb9091 100644 --- a/rpc/blob.go +++ b/rpc/blob.go @@ -62,9 +62,9 @@ func parseBlobInfoRes(res *apiv1.BlobInfoRes) (*store.BlobInfo, error) { if err != nil { return nil, errors.Wrap(err, "error parsing public key") } - merkleRoot, err := crypto.NewHashFromBytes(res.SectorTipHash) + sectorTipHash, err := crypto.NewHashFromBytes(res.SectorTipHash) if err != nil { - return nil, errors.Wrap(err, "error parsing merkle root") + return nil, errors.Wrap(err, "error parsing sector tip hash") } reservedRoot, err := crypto.NewHashFromBytes(res.ReservedRoot) if err != nil { @@ -81,7 +81,7 @@ func parseBlobInfoRes(res *apiv1.BlobInfoRes) (*store.BlobInfo, error) { ImportHeight: int(res.ImportHeight), EpochHeight: uint16(res.EpochHeight), SectorSize: uint16(res.SectorSize), - SectorTipHash: merkleRoot, + SectorTipHash: sectorTipHash, ReservedRoot: reservedRoot, Signature: sig, ReceivedAt: time.Unix(int64(res.ReceivedAt), 0), diff --git a/store/headers.go b/store/headers.go index 2771ffd..adafa81 100644 --- a/store/headers.go +++ b/store/headers.go @@ -192,7 +192,7 @@ func SetHeaderBan(tx *leveldb.Transaction, name string, at time.Time) error { func SetHeaderTx(tx *leveldb.Transaction, header *Header, sectorHashes blob.SectorHashes) error { var buf bytes.Buffer if err := sectorHashes.Encode(&buf); err != nil { - return errors.Wrap(err, "error encoding merkle tree") + return errors.Wrap(err, "error encoding sector hashes") } exists, err := tx.Has(headerDataPrefix(header.Name), nil) if err != nil { From 3ab2f86e717251b619e4a5746ae890ddc22cafab Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sun, 28 Feb 2021 16:58:45 +0530 Subject: [PATCH 71/71] cli: update blob info --- cmd/fnd-cli/cmd/blob/info.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/fnd-cli/cmd/blob/info.go b/cmd/fnd-cli/cmd/blob/info.go index cc01c33..27f4f8b 100644 --- a/cmd/fnd-cli/cmd/blob/info.go +++ b/cmd/fnd-cli/cmd/blob/info.go @@ -37,7 +37,8 @@ var infoCmd = &cobra.Command{ table.SetHeader([]string{ "Name", "Public Key", - "Timestamp", + "Epoch Height", + "Sector Size", "Sector Tip Hash", "Reserved Root", "Signature",