From 685eeafd2051a654da753576214912a86a55218e Mon Sep 17 00:00:00 2001 From: DylanYong Date: Sun, 19 Feb 2023 16:38:04 +0800 Subject: [PATCH 1/7] feat: stone node sends piece data to gateway --- config/config.toml | 8 +- go.mod | 31 +++- go.sum | 73 +++++++-- model/const.go | 29 +++- model/errors/http_error.go | 1 + model/errors/{errors.go => rpc_error.go} | 6 +- pkg/stone/upload_payload_stone.go | 5 +- proto/service/types/v1/stone_hub.proto | 8 +- service/client/piece_store_client.go | 9 +- service/gateway/admin_handler.go | 6 +- service/gateway/chain_client.go | 10 +- service/gateway/gateway.go | 8 +- service/gateway/gateway_config.go | 6 +- service/gateway/request_util.go | 7 +- service/gateway/response_util.go | 2 +- service/gateway/router.go | 6 +- service/gateway/sync_piece_handler.go | 181 +++++++++++++++++++++++ service/gateway/synce_piece_test.go | 46 ++++++ service/gateway/syncer_processor.go | 42 ++++++ service/stonenode/alloc_stone_job.go | 14 +- service/stonenode/http_client.go | 171 +++++++++++++++++++++ service/stonenode/stone_node.go | 14 -- service/stonenode/stone_node_config.go | 6 +- service/stonenode/sync_piece.go | 44 +----- service/stonenode/sync_piece_test.go | 35 +---- store/piecestore/storage/s3.go | 4 +- test/e2e/onebox/setup_onebox.go | 83 ++++++----- test/e2e/services/case_driver.go | 3 +- util/hash/checksum.go | 10 +- 29 files changed, 682 insertions(+), 186 deletions(-) create mode 100644 model/errors/http_error.go rename model/errors/{errors.go => rpc_error.go} (92%) create mode 100644 service/gateway/sync_piece_handler.go create mode 100644 service/gateway/synce_piece_test.go create mode 100644 service/gateway/syncer_processor.go create mode 100644 service/stonenode/http_client.go diff --git a/config/config.toml b/config/config.toml index 2948871e9..51cdd887e 100644 --- a/config/config.toml +++ b/config/config.toml @@ -18,6 +18,7 @@ Service = [ [UploaderCfg.PieceStoreConfig.Store] Storage = "file" BucketURL = "./data/primary_payload_data" + NoSignRequest = false MaxRetries = 5 TestMode = true [UploaderCfg.MetaLevelDBConfig] @@ -34,6 +35,7 @@ Service = [ [DownloaderCfg.PieceStoreConfig.Store] Storage = "file" BucketURL = "./data/primary_payload_data" + NoSignRequest = false MaxRetries = 5 TestMode = true @@ -49,18 +51,19 @@ Service = [ FileHandles = 1000 ReadOnly = false - [StoneNodeCfg] StorageProvider = "gnfd-test-sp" Address = "127.0.0.1:9433" + GatewayAddress = ["127.0.0.1:9034", "127.0.0.1:9035", "127.0.0.1:9036", "127.0.0.1:9037", "127.0.0.1:9038", "127.0.0.1:9039"] StoneHubServiceAddress = "127.0.0.1:9333" - SyncerServiceAddress = ["127.0.0.1:9543", "127.0.0.1:9553", "127.0.0.1:9563", "127.0.0.1:9573", "127.0.0.1:9583", "127.0.0.1:9593"] + SyncerAddress = ["127.0.0.1:9543", "127.0.0.1:9553", "127.0.0.1:9563", "127.0.0.1:9573", "127.0.0.1:9583", "127.0.0.1:9593"] StoneJobLimit = 64 [StoneNodeCfg.PieceConfig] Shards = 0 [StoneNodeCfg.PieceConfig.Store] Storage = "file" BucketURL = "./data/primary_payload_data" + NoSignRequest = false MaxRetries = 5 TestMode = true @@ -71,6 +74,7 @@ Service = [ [SyncerCfg.PieceConfig.Store] Storage = "file" BucketURL = "./data/secondary_payload_data" + NoSignRequest = false MaxRetries = 5 TestMode = true [SyncerCfg.MetaLevelDBConfig] diff --git a/go.mod b/go.mod index bd817caba..7e204ba9a 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ replace ( require ( github.com/GeertJohan/go.linenoise v0.0.0-20141120151038-1918ff89d613 github.com/aws/aws-sdk-go v1.44.159 + github.com/bnb-chain/greenfield v0.0.5 github.com/bnb-chain/greenfield-sdk-go v0.0.0-20230208161205-03ff5beb1419 github.com/bytedance/gopkg v0.0.0-20221122125632-68358b8ecec6 github.com/cosmos/cosmos-proto v1.0.0-beta.1 @@ -40,8 +41,12 @@ require ( cosmossdk.io/errors v1.0.0-beta.7 // indirect cosmossdk.io/math v1.0.0-beta.3 // indirect filippo.io/edwards25519 v1.0.0-rc.1 // indirect + github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect + github.com/99designs/keyring v1.2.1 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/armon/go-metrics v0.4.1 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/bgentry/speakeasy v0.1.0 // indirect github.com/btcsuite/btcd v0.22.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect @@ -49,14 +54,20 @@ require ( github.com/confio/ics23/go v0.7.0 // indirect github.com/cosmos/btcutil v1.0.4 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/cosmos/gogoproto v1.4.3 // indirect github.com/cosmos/gorocksdb v1.2.0 // indirect + github.com/cosmos/iavl v0.19.4 // indirect + github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect + github.com/cosmos/ledger-go v0.9.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac // indirect + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/evmos/ethermint v0.6.1-0.20220919141022-34226aa7b1fa // indirect github.com/ferranbt/fastssz v0.0.0-20210905181407-59cf6761a7d5 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect @@ -64,14 +75,19 @@ require ( github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-sql-driver/mysql v1.6.0 // indirect + github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/protobuf v1.3.3 // indirect github.com/golang/glog v1.0.0 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.0.1 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect @@ -86,6 +102,7 @@ require ( github.com/kr/fs v0.1.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/magiconair/properties v1.8.6 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/sha256-simd v1.0.0 // indirect @@ -93,6 +110,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/mtibben/percent v0.2.1 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect @@ -105,6 +123,7 @@ require ( github.com/prometheus/procfs v0.8.0 // indirect github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d // indirect github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/sirupsen/logrus v1.9.0 // indirect @@ -116,18 +135,24 @@ require ( github.com/spf13/viper v1.13.0 // indirect github.com/subosito/gotenv v1.4.1 // indirect github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344 // indirect + github.com/tendermint/btcd v0.1.1 // indirect github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tendermint/tendermint v0.34.22 // indirect github.com/tendermint/tm-db v0.6.7 // indirect github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect github.com/urfave/cli/v2 v2.3.0 // indirect + github.com/wealdtech/go-bytesutil v1.1.1 // indirect + github.com/wealdtech/go-eth2-types/v2 v2.5.2 // indirect + github.com/wealdtech/go-eth2-util v1.6.3 // indirect + github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.uber.org/atomic v1.10.0 // indirect golang.org/x/crypto v0.1.0 // indirect - golang.org/x/net v0.3.0 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/net v0.5.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/term v0.4.0 // indirect + golang.org/x/text v0.6.0 // indirect google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 35aec98a0..22f2632c9 100644 --- a/go.sum +++ b/go.sum @@ -56,7 +56,9 @@ filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmG filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= +github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= @@ -77,6 +79,7 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/GeertJohan/go.linenoise v0.0.0-20141120151038-1918ff89d613 h1:6icnpgpfaYbNFPvsZHrIPhUqNbubaeikWdpMdj40kp0= github.com/GeertJohan/go.linenoise v0.0.0-20141120151038-1918ff89d613/go.mod h1:hjDAY2N/A6k4IInagcBqLG/q8SyECV6TDzEu5dY0Mwg= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= @@ -93,6 +96,7 @@ github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrU github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= @@ -117,6 +121,7 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= @@ -148,11 +153,14 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/bnb-chain/gnfd-cosmos-sdk v0.0.5 h1:BiCZDtUCjivevjYqdrt/Hw536jLSB4KChNMfjgGcvzE= github.com/bnb-chain/gnfd-cosmos-sdk v0.0.5/go.mod h1:3NFoaEONuAGg9UA0FZJmQfzSijZNzaNQmhhwf3ROtqk= +github.com/bnb-chain/greenfield v0.0.5 h1:rBjR22e5+eSNPqrTDgNDoEY5mkasIklYfwTHXW263TY= +github.com/bnb-chain/greenfield v0.0.5/go.mod h1:ZXioeBnuVYqAYQ1TmAFX4XjXXW2iqX+VjKGj3+XbLLE= github.com/bnb-chain/greenfield-sdk-go v0.0.0-20230208161205-03ff5beb1419 h1:pMl5XQIBAL51WqkWWYUHITv6epA4y2ZmOjiDr9avbCk= github.com/bnb-chain/greenfield-sdk-go v0.0.0-20230208161205-03ff5beb1419/go.mod h1:+b9Ow9h0I6rmPxg54KlqUmrjUgGub7qu0RsUYUQzpYs= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= +github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= @@ -164,6 +172,7 @@ github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPx github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= @@ -181,7 +190,9 @@ github.com/bytedance/gopkg v0.0.0-20221122125632-68358b8ecec6 h1:FCLDGi1EmB7JzjV github.com/bytedance/gopkg v0.0.0-20221122125632-68358b8ecec6/go.mod h1:5FoAH5xUHHCMDvQPy1rnj8moqLkLHFaDVBjHhcFwEi0= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= @@ -195,6 +206,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= @@ -205,6 +218,7 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWH github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coinbase/rosetta-sdk-go v0.7.9 h1:lqllBjMnazTjIqYrOGv8h8jxjg9+hJazIGZr9ZvoCcA= github.com/confio/ics23/go v0.7.0 h1:00d2kukk7sPoHWL4zZBZwzxnpA2pec1NPdwbSokJ5w8= github.com/confio/ics23/go v0.7.0/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= @@ -224,21 +238,28 @@ github.com/cosmos/cosmos-proto v1.0.0-beta.1/go.mod h1:8k2GNZghi5sDRFw/scPL8gMSo github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= +github.com/cosmos/gogoproto v1.4.3 h1:RP3yyVREh9snv/lsOvmsAPQt8f44LgL281X0IOIhhcI= +github.com/cosmos/gogoproto v1.4.3/go.mod h1:0hLIG5TR7IvV1fme1HCFKjfzW9X2x0Mo+RooWXCnOWU= github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= github.com/cosmos/iavl v0.19.4 h1:t82sN+Y0WeqxDLJRSpNd8YFX5URIrT+p8n6oJbJ2Dok= +github.com/cosmos/iavl v0.19.4/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4= +github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI= +github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U= github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= +github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -255,6 +276,7 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeC github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= @@ -280,6 +302,7 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac h1:opbrjaN/L8gg6Xh5D04Tem+8xVcz6ajZlGCs49mQgyg= github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= @@ -379,6 +402,7 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= @@ -461,6 +485,7 @@ github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -496,20 +521,23 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/gregjones/httpcache v0.0.0-20170920190843-316c5e0ff04e/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1 h1:X2vfSnm1WC8HEo0MBHZg2TcuDUHJj6kd1TmEAQncnSA= github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1/go.mod h1:oVMjMN64nzEcepv1kdZKgx1qNYt4Ro0Gqefiq2JWdis= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 h1:1JYBfzqrWPcCclBwxFCPAou9n+q86mfnu7NAeHfte7A= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= @@ -521,16 +549,20 @@ github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoP github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= @@ -562,6 +594,7 @@ github.com/ianlancetaylor/cgosymbolizer v0.0.0-20200424224625-be1b05b0b279/go.mo github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= @@ -700,6 +733,7 @@ github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4F github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E= github.com/libp2p/go-addr-util v0.1.0/go.mod h1:6I3ZYuFr2O/9D+SoyM0zEw0EF3YkldtTX406BpdQMqw= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= @@ -841,6 +875,7 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -854,6 +889,7 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -914,6 +950,7 @@ github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= +github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= @@ -967,6 +1004,7 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -1013,6 +1051,8 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= @@ -1051,6 +1091,7 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= @@ -1110,6 +1151,7 @@ github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzywPxOvwMdxcg= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= @@ -1120,6 +1162,8 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= +github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -1211,6 +1255,7 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -1235,6 +1280,7 @@ github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cb github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= +github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= @@ -1251,7 +1297,9 @@ github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITn github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef/go.mod h1:+SV/613m53DNAmlXPTWGZhIyt4E/qDvn9g/lOPRiy0A= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -1282,8 +1330,8 @@ github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1 github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= -github.com/willf/bitset v1.1.3 h1:ekJIKh6+YbUIVt9DfNbkR5d6aFcFTLDRyJNAACURBg8= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= @@ -1299,7 +1347,9 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 h1:O9XLFXGkVswDFmH9LaYpqu+r/AAFWqr0DL6V00KEVFg= +github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= @@ -1500,8 +1550,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1624,6 +1674,7 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1633,15 +1684,17 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1653,8 +1706,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1878,6 +1931,7 @@ gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UD gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= @@ -1945,6 +1999,7 @@ k8s.io/klog/v2 v2.3.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200520001619-278ece378a50/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/model/const.go b/model/const.go index bce8e3d9c..3161aa452 100644 --- a/model/const.go +++ b/model/const.go @@ -30,7 +30,6 @@ const ( const ( BufPoolSize = 32 << 10 ChecksumAlgo = "Crc32c" - OctetStream = "application/octet-stream" ) // RPC config @@ -39,10 +38,21 @@ const ( MaxCallMsgSize = 25 * 1024 * 1024 ) +// http header constants +const ( + // http header key + OctetStream = "application/octet-stream" + ContentTypeHeader = "Content-Type" + ETagHeader = "ETag" + ContentLengthHeader = "Content-Length" + ContentTypeXMLHeaderValue = "application/xml" +) + // Gateway const ( // path AdminPath = "/greenfield/admin/v1/" + SyncerPath = "/greenfield/syncer/v1/sync-piece" GetApprovalSubPath = "get-approval" // query key @@ -64,13 +74,20 @@ const ( GnfdAuthorizationHeader = "Authorization" GnfdDateHeader = "X-Gnfd-Date" - // http header key - ContentTypeHeader = "Content-Type" - ETagHeader = "ETag" - ContentLengthHeader = "Content-Length" + // StoneNode to gateway request header + GnfdTraceIDHeader = "X-Gnfd-Trace-ID" + GnfdObjectIDHeader = "X-Gnfd-Object-ID" + GnfdSPIDHeader = "X-Gnfd-SP-ID" + GnfdPieceCountHeader = "X-Gnfd-Piece-Count" + GnfdPieceIndexHeader = "X-Gnfd-Piece-Index" + GnfdApprovalSignatureHeader = "X-Gnfd-Approval-Signature" + + // gateway to StoneNode response header + GnfdPieceChecksumHeader = "X-Gnfd-Piece-Checksum" + GnfdIntegrityHashHeader = "X-Gnfd-Integrity-Hash" + GnfdSealSignatureHeader = "X-Gnfd-Seal-Signature" // header value - ContentTypeXMLHeaderValue = "application/xml" ReplicaRedundancyTypeHeaderValue = "Replica" // signature const value diff --git a/model/errors/http_error.go b/model/errors/http_error.go new file mode 100644 index 000000000..04b32187b --- /dev/null +++ b/model/errors/http_error.go @@ -0,0 +1 @@ +package errors diff --git a/model/errors/errors.go b/model/errors/rpc_error.go similarity index 92% rename from model/errors/errors.go rename to model/errors/rpc_error.go index baaf92fc1..469b211f1 100644 --- a/model/errors/errors.go +++ b/model/errors/rpc_error.go @@ -30,6 +30,8 @@ var ( ErrRequestConsistent = errors.New("request consistent check failed") ErrSignatureConsistent = errors.New("signature consistent check failed") ErrUnsupportedSignType = errors.New("unsupported signature type") + ErrEmptyReqHeader = errors.New("request header is empty") + ErrReqHeader = errors.New("request header is wrong") ) // stone hub service errors @@ -67,7 +69,9 @@ var ( ErrInvalidSegmentData = errors.New("invalid segment data, length is not equal to 1") ErrInvalidECData = errors.New("invalid ec data, length is not equal to 6") ErrEmptyTargetIdx = errors.New("target index array is empty") - ErrSyncerNumber = errors.New("syncer number is not enough") + ErrGatewayNumber = errors.New("gateway number is not enough") + ErrEmptyRespHeader = errors.New("http response header is empty") + ErrRespHeader = errors.New("http response header is wrong") ) // syncer service errors diff --git a/pkg/stone/upload_payload_stone.go b/pkg/stone/upload_payload_stone.go index 1e68c021a..d1f509c7c 100644 --- a/pkg/stone/upload_payload_stone.go +++ b/pkg/stone/upload_payload_stone.go @@ -3,16 +3,15 @@ package stone import ( "context" - "github.com/bnb-chain/greenfield-storage-provider/store/spdb" "github.com/looplab/fsm" + merrors "github.com/bnb-chain/greenfield-storage-provider/model/errors" "github.com/bnb-chain/greenfield-storage-provider/pkg/job" ptypes "github.com/bnb-chain/greenfield-storage-provider/pkg/types/v1" stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" + "github.com/bnb-chain/greenfield-storage-provider/store/spdb" "github.com/bnb-chain/greenfield-storage-provider/util" "github.com/bnb-chain/greenfield-storage-provider/util/log" - - merrors "github.com/bnb-chain/greenfield-storage-provider/model/errors" ) type contextKey string diff --git a/proto/service/types/v1/stone_hub.proto b/proto/service/types/v1/stone_hub.proto index 0602e5066..25865ae85 100644 --- a/proto/service/types/v1/stone_hub.proto +++ b/proto/service/types/v1/stone_hub.proto @@ -60,8 +60,6 @@ message PieceJob { StorageProviderSealInfo storage_provider_seal_info = 8; } - - message StoneHubServiceBeginUploadPayloadV2Request { string trace_id = 1; // bytes tx_hash = 2; @@ -95,8 +93,10 @@ message StoneHubServiceAllocStoneJobRequest { message StoneHubServiceAllocStoneJobResponse { string trace_id = 1; // bytes tx_hash = 2; - PieceJob piece_job = 3; - ErrMessage err_message = 4; + string bucket_name = 3; + string object_name = 4; + PieceJob piece_job = 5; + ErrMessage err_message = 6; } message StoneHubServiceDoneSecondaryPieceJobRequest { diff --git a/service/client/piece_store_client.go b/service/client/piece_store_client.go index b6d36b723..24b81d202 100644 --- a/service/client/piece_store_client.go +++ b/service/client/piece_store_client.go @@ -36,15 +36,16 @@ func NewStoreClient(pieceConfig *storage.PieceStoreConfig) (*StoreClient, error) func (client *StoreClient) GetPiece(ctx context.Context, key string, offset, limit int64) ([]byte, error) { rc, err := client.ps.Get(ctx, key, offset, limit) if err != nil { - log.Errorw("stone node service invoke PieceStore Get failed", "error", err) + log.Errorw("get piece data from piece store failed", "error", err) return nil, err } - data, err := io.ReadAll(rc) + buf := &bytes.Buffer{} + _, err = io.Copy(buf, rc) if err != nil { - log.Errorw("stone node service invoke io.ReadAll failed", "error", err) + log.Errorw("copy data failed", "error", err) return nil, err } - return data, nil + return buf.Bytes(), nil } func (client *StoreClient) PutPiece(key string, value []byte) error { diff --git a/service/gateway/admin_handler.go b/service/gateway/admin_handler.go index e250a361c..dfbf95402 100644 --- a/service/gateway/admin_handler.go +++ b/service/gateway/admin_handler.go @@ -8,7 +8,7 @@ import ( "github.com/bnb-chain/greenfield-storage-provider/util/log" ) -// getApprovalnHandler +// getApprovalHandler func (g *Gateway) getApprovalHandler(w http.ResponseWriter, r *http.Request) { var ( err error @@ -25,7 +25,7 @@ func (g *Gateway) getApprovalHandler(w http.ResponseWriter, r *http.Request) { if statusCode == 200 { log.Debugf("action(%v) statusCode(%v) %v", "getApproval", statusCode, requestContext.generateRequestDetail()) } else { - log.Warnf("action(%v) statusCode(%v) %v", "getApproval", statusCode, requestContext.generateRequestDetail()) + log.Errorw("action(%v) statusCode(%v) %v", "getApproval", statusCode, requestContext.generateRequestDetail()) } }() @@ -37,7 +37,7 @@ func (g *Gateway) getApprovalHandler(w http.ResponseWriter, r *http.Request) { if err = requestContext.verifySignature(); err != nil { errorDescription = SignatureDoesNotMatch - log.Infow("failed to verify signature", "error", err) + log.Errorw("failed to verify signature", "error", err) return } diff --git a/service/gateway/chain_client.go b/service/gateway/chain_client.go index 125a1ccc2..ebd86bb68 100644 --- a/service/gateway/chain_client.go +++ b/service/gateway/chain_client.go @@ -51,14 +51,14 @@ func (dci *debugChainImpl) createBucket(bucketName string, option *createBucketO return nil } -// chainClientConfig is the configuration information when creating chainClient. +// ChainClientConfig is the configuration information when creating chainClient. // currently Mode only support "DebugMode". -type chainClientConfig struct { +type ChainClientConfig struct { Mode string DebugDir string } -var defaultChainClientConfig = &chainClientConfig{ +var DefaultChainClientConfig = &ChainClientConfig{ Mode: "DebugMode", DebugDir: "./debug", } @@ -69,9 +69,9 @@ type chainClient struct { impl chainClientInterface } -func newChainClient(c *chainClientConfig) (*chainClient, error) { +func newChainClient(c *ChainClientConfig) (*chainClient, error) { if c == nil { - c = defaultChainClientConfig + c = DefaultChainClientConfig } switch { case c.Mode == "DebugMode": diff --git a/service/gateway/gateway.go b/service/gateway/gateway.go index 7c6b9cf13..f321f5dd7 100644 --- a/service/gateway/gateway.go +++ b/service/gateway/gateway.go @@ -7,6 +7,7 @@ import ( "net/http" "sync/atomic" + "github.com/bnb-chain/greenfield-storage-provider/service/client" "github.com/gorilla/mux" "github.com/bnb-chain/greenfield-storage-provider/model" @@ -22,6 +23,7 @@ type Gateway struct { httpServer *http.Server uploadProcessor *uploadProcessor downloadProcessor *downloadProcessor + syncer client.SyncerAPI chain *chainClient retriever *retrieverClient } @@ -45,6 +47,10 @@ func NewGatewayService(cfg *GatewayConfig) (*Gateway, error) { log.Warnw("failed to create downloader", "err", err) return nil, err } + if g.syncer, err = client.NewSyncerClient(g.config.SyncerServiceAddress); err != nil { + log.Errorw("stone node inits syncer client failed", "error", err) + return nil, err + } if g.chain, err = newChainClient(g.config.ChainConfig); err != nil { log.Warnw("failed to create chain client", "err", err) return nil, err @@ -72,7 +78,7 @@ func (g *Gateway) Start(ctx context.Context) error { // Serve starts http service. func (g *Gateway) Serve() { router := mux.NewRouter().SkipClean(true) - g.registerhandler(router) + g.registerHandler(router) server := &http.Server{ Addr: g.config.Address, Handler: router, diff --git a/service/gateway/gateway_config.go b/service/gateway/gateway_config.go index 039dcbccc..82522a282 100644 --- a/service/gateway/gateway_config.go +++ b/service/gateway/gateway_config.go @@ -5,7 +5,8 @@ type GatewayConfig struct { Domain string UploaderServiceAddress string DownloaderServiceAddress string - ChainConfig *chainClientConfig + SyncerServiceAddress string + ChainConfig *ChainClientConfig } var DefaultGatewayConfig = &GatewayConfig{ @@ -13,5 +14,6 @@ var DefaultGatewayConfig = &GatewayConfig{ Domain: "bfs.nodereal.com", UploaderServiceAddress: "127.0.0.1:9133", DownloaderServiceAddress: "127.0.0.1:9233", - ChainConfig: defaultChainClientConfig, + SyncerServiceAddress: "127.0.0.1:9533", + ChainConfig: DefaultChainClientConfig, } diff --git a/service/gateway/request_util.go b/service/gateway/request_util.go index b13801f13..f4aee3d20 100644 --- a/service/gateway/request_util.go +++ b/service/gateway/request_util.go @@ -8,13 +8,14 @@ import ( "time" "github.com/bnb-chain/greenfield-sdk-go/pkg/signer" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/secp256k1" + "github.com/gorilla/mux" + "github.com/bnb-chain/greenfield-storage-provider/model" "github.com/bnb-chain/greenfield-storage-provider/model/errors" ptypes "github.com/bnb-chain/greenfield-storage-provider/pkg/types/v1" "github.com/bnb-chain/greenfield-storage-provider/util" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/secp256k1" - "github.com/gorilla/mux" ) // requestContext is a request context. diff --git a/service/gateway/response_util.go b/service/gateway/response_util.go index 20ec02dc0..509d94888 100644 --- a/service/gateway/response_util.go +++ b/service/gateway/response_util.go @@ -20,7 +20,7 @@ var ( InvalidBucketName = &errorDescription{errorCode: "InvalidBucketName", errorMessage: "The specified bucket is not valid.", statusCode: http.StatusBadRequest} InvalidKey = &errorDescription{errorCode: "InvalidKey", errorMessage: "Object key is Illegal", statusCode: http.StatusBadRequest} InvalidTxHash = &errorDescription{errorCode: "InvalidTxHash", errorMessage: "transaction hash is Illegal", statusCode: http.StatusBadRequest} - InvalidPayload = &errorDescription{errorCode: "InvalidPaload", errorMessage: "payload is empty", statusCode: http.StatusBadRequest} + InvalidPayload = &errorDescription{errorCode: "InvalidPayload", errorMessage: "payload is empty", statusCode: http.StatusBadRequest} UnauthorizedAccess = &errorDescription{errorCode: "UnauthorizedAccess", errorMessage: "UnauthorizedAccess", statusCode: http.StatusUnauthorized} AccessDenied = &errorDescription{errorCode: "AccessDenied", errorMessage: "Access Denied", statusCode: http.StatusForbidden} SignatureDoesNotMatch = &errorDescription{errorCode: "SignatureDoesNotMatch", errorMessage: "SignatureDoesNotMatch", statusCode: http.StatusForbidden} diff --git a/service/gateway/router.go b/service/gateway/router.go index 5d3d18ad6..68459c2d5 100644 --- a/service/gateway/router.go +++ b/service/gateway/router.go @@ -18,8 +18,8 @@ func (g *Gateway) notFoundHandler(w http.ResponseWriter, r *http.Request) { w.Write(s) } -// registerhandler is used to register mux handlers. -func (g *Gateway) registerhandler(r *mux.Router) { +// registerHandler is used to register mux handlers. +func (g *Gateway) registerHandler(r *mux.Router) { // bucket router, virtual-hosted style bucketRouter := r.Host("{bucket:.+}." + g.config.Domain).Subrouter() bucketRouter.NewRoute(). @@ -68,6 +68,8 @@ func (g *Gateway) registerhandler(r *mux.Router) { Methods(http.MethodGet). Queries(model.ActionQuery, "{action}"). HandlerFunc(g.getApprovalHandler) + // sync piece to syncer + r.Path(model.SyncerPath).Name("SyncPiece").Methods(http.MethodPut).HandlerFunc(g.syncPieceHandler) r.NotFoundHandler = http.HandlerFunc(g.notFoundHandler) } diff --git a/service/gateway/sync_piece_handler.go b/service/gateway/sync_piece_handler.go new file mode 100644 index 000000000..741055680 --- /dev/null +++ b/service/gateway/sync_piece_handler.go @@ -0,0 +1,181 @@ +package gateway + +import ( + "bytes" + "context" + "encoding/hex" + "encoding/json" + "io" + "net/http" + "strconv" + "strings" + + "github.com/bnb-chain/greenfield-storage-provider/model" + merrors "github.com/bnb-chain/greenfield-storage-provider/model/errors" + ptypes "github.com/bnb-chain/greenfield-storage-provider/pkg/types/v1" + stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" + "github.com/bnb-chain/greenfield-storage-provider/util/log" +) + +func (g *Gateway) syncPieceHandler(w http.ResponseWriter, r *http.Request) { + var ( + err error + errDescription *errorDescription + reqContext *requestContext + ) + + defer func() { + statusCode := 200 + if errDescription != nil { + statusCode = errDescription.statusCode + _ = errDescription.errorResponse(w, reqContext) + } + if statusCode == 200 { + log.Debugf("action(%v) statusCode(%v) %v", "syncPiece", statusCode, + reqContext.generateRequestDetail()) + } else { + log.Errorf("action(%v) statusCode(%v) %v", "syncPiece", statusCode, + reqContext.generateRequestDetail()) + } + }() + + reqContext = newRequestContext(r) + syncerInfo, err := getReqHeader(r.Header) + if err != nil { + log.Errorw("get request header failed", "error", err) + return + } + // get trace id + traceID := r.Header.Get(model.GnfdTraceIDHeader) + if traceID == "" { + log.Errorw("traceID header is empty") + return + } + pieceData, err := parseBody(r.Body) + if err != nil { + // TODO, add more error + log.Errorw("parse request body failed", "error", err) + return + } + resp, err := g.syncPiece(context.Background(), syncerInfo, pieceData, traceID) + if err != nil { + errDescription = InternalError + } + addRespHeader(resp, w) +} + +func parseBody(body io.ReadCloser) ([][]byte, error) { + buf := &bytes.Buffer{} + _, err := io.Copy(buf, body) + if err != nil { + log.Errorw("copy request body failed", "error", err) + return nil, merrors.ErrInternalError + } + pieceData := make([][]byte, 0) + if err := json.Unmarshal(buf.Bytes(), &pieceData); err != nil { + log.Errorw("unmarshal body failed", "error", err) + return nil, merrors.ErrInternalError + } + return pieceData, nil +} + +func getReqHeader(header http.Header) (*stypes.SyncerInfo, error) { + syncerInfo := &stypes.SyncerInfo{} + // get object id + objectID := header.Get(model.GnfdObjectIDHeader) + if objectID == "" { + log.Error("req header object id is empty") + return nil, merrors.ErrEmptyReqHeader + } + id, err := strconv.ParseUint(objectID, 10, 64) + if err != nil { + log.Errorw("parse object id failed", "error", err) + return nil, merrors.ErrReqHeader + } + syncerInfo.ObjectId = id + + // get storage provider id + spID := header.Get(model.GnfdSPIDHeader) + if spID == "" { + log.Error("req header sp id is empty") + return nil, merrors.ErrEmptyReqHeader + } + syncerInfo.StorageProviderId = spID + + // get piece count + pieceCount := header.Get(model.GnfdPieceCountHeader) + if pieceCount == "" { + log.Error("req header piece count is empty") + return nil, merrors.ErrEmptyReqHeader + } + pCount, err := strconv.ParseUint(pieceCount, 10, 32) + if err != nil { + log.Errorw("parse piece count failed", "error", err) + return nil, merrors.ErrReqHeader + } + syncerInfo.PieceCount = uint32(pCount) + + // get piece index + pieceIndex := header.Get(model.GnfdPieceIndexHeader) + if pieceIndex == "" { + log.Error("req header piece index is empty") + return nil, merrors.ErrEmptyReqHeader + } + pIdx, err := strconv.ParseUint(pieceIndex, 10, 32) + if err != nil { + log.Errorw("parse piece index failed", "error", err) + return nil, merrors.ErrReqHeader + } + syncerInfo.PieceIndex = uint32(pIdx) + + // get redundancy type + redundancyType := header.Get(model.GnfdRedundancyTypeHeader) + if redundancyType == "" { + log.Error("req header redundancy type is empty") + return nil, merrors.ErrEmptyReqHeader + } + rType, err := transferRedundancyType(redundancyType) + if err != nil { + log.Errorw("transfer redundancy type failed", "error", err) + return nil, err + } + syncerInfo.RedundancyType = rType + return syncerInfo, nil +} + +func addRespHeader(resp *stypes.SyncerServiceSyncPieceResponse, w http.ResponseWriter) { + w.Header().Set(model.GnfdTraceIDHeader, resp.GetTraceId()) + w.Header().Set(model.GnfdSPIDHeader, resp.GetSecondarySpInfo().GetStorageProviderId()) + w.Header().Set(model.GnfdPieceIndexHeader, strconv.Itoa(int(resp.GetSecondarySpInfo().GetPieceIdx()))) + + checksum := handlePieceChecksum(resp.GetSecondarySpInfo().GetPieceChecksum()) + log.Infow("gateway piece checksum", "cc", checksum) + w.Header().Set(model.GnfdPieceChecksumHeader, checksum) + + integrityHash := hex.EncodeToString(resp.GetSecondarySpInfo().GetIntegrityHash()) + w.Header().Set(model.GnfdIntegrityHashHeader, integrityHash) + + sig := hex.EncodeToString([]byte("test_signature")) + w.Header().Set(model.GnfdSealSignatureHeader, sig) +} + +func handlePieceChecksum(pieceChecksum [][]byte) string { + list := make([]string, len(pieceChecksum)) + for index, val := range pieceChecksum { + list[index] = hex.EncodeToString(val) + } + return strings.Join(list, ",") +} + +func transferRedundancyType(redundancyType string) (ptypes.RedundancyType, error) { + switch redundancyType { + case ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED.String(): + return ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED, nil + case ptypes.RedundancyType_REDUNDANCY_TYPE_REPLICA_TYPE.String(): + return ptypes.RedundancyType_REDUNDANCY_TYPE_REPLICA_TYPE, nil + case ptypes.RedundancyType_REDUNDANCY_TYPE_INLINE_TYPE.String(): + return ptypes.RedundancyType_REDUNDANCY_TYPE_INLINE_TYPE, nil + default: + return -1, merrors.ErrRedundancyType + } +} diff --git a/service/gateway/synce_piece_test.go b/service/gateway/synce_piece_test.go new file mode 100644 index 000000000..e071c0b6c --- /dev/null +++ b/service/gateway/synce_piece_test.go @@ -0,0 +1,46 @@ +package gateway + +//import ( +// "context" +// "testing" +// +// "github.com/golang/mock/gomock" +// "github.com/stretchr/testify/assert" +// "google.golang.org/grpc" +// +// ptypes "github.com/bnb-chain/greenfield-storage-provider/pkg/types/v1" +// "github.com/bnb-chain/greenfield-storage-provider/service/client/mock" +// stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" +//) +// +//func TestSyncPieceSuccess(t *testing.T) { +// node := setup(t) +// ctrl := gomock.NewController(t) +// defer ctrl.Finish() +// +// streamClient := makeStreamMock() +// syncer := mock.NewMockSyncerAPI(ctrl) +// node.syncer = append(node.syncer, syncer) +// syncer.EXPECT().SyncPiece(gomock.Any(), gomock.Any()).DoAndReturn( +// func(ctx context.Context, opts ...grpc.CallOption) (stypes.SyncerService_SyncPieceClient, error) { +// return streamClient, nil +// }).AnyTimes() +// +// sInfo := &stypes.SyncerInfo{ +// ObjectId: 123456, +// StorageProviderId: "440246a94fc4257096b8d4fa8db94a5655f455f88555f885b10da1466763f742", +// RedundancyType: ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED, +// } +// data := [][]byte{ +// []byte("test1"), +// []byte("test2"), +// []byte("test3"), +// []byte("test4"), +// []byte("test5"), +// []byte("test6"), +// } +// resp, err := node.syncPiece(context.TODO(), sInfo, data, 0, "test_traceID") +// assert.Equal(t, err, nil) +// assert.Equal(t, resp.GetTraceId(), "test_traceID") +// assert.Equal(t, resp.GetSecondarySpInfo().GetPieceIdx(), uint32(1)) +//} diff --git a/service/gateway/syncer_processor.go b/service/gateway/syncer_processor.go new file mode 100644 index 000000000..c92513a06 --- /dev/null +++ b/service/gateway/syncer_processor.go @@ -0,0 +1,42 @@ +package gateway + +import ( + "context" + "fmt" + + stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" + "github.com/bnb-chain/greenfield-storage-provider/util/log" +) + +// syncPiece send rpc request to secondary storage provider to sync the piece data +func (g *Gateway) syncPiece(ctx context.Context, syncerInfo *stypes.SyncerInfo, pieceData [][]byte, traceID string) ( + *stypes.SyncerServiceSyncPieceResponse, error) { + stream, err := g.syncer.SyncPiece(ctx) + if err != nil { + log.Errorw("sync secondary piece job error", "err", err) + return nil, err + } + + // send data one by one to avoid exceeding rpc max msg size + for _, value := range pieceData { + if err := stream.Send(&stypes.SyncerServiceSyncPieceRequest{ + TraceId: traceID, + SyncerInfo: syncerInfo, + PieceData: value, + }); err != nil { + log.Errorw("client send request error", "error", err) + return nil, err + } + } + + resp, err := stream.CloseAndRecv() + if err != nil { + log.Errorw("client close error", "error", err, "traceID", resp.GetTraceId()) + return nil, err + } + if resp.GetErrMessage() != nil && resp.GetErrMessage().GetErrCode() != stypes.ErrCode_ERR_CODE_SUCCESS_UNSPECIFIED { + log.Errorw("sync piece sends to stone node response code is not success", "error", err, "traceID", resp.GetTraceId()) + return nil, fmt.Errorf(resp.GetErrMessage().GetErrMsg()) + } + return resp, nil +} diff --git a/service/stonenode/alloc_stone_job.go b/service/stonenode/alloc_stone_job.go index 353c8aa6e..765e58229 100644 --- a/service/stonenode/alloc_stone_job.go +++ b/service/stonenode/alloc_stone_job.go @@ -36,7 +36,6 @@ func (node *StoneNodeService) loadAndSyncPieces(ctx context.Context, allocResp * // TBD:: check secondarySPs count by redundancyType. // EC_TYPE need EC_M + EC_K + backup // REPLICA_TYPE and INLINE_TYPE need segments count + backup - secondarySPs := mock.AllocUploadSecondarySP() // validate redundancyType and targetIdx redundancyType := allocResp.GetPieceJob().GetRedundancyType() @@ -60,6 +59,7 @@ func (node *StoneNodeService) loadAndSyncPieces(ctx context.Context, allocResp * } // 2. dispatch the piece data to different secondary sp + secondarySPs := mock.AllocUploadSecondarySP() secondaryPieceData, err := node.dispatchSecondarySP(pieceData, redundancyType, secondarySPs, targetIdx) if err != nil { log.CtxErrorw(ctx, "dispatch piece data to secondary sp error") @@ -67,14 +67,16 @@ func (node *StoneNodeService) loadAndSyncPieces(ctx context.Context, allocResp * return err } - if len(secondaryPieceData) > len(node.syncer) { - log.Errorw("syncer number is not enough") - node.reportErrToStoneHub(ctx, allocResp, merrors.ErrSyncerNumber) - return merrors.ErrSyncerNumber + secondaryGatewayList := node.cfg.GatewayAddress + if len(secondaryPieceData) > len(secondarySPs) || len(secondaryGatewayList) != len(secondarySPs) { + log.Errorw("secondary sp is not enough") + node.reportErrToStoneHub(ctx, allocResp, merrors.ErrSecondarySPNumber) + return merrors.ErrSecondarySPNumber } + log.Infow("secondary gateway address list", "list", secondaryGatewayList) // 3. send piece data to the secondary - node.doSyncToSecondarySP(ctx, allocResp, secondaryPieceData, secondarySPs) + node.doSyncToSecondarySP(ctx, allocResp, secondaryPieceData, secondaryGatewayList, secondarySPs) return nil } diff --git a/service/stonenode/http_client.go b/service/stonenode/http_client.go new file mode 100644 index 000000000..58bbef311 --- /dev/null +++ b/service/stonenode/http_client.go @@ -0,0 +1,171 @@ +package stonenode + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "net/http" + "strconv" + "strings" + + storagetypespb "github.com/bnb-chain/greenfield/x/storage/types" + + "github.com/bnb-chain/greenfield-storage-provider/model" + merrors "github.com/bnb-chain/greenfield-storage-provider/model/errors" + stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" + "github.com/bnb-chain/greenfield-storage-provider/util/log" +) + +// sendRequest send piece data to gateway through HTTP protocol +func sendRequest(pieceData [][]byte, httpEndpoint string, syncerInfo *stypes.SyncerInfo, traceID string) ( + *stypes.StorageProviderSealInfo, error) { + //TODO, use io.Copy to avoid using big memory + body, err := json.Marshal(pieceData) + if err != nil { + log.Errorw("marshal piece data failed", "error", err) + } + req, err := http.NewRequest(http.MethodPut, fmt.Sprintf("http://%s%s", httpEndpoint, model.SyncerPath), bytes.NewReader(body)) + if err != nil { + log.Errorw("http NewRequest failed", "error", err) + return nil, err + } + + log.Infow("send request info", "length", len(pieceData), "objectID", syncerInfo.GetObjectId(), + "spID", syncerInfo.GetStorageProviderId(), "index", syncerInfo.GetPieceIndex(), "count", syncerInfo.GetPieceCount(), + "redundancyType", syncerInfo.GetRedundancyType().String()) + req = addReqHeader(req, syncerInfo, traceID) + log.Infow("request header", "header", req.Header) + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + log.Errorw("client Do failed", "error", err) + return nil, err + } + defer resp.Body.Close() + + // if http.StatusCode isn't 200, return error + if resp.StatusCode != http.StatusOK { + log.Error("HTTP status code is not 200: ", resp.StatusCode) + if err := parseBody(resp.Body); err != nil { + log.Errorw("parse body error") + return nil, err + } + } + sealInfo, err := generateSealInfo(resp) + if err != nil { + log.Errorw("generate seal info", "error", err) + return nil, err + } + return sealInfo, nil +} + +func addReqHeader(req *http.Request, syncerInfo *stypes.SyncerInfo, traceID string) *http.Request { + req.Header.Add(model.ContentTypeHeader, model.OctetStream) + req.Header.Add(model.GnfdTraceIDHeader, traceID) + req.Header.Add(model.GnfdObjectIDHeader, strconv.FormatUint(syncerInfo.GetObjectId(), 10)) + req.Header.Add(model.GnfdSPIDHeader, syncerInfo.GetStorageProviderId()) + req.Header.Add(model.GnfdPieceCountHeader, strconv.FormatUint(uint64(syncerInfo.GetPieceCount()), 10)) + req.Header.Add(model.GnfdPieceIndexHeader, strconv.FormatUint(uint64(syncerInfo.GetPieceIndex()), 10)) + req.Header.Add(model.GnfdRedundancyTypeHeader, syncerInfo.GetRedundancyType().String()) + return req +} + +// TODO, perfect handling error message later +func parseBody(body io.ReadCloser) error { + buf := &bytes.Buffer{} + _, err := io.Copy(buf, body) + if err != nil { + log.Errorw("copy request body failed", "error", err) + return err + } + log.Error("error response body") + // parse error message in response body + //if err := xml.Unmarshal(buf.Bytes(), nil); err != nil { + // log.Errorw("unmarshal xml response body failed", "error", err) + // return err + //} + return fmt.Errorf("HTTP status code is not 200") +} + +func generateSealInfo(resp *http.Response) (*stypes.StorageProviderSealInfo, error) { + spSealInfo := &stypes.StorageProviderSealInfo{} + // get storage provider ID + spID := resp.Header.Get(model.GnfdSPIDHeader) + if spID == "" { + log.Error("resp header sp id is empty") + return nil, merrors.ErrEmptyRespHeader + } + spSealInfo.StorageProviderId = spID + + // get piece index + pieceIndex := resp.Header.Get(model.GnfdPieceIndexHeader) + if pieceIndex == "" { + log.Error("resp header piece index is empty") + return nil, merrors.ErrEmptyRespHeader + } + idx, err := strconv.ParseUint(pieceIndex, 10, 32) + if err != nil { + log.Errorw("parse piece index failed", "error", err) + return nil, merrors.ErrRespHeader + } + spSealInfo.PieceIdx = uint32(idx) + + // get piece checksum + pieceChecksum := resp.Header.Get(model.GnfdPieceChecksumHeader) + if pieceChecksum == "" { + log.Error("resp header piece checksum is empty") + return nil, merrors.ErrEmptyRespHeader + } + checksum, err := handlePieceChecksumHeader(pieceChecksum) + if err != nil { + return nil, err + } + spSealInfo.PieceChecksum = checksum + + // get integrity hash + integrityHash := resp.Header.Get(model.GnfdIntegrityHashHeader) + if integrityHash == "" { + log.Error("resp header integrity hash is empty") + return nil, merrors.ErrEmptyRespHeader + } + iHash, err := hex.DecodeString(integrityHash) + if err != nil { + log.Errorw("decode integrity hash failed", "error", err) + return nil, merrors.ErrRespHeader + } + spSealInfo.IntegrityHash = iHash + + // get signature + signature := resp.Header.Get(model.GnfdSealSignatureHeader) + if signature == "" { + log.Error("resp header seal signature is empty") + return nil, merrors.ErrEmptyRespHeader + } + sig, err := hex.DecodeString(signature) + if err != nil { + log.Errorw("decode seal signature failed", "error", err) + return nil, merrors.ErrRespHeader + } + spSealInfo.Signature = sig + return spSealInfo, nil +} + +func handlePieceChecksumHeader(pieceChecksum string) ([][]byte, error) { + list := strings.Split(pieceChecksum, ",") + checksum := make([][]byte, len(list)) + for i, val := range list { + data, err := hex.DecodeString(val) + if err != nil { + log.Errorw("decode piece checksum failed", "error", err) + return nil, merrors.ErrRespHeader + } + checksum[i] = data + } + return checksum, nil +} + +func getApprovalSigNature() { + storagetypespb.NewMsgCreateObject(nil, "", "", 0, false, nil, "", nil, nil) +} diff --git a/service/stonenode/stone_node.go b/service/stonenode/stone_node.go index a27bb25cd..268c7804d 100644 --- a/service/stonenode/stone_node.go +++ b/service/stonenode/stone_node.go @@ -20,7 +20,6 @@ const ( type StoneNodeService struct { cfg *StoneNodeConfig name string - syncer []client.SyncerAPI stoneHub client.StoneHubAPI store client.PieceStoreAPI stoneLimit int64 @@ -58,14 +57,6 @@ func (node *StoneNodeService) initClient() error { log.Errorw("stone node inits stone hub client failed", "error", err) return err } - for _, value := range node.cfg.SyncerServiceAddress { - syncer, err := client.NewSyncerClient(value) - if err != nil { - log.Errorw("stone node inits syncer client failed", "error", err) - return err - } - node.syncer = append(node.syncer, syncer) - } node.store = store node.stoneHub = stoneHub return nil @@ -126,11 +117,6 @@ func (node *StoneNodeService) Stop(ctx context.Context) error { if err := node.stoneHub.Close(); err != nil { errs = append(errs, err) } - for _, syncer := range node.syncer { - if err := syncer.Close(); err != nil { - errs = append(errs, err) - } - } if errs != nil { return fmt.Errorf("%v", errs) } diff --git a/service/stonenode/stone_node_config.go b/service/stonenode/stone_node_config.go index d62a661d4..1976c960c 100644 --- a/service/stonenode/stone_node_config.go +++ b/service/stonenode/stone_node_config.go @@ -4,8 +4,9 @@ import "github.com/bnb-chain/greenfield-storage-provider/store/piecestore/storag type StoneNodeConfig struct { Address string + GatewayAddress []string StoneHubServiceAddress string - SyncerServiceAddress []string + SyncerAddress []string StorageProvider string PieceConfig *storage.PieceStoreConfig StoneJobLimit int64 @@ -13,8 +14,9 @@ type StoneNodeConfig struct { var DefaultStoneNodeConfig = &StoneNodeConfig{ Address: "127.0.0.1:9433", + GatewayAddress: []string{"127.0.0.1:9034", "127.0.0.1:9035", "127.0.0.1:9036", "127.0.0.1:9037", "127.0.0.1:9038", "127.0.0.1:9039"}, StoneHubServiceAddress: "127.0.0.1:9333", - SyncerServiceAddress: []string{"127.0.0.1:9533", "127.0.0.1:9543", "127.0.0.1:9553", "127.0.0.1:9563", "127.0.0.1:9573", "127.0.0.1:9583"}, + SyncerAddress: []string{"127.0.0.1:9543", "127.0.0.1:9553", "127.0.0.1:9563", "127.0.0.1:9573", "127.0.0.1:9583", "127.0.0.1:9593"}, StorageProvider: "bnb-sp", PieceConfig: storage.DefaultPieceStoreConfig, StoneJobLimit: 64, diff --git a/service/stonenode/sync_piece.go b/service/stonenode/sync_piece.go index e0b4f0fed..1708e9021 100644 --- a/service/stonenode/sync_piece.go +++ b/service/stonenode/sync_piece.go @@ -3,7 +3,6 @@ package stonenode import ( "bytes" "context" - "errors" merrors "github.com/bnb-chain/greenfield-storage-provider/model/errors" stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" @@ -13,7 +12,7 @@ import ( // doSyncToSecondarySP send piece data to the secondary func (node *StoneNodeService) doSyncToSecondarySP(ctx context.Context, resp *stypes.StoneHubServiceAllocStoneJobResponse, - pieceDataBySecondary [][][]byte, secondarySPs []string) error { + pieceDataBySecondary [][][]byte, urlList []string, secondarySPs []string) error { var ( objectID = resp.GetPieceJob().GetObjectId() payloadSize = resp.GetPieceJob().GetPayloadSize() @@ -46,22 +45,20 @@ func (node *StoneNodeService) doSyncToSecondarySP(ctx context.Context, resp *sty } }() - syncResp, err := node.syncPiece(ctx, &stypes.SyncerInfo{ + spInfo, err := sendRequest(pieceData, urlList[index], &stypes.SyncerInfo{ ObjectId: objectID, StorageProviderId: secondarySPs[index], PieceIndex: uint32(index), PieceCount: uint32(len(pieceData)), RedundancyType: redundancyType, - }, pieceData, index, resp.GetTraceId()) - // TBD:: retry alloc secondary sp and rat again. + }, resp.GetTraceId()) if err != nil { - log.CtxErrorw(ctx, "sync to secondary piece job failed", "error", err) + log.CtxErrorw(ctx, "send request to gateway failed", "error", err) errMsg.ErrCode = stypes.ErrCode_ERR_CODE_ERROR errMsg.ErrMsg = err.Error() return } - spInfo := syncResp.GetSecondarySpInfo() if ok := verifyIntegrityHash(pieceData, spInfo); !ok { errMsg.ErrCode = stypes.ErrCode_ERR_CODE_ERROR errMsg.ErrMsg = merrors.ErrIntegrityHash.Error() @@ -92,36 +89,3 @@ func verifyIntegrityHash(pieceData [][]byte, spInfo *stypes.StorageProviderSealI "remote_integrity_hash", spInfo.GetIntegrityHash()) return true } - -// syncPiece send rpc request to secondary storage provider to sync the piece data -func (node *StoneNodeService) syncPiece(ctx context.Context, syncerInfo *stypes.SyncerInfo, - pieceData [][]byte, index int, traceID string) (*stypes.SyncerServiceSyncPieceResponse, error) { - stream, err := node.syncer[index].SyncPiece(ctx) - if err != nil { - log.Errorw("sync secondary piece job error", "err", err) - return nil, err - } - - // send data one by one to avoid exceeding rpc max msg size - for _, value := range pieceData { - if err := stream.Send(&stypes.SyncerServiceSyncPieceRequest{ - TraceId: traceID, - SyncerInfo: syncerInfo, - PieceData: value, - }); err != nil { - log.Errorw("client send request error", "error", err) - return nil, err - } - } - - resp, err := stream.CloseAndRecv() - if err != nil { - log.Errorw("client close error", "error", err, "traceID", resp.GetTraceId()) - return nil, err - } - if resp.GetErrMessage() != nil && resp.GetErrMessage().GetErrCode() != stypes.ErrCode_ERR_CODE_SUCCESS_UNSPECIFIED { - log.Errorw("sync piece sends to stone node response code is not success", "error", err, "traceID", resp.GetTraceId()) - return nil, errors.New(resp.GetErrMessage().GetErrMsg()) - } - return resp, nil -} diff --git a/service/stonenode/sync_piece_test.go b/service/stonenode/sync_piece_test.go index e80c14b60..4bea7edd5 100644 --- a/service/stonenode/sync_piece_test.go +++ b/service/stonenode/sync_piece_test.go @@ -87,40 +87,9 @@ func Test_doSyncToSecondarySP(t *testing.T) { for _, tt := range cases { t.Run(tt.name, func(t *testing.T) { allocResp := mockAllocResp(123456, 20*1024*1024, ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED) - err := node.doSyncToSecondarySP(context.TODO(), allocResp, tt.req1, spmock.AllocUploadSecondarySP()) + err := node.doSyncToSecondarySP(context.TODO(), allocResp, tt.req1, spmock.AllocUploadSecondarySP(), + spmock.AllocUploadSecondarySP()) assert.Equal(t, nil, err) }) } } - -func TestSyncPieceSuccess(t *testing.T) { - node := setup(t) - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - streamClient := makeStreamMock() - syncer := mock.NewMockSyncerAPI(ctrl) - node.syncer = append(node.syncer, syncer) - syncer.EXPECT().SyncPiece(gomock.Any(), gomock.Any()).DoAndReturn( - func(ctx context.Context, opts ...grpc.CallOption) (stypes.SyncerService_SyncPieceClient, error) { - return streamClient, nil - }).AnyTimes() - - sInfo := &stypes.SyncerInfo{ - ObjectId: 123456, - StorageProviderId: "440246a94fc4257096b8d4fa8db94a5655f455f88555f885b10da1466763f742", - RedundancyType: ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED, - } - data := [][]byte{ - []byte("test1"), - []byte("test2"), - []byte("test3"), - []byte("test4"), - []byte("test5"), - []byte("test6"), - } - resp, err := node.syncPiece(context.TODO(), sInfo, data, 0, "test_traceID") - assert.Equal(t, err, nil) - assert.Equal(t, resp.GetTraceId(), "test_traceID") - assert.Equal(t, resp.GetSecondarySpInfo().GetPieceIdx(), uint32(1)) -} diff --git a/store/piecestore/storage/s3.go b/store/piecestore/storage/s3.go index c06cafafb..fa4b81bf4 100644 --- a/store/piecestore/storage/s3.go +++ b/store/piecestore/storage/s3.go @@ -218,7 +218,7 @@ func (s *s3Store) ListAllObjects(ctx context.Context, prefix, marker string) (<- return nil, merrors.NotSupportedMethod } -// SessionCache holds session.Session according to model.ObjectStorage and it synchronizes access/modification +// SessionCache holds session.Session according to ObjectStorageConfig and it synchronizes access/modification type SessionCache struct { sync.Mutex sessions map[ObjectStorageConfig]*session.Session @@ -250,7 +250,7 @@ func (sc *SessionCache) newSession(cfg ObjectStorageConfig) (*session.Session, s } // if TestMode is true, you can communicate with private bucket or public bucket, // in this TestMode, if you want to visit private bucket, you should provide accessKey, secretKey. - // if TestMode is false, you can use service account or ec2 to visit you s3 straightly + // if TestMode is false, you can use service account or ec2 to visit your s3 straightly if cfg.TestMode { accessKey := os.Getenv(model.AWSAccessKey) secretKey := os.Getenv(model.AWSSecretKey) diff --git a/test/e2e/onebox/setup_onebox.go b/test/e2e/onebox/setup_onebox.go index ddcfd520b..6f40a371d 100644 --- a/test/e2e/onebox/setup_onebox.go +++ b/test/e2e/onebox/setup_onebox.go @@ -37,8 +37,8 @@ const ( ) func initConfig() { - cfg.Service = []string{model.SyncerService} - cfg.GatewayCfg = gateway.DefaultGatewayConfig + cfg.Service = []string{model.SyncerService, model.GatewayService} + //cfg.GatewayCfg = gateway.DefaultGatewayConfig cfg.UploaderCfg = uploader.DefaultUploaderConfig cfg.StoneHubCfg = stonehub.DefaultStoneHubConfig cfg.ChallengeCfg = challenge.DefaultChallengeConfig @@ -52,6 +52,42 @@ func initConfig() { if cfg.SyncerCfg.PieceConfig == nil { cfg.SyncerCfg.PieceConfig = storage.DefaultPieceStoreConfig } + if cfg.GatewayCfg.ChainConfig == nil { + cfg.GatewayCfg.ChainConfig = gateway.DefaultChainClientConfig + } +} + +func main() { + log.Info("begin setup one-box, deploy secondary syncers") + + cfg = config.LoadConfig(*configFile) + syncerAddrList := cfg.StoneNodeCfg.SyncerAddress + gatewayAddrList := cfg.StoneNodeCfg.GatewayAddress + if len(syncerAddrList) != len(gatewayAddrList) { + log.Errorw("syncer number is not equal to secondary gateway number") + os.Exit(1) + } + initConfig() + + // clear + // todo: polish not clear data + os.RemoveAll(oneboxDir) + pkillCMD := fmt.Sprintf("kill -9 $(pgrep -f %s)", destBinary) + runShell(pkillCMD) + if processNum, err := getProcessNum(); err != nil || processNum != 0 { + log.Errorw("failed to pkill", "error", err) + os.Exit(1) + return + } + + // setup + if err := os.Mkdir(oneboxDir, 0777); err != nil { + log.Errorw("failed to mkdir one-box directory", "error", err) + os.Exit(1) + return + } + multiSPService(syncerAddrList, gatewayAddrList) + log.Info("succeed to setup one-box") } func runShell(cmdStr string) (string, error) { @@ -71,7 +107,7 @@ func runShell(cmdStr string) (string, error) { } func getProcessNum() (int, error) { - time.Sleep(10 * time.Second) + time.Sleep(5 * time.Second) getProcessNumCMD := fmt.Sprintf("ps axu|grep %s | grep -v \"grep\" |wc -l", destBinary) processNumStr, err := runShell(getProcessNumCMD) if err != nil { @@ -87,35 +123,11 @@ func getProcessNum() (int, error) { return processNum, nil } -func main() { - log.Info("begin setup onebox, deploy secondary syncers") - - cfg = config.LoadConfig(*configFile) - addrList := cfg.StoneNodeCfg.SyncerServiceAddress - initConfig() - - // clear - // todo: polish not clear data - os.RemoveAll(oneboxDir) - pkillCMD := fmt.Sprintf("kill -9 $(pgrep -f %s)", destBinary) - runShell(pkillCMD) - if processNum, err := getProcessNum(); err != nil || processNum != 0 { - log.Errorw("failed to pkill", "error", err) - os.Exit(1) - return - } - - // setup - if err := os.Mkdir(oneboxDir, 0777); err != nil { - log.Errorw("failed to mkdir onebox directory", "error", err) - os.Exit(1) - return - } - - for index, addr := range addrList { +func multiSPService(syncerAddrList, gatewayAddrList []string) { + for index, addr := range syncerAddrList { spDir := oneboxDir + "/sp" + strconv.Itoa(index) if err := os.Mkdir(spDir, 0777); err != nil { - log.Errorw("failed to mkdir onebox sp directory", "error", err) + log.Errorw("failed to mkdir one-box sp directory", "error", err) os.Exit(1) return } @@ -135,6 +147,10 @@ func main() { cfg.SyncerCfg.StorageProvider = spDir cfg.SyncerCfg.MetaLevelDBConfig.Path = spDir + "/leveldb" cfg.SyncerCfg.PieceConfig.Store.BucketURL = spDir + "/piece_store" + cfg.GatewayCfg.Address = gatewayAddrList[index] + cfg.GatewayCfg.SyncerServiceAddress = addr + cfg.GatewayCfg.UploaderServiceAddress = "1" + cfg.GatewayCfg.DownloaderServiceAddress = "2" if err = util.TomlSettings.NewEncoder(f).Encode(cfg); err != nil { log.Errorw("failed to encode config", "error", err) os.Exit(1) @@ -156,11 +172,10 @@ func main() { } // check - if processNum, err := getProcessNum(); err != nil || processNum != len(addrList) { - log.Errorw("failed to setup onebox, syncer maybe down and please check log in ./onebox/sp*/log.txt", - "expect", len(addrList), "actual", processNum) + if processNum, err := getProcessNum(); err != nil || processNum != len(syncerAddrList) { + log.Errorw("failed to setup one-box, syncer maybe down and please check log in ./onebox/sp*/log.txt", + "expect", len(syncerAddrList), "actual", processNum) os.Exit(1) return } - log.Info("succeed to setup onebox") } diff --git a/test/e2e/services/case_driver.go b/test/e2e/services/case_driver.go index b4a108d81..44a9f3f61 100644 --- a/test/e2e/services/case_driver.go +++ b/test/e2e/services/case_driver.go @@ -10,10 +10,11 @@ import ( "time" "github.com/bnb-chain/greenfield-sdk-go/pkg/signer" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + "github.com/bnb-chain/greenfield-storage-provider/config" "github.com/bnb-chain/greenfield-storage-provider/model" "github.com/bnb-chain/greenfield-storage-provider/util/log" - "github.com/cosmos/cosmos-sdk/testutil/testdata" ) var ( diff --git a/util/hash/checksum.go b/util/hash/checksum.go index 8687c0da1..d6d0a6efb 100644 --- a/util/hash/checksum.go +++ b/util/hash/checksum.go @@ -1,21 +1,21 @@ package hash import ( + "bytes" "crypto/sha256" ) -// GenerateChecksum generates the checksum of piece data +// GenerateChecksum generates the checksum of one piece data func GenerateChecksum(pieceData []byte) []byte { hash := sha256.New() hash.Write(pieceData) return hash.Sum(nil) } -// GenerateIntegrityHash generate integrity hash of ec data +// GenerateIntegrityHash generates integrity hash of all piece data checksum func GenerateIntegrityHash(checksumList [][]byte) []byte { hash := sha256.New() - for _, j := range checksumList { - hash.Write(j) - } + checksumBytesTotal := bytes.Join(checksumList, []byte("")) + hash.Write(checksumBytesTotal) return hash.Sum(nil) } From bc312992e30bcdaeea4a61876a550978d6095c58 Mon Sep 17 00:00:00 2001 From: DylanYong Date: Tue, 21 Feb 2023 11:49:35 +0800 Subject: [PATCH 2/7] feat: alloc resp add bucket name and object name --- config/config.toml | 1 - service/gateway/sync_piece_handler.go | 1 - service/stonehub/stone_hub_service.go | 3 +++ service/stonenode/alloc_stone_job.go | 4 ++-- service/stonenode/http_client.go | 5 ----- service/stonenode/stone_node_config.go | 2 -- test/e2e/onebox/setup_onebox.go | 3 ++- 7 files changed, 7 insertions(+), 12 deletions(-) diff --git a/config/config.toml b/config/config.toml index 51cdd887e..805135d83 100644 --- a/config/config.toml +++ b/config/config.toml @@ -56,7 +56,6 @@ Service = [ Address = "127.0.0.1:9433" GatewayAddress = ["127.0.0.1:9034", "127.0.0.1:9035", "127.0.0.1:9036", "127.0.0.1:9037", "127.0.0.1:9038", "127.0.0.1:9039"] StoneHubServiceAddress = "127.0.0.1:9333" - SyncerAddress = ["127.0.0.1:9543", "127.0.0.1:9553", "127.0.0.1:9563", "127.0.0.1:9573", "127.0.0.1:9583", "127.0.0.1:9593"] StoneJobLimit = 64 [StoneNodeCfg.PieceConfig] Shards = 0 diff --git a/service/gateway/sync_piece_handler.go b/service/gateway/sync_piece_handler.go index 741055680..e816d4351 100644 --- a/service/gateway/sync_piece_handler.go +++ b/service/gateway/sync_piece_handler.go @@ -149,7 +149,6 @@ func addRespHeader(resp *stypes.SyncerServiceSyncPieceResponse, w http.ResponseW w.Header().Set(model.GnfdPieceIndexHeader, strconv.Itoa(int(resp.GetSecondarySpInfo().GetPieceIdx()))) checksum := handlePieceChecksum(resp.GetSecondarySpInfo().GetPieceChecksum()) - log.Infow("gateway piece checksum", "cc", checksum) w.Header().Set(model.GnfdPieceChecksumHeader, checksum) integrityHash := hex.EncodeToString(resp.GetSecondarySpInfo().GetIntegrityHash()) diff --git a/service/stonehub/stone_hub_service.go b/service/stonehub/stone_hub_service.go index acd76db2a..cbcaf089f 100644 --- a/service/stonehub/stone_hub_service.go +++ b/service/stonehub/stone_hub_service.go @@ -201,6 +201,9 @@ func (hub *StoneHub) AllocStoneJob(ctx context.Context, req *stypes.StoneHubServ } switch job := stoneJob.(type) { case *stypes.PieceJob: + objectInfo, _ := hub.jobDB.GetObjectInfo(job.GetObjectId()) + resp.BucketName = objectInfo.BucketName + resp.ObjectName = objectInfo.ObjectName resp.PieceJob = job default: resp.ErrMessage = merrors.MakeErrMsgResponse(merrors.ErrStoneJobTypeUnrecognized) diff --git a/service/stonenode/alloc_stone_job.go b/service/stonenode/alloc_stone_job.go index 765e58229..e40ee3ef5 100644 --- a/service/stonenode/alloc_stone_job.go +++ b/service/stonenode/alloc_stone_job.go @@ -68,12 +68,12 @@ func (node *StoneNodeService) loadAndSyncPieces(ctx context.Context, allocResp * } secondaryGatewayList := node.cfg.GatewayAddress - if len(secondaryPieceData) > len(secondarySPs) || len(secondaryGatewayList) != len(secondarySPs) { + if len(secondaryPieceData) > len(secondarySPs) { log.Errorw("secondary sp is not enough") node.reportErrToStoneHub(ctx, allocResp, merrors.ErrSecondarySPNumber) return merrors.ErrSecondarySPNumber } - log.Infow("secondary gateway address list", "list", secondaryGatewayList) + log.Debugw("secondary gateway address list", "list", secondaryGatewayList) // 3. send piece data to the secondary node.doSyncToSecondarySP(ctx, allocResp, secondaryPieceData, secondaryGatewayList, secondarySPs) diff --git a/service/stonenode/http_client.go b/service/stonenode/http_client.go index 58bbef311..b4a894bfb 100644 --- a/service/stonenode/http_client.go +++ b/service/stonenode/http_client.go @@ -32,11 +32,7 @@ func sendRequest(pieceData [][]byte, httpEndpoint string, syncerInfo *stypes.Syn return nil, err } - log.Infow("send request info", "length", len(pieceData), "objectID", syncerInfo.GetObjectId(), - "spID", syncerInfo.GetStorageProviderId(), "index", syncerInfo.GetPieceIndex(), "count", syncerInfo.GetPieceCount(), - "redundancyType", syncerInfo.GetRedundancyType().String()) req = addReqHeader(req, syncerInfo, traceID) - log.Infow("request header", "header", req.Header) client := &http.Client{} resp, err := client.Do(req) if err != nil { @@ -80,7 +76,6 @@ func parseBody(body io.ReadCloser) error { log.Errorw("copy request body failed", "error", err) return err } - log.Error("error response body") // parse error message in response body //if err := xml.Unmarshal(buf.Bytes(), nil); err != nil { // log.Errorw("unmarshal xml response body failed", "error", err) diff --git a/service/stonenode/stone_node_config.go b/service/stonenode/stone_node_config.go index 1976c960c..495f7be4e 100644 --- a/service/stonenode/stone_node_config.go +++ b/service/stonenode/stone_node_config.go @@ -6,7 +6,6 @@ type StoneNodeConfig struct { Address string GatewayAddress []string StoneHubServiceAddress string - SyncerAddress []string StorageProvider string PieceConfig *storage.PieceStoreConfig StoneJobLimit int64 @@ -16,7 +15,6 @@ var DefaultStoneNodeConfig = &StoneNodeConfig{ Address: "127.0.0.1:9433", GatewayAddress: []string{"127.0.0.1:9034", "127.0.0.1:9035", "127.0.0.1:9036", "127.0.0.1:9037", "127.0.0.1:9038", "127.0.0.1:9039"}, StoneHubServiceAddress: "127.0.0.1:9333", - SyncerAddress: []string{"127.0.0.1:9543", "127.0.0.1:9553", "127.0.0.1:9563", "127.0.0.1:9573", "127.0.0.1:9583", "127.0.0.1:9593"}, StorageProvider: "bnb-sp", PieceConfig: storage.DefaultPieceStoreConfig, StoneJobLimit: 64, diff --git a/test/e2e/onebox/setup_onebox.go b/test/e2e/onebox/setup_onebox.go index 6f40a371d..3c07c2e19 100644 --- a/test/e2e/onebox/setup_onebox.go +++ b/test/e2e/onebox/setup_onebox.go @@ -57,11 +57,12 @@ func initConfig() { } } +// SyncerAddress = ["127.0.0.1:9543", "127.0.0.1:9553", "127.0.0.1:9563", "127.0.0.1:9573", "127.0.0.1:9583", "127.0.0.1:9593"] func main() { log.Info("begin setup one-box, deploy secondary syncers") cfg = config.LoadConfig(*configFile) - syncerAddrList := cfg.StoneNodeCfg.SyncerAddress + syncerAddrList := []string{"127.0.0.1:9543", "127.0.0.1:9553", "127.0.0.1:9563", "127.0.0.1:9573", "127.0.0.1:9583", "127.0.0.1:9593"} gatewayAddrList := cfg.StoneNodeCfg.GatewayAddress if len(syncerAddrList) != len(gatewayAddrList) { log.Errorw("syncer number is not equal to secondary gateway number") From 20582f61a41b0c1d2ef5aef1e4e6c361e4d4e3f8 Mon Sep 17 00:00:00 2001 From: DylanYong Date: Tue, 21 Feb 2023 13:23:11 +0800 Subject: [PATCH 3/7] fix: fix errors of stone node uint test --- model/const.go | 2 ++ service/gateway/gateway.go | 2 +- service/gateway/gateway_config.go | 2 +- service/stonenode/helper_test.go | 1 - service/stonenode/sync_piece_test.go | 51 ++-------------------------- 5 files changed, 6 insertions(+), 52 deletions(-) diff --git a/model/const.go b/model/const.go index 9479c39fd..d450c4ff8 100644 --- a/model/const.go +++ b/model/const.go @@ -47,6 +47,8 @@ const ( ETagHeader = "ETag" ContentLengthHeader = "Content-Length" ContentTypeXMLHeaderValue = "application/xml" + RangeHeader = "Range" + ContentRangeHeader = "Content-Range" ) // Gateway diff --git a/service/gateway/gateway.go b/service/gateway/gateway.go index 1678f211a..35c6d7f0e 100644 --- a/service/gateway/gateway.go +++ b/service/gateway/gateway.go @@ -58,7 +58,7 @@ func NewGatewayService(cfg *GatewayConfig) (*Gateway, error) { return nil, err } if g.syncer, err = client.NewSyncerClient(g.config.SyncerServiceAddress); err != nil { - log.Errorw("stone node inits syncer client failed", "error", err) + log.Errorw("gateway inits syncer client failed", "error", err) return nil, err } if g.chain, err = newChainClient(g.config.ChainConfig); err != nil { diff --git a/service/gateway/gateway_config.go b/service/gateway/gateway_config.go index 16106fb50..8c9d17788 100644 --- a/service/gateway/gateway_config.go +++ b/service/gateway/gateway_config.go @@ -17,7 +17,7 @@ var DefaultGatewayConfig = &GatewayConfig{ Domain: "gnfd.nodereal.com", UploaderServiceAddress: "127.0.0.1:9133", DownloaderServiceAddress: "127.0.0.1:9233", - ChallengeServiceAddress: "127.0.0.1:9633", SyncerServiceAddress: "127.0.0.1:9533", + ChallengeServiceAddress: "127.0.0.1:9633", ChainConfig: DefaultChainClientConfig, } diff --git a/service/stonenode/helper_test.go b/service/stonenode/helper_test.go index f3ee8bdf5..f8db5c0f0 100644 --- a/service/stonenode/helper_test.go +++ b/service/stonenode/helper_test.go @@ -17,7 +17,6 @@ func setup(t *testing.T) *StoneNodeService { cfg: &StoneNodeConfig{ Address: "test1", StoneHubServiceAddress: "test2", - SyncerServiceAddress: []string{"test3"}, StorageProvider: "test", StoneJobLimit: 0, }, diff --git a/service/stonenode/sync_piece_test.go b/service/stonenode/sync_piece_test.go index 4bea7edd5..2a65cdd59 100644 --- a/service/stonenode/sync_piece_test.go +++ b/service/stonenode/sync_piece_test.go @@ -1,19 +1,6 @@ package stonenode -import ( - "context" - "testing" - - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/assert" - "google.golang.org/grpc" - - spmock "github.com/bnb-chain/greenfield-storage-provider/mock" - ptypes "github.com/bnb-chain/greenfield-storage-provider/pkg/types/v1" - "github.com/bnb-chain/greenfield-storage-provider/service/client/mock" - stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" -) - +/* func Test_doSyncToSecondarySP(t *testing.T) { list := make([][][]byte, 0) ecList := [][]byte{[]byte("1"), []byte("2"), []byte("3"), []byte("4"), []byte("5"), []byte("6")} @@ -49,41 +36,6 @@ func Test_doSyncToSecondarySP(t *testing.T) { return streamClient, nil }).AnyTimes() - syncer2 := mock.NewMockSyncerAPI(ctrl) - node.syncer = append(node.syncer, syncer2) - syncer2.EXPECT().SyncPiece(gomock.Any(), gomock.Any()).DoAndReturn( - func(ctx context.Context, opts ...grpc.CallOption) (stypes.SyncerService_SyncPieceClient, error) { - return streamClient, nil - }).AnyTimes() - - syncer3 := mock.NewMockSyncerAPI(ctrl) - node.syncer = append(node.syncer, syncer3) - syncer3.EXPECT().SyncPiece(gomock.Any(), gomock.Any()).DoAndReturn( - func(ctx context.Context, opts ...grpc.CallOption) (stypes.SyncerService_SyncPieceClient, error) { - return streamClient, nil - }).AnyTimes() - - syncer4 := mock.NewMockSyncerAPI(ctrl) - node.syncer = append(node.syncer, syncer4) - syncer4.EXPECT().SyncPiece(gomock.Any(), gomock.Any()).DoAndReturn( - func(ctx context.Context, opts ...grpc.CallOption) (stypes.SyncerService_SyncPieceClient, error) { - return streamClient, nil - }).AnyTimes() - - syncer5 := mock.NewMockSyncerAPI(ctrl) - node.syncer = append(node.syncer, syncer5) - syncer5.EXPECT().SyncPiece(gomock.Any(), gomock.Any()).DoAndReturn( - func(ctx context.Context, opts ...grpc.CallOption) (stypes.SyncerService_SyncPieceClient, error) { - return streamClient, nil - }).AnyTimes() - - syncer6 := mock.NewMockSyncerAPI(ctrl) - node.syncer = append(node.syncer, syncer6) - syncer6.EXPECT().SyncPiece(gomock.Any(), gomock.Any()).DoAndReturn( - func(ctx context.Context, opts ...grpc.CallOption) (stypes.SyncerService_SyncPieceClient, error) { - return streamClient, nil - }).AnyTimes() - for _, tt := range cases { t.Run(tt.name, func(t *testing.T) { allocResp := mockAllocResp(123456, 20*1024*1024, ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED) @@ -93,3 +45,4 @@ func Test_doSyncToSecondarySP(t *testing.T) { }) } } +*/ From a579c7bd27a939c9a31ec66c5800e5590ae88554 Mon Sep 17 00:00:00 2001 From: DylanYong Date: Tue, 21 Feb 2023 14:06:06 +0800 Subject: [PATCH 4/7] fix: fix gateway config --- config/config.toml | 3 ++- service/client/syncer_client.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config/config.toml b/config/config.toml index 92fc74f46..3cbc27af9 100644 --- a/config/config.toml +++ b/config/config.toml @@ -8,6 +8,7 @@ Service = [ Domain = "gnfd.nodereal.com" UploaderServiceAddress = "127.0.0.1:9133" DownloaderServiceAddress = "127.0.0.1:9233" + SyncerServiceAddress = "127.0.0.1:9533" ChallengeServiceAddress = "127.0.0.1:9633" @@ -87,7 +88,7 @@ Service = [ ReadOnly = false [SignerCfg] - Address = "127.0.0.1:9633" + Address = "127.0.0.1:9733" WhitelistCIDR = ["127.0.0.1/32","10.0.0.0/8","172.16.0.0/12","192.168.0.0/16"] APIKey = "" [SignerCfg.GreenfieldChainConfig] diff --git a/service/client/syncer_client.go b/service/client/syncer_client.go index cb2d303d9..e3d4bc624 100644 --- a/service/client/syncer_client.go +++ b/service/client/syncer_client.go @@ -32,7 +32,7 @@ func NewSyncerClient(address string) (*SyncerClient, error) { conn, err := grpc.DialContext(context.Background(), address, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(model.MaxCallMsgSize), grpc.MaxCallSendMsgSize(model.MaxCallMsgSize))) if err != nil { - log.Errorw("invoke syncer service grpc.DialContext failed", "error", err) + log.Errorw("invoke syncer service failed", "error", err) return nil, err } client := &SyncerClient{ From 4bf940c72d2cce09d811958492794a3e8a411e9f Mon Sep 17 00:00:00 2001 From: DylanYong Date: Tue, 21 Feb 2023 14:23:14 +0800 Subject: [PATCH 5/7] fix: add gateway syncer rpc ut --- service/gateway/helper_test.go | 64 ++++++++++++++++++++ service/gateway/synce_piece_test.go | 87 ++++++++++++++-------------- service/stonenode/helper_test.go | 40 ------------- service/stonenode/http_client.go | 9 ++- service/stonenode/sync_piece_test.go | 25 ++++---- 5 files changed, 125 insertions(+), 100 deletions(-) create mode 100644 service/gateway/helper_test.go diff --git a/service/gateway/helper_test.go b/service/gateway/helper_test.go new file mode 100644 index 000000000..34fa9fd61 --- /dev/null +++ b/service/gateway/helper_test.go @@ -0,0 +1,64 @@ +package gateway + +import ( + "context" + "encoding/base64" + "testing" + + "github.com/bnb-chain/greenfield-storage-provider/model" + "google.golang.org/grpc" + + stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" +) + +func setup(t *testing.T) *Gateway { + return &Gateway{ + config: &GatewayConfig{ + StorageProvider: "test1", + Address: "test2", + Domain: "test3", + UploaderServiceAddress: "test4", + DownloaderServiceAddress: "test5", + ChallengeServiceAddress: "test6", + SyncerServiceAddress: "test7", + ChainConfig: DefaultChainClientConfig, + }, + name: model.GatewayService, + } +} + +func makeStreamMock() *StreamMock { + return &StreamMock{ + ctx: context.Background(), + recvToServer: make(chan *stypes.SyncerServiceSyncPieceRequest, 10), + } +} + +type StreamMock struct { + grpc.ClientStream + ctx context.Context + recvToServer chan *stypes.SyncerServiceSyncPieceRequest +} + +func (m *StreamMock) Send(resp *stypes.SyncerServiceSyncPieceRequest) error { + m.recvToServer <- resp + return nil +} + +func (m *StreamMock) CloseAndRecv() (*stypes.SyncerServiceSyncPieceResponse, error) { + integrityHash, _ := base64.URLEncoding.DecodeString("pgPGdR4c9_KYz6wQxl-SifyzHXlHhx5XfNa89LzdNCI=") + return &stypes.SyncerServiceSyncPieceResponse{ + TraceId: "test_traceID", + SecondarySpInfo: &stypes.StorageProviderSealInfo{ + StorageProviderId: "sp1", + PieceIdx: 1, + PieceChecksum: [][]byte{[]byte("1"), []byte("2"), []byte("3"), []byte("4"), []byte("5"), []byte("6")}, + IntegrityHash: integrityHash, + Signature: nil, + }, + ErrMessage: &stypes.ErrMessage{ + ErrCode: stypes.ErrCode_ERR_CODE_SUCCESS_UNSPECIFIED, + ErrMsg: "Success", + }, + }, nil +} diff --git a/service/gateway/synce_piece_test.go b/service/gateway/synce_piece_test.go index e071c0b6c..fd9ef6df0 100644 --- a/service/gateway/synce_piece_test.go +++ b/service/gateway/synce_piece_test.go @@ -1,46 +1,45 @@ package gateway -//import ( -// "context" -// "testing" -// -// "github.com/golang/mock/gomock" -// "github.com/stretchr/testify/assert" -// "google.golang.org/grpc" -// -// ptypes "github.com/bnb-chain/greenfield-storage-provider/pkg/types/v1" -// "github.com/bnb-chain/greenfield-storage-provider/service/client/mock" -// stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" -//) -// -//func TestSyncPieceSuccess(t *testing.T) { -// node := setup(t) -// ctrl := gomock.NewController(t) -// defer ctrl.Finish() -// -// streamClient := makeStreamMock() -// syncer := mock.NewMockSyncerAPI(ctrl) -// node.syncer = append(node.syncer, syncer) -// syncer.EXPECT().SyncPiece(gomock.Any(), gomock.Any()).DoAndReturn( -// func(ctx context.Context, opts ...grpc.CallOption) (stypes.SyncerService_SyncPieceClient, error) { -// return streamClient, nil -// }).AnyTimes() -// -// sInfo := &stypes.SyncerInfo{ -// ObjectId: 123456, -// StorageProviderId: "440246a94fc4257096b8d4fa8db94a5655f455f88555f885b10da1466763f742", -// RedundancyType: ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED, -// } -// data := [][]byte{ -// []byte("test1"), -// []byte("test2"), -// []byte("test3"), -// []byte("test4"), -// []byte("test5"), -// []byte("test6"), -// } -// resp, err := node.syncPiece(context.TODO(), sInfo, data, 0, "test_traceID") -// assert.Equal(t, err, nil) -// assert.Equal(t, resp.GetTraceId(), "test_traceID") -// assert.Equal(t, resp.GetSecondarySpInfo().GetPieceIdx(), uint32(1)) -//} +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "google.golang.org/grpc" + + ptypes "github.com/bnb-chain/greenfield-storage-provider/pkg/types/v1" + "github.com/bnb-chain/greenfield-storage-provider/service/client/mock" + stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" +) + +func TestSyncPieceSuccess(t *testing.T) { + gw := setup(t) + ctrl := gomock.NewController(t) + + streamClient := makeStreamMock() + syncer := mock.NewMockSyncerAPI(ctrl) + gw.syncer = syncer + syncer.EXPECT().SyncPiece(gomock.Any(), gomock.Any()).DoAndReturn( + func(ctx context.Context, opts ...grpc.CallOption) (stypes.SyncerService_SyncPieceClient, error) { + return streamClient, nil + }).AnyTimes() + + sInfo := &stypes.SyncerInfo{ + ObjectId: 123456, + StorageProviderId: "440246a94fc4257096b8d4fa8db94a5655f455f88555f885b10da1466763f742", + RedundancyType: ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED, + } + data := [][]byte{ + []byte("test1"), + []byte("test2"), + []byte("test3"), + []byte("test4"), + []byte("test5"), + []byte("test6"), + } + resp, err := gw.syncPiece(context.TODO(), sInfo, data, "test_traceID") + assert.Equal(t, err, nil) + assert.Equal(t, resp.GetTraceId(), "test_traceID") + assert.Equal(t, resp.GetSecondarySpInfo().GetPieceIdx(), uint32(1)) +} diff --git a/service/stonenode/helper_test.go b/service/stonenode/helper_test.go index f8db5c0f0..99b558378 100644 --- a/service/stonenode/helper_test.go +++ b/service/stonenode/helper_test.go @@ -1,12 +1,8 @@ package stonenode import ( - "context" - "encoding/base64" "testing" - "google.golang.org/grpc" - "github.com/bnb-chain/greenfield-storage-provider/model" ptypes "github.com/bnb-chain/greenfield-storage-provider/pkg/types/v1" stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" @@ -67,39 +63,3 @@ func dispatchInlinePieceSlice() [][][]byte { inlineSlice = append(inlineSlice, inlineList) return inlineSlice } - -func makeStreamMock() *StreamMock { - return &StreamMock{ - ctx: context.Background(), - recvToServer: make(chan *stypes.SyncerServiceSyncPieceRequest, 10), - } -} - -type StreamMock struct { - grpc.ClientStream - ctx context.Context - recvToServer chan *stypes.SyncerServiceSyncPieceRequest -} - -func (m *StreamMock) Send(resp *stypes.SyncerServiceSyncPieceRequest) error { - m.recvToServer <- resp - return nil -} - -func (m *StreamMock) CloseAndRecv() (*stypes.SyncerServiceSyncPieceResponse, error) { - integrityHash, _ := base64.URLEncoding.DecodeString("pgPGdR4c9_KYz6wQxl-SifyzHXlHhx5XfNa89LzdNCI=") - return &stypes.SyncerServiceSyncPieceResponse{ - TraceId: "test_traceID", - SecondarySpInfo: &stypes.StorageProviderSealInfo{ - StorageProviderId: "sp1", - PieceIdx: 1, - PieceChecksum: [][]byte{[]byte("1"), []byte("2"), []byte("3"), []byte("4"), []byte("5"), []byte("6")}, - IntegrityHash: integrityHash, - Signature: nil, - }, - ErrMessage: &stypes.ErrMessage{ - ErrCode: stypes.ErrCode_ERR_CODE_SUCCESS_UNSPECIFIED, - ErrMsg: "Success", - }, - }, nil -} diff --git a/service/stonenode/http_client.go b/service/stonenode/http_client.go index b4a894bfb..ae22ccc1b 100644 --- a/service/stonenode/http_client.go +++ b/service/stonenode/http_client.go @@ -10,8 +10,6 @@ import ( "strconv" "strings" - storagetypespb "github.com/bnb-chain/greenfield/x/storage/types" - "github.com/bnb-chain/greenfield-storage-provider/model" merrors "github.com/bnb-chain/greenfield-storage-provider/model/errors" stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" @@ -161,6 +159,7 @@ func handlePieceChecksumHeader(pieceChecksum string) ([][]byte, error) { return checksum, nil } -func getApprovalSigNature() { - storagetypespb.NewMsgCreateObject(nil, "", "", 0, false, nil, "", nil, nil) -} +// +//func getApprovalSigNature() { +// storagetypespb.NewMsgCreateObject(nil, "", "", 0, false, nil, "", nil, nil) +//} diff --git a/service/stonenode/sync_piece_test.go b/service/stonenode/sync_piece_test.go index 2a65cdd59..7fcf11a2b 100644 --- a/service/stonenode/sync_piece_test.go +++ b/service/stonenode/sync_piece_test.go @@ -1,6 +1,19 @@ package stonenode -/* +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "google.golang.org/grpc" + + spmock "github.com/bnb-chain/greenfield-storage-provider/mock" + ptypes "github.com/bnb-chain/greenfield-storage-provider/pkg/types/v1" + "github.com/bnb-chain/greenfield-storage-provider/service/client/mock" + stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" +) + func Test_doSyncToSecondarySP(t *testing.T) { list := make([][][]byte, 0) ecList := [][]byte{[]byte("1"), []byte("2"), []byte("3"), []byte("4"), []byte("5"), []byte("6")} @@ -27,15 +40,6 @@ func Test_doSyncToSecondarySP(t *testing.T) { return nil, nil }).AnyTimes() - // syncer service stub - streamClient := makeStreamMock() - syncer1 := mock.NewMockSyncerAPI(ctrl) - node.syncer = append(node.syncer, syncer1) - syncer1.EXPECT().SyncPiece(gomock.Any(), gomock.Any()).DoAndReturn( - func(ctx context.Context, opts ...grpc.CallOption) (stypes.SyncerService_SyncPieceClient, error) { - return streamClient, nil - }).AnyTimes() - for _, tt := range cases { t.Run(tt.name, func(t *testing.T) { allocResp := mockAllocResp(123456, 20*1024*1024, ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED) @@ -45,4 +49,3 @@ func Test_doSyncToSecondarySP(t *testing.T) { }) } } -*/ From 83d4edceccc56827494ec58d7434462a47ea86d6 Mon Sep 17 00:00:00 2001 From: DylanYong Date: Tue, 21 Feb 2023 17:44:19 +0800 Subject: [PATCH 6/7] fix: add one log in gateway sync piece handler func --- service/gateway/sync_piece_handler.go | 1 + 1 file changed, 1 insertion(+) diff --git a/service/gateway/sync_piece_handler.go b/service/gateway/sync_piece_handler.go index e816d4351..a7fbc9770 100644 --- a/service/gateway/sync_piece_handler.go +++ b/service/gateway/sync_piece_handler.go @@ -62,6 +62,7 @@ func (g *Gateway) syncPieceHandler(w http.ResponseWriter, r *http.Request) { errDescription = InternalError } addRespHeader(resp, w) + log.Info("sync piece handler reply response to stone node") } func parseBody(body io.ReadCloser) ([][]byte, error) { From 845cc910d238f0f298d13ef892acd79cb6dc5be8 Mon Sep 17 00:00:00 2001 From: DylanYong Date: Tue, 21 Feb 2023 19:28:57 +0800 Subject: [PATCH 7/7] fix: add detailed log in gateway sync piece handler --- config/config.toml | 2 +- model/const.go | 1 - service/gateway/sync_piece_handler.go | 48 ++++++++------------------- service/stonenode/http_client.go | 24 +++----------- service/syncer/syncer_service.go | 4 ++- util/utils.go | 23 ++++++++++--- 6 files changed, 40 insertions(+), 62 deletions(-) diff --git a/config/config.toml b/config/config.toml index 63fd0f398..1b6a5be39 100644 --- a/config/config.toml +++ b/config/config.toml @@ -88,7 +88,7 @@ Service = [ ReadOnly = false [SignerCfg] - Address = "127.0.0.1:9733" + Address = "127.0.0.1:9633" WhitelistCIDR = ["127.0.0.1/32","10.0.0.0/8","172.16.0.0/12","192.168.0.0/16"] APIKey = "" [SignerCfg.GreenfieldChainConfig] diff --git a/model/const.go b/model/const.go index 96537f31a..bf0e56ca1 100644 --- a/model/const.go +++ b/model/const.go @@ -81,7 +81,6 @@ const ( GnfdPieceHashHeader = "X-Gnfd-Piece-Hash" // StoneNode to gateway request header - GnfdTraceIDHeader = "X-Gnfd-Trace-ID" GnfdSPIDHeader = "X-Gnfd-SP-ID" GnfdPieceCountHeader = "X-Gnfd-Piece-Count" GnfdApprovalSignatureHeader = "X-Gnfd-Approval-Signature" diff --git a/service/gateway/sync_piece_handler.go b/service/gateway/sync_piece_handler.go index a7fbc9770..caacbd5aa 100644 --- a/service/gateway/sync_piece_handler.go +++ b/service/gateway/sync_piece_handler.go @@ -8,12 +8,11 @@ import ( "io" "net/http" "strconv" - "strings" "github.com/bnb-chain/greenfield-storage-provider/model" merrors "github.com/bnb-chain/greenfield-storage-provider/model/errors" - ptypes "github.com/bnb-chain/greenfield-storage-provider/pkg/types/v1" stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" + "github.com/bnb-chain/greenfield-storage-provider/util" "github.com/bnb-chain/greenfield-storage-provider/util/log" ) @@ -40,16 +39,16 @@ func (g *Gateway) syncPieceHandler(w http.ResponseWriter, r *http.Request) { }() reqContext = newRequestContext(r) + log.Infow("sync piece handler receive data", "request", reqContext.generateRequestDetail()) syncerInfo, err := getReqHeader(r.Header) if err != nil { log.Errorw("get request header failed", "error", err) return } // get trace id - traceID := r.Header.Get(model.GnfdTraceIDHeader) + traceID := r.Header.Get(model.GnfdRequestIDHeader) if traceID == "" { - log.Errorw("traceID header is empty") - return + traceID = reqContext.requestID } pieceData, err := parseBody(r.Body) if err != nil { @@ -62,7 +61,7 @@ func (g *Gateway) syncPieceHandler(w http.ResponseWriter, r *http.Request) { errDescription = InternalError } addRespHeader(resp, w) - log.Info("sync piece handler reply response to stone node") + log.Infow("sync piece handler reply response to stone node", "response header", w.Header()) } func parseBody(body io.ReadCloser) ([][]byte, error) { @@ -88,7 +87,7 @@ func getReqHeader(header http.Header) (*stypes.SyncerInfo, error) { log.Error("req header object id is empty") return nil, merrors.ErrEmptyReqHeader } - id, err := strconv.ParseUint(objectID, 10, 64) + id, err := util.HeaderToUint64(objectID) if err != nil { log.Errorw("parse object id failed", "error", err) return nil, merrors.ErrReqHeader @@ -109,12 +108,12 @@ func getReqHeader(header http.Header) (*stypes.SyncerInfo, error) { log.Error("req header piece count is empty") return nil, merrors.ErrEmptyReqHeader } - pCount, err := strconv.ParseUint(pieceCount, 10, 32) + pCount, err := util.HeaderToUint32(pieceCount) if err != nil { log.Errorw("parse piece count failed", "error", err) return nil, merrors.ErrReqHeader } - syncerInfo.PieceCount = uint32(pCount) + syncerInfo.PieceCount = pCount // get piece index pieceIndex := header.Get(model.GnfdPieceIndexHeader) @@ -122,12 +121,12 @@ func getReqHeader(header http.Header) (*stypes.SyncerInfo, error) { log.Error("req header piece index is empty") return nil, merrors.ErrEmptyReqHeader } - pIdx, err := strconv.ParseUint(pieceIndex, 10, 32) + pIdx, err := util.HeaderToUint32(pieceIndex) if err != nil { log.Errorw("parse piece index failed", "error", err) return nil, merrors.ErrReqHeader } - syncerInfo.PieceIndex = uint32(pIdx) + syncerInfo.PieceIndex = pIdx // get redundancy type redundancyType := header.Get(model.GnfdRedundancyTypeHeader) @@ -135,7 +134,7 @@ func getReqHeader(header http.Header) (*stypes.SyncerInfo, error) { log.Error("req header redundancy type is empty") return nil, merrors.ErrEmptyReqHeader } - rType, err := transferRedundancyType(redundancyType) + rType, err := util.TransferRedundancyType(redundancyType) if err != nil { log.Errorw("transfer redundancy type failed", "error", err) return nil, err @@ -145,11 +144,11 @@ func getReqHeader(header http.Header) (*stypes.SyncerInfo, error) { } func addRespHeader(resp *stypes.SyncerServiceSyncPieceResponse, w http.ResponseWriter) { - w.Header().Set(model.GnfdTraceIDHeader, resp.GetTraceId()) + w.Header().Set(model.GnfdRequestIDHeader, resp.GetTraceId()) w.Header().Set(model.GnfdSPIDHeader, resp.GetSecondarySpInfo().GetStorageProviderId()) w.Header().Set(model.GnfdPieceIndexHeader, strconv.Itoa(int(resp.GetSecondarySpInfo().GetPieceIdx()))) - checksum := handlePieceChecksum(resp.GetSecondarySpInfo().GetPieceChecksum()) + checksum := util.EncodePieceHash(resp.GetSecondarySpInfo().GetPieceChecksum()) w.Header().Set(model.GnfdPieceChecksumHeader, checksum) integrityHash := hex.EncodeToString(resp.GetSecondarySpInfo().GetIntegrityHash()) @@ -158,24 +157,3 @@ func addRespHeader(resp *stypes.SyncerServiceSyncPieceResponse, w http.ResponseW sig := hex.EncodeToString([]byte("test_signature")) w.Header().Set(model.GnfdSealSignatureHeader, sig) } - -func handlePieceChecksum(pieceChecksum [][]byte) string { - list := make([]string, len(pieceChecksum)) - for index, val := range pieceChecksum { - list[index] = hex.EncodeToString(val) - } - return strings.Join(list, ",") -} - -func transferRedundancyType(redundancyType string) (ptypes.RedundancyType, error) { - switch redundancyType { - case ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED.String(): - return ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED, nil - case ptypes.RedundancyType_REDUNDANCY_TYPE_REPLICA_TYPE.String(): - return ptypes.RedundancyType_REDUNDANCY_TYPE_REPLICA_TYPE, nil - case ptypes.RedundancyType_REDUNDANCY_TYPE_INLINE_TYPE.String(): - return ptypes.RedundancyType_REDUNDANCY_TYPE_INLINE_TYPE, nil - default: - return -1, merrors.ErrRedundancyType - } -} diff --git a/service/stonenode/http_client.go b/service/stonenode/http_client.go index ae22ccc1b..74662ef6f 100644 --- a/service/stonenode/http_client.go +++ b/service/stonenode/http_client.go @@ -8,11 +8,11 @@ import ( "io" "net/http" "strconv" - "strings" "github.com/bnb-chain/greenfield-storage-provider/model" merrors "github.com/bnb-chain/greenfield-storage-provider/model/errors" stypes "github.com/bnb-chain/greenfield-storage-provider/service/types/v1" + "github.com/bnb-chain/greenfield-storage-provider/util" "github.com/bnb-chain/greenfield-storage-provider/util/log" ) @@ -57,7 +57,7 @@ func sendRequest(pieceData [][]byte, httpEndpoint string, syncerInfo *stypes.Syn func addReqHeader(req *http.Request, syncerInfo *stypes.SyncerInfo, traceID string) *http.Request { req.Header.Add(model.ContentTypeHeader, model.OctetStream) - req.Header.Add(model.GnfdTraceIDHeader, traceID) + req.Header.Add(model.GnfdRequestIDHeader, traceID) req.Header.Add(model.GnfdObjectIDHeader, strconv.FormatUint(syncerInfo.GetObjectId(), 10)) req.Header.Add(model.GnfdSPIDHeader, syncerInfo.GetStorageProviderId()) req.Header.Add(model.GnfdPieceCountHeader, strconv.FormatUint(uint64(syncerInfo.GetPieceCount()), 10)) @@ -98,12 +98,12 @@ func generateSealInfo(resp *http.Response) (*stypes.StorageProviderSealInfo, err log.Error("resp header piece index is empty") return nil, merrors.ErrEmptyRespHeader } - idx, err := strconv.ParseUint(pieceIndex, 10, 32) + idx, err := util.HeaderToUint32(pieceIndex) if err != nil { log.Errorw("parse piece index failed", "error", err) return nil, merrors.ErrRespHeader } - spSealInfo.PieceIdx = uint32(idx) + spSealInfo.PieceIdx = idx // get piece checksum pieceChecksum := resp.Header.Get(model.GnfdPieceChecksumHeader) @@ -111,7 +111,7 @@ func generateSealInfo(resp *http.Response) (*stypes.StorageProviderSealInfo, err log.Error("resp header piece checksum is empty") return nil, merrors.ErrEmptyRespHeader } - checksum, err := handlePieceChecksumHeader(pieceChecksum) + checksum, err := util.DecodePieceHash(pieceChecksum) if err != nil { return nil, err } @@ -145,20 +145,6 @@ func generateSealInfo(resp *http.Response) (*stypes.StorageProviderSealInfo, err return spSealInfo, nil } -func handlePieceChecksumHeader(pieceChecksum string) ([][]byte, error) { - list := strings.Split(pieceChecksum, ",") - checksum := make([][]byte, len(list)) - for i, val := range list { - data, err := hex.DecodeString(val) - if err != nil { - log.Errorw("decode piece checksum failed", "error", err) - return nil, merrors.ErrRespHeader - } - checksum[i] = data - } - return checksum, nil -} - // //func getApprovalSigNature() { // storagetypespb.NewMsgCreateObject(nil, "", "", 0, false, nil, "", nil, nil) diff --git a/service/syncer/syncer_service.go b/service/syncer/syncer_service.go index 3c59a63a8..e8c20302f 100644 --- a/service/syncer/syncer_service.go +++ b/service/syncer/syncer_service.go @@ -18,6 +18,7 @@ func (s *Syncer) SyncPiece(stream stypes.SyncerService_SyncPieceServer) error { var count uint32 var integrityMeta *spdb.IntegrityMeta var spID string + var traceID string var value []byte pieceHash := make([][]byte, 0) @@ -37,7 +38,7 @@ func (s *Syncer) SyncPiece(stream stypes.SyncerService_SyncPieceServer) error { return err } resp := &stypes.SyncerServiceSyncPieceResponse{ - TraceId: req.GetTraceId(), + TraceId: traceID, SecondarySpInfo: sealInfo, ErrMessage: &stypes.ErrMessage{ ErrCode: stypes.ErrCode_ERR_CODE_SUCCESS_UNSPECIFIED, @@ -58,6 +59,7 @@ func (s *Syncer) SyncPiece(stream stypes.SyncerService_SyncPieceServer) error { if err != nil { return err } + traceID = req.GetTraceId() pieceHash = append(pieceHash, hash.GenerateChecksum(value)) } } diff --git a/util/utils.go b/util/utils.go index b003136a7..cfd2a7a9a 100644 --- a/util/utils.go +++ b/util/utils.go @@ -156,18 +156,18 @@ func Uint64ToHeader(u uint64) string { } // EncodePieceHash is used to serialize -func EncodePieceHash(PieceHash [][]byte) string { - PieceStringList := make([]string, len(PieceHash)) - for index, h := range PieceHash { +func EncodePieceHash(pieceHash [][]byte) string { + PieceStringList := make([]string, len(pieceHash)) + for index, h := range pieceHash { PieceStringList[index] = hex.EncodeToString(h) } return StringSliceToHeader(PieceStringList) } // DecodePieceHash is used to deserialize -func DecodePieceHash(PieceHash string) ([][]byte, error) { +func DecodePieceHash(pieceHash string) ([][]byte, error) { var err error - pieceStringList := HeaderToStringSlice(PieceHash) + pieceStringList := HeaderToStringSlice(pieceHash) hashList := make([][]byte, len(pieceStringList)) for idx := range pieceStringList { if hashList[idx], err = hex.DecodeString(pieceStringList[idx]); err != nil { @@ -176,3 +176,16 @@ func DecodePieceHash(PieceHash string) ([][]byte, error) { } return hashList, nil } + +func TransferRedundancyType(redundancyType string) (ptypes.RedundancyType, error) { + switch redundancyType { + case ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED.String(): + return ptypes.RedundancyType_REDUNDANCY_TYPE_EC_TYPE_UNSPECIFIED, nil + case ptypes.RedundancyType_REDUNDANCY_TYPE_REPLICA_TYPE.String(): + return ptypes.RedundancyType_REDUNDANCY_TYPE_REPLICA_TYPE, nil + case ptypes.RedundancyType_REDUNDANCY_TYPE_INLINE_TYPE.String(): + return ptypes.RedundancyType_REDUNDANCY_TYPE_INLINE_TYPE, nil + default: + return -1, merrors.ErrRedundancyType + } +}