diff --git a/go.mod b/go.mod index 7b4ea7d..7d73c8c 100644 --- a/go.mod +++ b/go.mod @@ -3,40 +3,45 @@ module github.com/cosmostation/cvms go 1.23 require ( - github.com/cometbft/cometbft v0.38.13-0.20240930095538-e339afc0bced // v0.38.x - github.com/go-playground/validator/v10 v10.22.0 - github.com/go-resty/resty/v2 v2.13.1 - github.com/golang/protobuf v1.5.4 + github.com/cometbft/cometbft v0.38.16 // v0.38.x + github.com/go-playground/validator/v10 v10.24.0 + github.com/go-resty/resty/v2 v2.16.5 + github.com/golang/protobuf v1.5.4 // indirect github.com/gorilla/mux v1.8.1 - github.com/jhump/protoreflect v1.15.1 + github.com/jhump/protoreflect v1.17.0 github.com/jinzhu/inflection v1.0.0 github.com/joho/godotenv v1.5.1 - github.com/klauspost/compress v1.17.9 + github.com/klauspost/compress v1.17.11 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.20.1 + github.com/prometheus/client_golang v1.20.5 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/uptrace/bun v1.2.8 github.com/uptrace/bun/dialect/pgdialect v1.2.8 github.com/uptrace/bun/driver/pgdriver v1.2.8 github.com/uptrace/bun/extra/bundebug v1.2.8 - golang.org/x/crypto v0.31.0 - google.golang.org/grpc v1.66.1 + golang.org/x/crypto v0.32.0 + google.golang.org/grpc v1.70.0 // v1.70.x gopkg.in/yaml.v3 v3.0.1 ) +require ( + cosmossdk.io/api v0.8.2 + google.golang.org/protobuf v1.36.3 +) + require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect - github.com/bufbuild/protocompile v0.10.0 // indirect + github.com/bufbuild/protocompile v0.14.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect github.com/cosmos/gogoproto v1.7.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/fatih/color v1.18.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -45,21 +50,23 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae // indirect - github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect + github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect + github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.57.0 // indirect + github.com/prometheus/common v0.61.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect - github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/sasha-s/go-deadlock v0.3.5 // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - golang.org/x/net v0.29.0 // indirect + go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect + golang.org/x/net v0.34.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect - google.golang.org/protobuf v1.34.2 // indirect + golang.org/x/time v0.9.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250122153221-138b5a5a4fd4 // indirect mellium.im/sasl v0.3.2 // indirect ) diff --git a/go.sum b/go.sum index 5e45f7c..9a3e80e 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,17 @@ +cosmossdk.io/api v0.8.2 h1:klzA1RODd9tTawJ2CbBd/34RV/cB9qtd9oJN6rcRqqg= +cosmossdk.io/api v0.8.2/go.mod h1:XJUwQrihIDjErzs3+jm1zO/9KRzKf4HMjRzXC+l+Cio= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= -github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c= github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/bufbuild/protocompile v0.10.0 h1:+jW/wnLMLxaCEG8AX9lD0bQ5v9h1RUiMKOBOT5ll9dM= -github.com/bufbuild/protocompile v0.10.0/go.mod h1:G9qQIQo0xZ6Uyj6CMNz0saGmx2so+KONo8/KrELABiY= +github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= +github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cometbft/cometbft v0.38.13-0.20240930095538-e339afc0bced h1:GOU2lhlBI6+9bfVVr8sxMCfGBoKPsDKDZv9j+rL6ZYs= -github.com/cometbft/cometbft v0.38.13-0.20240930095538-e339afc0bced/go.mod h1:a8NBI2IdO283RZdpH0MuXlze3j+lv6PXuzOtTCq4YGE= +github.com/cometbft/cometbft v0.38.16 h1:1xqGPgtVj0qA5B8sSQueaZ/MTsP5JSDIOCh/phGral8= +github.com/cometbft/cometbft v0.38.16/go.mod h1:hT4QQzD+SAqZOJm8M81o+RbRoPE081flo6pRZWkd5rI= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro= github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -19,40 +19,46 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= -github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= -github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g= -github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0= +github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg= +github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= +github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= +github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= -github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= +github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -68,21 +74,22 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae h1:FatpGJD2jmJfhZiFDElaC0QhZUDQnxUeAwTGkfAHN3I= -github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= -github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= -github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= +github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= +github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43 h1:ah1dvbqPMN5+ocrg/ZSgZ6k8bOk+kcZQ7fnyx6UvOm4= +github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.1 h1:IMJXHOD6eARkQpxo8KkhgEVFlBNm+nkrFUyGlIu7Na8= -github.com/prometheus/client_golang v1.20.1/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY= -github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= +github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= +github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4= @@ -90,8 +97,8 @@ github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPK github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= -github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/sasha-s/go-deadlock v0.3.5 h1:tNCOEEDG6tBqrNDOX35j/7hL5FcFViG6awUGROb2NsU= +github.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6vCBBsiChJQ5U= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= @@ -100,8 +107,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= github.com/uptrace/bun v1.2.8 h1:HEiLvy9wc7ehU5S02+O6NdV5BLz48lL4REPhTkMX3Dg= @@ -116,71 +123,39 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.66.1 h1:hO5qAXR19+/Z44hmvIM4dQFMSYX9XcWsByfoxutBpAM= -google.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250122153221-138b5a5a4fd4 h1:yrTuav+chrF0zF/joFGICKTzYv7mh/gr9AgEXrVU8ao= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250122153221-138b5a5a4fd4/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= +google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= +google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= +google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= diff --git a/internal/common/api/api.go b/internal/common/api/api.go index cce6d0c..395c4a1 100644 --- a/internal/common/api/api.go +++ b/internal/common/api/api.go @@ -3,7 +3,6 @@ package api import ( "context" "encoding/json" - "net/http" "strconv" "time" @@ -22,16 +21,16 @@ func GetStatus(c common.CommonClient) ( ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - requester := c.RPCClient.R().SetContext(ctx) - resp, err := requester.Get(types.CosmosStatusQueryPath) + // requester := c.RPCClient.R().SetContext(ctx) + resp, err := c.RPCClient.Get(ctx, types.CosmosStatusQueryPath) if err != nil { - return 0, time.Time{}, errors.Errorf("rpc call is failed from %s: %s", resp.Request.URL, err) - } - if resp.StatusCode() != http.StatusOK { - return 0, time.Time{}, errors.Errorf("stanage status code from %s: [%d]", resp.Request.URL, resp.StatusCode()) + return 0, time.Time{}, errors.Errorf("rpc call is failed from: %s", err) } + // if resp.StatusCode() != http.StatusOK { + // return 0, time.Time{}, errors.Errorf("stanage status code from %s: [%d]", resp.Request.URL, resp.StatusCode()) + // } - latestBlockHeight, latestBlockTimestamp, err := parser.CosmosStatusParser(resp.Body()) + latestBlockHeight, latestBlockTimestamp, err := parser.CosmosStatusParser(resp) if err != nil { return 0, time.Time{}, errors.Wrapf(err, "got data, but failed to parse the data") } @@ -54,17 +53,17 @@ func GetBlock(c common.CommonClient, height int64) ( defer cancel() // create requester - requester := c.RPCClient.R().SetContext(ctx) + // requester := c.RPCClient.R().SetContext(ctx) - resp, err := requester.Get(types.CosmosBlockQueryPath(height)) + resp, err := c.RPCClient.Get(ctx, types.CosmosBlockQueryPath(height)) if err != nil { - return 0, time.Time{}, "", nil, 0, nil, errors.Errorf("rpc call is failed from %s: %s", resp.Request.URL, err) - } - if resp.StatusCode() != http.StatusOK { - return 0, time.Time{}, "", nil, 0, nil, errors.Errorf("stanage status code from %s: [%d]", resp.Request.URL, resp.StatusCode()) + return 0, time.Time{}, "", nil, 0, nil, errors.Errorf("rpc call is failed from: %s", err) } + // if resp.StatusCode() != http.StatusOK { + // return 0, time.Time{}, "", nil, 0, nil, errors.Errorf("stanage status code from %s: [%d]", resp.Request.URL, resp.StatusCode()) + // } - blockHeight, blockTimeStamp, blockProposerAddress, blockTxs, lastCommitBlockHeight, blockSignatures, err := parser.CosmosBlockParser(resp.Body()) + blockHeight, blockTimeStamp, blockProposerAddress, blockTxs, lastCommitBlockHeight, blockSignatures, err := parser.CosmosBlockParser(resp) if err != nil { return 0, time.Time{}, "", nil, 0, nil, errors.Wrapf(err, "got data, but failed to parse the data") } @@ -78,9 +77,6 @@ func GetValidators(c common.CommonClient, height ...int64) ([]types.CosmosValida ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - // create requester - requester := c.RPCClient.R().SetContext(ctx) - totalValidators := make([]types.CosmosValidator, 0) var queryPath string page := 1 @@ -94,15 +90,15 @@ func GetValidators(c common.CommonClient, height ...int64) ([]types.CosmosValida queryPath = types.CosmosValidatorQueryPath(page) } - resp, err := requester.Get(queryPath) + resp, err := c.RPCClient.Get(ctx, queryPath) if err != nil { - return nil, errors.Errorf("rpc call is failed from %s: %s", resp.Request.URL, err) - } - if resp.StatusCode() != http.StatusOK { - return nil, errors.Errorf("stanage status code from %s: [%d]", resp.Request.URL, resp.StatusCode()) + return nil, errors.Errorf("rpc call is failed from: %s", err) } + // if resp.StatusCode() != http.StatusOK { + // return nil, errors.Errorf("stanage status code from %s: [%d]", resp.Request.URL, resp.StatusCode()) + // } - validators, totalValidatorsCount, err := parser.CosmosValidatorParser(resp.Body()) + validators, totalValidatorsCount, err := parser.CosmosValidatorParser(resp) if err != nil { return nil, errors.Wrapf(err, "got data, but failed to parse the data") } @@ -132,25 +128,19 @@ func GetStakingValidatorsByHeight(c common.CommonClient, chainName string, heigh ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - // create requester - requester := c.APIClient.R().SetContext(ctx) - // set header by block height heightStr := strconv.FormatInt(height, 10) header := map[string]string{"Content-Type": "application/json", "x-cosmos-block-height": heightStr} - requester.SetHeaders(header) + c.APIClient.SetHeaders(header) // get on-chain validators in staking module - resp, err := requester.Get(queryPath) + resp, err := c.APIClient.Get(ctx, queryPath) if err != nil { // c.Errorf("api error: %s", err) return nil, errors.Wrap(err, "failed in api") } - if resp.StatusCode() != http.StatusOK { - return nil, errors.Errorf("got %d code from %s", resp.StatusCode(), resp.Request.URL) - } - stakingValidators, err := stakingValidatorParser(resp.Body()) + stakingValidators, err := stakingValidatorParser(resp) if err != nil { return nil, errors.Wrap(err, "failed in api") } @@ -192,19 +182,16 @@ func GetStakingValidators(c common.CommonClient, chainName string, status ...str defer cancel() // create requester - requester := c.APIClient.R().SetContext(ctx) + requester := c.APIClient // get on-chain validators in staking module - resp, err := requester.Get(queryPath) + resp, err := requester.Get(ctx, queryPath) if err != nil { // c.Errorf("api error: %s", err) return nil, errors.Wrap(err, "failed in api") } - if resp.StatusCode() != http.StatusOK { - return nil, errors.Errorf("got %d code from %s", resp.StatusCode(), resp.Request.URL) - } - stakingValidators, err := stakingValidatorParser(resp.Body()) + stakingValidators, err := stakingValidatorParser(resp) if err != nil { return nil, errors.Wrap(err, "failed in api") } @@ -218,17 +205,14 @@ func GetProviderValidators(c common.CommonClient, consumerID string) ([]types.Pr ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - requester := c.APIClient.R().SetContext(ctx) - resp, err := requester.Get(types.ProviderValidatorsQueryPath(consumerID)) + requester := c.APIClient + resp, err := requester.Get(ctx, types.ProviderValidatorsQueryPath(consumerID)) if err != nil { return nil, errors.Cause(err) } - if resp.StatusCode() != http.StatusOK { - return nil, errors.Wrapf(err, "api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - } var result types.CosmosProviderValidatorsResponse - if err := json.Unmarshal(resp.Body(), &result); err != nil { + if err := json.Unmarshal(resp, &result); err != nil { return nil, errors.Cause(err) } @@ -239,17 +223,14 @@ func GetConsumerChainID(c common.CommonClient) ([]types.ConsumerChain, error) { ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - requester := c.APIClient.R().SetContext(ctx) - resp, err := requester.Get(types.ConsumerChainListQueryPath) + requester := c.APIClient + resp, err := requester.Get(ctx, types.ConsumerChainListQueryPath) if err != nil { return nil, err } - if resp.StatusCode() != http.StatusOK { - return nil, errors.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - } var result types.CosmosConsumerChainsResponse - if err := json.Unmarshal(resp.Body(), &result); err != nil { + if err := json.Unmarshal(resp, &result); err != nil { return nil, err } @@ -260,17 +241,14 @@ func GetConsumerChainHRP(c common.CommonClient) (string, error) { ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - requester := c.APIClient.R().SetContext(ctx) - resp, err := requester.Get(types.CosmosSlashingLimitQueryPath) + requester := c.APIClient + resp, err := requester.Get(ctx, types.CosmosSlashingLimitQueryPath) if err != nil { return "", errors.Cause(err) } - if resp.StatusCode() != http.StatusOK { - return "", errors.Wrapf(err, "api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - } var result types.CosmosSlashingResponse - if err := json.Unmarshal(resp.Body(), &result); err != nil { + if err := json.Unmarshal(resp, &result); err != nil { return "", errors.Cause(err) } @@ -300,19 +278,12 @@ func GetBlockResults(c common.CommonClient, height int64) ( ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - // create requester - requester := c.RPCClient.R().SetContext(ctx) - - resp, err := requester.Get(types.CosmosBlockResultsQueryPath(height)) + resp, err := c.RPCClient.Get(ctx, types.CosmosBlockResultsQueryPath(height)) if err != nil { - return nil, nil, errors.Errorf("rpc call is failed from %s: %s", resp.Request.URL, err) - } - if resp.StatusCode() != http.StatusOK { - return nil, nil, errors.Errorf("stanage status code from %s: [%d]", resp.Request.URL, resp.StatusCode()) - + return nil, nil, errors.Errorf("rpc call is failed from %s: %s", types.CosmosBlockResultsQueryPath(height), err) } - txsEvents, blockEvents, err := parser.CosmosBlockResultsParser(resp.Body()) + txsEvents, blockEvents, err := parser.CosmosBlockResultsParser(resp) if err != nil { return nil, nil, errors.WithStack(err) } diff --git a/internal/common/api/babylon.go b/internal/common/api/babylon.go index 6b50244..2a47ab7 100644 --- a/internal/common/api/babylon.go +++ b/internal/common/api/babylon.go @@ -2,7 +2,6 @@ package api import ( "context" - "net/http" "net/url" "sync" "time" @@ -19,16 +18,12 @@ func GetActiveFinalityProviderByHeight(c common.CommonClient, height int64) ([]t ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - requester := c.APIClient.R().SetContext(ctx) - resp, err := requester.Get(types.BabylonFinalityProvidersQueryPath(height)) + resp, err := c.APIClient.Get(ctx, types.BabylonFinalityProvidersQueryPath(height)) if err != nil { - return nil, errors.Errorf("rpc call is failed from %s: %s", resp.Request.URL, err) - } - if resp.StatusCode() != http.StatusOK { - return nil, errors.Errorf("stanage status code from %s: [%d]", resp.Request.URL, resp.StatusCode()) + return nil, errors.Errorf("rpc call is failed from %s: %s", types.BabylonFinalityProvidersQueryPath(height), err) } - fps, err := parser.ParseFinalityProviders(resp.Body()) + fps, err := parser.ParseFinalityProviders(resp) if err != nil { return nil, errors.WithStack(err) } @@ -40,16 +35,12 @@ func GetFinalityVotesByHeight(c common.CommonClient, height int64) ([]string, er ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - requester := c.APIClient.R().SetContext(ctx) - resp, err := requester.Get(types.BabylonFinalityVotesQueryPath(height)) + resp, err := c.APIClient.Get(ctx, types.BabylonFinalityVotesQueryPath(height)) if err != nil { - return nil, errors.Errorf("rpc call is failed from %s: %s", resp.Request.URL, err) - } - if resp.StatusCode() != http.StatusOK { - return nil, errors.Errorf("stanage status code from %s: [%d]", resp.Request.URL, resp.StatusCode()) + return nil, errors.Errorf("rpc call is failed from %s: %s", types.BabylonFinalityVotesQueryPath(height), err) } - votes, err := parser.ParseFinalityProviderVotings(resp.Body()) + votes, err := parser.ParseFinalityProviderVotings(resp) if err != nil { return nil, errors.WithStack(err) } @@ -61,21 +52,16 @@ func GetBabylonFinalityProviderInfos(c common.CommonClient) ([]types.FinalityPro ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - requester := c.APIClient.R().SetContext(ctx) fpInfoList := make([]types.FinalityProviderInfo, 0) maxCnt := 10 key := "" for cnt := 0; cnt <= maxCnt; cnt++ { - resp, err := requester.Get(types.BabylonFinalityProviderInfosQueryPath(key)) + resp, err := c.APIClient.Get(ctx, types.BabylonFinalityProviderInfosQueryPath(key)) if err != nil { - return nil, errors.Errorf("rpc call is failed from %s: %s", resp.Request.URL, err) - } - - if resp.StatusCode() != http.StatusOK { - return nil, errors.Errorf("stanage status code from %s: [%d]", resp.Request.URL, resp.StatusCode()) + return nil, errors.Errorf("rpc call is failed from %s: %s", types.BabylonFinalityProviderInfosQueryPath(key), err) } - fpInfos, err := parser.ParseFinalityProviderInfos(resp.Body()) + fpInfos, err := parser.ParseFinalityProviderInfos(resp) if err != nil { return nil, errors.WithStack(err) } @@ -99,8 +85,6 @@ func GetFinalityProviderUptime(c common.CommonClient, fpInfoList []types.Finalit ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - requester := c.APIClient.R().SetContext(ctx) - ch := make(chan helper.Result) var wg sync.WaitGroup validatorResult := make([]fputypes.FinalityProviderUptimeStatus, 0) @@ -114,7 +98,7 @@ func GetFinalityProviderUptime(c common.CommonClient, fpInfoList []types.Finalit defer helper.HandleOutOfNilResponse(c.Entry) defer wg.Done() - resp, err := requester.Get(queryPath) + resp, err := c.APIClient.Get(ctx, queryPath) if err != nil { if resp == nil { c.Errorln("unexpected nil response") @@ -125,13 +109,8 @@ func GetFinalityProviderUptime(c common.CommonClient, fpInfoList []types.Finalit ch <- helper.Result{Item: nil, Success: false} return } - if resp.StatusCode() != http.StatusOK { - c.Errorf("unexpected status from node: %d from %s", resp.StatusCode(), resp.Request.URL) - ch <- helper.Result{Item: nil, Success: false} - return - } - missedBlockCounter, err := parser.ParserFinalityProviderSigningInfo(resp.Body()) + missedBlockCounter, err := parser.ParserFinalityProviderSigningInfo(resp) if err != nil { c.Errorf("unexpected err: %s", err) ch <- helper.Result{Item: nil, Success: false} @@ -176,17 +155,12 @@ func GetBabylonFinalityProviderParams(c common.CommonClient) (float64, float64, ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - requester := c.APIClient.R().SetContext(ctx) - resp, err := requester.Get(types.BabylonFinalityParamsQueryPath) + resp, err := c.APIClient.Get(ctx, types.BabylonFinalityParamsQueryPath) if err != nil { - return 0, 0, errors.Errorf("rpc call is failed from %s: %s", resp.Request.URL, err) - } - - if resp.StatusCode() != http.StatusOK { - return 0, 0, errors.Errorf("stanage status code from %s: [%d]", resp.Request.URL, resp.StatusCode()) + return 0, 0, errors.Errorf("rpc call is failed from %s: %s", types.BabylonFinalityParamsQueryPath, err) } - signedBlocksWindow, minSignedPerWindow, err := parser.ParserFinalityParams(resp.Body()) + signedBlocksWindow, minSignedPerWindow, err := parser.ParserFinalityParams(resp) if err != nil { return 0, 0, errors.WithStack(err) } @@ -198,17 +172,14 @@ func GetBabylonBTCLightClientParams(c common.CommonClient) ([]string, error) { ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - requester := c.APIClient.R().SetContext(ctx) - resp, err := requester.Get(types.BabylonBTCLightClientParamsQueryPath) + requester := c.APIClient + resp, err := requester.Get(ctx, types.BabylonBTCLightClientParamsQueryPath) if err != nil { - return nil, errors.Errorf("rpc call is failed from %s: %s", resp.Request.URL, err) - } - - if resp.StatusCode() != http.StatusOK { - return nil, errors.Errorf("stanage status code from %s: [%d]", resp.Request.URL, resp.StatusCode()) + endpoint, _ := requester.GetEndpoint() + return nil, errors.Errorf("rpc call is failed from %s: %s", endpoint, err) } - allowList, err := parser.ParserBTCLightClientParams(resp.Body()) + allowList, err := parser.ParserBTCLightClientParams(resp) if err != nil { return nil, errors.WithStack(err) } diff --git a/internal/common/client/grpc.go b/internal/common/client/grpc.go new file mode 100644 index 0000000..860d262 --- /dev/null +++ b/internal/common/client/grpc.go @@ -0,0 +1,254 @@ +package client + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "strings" + "time" + + "github.com/jhump/protoreflect/grpcreflect" + "github.com/sirupsen/logrus" + "google.golang.org/grpc" + "google.golang.org/grpc/connectivity" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/peer" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/types/dynamicpb" + + // Below are necessary imports for the cosmos SDK types + // Otherwise we would have to manually import the relevant SDK types + _ "cosmossdk.io/api/cosmos/crypto/ed25519" + _ "cosmossdk.io/api/cosmos/crypto/secp256k1" +) + +type GrpcClient struct { + client *grpc.ClientConn + endpoint string + logger *logrus.Logger + timeout time.Duration + headers map[string]string +} + +func (gc *GrpcClient) SetLogger(logger *logrus.Logger) Client { + gc.logger = logger + return gc +} + +// Basically returns a new GrpcClient instance as it does not +// support changing the endpoint +func (gc *GrpcClient) SetEndpoint(endpoint string) Client { + + var dialOptions []grpc.DialOption + + tlsConf := &tls.Config{ + NextProtos: []string{"h2"}, // only allow HTTP/2 + MinVersion: tls.VersionTLS12, + } + gCreds := credentials.NewTLS(tlsConf) + + // Simple handshake check to determine if the server supports TLS + dialer := &tls.Dialer{ + Config: tlsConf, + } + ctx, ctxCancel := context.WithTimeout(context.Background(), gc.timeout) + conn, err := dialer.DialContext(ctx, "tcp", endpoint) + // conn, err := Dialer.DialContext("tcp", endpoint, tlsConf) + if err != nil { + var recordHeaderError tls.RecordHeaderError + if errors.As(err, &recordHeaderError) { + gc.logger.Warnf("TLS handshake failed for endpoint: %s", endpoint) + dialOptions = append(dialOptions, grpc.WithTransportCredentials(insecure.NewCredentials())) + + } else { + gc.logger.Errorf("error setting up gRPC connection: %s", err.Error()) + ctxCancel() + return nil + } + } else { + conn.Close() + dialOptions = append(dialOptions, grpc.WithTransportCredentials(gCreds)) + } + ctxCancel() + client, err := grpc.NewClient(endpoint, dialOptions...) + if err != nil { + gc.logger.Errorf("error setting up grpc client: %s", err.Error()) + return nil + } + gc.client = client + gc.endpoint = endpoint + return gc +} + +func (gc *GrpcClient) SetHeaders(headers map[string]string) { + gc.headers = headers + gc.logger.Warnf("setting headers not implemented in grpc client yet!") +} + +func (gc *GrpcClient) GetEndpoint() (string, error) { + if gc.endpoint == "" { + gc.logger.Error("grpc endpoint is not set") + return "", errors.New("endpoint is not set") + } + return gc.endpoint, nil +} + +// As Get is similar to Post with an empty body, it is implemented as a simple wrapper around Post +func (gc *GrpcClient) Get(ctx context.Context, uri string) ([]byte, error) { + respJSON, err := gc.Post(ctx, uri, []byte(``)) + if err != nil { + gc.logger.Errorf("grpc api failed to get: %s", err.Error()) + return nil, err + } + return respJSON, nil +} + +func (gc *GrpcClient) Post(ctx context.Context, uri string, body ...[]byte) ([]byte, error) { + + var protoResolver CosmosAnyMessageResolver + // var reflectionHeader metadata.MD + var respHeader metadata.MD + + if body == nil { + gc.logger.Errorf("grpc api requires a body for POST request. Use Get method instead.") + return nil, errors.New("grpc api requires a body for POST request") + } + + // wakes up the client if it's not ready + if gc.client.GetState() != connectivity.Ready { + gc.logger.Info("grpc client is not ready yet. Waking up...") + gc.client.Connect() + if !gc.client.WaitForStateChange(ctx, connectivity.Ready) { + gc.logger.Error("grpc client still not ready after waiting for connection") + return nil, errors.New("grpc connection not ready") + } + } + + refCtx := metadata.NewOutgoingContext(ctx, make(metadata.MD)) + + reflectionClient := grpcreflect.NewClientAuto( + refCtx, + gc.client, + ) + + descriptor, err := resolveMessage(uri, reflectionClient) + if err != nil { + gc.logger.Errorf("grpc api failed to resolve proto message: %s", err.Error()) + return nil, err + } + + msg, err := createMessage(descriptor, string(body[0])) + if err != nil { + gc.logger.Errorf("grpc api failed to create proto message: %s", err.Error()) + return nil, err + } + + // This only exists to support the current variable syntax + // e.g. "cosmos.staking.v1beta1.Query.Validators" to actually use the method it + // must be re-formatted to "/cosmos.staking.v1beta1.Query/Validators" + response := dynamicpb.NewMessage(descriptor.Output()) + idx := strings.LastIndex(uri, ".") + fullMethodName := "/" + uri[:idx] + "/" + uri[idx+1:] + + peer := &peer.Peer{} + gc.logger.Debugf("Invoking method: %s", fullMethodName) + err = gc.client.Invoke(ctx, fullMethodName, msg, response, grpc.Header(&respHeader), grpc.Peer(peer)) + gc.logger.Debugf( + "GRPC connection info: Protocol: %s Target: %s Local Address: %s Authentication Type: %s", + peer.Addr.Network(), + peer.Addr.String(), + peer.LocalAddr.String(), + peer.AuthInfo.AuthType(), + ) + gc.logger.Debugf("GRPC header returned: %+v", respHeader) + if err != nil { + gc.logger.Errorf("failed to invoke grpc request: %s", err.Error()) + return nil, err + } + marshaller := protojson.MarshalOptions{ + AllowPartial: true, + Indent: " ", + UseProtoNames: true, + EmitUnpopulated: false, + Resolver: protoResolver, + } + + respJSON, err := marshaller.Marshal(response) + if err != nil { + gc.logger.Errorf("grpc api failed to marshal string with grpc data: %s", err.Error()) + return nil, err + } + return respJSON, nil +} + +func NewGrpcClient(timeout time.Duration) *GrpcClient { + gc := &GrpcClient{ + timeout: timeout, + } + return gc +} + +// Internal non-public helper methods originally part of the +// grpchelper package + +// grpc reflection helper methods +func resolveMessage(fullMethodName string, rcli *grpcreflect.Client) (protoreflect.MethodDescriptor, error) { + // assume that fully-qualified method name cosists of + // FULL_SERVER_NAME + "." + METHOD_NAME + // so split the last dot to get service name + n := strings.LastIndex(fullMethodName, ".") + if n < 0 { + return nil, fmt.Errorf("invalid method name: %v", fullMethodName) + } + serviceName := fullMethodName[0:n] + methodName := fullMethodName[n+1:] + + sdesc, err := rcli.ResolveService(serviceName) + if err != nil { + return nil, fmt.Errorf("service couldn't be resolved: %v: %v", err, serviceName) + } + mdesc := sdesc.UnwrapService().Methods().ByName(protoreflect.Name(methodName)) + + if mdesc == nil { + return nil, fmt.Errorf("method couldn't be found") + } + + return mdesc, nil +} + +func createMessage(mdesc protoreflect.MethodDescriptor, inputJsonString string) (*dynamicpb.Message, error) { + + msg := dynamicpb.NewMessage(mdesc.Input()) + if err := protojson.Unmarshal([]byte(inputJsonString), msg); err != nil { + return nil, fmt.Errorf("unmarshal %v", err) + } + return msg, nil +} + +// grpc resolver to decode protobuf messages +type CosmosAnyMessageResolver struct { + protoregistry.MessageTypeResolver + protoregistry.ExtensionTypeResolver +} + +// Every resolver MUST implement the FindMessageByURL method. This message will be called by the +// Marshaller to resolve the message. +func (r CosmosAnyMessageResolver) FindMessageByURL(typeURL string) (protoreflect.MessageType, error) { + // Only the part of typeUrl after the last slash is relevant. + mname := typeURL + if slash := strings.LastIndex(mname, "/"); slash >= 0 { + mname = mname[slash+1:] + } + + a, err := protoregistry.GlobalTypes.FindMessageByURL(mname) + if err != nil { + return nil, err + } + + return a, nil +} diff --git a/internal/common/client/mock.go b/internal/common/client/mock.go new file mode 100644 index 0000000..148afa0 --- /dev/null +++ b/internal/common/client/mock.go @@ -0,0 +1,46 @@ +// this client can be used to mock the client.Client interface +// It will implement all the methods and just returns what you want it to return +package client + +import ( + "context" + + "github.com/sirupsen/logrus" +) + +type MockClient struct { + endpoint string + returnMessage map[string][]byte +} + +func (m *MockClient) SetLogger(logger *logrus.Logger) Client { + return m +} + +func (m *MockClient) SetEndpoint(endpoint string) Client { + m.endpoint = endpoint + return m +} + +func (m *MockClient) SetHeaders(headers map[string]string) { + // do nothing +} + +func (m *MockClient) GetEndpoint() (string, error) { + return m.endpoint, nil +} + +func (m *MockClient) Get(ctx context.Context, uri string) ([]byte, error) { + return m.returnMessage[uri], nil +} + +func (m *MockClient) Post(ctx context.Context, uri string, body ...[]byte) ([]byte, error) { + return m.returnMessage[uri], nil +} + +func NewMockClient(endpoint string, returnMessage map[string][]byte) *MockClient { + return &MockClient{ + endpoint: endpoint, + returnMessage: returnMessage, + } +} diff --git a/internal/common/client/rest.go b/internal/common/client/rest.go new file mode 100644 index 0000000..0de9688 --- /dev/null +++ b/internal/common/client/rest.go @@ -0,0 +1,96 @@ +package client + +import ( + "context" + "fmt" + "net/http" + "time" + + "errors" + + "github.com/go-resty/resty/v2" + "github.com/sirupsen/logrus" +) + +const ( + retryCount = 10 + retryWaitTimeDuration = 10 * time.Millisecond + retryMaxWaitTimeDuration = 3 * time.Second +) + +type RestyClient struct { + client *resty.Client + endpoint string + logger *logrus.Logger +} + +func (rc *RestyClient) SetLogger(logger *logrus.Logger) Client { + rc.logger = logger + rc.client.SetLogger(logger) + return rc +} + +func (rc *RestyClient) SetEndpoint(endpoint string) Client { + rc.endpoint = endpoint + rc.client.SetBaseURL(endpoint) + + return rc +} + +func (rc *RestyClient) GetEndpoint() (string, error) { + if rc.endpoint == "" { + return "", errors.New("endpoint is not set") + } + return rc.endpoint, nil +} + +func (rc *RestyClient) SetHeaders(header map[string]string) { + rc.client.SetHeaders(header) +} + +func NewRestyClient() *RestyClient { + rc := &RestyClient{} + rc.client = resty.New(). + SetRetryCount(retryCount). + SetRetryWaitTime(retryMaxWaitTimeDuration). + SetRetryMaxWaitTime(retryMaxWaitTimeDuration). + SetHeader("Content-Type", "application/json") + + return rc +} + +func (rc *RestyClient) Get(context context.Context, uri string) ([]byte, error) { + resp, err := rc.client.R(). + SetContext(context). + Get(rc.endpoint + uri) + if err != nil { + rc.logger.Errorf("GET request failed: %s", err.Error()) + return nil, err + } + rc.logger.Debugf("Received %d status code from %s", resp.StatusCode(), resp.Request.URL) + if resp.StatusCode() != http.StatusOK { + rc.logger.Errorf("GET request failed with status code: %d", resp.StatusCode()) + return nil, fmt.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) + } + return resp.Body(), nil +} + +func (rc *RestyClient) Post(context context.Context, uri string, body ...[]byte) ([]byte, error) { + resp, err := rc.client.R(). + SetHeader("Content-Type", "application/json"). + SetContext(context). + SetBody(body). + Post(rc.endpoint + uri) + if err != nil { + rc.logger.Errorf("POST request failed: %s", err.Error()) + return nil, err + } + rc.logger.Debugf("Received %d status code from %s", resp.StatusCode(), resp.Request.URL) + // This ensures that the response status code is within the 200-202 range, + // which indicates a successful POST request. + if resp.StatusCode() <= http.StatusOK && resp.StatusCode() <= http.StatusAccepted { + rc.logger.Errorf("POST request failed with status code: %d", resp.StatusCode()) + return nil, fmt.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) + } + return resp.Body(), nil +} diff --git a/internal/common/client/types.go b/internal/common/client/types.go new file mode 100644 index 0000000..ac69578 --- /dev/null +++ b/internal/common/client/types.go @@ -0,0 +1,12 @@ +package client + +import "context" + +// abstract Client interface +type Client interface { + SetEndpoint(endpoint string) Client + GetEndpoint() (string, error) + SetHeaders(header map[string]string) + Get(context context.Context, uri string) ([]byte, error) + Post(context context.Context, uri string, body ...[]byte) ([]byte, error) +} diff --git a/internal/common/exporter.go b/internal/common/exporter.go index 3fc3f79..2317221 100644 --- a/internal/common/exporter.go +++ b/internal/common/exporter.go @@ -1,15 +1,5 @@ package common -import ( - "time" -) - -const ( - retryCount = 10 - retryWaitTimeDuration = 10 * time.Millisecond - retryMaxWaitTimeDuration = 3 * time.Second -) - type Exporter struct { CommonApp Monikers []string diff --git a/internal/common/types.go b/internal/common/types.go index ef1a3c2..f5d9318 100644 --- a/internal/common/types.go +++ b/internal/common/types.go @@ -1,11 +1,11 @@ package common import ( - "io" - "github.com/cosmostation/cvms/internal/helper/logger" - "github.com/go-resty/resty/v2" + "github.com/sirupsen/logrus" + + "github.com/cosmostation/cvms/internal/common/client" ) // TODO: All Methods in VoteIndexer, we need to add here? @@ -63,9 +63,9 @@ func (a Mode) String() string { } type CommonClient struct { - RPCClient *resty.Client - APIClient *resty.Client - GRPCClient *resty.Client + RPCClient client.Client + APIClient client.Client + GRPCClient client.Client *logrus.Entry } type CommonApp struct { @@ -76,23 +76,9 @@ type CommonApp struct { } func NewCommonApp(p Packager) CommonApp { - restyLogger := logrus.New() - restyLogger.Out = io.Discard - rpcClient := resty.New(). - SetRetryCount(retryCount). - SetRetryWaitTime(retryMaxWaitTimeDuration). - SetRetryMaxWaitTime(retryMaxWaitTimeDuration). - SetLogger(restyLogger) - apiClient := resty.New(). - SetRetryCount(retryCount). - SetRetryWaitTime(retryMaxWaitTimeDuration). - SetRetryMaxWaitTime(retryMaxWaitTimeDuration). - SetLogger(restyLogger) - grpcClient := resty.New(). - SetRetryCount(retryCount). - SetRetryWaitTime(retryMaxWaitTimeDuration). - SetRetryMaxWaitTime(retryMaxWaitTimeDuration). - SetLogger(restyLogger) + rpcClient := client.NewRestyClient().SetLogger(p.Logger) + apiClient := client.NewRestyClient().SetLogger(p.Logger) + grpcClient := client.NewGrpcClient(Timeout).SetLogger(p.Logger) entry := p.Logger.WithFields( logrus.Fields{ logger.FieldKeyChain: p.ChainName, @@ -107,42 +93,36 @@ func NewCommonApp(p Packager) CommonApp { } } -func (c *CommonClient) SetRPCEndPoint(endpoint string) *resty.Client { - return c.RPCClient.SetBaseURL(endpoint) +func (c *CommonClient) SetRPCEndPoint(endpoint string) client.Client { + return c.RPCClient.SetEndpoint(endpoint) } func (c *CommonClient) GetRPCEndPoint() string { - return c.RPCClient.BaseURL + endpoint, _ := c.RPCClient.GetEndpoint() + return endpoint } -func (c *CommonClient) SetAPIEndPoint(endpoint string) *resty.Client { - return c.APIClient.SetBaseURL(endpoint) +func (c *CommonClient) SetAPIEndPoint(endpoint string) client.Client { + return c.APIClient.SetEndpoint(endpoint) } func (c *CommonClient) GetAPIEndPoint() string { - return c.APIClient.BaseURL + endpoint, _ := c.APIClient.GetEndpoint() + return endpoint } -func (c *CommonClient) SetGRPCEndPoint(endpoint string) *resty.Client { - return c.GRPCClient.SetBaseURL(endpoint) +func (c *CommonClient) SetGRPCEndPoint(endpoint string) client.Client { + return c.GRPCClient.SetEndpoint(endpoint) } func (c *CommonClient) GetGRPCEndPoint() string { - return c.GRPCClient.BaseURL + endpoint, _ := c.GRPCClient.GetEndpoint() + return endpoint } func NewOptionalClient(entry *logrus.Entry) CommonClient { - restyLogger := logrus.New() - restyLogger.Out = io.Discard - rpcClient := resty.New(). - SetRetryCount(retryCount). - SetRetryWaitTime(retryMaxWaitTimeDuration). - SetRetryMaxWaitTime(retryMaxWaitTimeDuration). - SetLogger(restyLogger) - apiClient := resty.New(). - SetRetryCount(retryCount). - SetRetryWaitTime(retryMaxWaitTimeDuration). - SetRetryMaxWaitTime(retryMaxWaitTimeDuration). - SetLogger(restyLogger) - return CommonClient{rpcClient, apiClient, nil, entry} + rpcClient := client.NewRestyClient().SetLogger(entry.Logger) + apiClient := client.NewRestyClient().SetLogger(entry.Logger) + grpcClient := client.NewGrpcClient(Timeout).SetLogger(entry.Logger) + return CommonClient{rpcClient, apiClient, grpcClient, entry} } diff --git a/internal/helper/grpc/grpc_query.go b/internal/helper/grpc/grpc_query.go deleted file mode 100644 index a5c2355..0000000 --- a/internal/helper/grpc/grpc_query.go +++ /dev/null @@ -1,108 +0,0 @@ -package grpchelper - -import ( - "context" - - "github.com/golang/protobuf/jsonpb" - "github.com/jhump/protoreflect/desc" - "github.com/jhump/protoreflect/dynamic/grpcdynamic" - "github.com/pkg/errors" - - "log" - - "github.com/jhump/protoreflect/grpcreflect" - "google.golang.org/grpc" - "google.golang.org/grpc/metadata" -) - -var ( - jsonPbMarshaler = jsonpb.Marshaler{ - OrigName: true, - EmitDefaults: true, - AnyResolver: DynamicAnyResolver{}, - } - - jsonPbUnmarshaler = jsonpb.Unmarshaler{ - AllowUnknownFields: true, - } -) - -func GrpcMakeDescriptor(reflectionClient *grpcreflect.Client, queryPath string) (*desc.MethodDescriptor, error) { - methodDescriptor, err := ResolveMessage(queryPath, reflectionClient) - if err != nil { - return nil, errors.Wrapf(err, "by query path: %s", queryPath) - } - - return methodDescriptor, nil -} - -func GrpcInvokeQuery( - ctx context.Context, - methodDescriptor *desc.MethodDescriptor, - stub *grpcdynamic.Stub, - queryData string, -) (string, error) { - - msg, err := CreateMessage(methodDescriptor, &jsonPbUnmarshaler, queryData) - if err != nil { - // client.Logger.Errorf("grpc api failed to create proto message: %v", err) - return "", err - } - - _, err = msg.MarshalJSONPB(&jsonPbMarshaler) - if err != nil { - // client.Logger.Errorf("grpc api failed to mashal jsonpb: %v", err) - return "", err - } - - var headerMD metadata.MD - - resp, err := stub.InvokeRpc(context.Background(), methodDescriptor, msg, grpc.Header(&headerMD)) - if err != nil { - // client.Logger.Errorf("grpc api failed to invoke rpc: %v", err) - return "", err - } - - respJSON, err := jsonPbMarshaler.MarshalToString(resp) - if err != nil { - // client.Logger.Errorf("grpc api failed to marshal string with grpc data: %v", err) - return "", err - } - - return respJSON, nil -} - -func GrpcDynamicQuery(ctx context.Context, reflectionClient *grpcreflect.Client, stub *grpcdynamic.Stub, queryPath string, queryData string) (string, error) { - methodDescriptor, err := ResolveMessage(queryPath, reflectionClient) - if err != nil { - log.Printf("grpc api failed to resolve proto message: %s", err.Error()) - return "", err - } - - msg, err := CreateMessage(methodDescriptor, &jsonPbUnmarshaler, queryData) - if err != nil { - log.Printf("grpc api failed to create proto message: %s", err.Error()) - return "", err - } - - _, err = msg.MarshalJSONPB(&jsonPbMarshaler) - if err != nil { - log.Printf("grpc api failed to mashal jsonpb: %s", err.Error()) - return "", err - } - - var headerMD metadata.MD - resp, err := stub.InvokeRpc(ctx, methodDescriptor, msg, grpc.Header(&headerMD)) - if err != nil { - log.Printf("grpc api failed to invoke rpc: %s", resp) - return "", err - } - - respJSON, err := jsonPbMarshaler.MarshalToString(resp) - if err != nil { - log.Printf("grpc api failed to marshal string with grpc data: %s", err.Error()) - return "", err - } - - return respJSON, nil -} diff --git a/internal/helper/grpc/grpc_reflection.go b/internal/helper/grpc/grpc_reflection.go deleted file mode 100644 index 47f4dc7..0000000 --- a/internal/helper/grpc/grpc_reflection.go +++ /dev/null @@ -1,44 +0,0 @@ -package grpchelper - -import ( - "fmt" - "strings" - - "github.com/golang/protobuf/jsonpb" - "github.com/jhump/protoreflect/desc" - "github.com/jhump/protoreflect/dynamic" - "github.com/jhump/protoreflect/grpcreflect" -) - -func ResolveMessage(fullMethodName string, rcli *grpcreflect.Client) (*desc.MethodDescriptor, error) { - // assume that fully-qualified method name cosists of - // FULL_SERVER_NAME + "." + METHOD_NAME - // so split the last dot to get service name - n := strings.LastIndex(fullMethodName, ".") - if n < 0 { - return nil, fmt.Errorf("invalid method name: %v", fullMethodName) - } - serviceName := fullMethodName[0:n] - methodName := fullMethodName[n+1:] - - sdesc, err := rcli.ResolveService(serviceName) - if err != nil { - return nil, fmt.Errorf("service couldn't be resolve: %v: %v", err, serviceName) - } - - mdesc := sdesc.FindMethodByName(methodName) - if mdesc == nil { - return nil, fmt.Errorf("method couldn't be found") - } - - return mdesc, nil -} - -func CreateMessage(mdesc *desc.MethodDescriptor, unmarshaler *jsonpb.Unmarshaler, inputJsonString string) (*dynamic.Message, error) { - msg := dynamic.NewMessage(mdesc.GetInputType()) - - if err := msg.UnmarshalJSONPB(unmarshaler, []byte(inputJsonString)); err != nil { - return nil, fmt.Errorf("unmarshal %v", err) - } - return msg, nil -} diff --git a/internal/helper/grpc/grpc_resolver.go b/internal/helper/grpc/grpc_resolver.go deleted file mode 100644 index 5dfd756..0000000 --- a/internal/helper/grpc/grpc_resolver.go +++ /dev/null @@ -1,38 +0,0 @@ -package grpchelper - -import ( - "fmt" - "reflect" - "strings" - - "github.com/golang/protobuf/jsonpb" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/empty" -) - -type DynamicAnyResolver struct { - jsonpb.AnyResolver // https://godoc.org/github.com/golang/protobuf/jsonpb#AnyResolver -} - -// Resolve implements jsonpb.AnyResolver.Resolve -func (DynamicAnyResolver) Resolve(typeURL string) (proto.Message, error) { - msg, err := defaultResolveAny(typeURL) - if err == nil { - return msg, nil - } - return &empty.Empty{}, nil -} - -// copied from https://github.com/golang/protobuf/blob/c823c79ea1570fb5ff454033735a8e68575d1d0f/jsonpb/jsonpb.go#L92-L103 -func defaultResolveAny(typeURL string) (proto.Message, error) { - // Only the part of typeUrl after the last slash is relevant. - mname := typeURL - if slash := strings.LastIndex(mname, "/"); slash >= 0 { - mname = mname[slash+1:] - } - mt := proto.MessageType(mname) - if mt == nil { - return nil, fmt.Errorf("unknown message type %q", mname) - } - return reflect.New(mt.Elem()).Interface().(proto.Message), nil -} diff --git a/internal/packages/consensus/babylon-checkpoint/indexer/batch_sync.go b/internal/packages/consensus/babylon-checkpoint/indexer/batch_sync.go index 7e97eb0..dd5a6e9 100644 --- a/internal/packages/consensus/babylon-checkpoint/indexer/batch_sync.go +++ b/internal/packages/consensus/babylon-checkpoint/indexer/batch_sync.go @@ -35,13 +35,13 @@ func (idx *CheckpointIndexer) batchSync(lastIndexPointerEpoch int64) ( /* error */ error, ) { newIndexerPointerEpoch := lastIndexPointerEpoch + 1 - requester := idx.APIClient.R().SetContext(context.Background()) - resp, err := requester.Get(CurrentEpochQueryPath) + ctx := context.Background() + resp, err := idx.APIClient.Get(ctx, CurrentEpochQueryPath) if err != nil { return lastIndexPointerEpoch, errors.Wrap(err, "failed to call current epoch api") } - currentEpoch, _, err := ParseCurrentEpoch(resp.Body()) + currentEpoch, _, err := ParseCurrentEpoch(resp) if err != nil { return lastIndexPointerEpoch, errors.Wrap(err, "failed to parse current epoch response") } @@ -78,12 +78,12 @@ func (idx *CheckpointIndexer) batchSync(lastIndexPointerEpoch int64) ( } idx.Debugf("sync epoch: %d", epoch) - resp, err := requester.Get(EpochQueryPath(epoch)) + resp, err := idx.APIClient.Get(ctx, EpochQueryPath(epoch)) if err != nil { return lastIndexPointerEpoch, errors.Wrap(err, "failed to get epoch data") } - firstBlockHeightInEpoch, _, err := ParseEpoch(resp.Body()) + firstBlockHeightInEpoch, _, err := ParseEpoch(resp) if err != nil { return lastIndexPointerEpoch, errors.Wrap(err, "failed to get epoch data") } @@ -157,13 +157,13 @@ func (idx *CheckpointIndexer) batchSync(lastIndexPointerEpoch int64) ( } // get epoch data - resp, err = requester.Get(BlockTxsQueryPath(firstBlockHeightInEpoch)) + resp, err = idx.APIClient.Get(ctx, BlockTxsQueryPath(firstBlockHeightInEpoch)) if err != nil { idx.Errorln(err) return lastIndexPointerEpoch, err } - blockHeight, blockTimestamp, bexVotes, err := ExtractBabylonExtendVoteAndBlockInfo(resp.Body()) + blockHeight, blockTimestamp, bexVotes, err := ExtractBabylonExtendVoteAndBlockInfo(resp) if err != nil { idx.Errorln(err) return lastIndexPointerEpoch, err diff --git a/internal/packages/consensus/babylon-checkpoint/indexer/indexer_test.go b/internal/packages/consensus/babylon-checkpoint/indexer/indexer_test.go index 7bc98c4..d43e4c1 100644 --- a/internal/packages/consensus/babylon-checkpoint/indexer/indexer_test.go +++ b/internal/packages/consensus/babylon-checkpoint/indexer/indexer_test.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "encoding/json" "fmt" - "net/http" "strconv" "testing" "time" @@ -91,14 +90,14 @@ func TestSyncEpoch(t *testing.T) { idx, err := NewCheckpointIndexer(p) assert.NoError(t, err) - requester := idx.APIClient.R().SetContext(context.Background()) - resp, err := requester.Get("/babylon/epoching/v1/current_epoch") - assert.NoErrorf(t, err, "error from : %s", resp.Request.URL) - assert.NotSame(t, http.StatusOK, resp.StatusCode()) + ctx := context.Background() + uri := "/babylon/epoching/v1/current_epoch" + resp, err := idx.APIClient.Get(ctx, uri) + assert.NoErrorf(t, err, "error from : %s", uri) // pasrse var currentEpochResponse CurrentEpochResponse - err = json.Unmarshal(resp.Body(), ¤tEpochResponse) + err = json.Unmarshal(resp, ¤tEpochResponse) assert.NoError(t, err) currentEpoch, err := strconv.Atoi(currentEpochResponse.CurrentEpoch) @@ -111,12 +110,12 @@ func TestSyncEpoch(t *testing.T) { continue } path := fmt.Sprintf("/babylon/epoching/v1/epochs/%d", epoch) - resp, err := requester.Get(path) + resp, err := idx.APIClient.Get(ctx, path) assert.NoError(t, err) // pasre type EpochsResponse := EpochResponse{} - err = json.Unmarshal(resp.Body(), &EpochsResponse) + err = json.Unmarshal(resp, &EpochsResponse) assert.NoError(t, err) // parse @@ -127,7 +126,7 @@ func TestSyncEpoch(t *testing.T) { path = fmt.Sprintf("/cosmos/tx/v1beta1/txs/block/%d?pagination.limit=1", firstBlockOfEpoch) // get first tx in the first block in the each epoch - resp, err = requester.Get(path) + resp, err = idx.APIClient.Get(ctx, path) assert.NoError(t, err) // parse @@ -135,7 +134,7 @@ func TestSyncEpoch(t *testing.T) { // pasre type txsReponse := BlockTxsResponse{} - err = json.Unmarshal(resp.Body(), &txsReponse) + err = json.Unmarshal(resp, &txsReponse) assert.NoError(t, err) for _, tx := range txsReponse.Txs { diff --git a/internal/packages/consensus/uptime/api/uptime.go b/internal/packages/consensus/uptime/api/uptime.go index 50e49cb..1848347 100644 --- a/internal/packages/consensus/uptime/api/uptime.go +++ b/internal/packages/consensus/uptime/api/uptime.go @@ -3,7 +3,6 @@ package api import ( "context" "encoding/hex" - "net/http" "sort" "strconv" "sync" @@ -48,7 +47,7 @@ func getValidatorUptimeStatus(c common.CommonApp, chainName string, validators [ defer cancel() // create requester - requester := c.APIClient.R().SetContext(ctx) + requester := c.APIClient // 2. extract bech32 valcons prefix using staking validator address var bech32ValconsPrefix string @@ -96,7 +95,7 @@ func getValidatorUptimeStatus(c common.CommonApp, chainName string, validators [ defer helper.HandleOutOfNilResponse(c.Entry) defer wg.Done() - resp, err := requester.Get(queryPath) + resp, err := requester.Get(ctx, queryPath) if err != nil { if resp == nil { ch <- helper.Result{Item: nil, Success: false} @@ -106,12 +105,8 @@ func getValidatorUptimeStatus(c common.CommonApp, chainName string, validators [ ch <- helper.Result{Item: nil, Success: false} return } - if resp.StatusCode() != http.StatusOK { - ch <- helper.Result{Item: nil, Success: false} - return - } - _, _, isTomstoned, missedBlocksCounter, err := parser(resp.Body()) + _, _, isTomstoned, missedBlocksCounter, err := parser(resp) if err != nil { c.Errorf("errors: %s", err) ch <- helper.Result{Item: nil, Success: false} @@ -169,7 +164,7 @@ func getConsumerValidatorUptimeStatus( defer cancel() // create requester - requester := app.APIClient.R().SetContext(ctx) + requester := app.APIClient // 5. init channel and waitgroup for go-routine ch := make(chan helper.Result) @@ -190,7 +185,7 @@ func getConsumerValidatorUptimeStatus( defer helper.HandleOutOfNilResponse(app.Entry) defer wg.Done() - resp, err := requester.Get(uptimeQueryPath) + resp, err := requester.Get(ctx, uptimeQueryPath) if err != nil { if resp == nil { ch <- helper.Result{Item: nil, Success: false} @@ -199,12 +194,8 @@ func getConsumerValidatorUptimeStatus( ch <- helper.Result{Item: nil, Success: false} return } - if resp.StatusCode() != http.StatusOK { - ch <- helper.Result{Item: nil, Success: false} - return - } - _, _, isTomstoned, missedBlocksCounter, err := commonparser.CosmosSlashingParser(resp.Body()) + _, _, isTomstoned, missedBlocksCounter, err := commonparser.CosmosSlashingParser(resp) if err != nil { ch <- helper.Result{Item: nil, Success: false} return @@ -273,16 +264,13 @@ func getUptimeParams(c common.CommonClient, chainName string) ( ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - requester := c.APIClient.R().SetContext(ctx) - resp, err := requester.Get(queryPath) + requester := c.APIClient + resp, err := requester.Get(ctx, queryPath) if err != nil { return 0, 0, errors.Cause(err) } - if resp.StatusCode() != http.StatusOK { - return 0, 0, errors.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - } - signedBlocksWindow, minSignedPerWindow, err := parser(resp.Body()) + signedBlocksWindow, minSignedPerWindow, err := parser(resp) if err != nil { return 0, 0, errors.Cause(err) } diff --git a/internal/packages/consensus/uptime/api/uptime_test.go b/internal/packages/consensus/uptime/api/uptime_test.go new file mode 100644 index 0000000..70b399c --- /dev/null +++ b/internal/packages/consensus/uptime/api/uptime_test.go @@ -0,0 +1,101 @@ +package api + +import ( + "testing" + + "github.com/cosmostation/cvms/internal/common" + "github.com/cosmostation/cvms/internal/common/client" + commontypes "github.com/cosmostation/cvms/internal/common/types" + "github.com/cosmostation/cvms/internal/helper/logger" + + "github.com/stretchr/testify/assert" +) + +func TestGetValidatorUptimeStatus(t *testing.T) { + + goodResults := make(map[string][]byte) + goodResults["/cosmos/slashing/v1beta1/signing_infos/cosmosvalcons1m8u2gxmc92n2v6kus8u48y3u0h88kcqp69cr3a"] = []byte(`{ + "val_signing_info": { + "address": "cosmosvalcons1m8u2gxmc92n2v6kus8u48y3u0h88kcqp69cr3a", + "start_height": "0", + "index_offset": "27266009", + "jailed_until": "1970-01-01T00:00:00Z", + "tombstoned": false, + "missed_blocks_counter": "39" + } +}`) + + goodResults["/cosmos/slashing/v1beta1/signing_infos/"] = []byte(`{ + "info": [ + { + "address": "cosmosvalcons1qqqqrezrl53hujmpdch6d805ac75n220ku09rl", + "start_height": "0", + "index_offset": "27266009", + "jailed_until": "1970-01-01T00:00:00Z", + "tombstoned": false, + "missed_blocks_counter": "1" + }, + { + "address": "cosmosvalcons1m8u2gxmc92n2v6kus8u48y3u0h88kcqp69cr3a", + "start_height": "0", + "index_offset": "27550724", + "jailed_until": "1970-01-01T00:00:00Z", + "tombstoned": false, + "missed_blocks_counter": "39" + }], + "pagination": { + "total": "2" + } +}`) + + validators := []commontypes.CosmosValidator{ + { + Address: "D9F8A41B782AA6A66ADC81F953923C7DCE7B6001", + Pubkey: struct { + Type string "json:\"type\"" + Value string "json:\"value\"" + }{ + Type: "tendermint/PubKeyEd25519", + Value: "CiCf1tb2Ga/BLCb8Ccm0PBk0YD7ZFKhCx+gwWxzZGtvS9g==", + }, + VotingPower: "1", + ProposerPriority: "0", + }, + } + + stakingValidators := []commontypes.CosmosStakingValidator{ + { + OperatorAddress: "cosmosvaloper1hjct6q7npsspsg3dgvzk3sdf89spmlpfdn6m9d", + ConsensusPubkey: commontypes.ConsensusPubkey{ + Type: "/cosmos.crypto.ed25519.PubKey", + Key: "CiCf1tb2Ga/BLCb8Ccm0PBk0YD7ZFKhCx+gwWxzZGtvS9g==", + }, + Description: struct { + Moniker string "json:\"moniker\"" + }{ + Moniker: "asdf", + }, + Tokens: "1000", + }, + } + + l := logger.GetTestLogger() + + commonApp := common.CommonApp{ + + CommonClient: common.CommonClient{ + RPCClient: nil, + GRPCClient: nil, + APIClient: client.NewMockClient("127.0.0.1:9090", goodResults).SetLogger(l), + Entry: l.WithField("mode", "test"), + }, + EndPoint: "127.0.0.1:9090", + OptionalClient: common.CommonClient{}, + } + + status, _ := getValidatorUptimeStatus(commonApp, "cosmoshub", validators, stakingValidators) + + assert.Equal(t, float64(39), status[0].MissedBlockCounter) + assert.Equal(t, float64(0), status[0].IsTomstoned) + +} diff --git a/internal/packages/duty/axelar-evm/api/api.go b/internal/packages/duty/axelar-evm/api/api.go index 1f1f438..cc2b0a8 100644 --- a/internal/packages/duty/axelar-evm/api/api.go +++ b/internal/packages/duty/axelar-evm/api/api.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "errors" - "net/http" "strings" "sync" "time" @@ -26,38 +25,30 @@ func GetAxelarNexusStatus( defer cancel() // create requester - requester := exporter.APIClient.R().SetContext(ctx) + requester := exporter.APIClient // get on-chain validators - resp, err := requester.Get(types.CommonValidatorQueryPath) + resp, err := requester.Get(ctx, types.CommonValidatorQueryPath) if err != nil { exporter.Errorf("api error: %s", err) return types.CommonAxelarNexus{}, common.ErrFailedHttpRequest } - if resp.StatusCode() != http.StatusOK { - exporter.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - return types.CommonAxelarNexus{}, common.ErrGotStrangeStatusCode - } // json unmarsharling received validators data var validators types.CommonValidatorsQueryResponse - if err := json.Unmarshal(resp.Body(), &validators); err != nil { + if err := json.Unmarshal(resp, &validators); err != nil { exporter.Errorf("api error: %s", err) return types.CommonAxelarNexus{}, common.ErrFailedJsonUnmarshal } // get on-chain active evm-chains - resp, err = requester.Get(CommonEvmChainsQueryPath) + resp, err = requester.Get(ctx, CommonEvmChainsQueryPath) if err != nil { exporter.Errorf("api error: %s", err) return types.CommonAxelarNexus{}, common.ErrFailedHttpRequest } - if resp.StatusCode() != http.StatusOK { - exporter.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - return types.CommonAxelarNexus{}, common.ErrGotStrangeStatusCode - } - activatedEvmChains, err := CommonEvmChainsParser(resp.Body()) + activatedEvmChains, err := CommonEvmChainsParser(resp) if err != nil { return types.CommonAxelarNexus{}, err } @@ -84,7 +75,7 @@ func GetAxelarNexusStatus( defer helper.HandleOutOfNilResponse(exporter.Entry) defer wg.Done() - resp, err = requester.Get(queryPath) + resp, err = requester.Get(ctx, queryPath) if err != nil { if resp == nil { exporter.Errorln("[panic] passed resp.Time() nil point err") @@ -95,13 +86,8 @@ func GetAxelarNexusStatus( ch <- helper.Result{Item: nil, Success: false} return } - if resp.StatusCode() != http.StatusOK { - exporter.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - ch <- helper.Result{Item: nil, Success: false} - return - } - maintainers, err := CommonChainMaintainersParser(resp.Body()) + maintainers, err := CommonChainMaintainersParser(resp) if err != nil { exporter.Errorf("api error: %s", err) ch <- helper.Result{Item: nil, Success: false} diff --git a/internal/packages/duty/axelar-evm/types/types.go b/internal/packages/duty/axelar-evm/types/types.go index 1a67734..9fa8d20 100644 --- a/internal/packages/duty/axelar-evm/types/types.go +++ b/internal/packages/duty/axelar-evm/types/types.go @@ -9,7 +9,7 @@ const ( CommonValidatorQueryPath = "/cosmos/staking/v1beta1/validators?status=BOND_STATUS_BONDED&pagination.count_total=true&pagination.limit=500" // axelar - AxelarEvmChainsQueryPath = "axelar/evm/v1beta1/chains?status=1" + AxelarEvmChainsQueryPath = "/axelar/evm/v1beta1/chains?status=1" AxelarChainMaintainersQueryPath = "/axelar/nexus/v1beta1/chain_maintainers/{chain}" ) diff --git a/internal/packages/duty/eventnonce/api/api.go b/internal/packages/duty/eventnonce/api/api.go index 53cf8cb..147052f 100644 --- a/internal/packages/duty/eventnonce/api/api.go +++ b/internal/packages/duty/eventnonce/api/api.go @@ -3,7 +3,6 @@ package api import ( "context" "encoding/json" - "net/http" "strings" "sync" "time" @@ -25,22 +24,18 @@ func GetEventNonceStatus( defer cancel() // create requester - requester := c.APIClient.R().SetContext(ctx) + requester := c.APIClient // get on-chain validators - resp, err := requester.Get(types.CommonValidatorQueryPath) + resp, err := requester.Get(ctx, types.CommonValidatorQueryPath) if err != nil { c.Errorf("api error: %s", err) return types.CommonEventNonceStatus{}, common.ErrFailedHttpRequest } - if resp.StatusCode() != http.StatusOK { - c.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - return types.CommonEventNonceStatus{}, common.ErrGotStrangeStatusCode - } // json unmarsharling received validators data var validators types.CommonValidatorsQueryResponse - if err := json.Unmarshal(resp.Body(), &validators); err != nil { + if err := json.Unmarshal(resp, &validators); err != nil { c.Errorf("api error: %s", err) return types.CommonEventNonceStatus{}, common.ErrFailedJsonUnmarshal } @@ -65,7 +60,7 @@ func GetEventNonceStatus( defer helper.HandleOutOfNilResponse(c.Entry) defer wg.Done() - resp, err := requester.Get(queryPath) + resp, err := requester.Get(ctx, queryPath) if err != nil { if resp == nil { c.Errorln("[panic] passed resp.Time() nil point err") @@ -77,13 +72,7 @@ func GetEventNonceStatus( return } - if resp.StatusCode() != http.StatusOK { - c.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - ch <- helper.Result{Item: nil, Success: false} - return - } - - orchestratorAddress, err := CommonOrchestratorParser(resp.Body()) + orchestratorAddress, err := CommonOrchestratorParser(resp) if err != nil { c.Errorf("api error: %s", err) ch <- helper.Result{Success: false, Item: nil} @@ -148,7 +137,7 @@ func GetEventNonceStatus( defer helper.HandleOutOfNilResponse(c.Entry) defer wg.Done() - resp, err := requester.Get(queryPath) + resp, err := requester.Get(ctx, queryPath) if err != nil { if resp == nil { c.Errorln("[panic] passed resp.Time() nil point err") @@ -159,13 +148,8 @@ func GetEventNonceStatus( ch <- helper.Result{Item: nil, Success: false} return } - if resp.StatusCode() != http.StatusOK { - c.Errorf("api error: %d code from %s", resp.StatusCode(), resp.Request.URL) - ch <- helper.Result{Item: nil, Success: false} - return - } - eventNonce, err := CommonEventNonceParser(resp.Body()) + eventNonce, err := CommonEventNonceParser(resp) if err != nil { c.Errorf("api error: %s", err) ch <- helper.Result{Success: false, Item: nil} diff --git a/internal/packages/duty/eventnonce/api/grpc.go b/internal/packages/duty/eventnonce/api/grpc.go index e8321e7..33cefc7 100644 --- a/internal/packages/duty/eventnonce/api/grpc.go +++ b/internal/packages/duty/eventnonce/api/grpc.go @@ -9,16 +9,7 @@ import ( "github.com/cosmostation/cvms/internal/common" "github.com/cosmostation/cvms/internal/helper" - grpchelper "github.com/cosmostation/cvms/internal/helper/grpc" "github.com/cosmostation/cvms/internal/packages/duty/eventnonce/types" - "github.com/jhump/protoreflect/desc" - "github.com/jhump/protoreflect/dynamic/grpcdynamic" - "github.com/jhump/protoreflect/grpcreflect" - "google.golang.org/grpc" - - "google.golang.org/grpc/credentials/insecure" - "google.golang.org/grpc/metadata" - reflectpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" ) // NOTE: debug @@ -36,35 +27,7 @@ func GetEventNonceStatusByGRPC( ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) defer cancel() - // NOTE: currently it don't support nginx grpc proxy ssl server like grpc.cosmostation.io:443 - // create grpc connection - grpcConnection, err := grpc.NewClient(c.GetGRPCEndPoint(), - grpc.WithTransportCredentials(insecure.NewCredentials()), - ) - if err != nil { - c.Errorf("grpc request error: %s", err.Error()) - return types.CommonEventNonceStatus{}, common.ErrFailedCreateGrpcConnection - } - defer grpcConnection.Close() - - // create grpc reflection client & stub - stub := grpcdynamic.NewStub(grpcConnection) - - var headerMD metadata.MD - reflectionClient := grpcreflect.NewClientV1Alpha( - metadata.NewOutgoingContext(ctx, headerMD), - reflectpb.NewServerReflectionClient(grpcConnection), - ) - - // get on-chain validators - resp, err := grpchelper.GrpcDynamicQuery( - ctx, // common context - reflectionClient, // grpc reflection client - &stub, // grpc query stub - types.CommonValidatorGrpcQueryPath, // grpc query method - types.CommonValidatorGrpcQueryOption, // grpc query payload - ) - + resp, err := c.GRPCClient.Post(ctx, types.CommonValidatorGrpcQueryPath, []byte(types.CommonValidatorGrpcQueryOption)) if err != nil { c.Errorf("grpc request err: %s", err.Error()) return types.CommonEventNonceStatus{}, common.ErrFailedGrpcRequest @@ -72,7 +35,7 @@ func GetEventNonceStatusByGRPC( // json unmarsharling received validators data var validators types.CommonValidatorsQueryResponse - if err := json.Unmarshal([]byte(resp), &validators); err != nil { + if err := json.Unmarshal(resp, &validators); err != nil { c.Errorf("parser error: %s", err) return types.CommonEventNonceStatus{}, common.ErrFailedJsonUnmarshal } @@ -80,25 +43,25 @@ func GetEventNonceStatusByGRPC( // init channel and waitgroup ch := make(chan helper.Result) var wg sync.WaitGroup - var methodDescriptor *desc.MethodDescriptor + // var methodDescriptor protoreflect.MethodDescriptor validatorResults := make([]types.ValidatorStatus, 0) // add wg by the number of total validators wg.Add(len(validators.Validators)) // get validators orchestrator address - for idx, item := range validators.Validators { + for _, item := range validators.Validators { // in only first time, make a method descriptor by using grpc reflection client - if idx == 0 { - methodDescriptor, err = grpchelper.GrpcMakeDescriptor( - reflectionClient, // grpc reflection client - commonOrchestratorPath, // grpc reflection method path - ) - if err != nil { - c.Errorln("grpc api err: failed to make method descprtior") - return types.CommonEventNonceStatus{}, common.ErrFailedGrpcRequest - } - } + // if idx == 0 { + // methodDescriptor, err = grpchelper.GrpcMakeDescriptor( + // reflectionClient, // grpc reflection client + // commonOrchestratorPath, // grpc reflection method path + // ) + // if err != nil { + // c.Errorln("grpc api err: failed to make method descprtior") + // return types.CommonEventNonceStatus{}, common.ErrFailedGrpcRequest + // } + // } validatorOperatorAddress := item.OperatorAddress validatorMoniker := item.Description.Moniker @@ -107,20 +70,14 @@ func GetEventNonceStatusByGRPC( go func(ch chan helper.Result) { defer wg.Done() - resp, err := grpchelper.GrpcInvokeQuery( - ctx, // common context - methodDescriptor, // grpc query method descriptor - &stub, // grpc query stub - commonOrchestratorPayload, // grpc query payload - ) - + resp, err := c.GRPCClient.Post(ctx, commonOrchestratorPath, []byte(commonOrchestratorPayload)) if err != nil { c.Errorf("grpc error: %s", err) ch <- helper.Result{Success: false, Item: nil} return } - orchestratorAddress, err := commonOrchestratorParser([]byte(resp)) + orchestratorAddress, err := commonOrchestratorParser(resp) if err != nil { c.Errorf("grpc error: %v", err) ch <- helper.Result{Success: false, Item: nil} @@ -181,17 +138,17 @@ func GetEventNonceStatusByGRPC( wg.Add(len(validatorResults)) // get eventnonce by each orchestrator - for idx, item := range validatorResults { - if idx == 0 { - methodDescriptor, err = grpchelper.GrpcMakeDescriptor( - reflectionClient, // grpc reflection client - commonEventNonceQueryPath, // grpc reflection method path - ) - if err != nil { - c.Errorln("grpc api err: failed to make method descprtior") - return types.CommonEventNonceStatus{}, common.ErrFailedGrpcRequest - } - } + for _, item := range validatorResults { + // if idx == 0 { + // methodDescriptor, err = grpchelper.GrpcMakeDescriptor( + // reflectionClient, // grpc reflection client + // commonEventNonceQueryPath, // grpc reflection method path + // ) + // if err != nil { + // c.Errorln("grpc api err: failed to make method descprtior") + // return types.CommonEventNonceStatus{}, common.ErrFailedGrpcRequest + // } + // } orchestratorAddress := item.OrchestratorAddress validatorOperatorAddress := item.ValidatorOperatorAddress @@ -213,12 +170,7 @@ func GetEventNonceStatusByGRPC( return } - resp, err := grpchelper.GrpcInvokeQuery( - ctx, // common context - methodDescriptor, // grpc query method descriptor - &stub, // grpc query stub - payload, // grpc query payload - ) + resp, err := c.GRPCClient.Post(ctx, commonEventNonceQueryPath, []byte(payload)) if err != nil { c.Errorf("grpc error: %s", err) ch <- helper.Result{Success: false, Item: nil} diff --git a/internal/packages/duty/eventnonce/collector/collector.go b/internal/packages/duty/eventnonce/collector/collector.go index ed89df4..399f339 100644 --- a/internal/packages/duty/eventnonce/collector/collector.go +++ b/internal/packages/duty/eventnonce/collector/collector.go @@ -30,8 +30,13 @@ func Start(p common.Packager) error { if ok := helper.Contains(types.SupportedChains, p.ChainName); ok { for _, baseURL := range p.GRPCs { client := common.NewExporter(p) - client.SetGRPCEndPoint(baseURL) - go loop(client, p) + if client.SetGRPCEndPoint(baseURL) == nil { + client.Warnf("Failed to establish gRPC connection with: %s", baseURL) + continue + } else { + client.Debugf("Endpoint: %s", client.GetGRPCEndPoint()) + go loop(client, p) + } break } return nil diff --git a/internal/packages/duty/oracle/api/api.go b/internal/packages/duty/oracle/api/api.go index 8f59d08..86f511e 100644 --- a/internal/packages/duty/oracle/api/api.go +++ b/internal/packages/duty/oracle/api/api.go @@ -3,7 +3,6 @@ package api import ( "context" "encoding/json" - "net/http" "strconv" "strings" "sync" @@ -26,22 +25,18 @@ func GetOracleStatus( defer cancel() // create requester - requester := c.APIClient.R().SetContext(ctx) + requester := c.APIClient // get on-chain validators - resp, err := requester.Get(types.CommonValidatorQueryPath) + resp, err := requester.Get(ctx, types.CommonValidatorQueryPath) if err != nil { c.Errorf("api error: %s", err) return types.CommonOracleStatus{}, common.ErrFailedHttpRequest } - if resp.StatusCode() != http.StatusOK { - c.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - return types.CommonOracleStatus{}, common.ErrGotStrangeStatusCode - } // json unmarsharling received validators data var validators types.CommonValidatorsQueryResponse - if err := json.Unmarshal(resp.Body(), &validators); err != nil { + if err := json.Unmarshal(resp, &validators); err != nil { c.Errorf("api error: %s", err) return types.CommonOracleStatus{}, common.ErrFailedJsonUnmarshal } @@ -66,7 +61,7 @@ func GetOracleStatus( defer helper.HandleOutOfNilResponse(c.Entry) defer wg.Done() - resp, err := requester.Get(queryPath) + resp, err := requester.Get(ctx, queryPath) if err != nil { if resp == nil { c.Errorln("[panic] passed resp.Time() nil point err") @@ -77,13 +72,8 @@ func GetOracleStatus( ch <- helper.Result{Item: nil, Success: false} return } - if resp.StatusCode() != http.StatusOK { - c.Errorf("api error: [%d] from %s", resp.StatusCode(), resp.Request.URL) - ch <- helper.Result{Item: nil, Success: false} - return - } - missCount, err := CommonOracleParser(resp.Body()) + missCount, err := CommonOracleParser(resp) if err != nil { c.Errorf("api error: %s", err) ch <- helper.Result{Item: nil, Success: false} @@ -123,17 +113,13 @@ func GetOracleStatus( } // get oracle params by each chain - resp, err = requester.Get(CommonOracleParamsQueryPath) + resp, err = requester.Get(ctx, CommonOracleParamsQueryPath) if err != nil { c.Errorf("api error: %s", err) return types.CommonOracleStatus{}, common.ErrFailedHttpRequest } - if resp.StatusCode() != http.StatusOK { - c.Errorf("api error: [%d] %s", resp.StatusCode(), err) - return types.CommonOracleStatus{}, common.ErrGotStrangeStatusCode - } - slashWindow, votePeriod, minValidPerWindow, voteWindow, err := CommonOracleParamsParser(resp.Body()) + slashWindow, votePeriod, minValidPerWindow, voteWindow, err := CommonOracleParamsParser(resp) if err != nil { c.Errorf("api error: %s", err) return types.CommonOracleStatus{}, common.ErrFailedJsonUnmarshal @@ -146,19 +132,15 @@ func GetOracleStatus( } // get latest height by each chain - resp, err = requester.Get(types.CommonBlockHeightQueryPath) + resp, err = requester.Get(ctx, types.CommonBlockHeightQueryPath) if err != nil { c.Errorf("api error: %s", err) return types.CommonOracleStatus{}, common.ErrFailedHttpRequest } - if resp.StatusCode() != http.StatusOK { - c.Errorf("api error: [%d] %s", resp.StatusCode(), err) - return types.CommonOracleStatus{}, common.ErrGotStrangeStatusCode - } // json unmarsharling var block types.CommonLatestBlockQueryResponse - if err := json.Unmarshal(resp.Body(), &block); err != nil { + if err := json.Unmarshal(resp, &block); err != nil { c.Errorf("parser error: %s", err) return types.CommonOracleStatus{}, common.ErrFailedJsonUnmarshal } diff --git a/internal/packages/duty/yoda/api/api.go b/internal/packages/duty/yoda/api/api.go index 7866280..2a43404 100644 --- a/internal/packages/duty/yoda/api/api.go +++ b/internal/packages/duty/yoda/api/api.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "math" - "net/http" "slices" "strconv" "strings" @@ -17,6 +16,32 @@ import ( "github.com/cosmostation/cvms/internal/packages/duty/yoda/types" ) +func GetBlockHeight( + c *common.Exporter, + CommonYodaBlockHeightRequestPath string, + CommonYodaBlockHeightResponseParser func([]byte) (blockHeight int64, err error), +) (int64, error) { + // init context + ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) + defer cancel() + + // create requester + requester := c.APIClient + // get current blockheight + resp, err := requester.Get(ctx, CommonYodaBlockHeightRequestPath) + if err != nil { + c.Errorf("api error: %s", err) + return 0, common.ErrFailedHttpRequest + } + + blockHeight, err := CommonYodaBlockHeightResponseParser(resp) + if err != nil { + c.Errorf("api error: %s", err) + return 0, common.ErrFailedJsonUnmarshal + } + return blockHeight, nil +} + func GetYodaStatus( c *common.Exporter, CommonYodaQueryPath string, @@ -33,39 +58,31 @@ func GetYodaStatus( defer cancel() // create requester - requester := c.APIClient.R().SetContext(ctx) + requester := c.APIClient // get on-chain validators - resp, err := requester.Get(types.CommonValidatorQueryPath) + resp, err := requester.Get(ctx, types.CommonValidatorQueryPath) if err != nil { c.Errorf("api error: %s", err) return types.CommonYodaStatus{}, common.ErrFailedHttpRequest } - if resp.StatusCode() != http.StatusOK { - c.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - return types.CommonYodaStatus{}, common.ErrGotStrangeStatusCode - } // json unmarsharling received validators data var validators types.CommonValidatorsQueryResponse - if err := json.Unmarshal(resp.Body(), &validators); err != nil { + if err := json.Unmarshal(resp, &validators); err != nil { c.Errorf("api error: %s", err) return types.CommonYodaStatus{}, common.ErrFailedJsonUnmarshal } // get current request count - resp, err = requester.Get(CommonYodaRequestCountsPath) + resp, err = requester.Get(ctx, CommonYodaRequestCountsPath) if err != nil { c.Errorf("api error: %s", err) return types.CommonYodaStatus{}, common.ErrFailedHttpRequest } - if resp.StatusCode() != http.StatusOK { - c.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - return types.CommonYodaStatus{}, common.ErrGotStrangeStatusCode - } // json unmarsharling received request count data - requestCount, err := CommonYodaRequestCountsParser(resp.Body()) + requestCount, err := CommonYodaRequestCountsParser(resp) if err != nil { c.Errorf("api error: %s", err) return types.CommonYodaStatus{}, common.ErrFailedJsonUnmarshal @@ -73,17 +90,13 @@ func GetYodaStatus( c.Debugf("Current total request count: %.2f", requestCount) // get oracle params by each chain - resp, err = requester.Get(CommonYodaParamsPath) + resp, err = requester.Get(ctx, CommonYodaParamsPath) if err != nil { c.Errorf("api error: %s", err) return types.CommonYodaStatus{}, common.ErrFailedHttpRequest } - if resp.StatusCode() != http.StatusOK { - c.Errorf("api error: [%d] %s", resp.StatusCode(), err) - return types.CommonYodaStatus{}, common.ErrGotStrangeStatusCode - } - yodaSlashWindow, err := CommonYodaParamsParser(resp.Body()) + yodaSlashWindow, err := CommonYodaParamsParser(resp) if err != nil { c.Errorf("api error: %s", err) return types.CommonYodaStatus{}, common.ErrFailedJsonUnmarshal @@ -123,7 +136,7 @@ func GetYodaStatus( defer helper.HandleOutOfNilResponse(c.Entry) defer nerWg.Done() - resp, err := requester.Get(queryPath) + resp, err := requester.Get(ctx, queryPath) if err != nil { if resp == nil { c.Errorln("[panic] passed resp.Time() nil point err") @@ -134,13 +147,8 @@ func GetYodaStatus( nerCh <- helper.Result{Item: nil, Success: false} return } - if resp.StatusCode() != 200 { - c.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - nerCh <- helper.Result{Item: nil, Success: false} - return - } - requestBlock, validatorsFailedToRespond, status, err := CommonYodaRequestParser(resp.Body()) + requestBlock, validatorsFailedToRespond, status, err := CommonYodaRequestParser(resp) if err != nil { c.Errorf("api error: %s", err) nerCh <- helper.Result{Item: nil, Success: false} @@ -208,7 +216,7 @@ func GetYodaStatus( defer helper.HandleOutOfNilResponse(c.Entry) defer wg.Done() - resp, err := requester.Get(queryPath) + resp, err := requester.Get(ctx, queryPath) if err != nil { if resp == nil { c.Errorln("[panic] passed resp.Time() nil point err") @@ -219,13 +227,8 @@ func GetYodaStatus( ch <- helper.Result{Item: nil, Success: false} return } - if resp.StatusCode() != 200 { - c.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - ch <- helper.Result{Item: nil, Success: false} - return - } - isActive, err := CommonYodaParser(resp.Body()) + isActive, err := CommonYodaParser(resp) if err != nil { c.Errorf("api error: %s", err) ch <- helper.Result{Item: nil, Success: false} diff --git a/internal/packages/health/block/api/api.go b/internal/packages/health/block/api/api.go index 44382bb..09752d4 100644 --- a/internal/packages/health/block/api/api.go +++ b/internal/packages/health/block/api/api.go @@ -2,12 +2,9 @@ package api import ( "context" - "net/http" "github.com/cosmostation/cvms/internal/common" "github.com/cosmostation/cvms/internal/packages/health/block/types" - - "github.com/go-resty/resty/v2" ) func GetBlockStatus( @@ -22,26 +19,21 @@ func GetBlockStatus( defer cancel() // create requester - var requester *resty.Request + // var requester *resty.Request if CommonBlockCallClient == common.RPC { - requester = c.RPCClient.R().SetContext(ctx) + // requester = c.RPCClient.R().SetContext(ctx) } else { - requester = c.APIClient.R().SetContext(ctx) + // requester = c.APIClient.R().SetContext(ctx) } - var resp = &resty.Response{} + // var resp = &resty.Response{} + var resp []byte var err error if CommonBlockCallMethod == common.GET { - resp, err = requester. - SetHeader("Content-Type", "application/json"). - SetBody(CommonBlockPayload). - Get(CommonBlockQueryPath) + resp, err = c.RPCClient.Get(ctx, CommonBlockQueryPath) } else if CommonBlockCallMethod == common.POST { - resp, err = requester. - SetHeader("Content-Type", "application/json"). - SetBody(CommonBlockPayload). - Post(CommonBlockQueryPath) + resp, err = c.RPCClient.Post(ctx, CommonBlockQueryPath, []byte(CommonBlockPayload)) } else { return types.CommonBlock{}, common.ErrUnSupportedMethod } @@ -51,14 +43,10 @@ func GetBlockStatus( return types.CommonBlock{}, common.ErrFailedHttpRequest } - if resp.StatusCode() != http.StatusOK { - c.Errorf("request error: [%d] %s", resp.StatusCode(), err) - return types.CommonBlock{}, common.ErrGotStrangeStatusCode - } - - blockHeight, blockTimeStamp, err := CommonBlockParser(resp.Body()) + blockHeight, blockTimeStamp, err := CommonBlockParser(resp) if err != nil { c.Errorf("parser error: %s", err) + c.Debugf("received response: %s", string(resp)) return types.CommonBlock{}, common.ErrFailedJsonUnmarshal } diff --git a/internal/packages/utility/balance/api/api.go b/internal/packages/utility/balance/api/api.go index 31d843e..0dc61c2 100644 --- a/internal/packages/utility/balance/api/api.go +++ b/internal/packages/utility/balance/api/api.go @@ -4,7 +4,6 @@ import ( "context" "errors" "math" - "net/http" "strings" "sync" "time" @@ -13,7 +12,6 @@ import ( "github.com/cosmostation/cvms/internal/helper" balanceErrors "github.com/cosmostation/cvms/internal/packages/utility/balance/errors" "github.com/cosmostation/cvms/internal/packages/utility/balance/types" - "github.com/go-resty/resty/v2" ) func GetBalanceStatus( @@ -29,7 +27,7 @@ func GetBalanceStatus( defer cancel() // create requester - requester := c.APIClient.R().SetContext(ctx).SetHeader("Content-Type", "application/json") + requester := c.APIClient // init channel and waitgroup for go-routine ch := make(chan helper.Result) @@ -40,7 +38,7 @@ func GetBalanceStatus( // get evm status by each validator for _, address := range BalanceAddresses { - var resp = &resty.Response{} + var resp = []byte{} var err error address := address @@ -53,9 +51,9 @@ func GetBalanceStatus( defer wg.Done() if CommonBalanceCallMethod == common.GET { - resp, err = requester.SetBody(payload).Get(queryPath) + resp, err = requester.Get(ctx, queryPath) } else { - resp, err = requester.SetBody(payload).Post(queryPath) + resp, err = requester.Post(ctx, queryPath, []byte(payload)) } if err != nil { @@ -69,13 +67,7 @@ func GetBalanceStatus( return } - if resp.StatusCode() != http.StatusOK { - c.Errorf("api error: got %d code from %s", resp.StatusCode(), resp.Request.URL) - ch <- helper.Result{Item: nil, Success: false} - return - } - - remainingBalance, err := CommonBalanceParser(resp.Body(), BalanceDenom) + remainingBalance, err := CommonBalanceParser(resp, BalanceDenom) // catch expected error when balance is not found and assuming balance as 0 if errors.Is(err, balanceErrors.ErrBalanceNotFound) { c.Warningf("Balance not found for %s and denom %s, assuming balance as 0", address, BalanceDenom) diff --git a/internal/packages/utility/upgrade/api/api.go b/internal/packages/utility/upgrade/api/api.go index 8c9ec5e..8d7b23e 100644 --- a/internal/packages/utility/upgrade/api/api.go +++ b/internal/packages/utility/upgrade/api/api.go @@ -2,7 +2,6 @@ package api import ( "context" - "net/http" "github.com/cosmostation/cvms/internal/common" "github.com/cosmostation/cvms/internal/common/api" @@ -19,18 +18,14 @@ func GetUpgradeStatus( ctx, cancel := context.WithTimeout(ctx, common.Timeout) defer cancel() - requester := c.APIClient.R().SetContext(ctx) - resp, err := requester.Get(CommonUpgradeQueryPath) + requester := c.APIClient + resp, err := requester.Get(ctx, CommonUpgradeQueryPath) if err != nil { c.Errorf("api error: %s", err) return types.CommonUpgrade{}, common.ErrFailedHttpRequest } - if resp.StatusCode() != http.StatusOK { - c.Errorf("api error: status code is %d from %s", resp.StatusCode(), resp.Request.URL) - return types.CommonUpgrade{}, common.ErrGotStrangeStatusCode - } - upgradeHeight, upgradeName, err := CommonUpgradeParser(resp.Body()) + upgradeHeight, upgradeName, err := CommonUpgradeParser(resp) if err != nil { c.Errorf("parser error: %s", err) return types.CommonUpgrade{}, common.ErrFailedJsonUnmarshal diff --git a/internal/testutil/setup.go b/internal/testutil/setup.go index fadacad..fab6b83 100644 --- a/internal/testutil/setup.go +++ b/internal/testutil/setup.go @@ -9,11 +9,10 @@ import ( "os/exec" "regexp" "strings" - "time" "github.com/cosmostation/cvms/internal/common" + "github.com/cosmostation/cvms/internal/common/client" "github.com/cosmostation/cvms/internal/helper/logger" - "github.com/go-resty/resty/v2" "github.com/joho/godotenv" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -86,21 +85,9 @@ func GetTestExporter() *common.Exporter { l := logger.GetTestLogger() restyLogger := logrus.New() restyLogger.Out = io.Discard - RPCClient := resty.New(). - SetRetryCount(10). - SetRetryWaitTime(10 * time.Millisecond). - SetRetryMaxWaitTime(3 * time.Second). - SetLogger(restyLogger) - APIClient := resty.New(). - SetRetryCount(10). - SetRetryWaitTime(10 * time.Millisecond). - SetRetryMaxWaitTime(3 * time.Second). - SetLogger(restyLogger) - GRPCClient := resty.New(). - SetRetryCount(10). - SetRetryWaitTime(10 * time.Millisecond). - SetRetryMaxWaitTime(3 * time.Second). - SetLogger(restyLogger) + RPCClient := client.NewRestyClient().SetLogger(restyLogger) + APIClient := client.NewRestyClient().SetLogger(restyLogger) + GRPCClient := client.NewGrpcClient(common.Timeout).SetLogger(restyLogger) entry := l.WithField("mode", "test") monikers := []string{"Cosmostation"} commonClient := common.CommonClient{