Feature/refactor api (#34)
* Refactor error handling and comments * Refactor and improve error handling and logs
This commit is contained in:
parent
d7e2cd55fe
commit
8ed4804d63
|
@ -1,9 +0,0 @@
|
||||||
package api
|
|
||||||
|
|
||||||
// API codes used in guardian node.
|
|
||||||
// The same codes are used to facilitate portability to the new api.
|
|
||||||
const (
|
|
||||||
InvalidArgument = 3
|
|
||||||
NotFound = 5
|
|
||||||
Internal = 13
|
|
||||||
)
|
|
|
@ -1,12 +0,0 @@
|
||||||
package errors
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
func IsOf(received error, targets ...error) bool {
|
|
||||||
for _, t := range targets {
|
|
||||||
if errors.Is(received, t) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
|
@ -3,27 +3,26 @@ module github.com/wormhole-foundation/wormhole-explorer/api
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/ansrivas/fiberprometheus/v2 v2.4.1
|
||||||
github.com/certusone/wormhole/node v0.0.0-20220907133901-8e231501b6cd
|
github.com/certusone/wormhole/node v0.0.0-20220907133901-8e231501b6cd
|
||||||
github.com/gofiber/fiber/v2 v2.39.0
|
github.com/gofiber/fiber/v2 v2.39.0
|
||||||
|
github.com/ipfs/go-log/v2 v2.5.1
|
||||||
github.com/spf13/viper v1.13.0
|
github.com/spf13/viper v1.13.0
|
||||||
go.mongodb.org/mongo-driver v1.10.3
|
go.mongodb.org/mongo-driver v1.10.3
|
||||||
|
go.uber.org/zap v1.22.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||||
github.com/ansrivas/fiberprometheus/v2 v2.4.1 // indirect
|
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/btcsuite/btcd v0.22.1 // indirect
|
github.com/btcsuite/btcd v0.22.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
github.com/ethereum/go-ethereum v1.10.6 // indirect
|
github.com/ethereum/go-ethereum v1.10.6 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||||
github.com/gofiber/adaptor/v2 v2.1.29 // indirect
|
github.com/gofiber/adaptor/v2 v2.1.29 // indirect
|
||||||
github.com/gogo/protobuf v1.3.3 // indirect
|
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
github.com/golang/snappy v0.0.3 // indirect
|
github.com/golang/snappy v0.0.3 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/ipfs/go-log v1.0.5 // indirect
|
|
||||||
github.com/ipfs/go-log/v2 v2.5.1 // indirect
|
|
||||||
github.com/klauspost/compress v1.15.12 // indirect
|
github.com/klauspost/compress v1.15.12 // indirect
|
||||||
github.com/magiconair/properties v1.8.6 // indirect
|
github.com/magiconair/properties v1.8.6 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
@ -32,7 +31,6 @@ require (
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
||||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
|
||||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
@ -55,7 +53,6 @@ require (
|
||||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||||
go.uber.org/atomic v1.10.0 // indirect
|
go.uber.org/atomic v1.10.0 // indirect
|
||||||
go.uber.org/multierr v1.8.0 // indirect
|
go.uber.org/multierr v1.8.0 // indirect
|
||||||
go.uber.org/zap v1.22.0 // indirect
|
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
||||||
golang.org/x/sys v0.1.0 // indirect
|
golang.org/x/sys v0.1.0 // indirect
|
||||||
|
|
22
api/go.sum
22
api/go.sum
|
@ -83,6 +83,7 @@ github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbE
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM=
|
github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM=
|
||||||
github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw=
|
github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw=
|
||||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
|
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
|
@ -105,7 +106,6 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
|
||||||
github.com/certusone/wormhole/node v0.0.0-20220907133901-8e231501b6cd h1:j/D2a0Hvs+JBKteCTFGhi9f7MA0SaDE+BPFoGNqSENo=
|
github.com/certusone/wormhole/node v0.0.0-20220907133901-8e231501b6cd h1:j/D2a0Hvs+JBKteCTFGhi9f7MA0SaDE+BPFoGNqSENo=
|
||||||
github.com/certusone/wormhole/node v0.0.0-20220907133901-8e231501b6cd/go.mod h1:hbEdpBxPoBplIJ+PMVitVGX5194g+Opd7dvONcxhykQ=
|
github.com/certusone/wormhole/node v0.0.0-20220907133901-8e231501b6cd/go.mod h1:hbEdpBxPoBplIJ+PMVitVGX5194g+Opd7dvONcxhykQ=
|
||||||
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||||
|
@ -173,8 +173,6 @@ github.com/gofiber/adaptor/v2 v2.1.25/go.mod h1:gOxtwMVqUStB5goAYtKd+hSvGupdd+aR
|
||||||
github.com/gofiber/adaptor/v2 v2.1.29 h1:JnYd6fbqVM9D4zPchk+kg89PfxyuKqZKhBWGQDHfKH4=
|
github.com/gofiber/adaptor/v2 v2.1.29 h1:JnYd6fbqVM9D4zPchk+kg89PfxyuKqZKhBWGQDHfKH4=
|
||||||
github.com/gofiber/adaptor/v2 v2.1.29/go.mod h1:z4mAV9mMsUgIEVGGS5Ii6ZMTJq4VdV1KWL1JAbsZdUA=
|
github.com/gofiber/adaptor/v2 v2.1.29/go.mod h1:z4mAV9mMsUgIEVGGS5Ii6ZMTJq4VdV1KWL1JAbsZdUA=
|
||||||
github.com/gofiber/fiber/v2 v2.36.0/go.mod h1:tgCr+lierLwLoVHHO/jn3Niannv34WRkQETU8wiL9fQ=
|
github.com/gofiber/fiber/v2 v2.36.0/go.mod h1:tgCr+lierLwLoVHHO/jn3Niannv34WRkQETU8wiL9fQ=
|
||||||
github.com/gofiber/fiber/v2 v2.38.1 h1:GEQ/Yt3Wsf2a30iTqtLXlBYJZso0JXPovt/tmj5H9jU=
|
|
||||||
github.com/gofiber/fiber/v2 v2.38.1/go.mod h1:t0NlbaXzuGH7I+7M4paE848fNWInZ7mfxI/Er1fTth8=
|
|
||||||
github.com/gofiber/fiber/v2 v2.39.0 h1:uhWpYQ6EHN8J7FOPYbI2hrdBD/KNZBC5CjbuOd4QUt4=
|
github.com/gofiber/fiber/v2 v2.39.0 h1:uhWpYQ6EHN8J7FOPYbI2hrdBD/KNZBC5CjbuOd4QUt4=
|
||||||
github.com/gofiber/fiber/v2 v2.39.0/go.mod h1:Cmuu+elPYGqlvQvdKyjtYsjGMi69PDp8a1AY2I5B2gM=
|
github.com/gofiber/fiber/v2 v2.39.0/go.mod h1:Cmuu+elPYGqlvQvdKyjtYsjGMi69PDp8a1AY2I5B2gM=
|
||||||
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
|
@ -271,9 +269,6 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y
|
||||||
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
|
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
|
||||||
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
|
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
|
||||||
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
|
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
|
||||||
github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8=
|
|
||||||
github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo=
|
|
||||||
github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g=
|
|
||||||
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
|
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
|
||||||
github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
|
github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
|
||||||
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
|
@ -302,8 +297,6 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6
|
||||||
github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A=
|
|
||||||
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
|
||||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||||
github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM=
|
github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM=
|
||||||
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||||
|
@ -371,8 +364,6 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
|
||||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
|
||||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
|
||||||
github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE=
|
github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE=
|
||||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
|
@ -420,7 +411,6 @@ github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
|
||||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
||||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4=
|
|
||||||
github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI=
|
github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI=
|
||||||
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
|
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
@ -482,7 +472,6 @@ github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/X
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
github.com/valyala/fasthttp v1.38.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
github.com/valyala/fasthttp v1.38.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
||||||
github.com/valyala/fasthttp v1.40.0 h1:CRq/00MfruPGFLTQKY8b+8SfdK60TxNztjRMnH0t1Yc=
|
|
||||||
github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
||||||
github.com/valyala/fasthttp v1.41.0 h1:zeR0Z1my1wDHTRiamBCXVglQdbUwgb9uWG3k1HQz6jY=
|
github.com/valyala/fasthttp v1.41.0 h1:zeR0Z1my1wDHTRiamBCXVglQdbUwgb9uWG3k1HQz6jY=
|
||||||
github.com/valyala/fasthttp v1.41.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY=
|
github.com/valyala/fasthttp v1.41.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY=
|
||||||
|
@ -512,19 +501,16 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||||
|
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
|
||||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
|
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
|
||||||
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
|
||||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
|
|
||||||
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
|
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
|
||||||
go.uber.org/zap v1.22.0 h1:Zcye5DUgBloQ9BaT4qc9BnjOFog5TvBSAGkJ3Nf70c0=
|
go.uber.org/zap v1.22.0 h1:Zcye5DUgBloQ9BaT4qc9BnjOFog5TvBSAGkJ3Nf70c0=
|
||||||
go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U=
|
go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U=
|
||||||
|
@ -709,7 +695,6 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
|
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
@ -746,8 +731,6 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
@ -891,7 +874,6 @@ google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175
|
||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|
|
@ -1,23 +1,26 @@
|
||||||
|
// Package governor handle the request of governor data from governor endpoint defined in the api.
|
||||||
package governor
|
package governor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/middleware"
|
"github.com/wormhole-foundation/wormhole-explorer/api/middleware"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/pagination"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Controller definition.
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
srv *Service
|
srv *Service
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewController create a new controler.
|
||||||
func NewController(serv *Service, logger *zap.Logger) *Controller {
|
func NewController(serv *Service, logger *zap.Logger) *Controller {
|
||||||
return &Controller{srv: serv, logger: logger.With(zap.String("module", "GovernorController"))}
|
return &Controller{srv: serv, logger: logger.With(zap.String("module", "GovernorController"))}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindGovernorConfigurations handler for the endpoint /governor/config/
|
||||||
func (c *Controller) FindGovernorConfigurations(ctx *fiber.Ctx) error {
|
func (c *Controller) FindGovernorConfigurations(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
governorConfigs, err := c.srv.FindGovernorConfig(ctx.Context(), p)
|
governorConfigs, err := c.srv.FindGovernorConfig(ctx.Context(), p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -25,9 +28,10 @@ func (c *Controller) FindGovernorConfigurations(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(governorConfigs)
|
return ctx.JSON(governorConfigs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindGovernorConfigurationByGuardianAddress handler for the endpoint /governor/config/:guardian_address.
|
||||||
func (c *Controller) FindGovernorConfigurationByGuardianAddress(ctx *fiber.Ctx) error {
|
func (c *Controller) FindGovernorConfigurationByGuardianAddress(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
guardianAddress, err := middleware.ExtractGuardianAddress(ctx)
|
guardianAddress, err := middleware.ExtractGuardianAddress(ctx, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -38,8 +42,9 @@ func (c *Controller) FindGovernorConfigurationByGuardianAddress(ctx *fiber.Ctx)
|
||||||
return ctx.JSON(govConfig)
|
return ctx.JSON(govConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindGovernorStatus handler for the endpoint /governor/status/.
|
||||||
func (c *Controller) FindGovernorStatus(ctx *fiber.Ctx) error {
|
func (c *Controller) FindGovernorStatus(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
governorStatus, err := c.srv.FindGovernorStatus(ctx.Context(), p)
|
governorStatus, err := c.srv.FindGovernorStatus(ctx.Context(), p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -47,9 +52,10 @@ func (c *Controller) FindGovernorStatus(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(governorStatus)
|
return ctx.JSON(governorStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindGovernorStatusByGuardianAddress handler for the endpoint /governor/status/:guardian_address.
|
||||||
func (c *Controller) FindGovernorStatusByGuardianAddress(ctx *fiber.Ctx) error {
|
func (c *Controller) FindGovernorStatusByGuardianAddress(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
guardianAddress, err := middleware.ExtractGuardianAddress(ctx)
|
guardianAddress, err := middleware.ExtractGuardianAddress(ctx, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -60,8 +66,9 @@ func (c *Controller) FindGovernorStatusByGuardianAddress(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(govStatus)
|
return ctx.JSON(govStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetGovernorLimit handler for the endpoint /governor/limit/
|
||||||
func (c *Controller) GetGovernorLimit(ctx *fiber.Ctx) error {
|
func (c *Controller) GetGovernorLimit(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
governorLimit, err := c.srv.GetGovernorLimit(ctx.Context(), p)
|
governorLimit, err := c.srv.GetGovernorLimit(ctx.Context(), p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -69,8 +76,9 @@ func (c *Controller) GetGovernorLimit(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(governorLimit)
|
return ctx.JSON(governorLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindNotionalLimit handler for the endpoint governor/notional/limit/
|
||||||
func (c *Controller) FindNotionalLimit(ctx *fiber.Ctx) error {
|
func (c *Controller) FindNotionalLimit(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
notionalLimit, err := c.srv.FindNotionalLimit(ctx.Context(), p)
|
notionalLimit, err := c.srv.FindNotionalLimit(ctx.Context(), p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -78,9 +86,10 @@ func (c *Controller) FindNotionalLimit(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(notionalLimit)
|
return ctx.JSON(notionalLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetNotionalLimitByChainID handler for the endpoint governor/notional/limit/:chain.
|
||||||
func (c *Controller) GetNotionalLimitByChainID(ctx *fiber.Ctx) error {
|
func (c *Controller) GetNotionalLimitByChainID(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
chainID, err := middleware.ExtractChainID(ctx)
|
chainID, err := middleware.ExtractChainID(ctx, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -91,8 +100,9 @@ func (c *Controller) GetNotionalLimitByChainID(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(notionalLimit)
|
return ctx.JSON(notionalLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAvailableNotional handler for the endpoint governor/notional/available/
|
||||||
func (c *Controller) GetAvailableNotional(ctx *fiber.Ctx) error {
|
func (c *Controller) GetAvailableNotional(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
notionalAvaialabilies, err := c.srv.GetAvailableNotional(ctx.Context(), p)
|
notionalAvaialabilies, err := c.srv.GetAvailableNotional(ctx.Context(), p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -100,9 +110,10 @@ func (c *Controller) GetAvailableNotional(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(notionalAvaialabilies)
|
return ctx.JSON(notionalAvaialabilies)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAvailableNotionalByChainID handler for the endpoint governor/notional/available/:chain
|
||||||
func (c *Controller) GetAvailableNotionalByChainID(ctx *fiber.Ctx) error {
|
func (c *Controller) GetAvailableNotionalByChainID(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
chainID, err := middleware.ExtractChainID(ctx)
|
chainID, err := middleware.ExtractChainID(ctx, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -113,9 +124,10 @@ func (c *Controller) GetAvailableNotionalByChainID(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(response)
|
return ctx.JSON(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMaxNotionalAvailableByChainID handler for the endpoint governor/max_available/:chain.
|
||||||
func (c *Controller) GetMaxNotionalAvailableByChainID(ctx *fiber.Ctx) error {
|
func (c *Controller) GetMaxNotionalAvailableByChainID(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
chainID, err := middleware.ExtractChainID(ctx)
|
chainID, err := middleware.ExtractChainID(ctx, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -126,8 +138,9 @@ func (c *Controller) GetMaxNotionalAvailableByChainID(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(response)
|
return ctx.JSON(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetEnqueueVass handler for the endpoint governor/enqueued_vaas/
|
||||||
func (c *Controller) GetEnqueueVass(ctx *fiber.Ctx) error {
|
func (c *Controller) GetEnqueueVass(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
enqueuedVaas, err := c.srv.GetEnqueueVass(ctx.Context(), p)
|
enqueuedVaas, err := c.srv.GetEnqueueVass(ctx.Context(), p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -135,9 +148,10 @@ func (c *Controller) GetEnqueueVass(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(enqueuedVaas)
|
return ctx.JSON(enqueuedVaas)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetEnqueueVassByChainID handler for the endpoint governor/enqueued_vaas/:chain.
|
||||||
func (c *Controller) GetEnqueueVassByChainID(ctx *fiber.Ctx) error {
|
func (c *Controller) GetEnqueueVassByChainID(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
chainID, err := middleware.ExtractChainID(ctx)
|
chainID, err := middleware.ExtractChainID(ctx, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Package governor handle the request of governor data from governor endpoint defined in the api.
|
||||||
package governor
|
package governor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -6,7 +7,7 @@ import (
|
||||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GovConfigPage definition.
|
// GovConfigPage represent a governor configuration.
|
||||||
type GovConfig struct {
|
type GovConfig struct {
|
||||||
ID string `bson:"_id" json:"id"`
|
ID string `bson:"_id" json:"id"`
|
||||||
CreatedAt *time.Time `bson:"createdAt" json:"createdAt"`
|
CreatedAt *time.Time `bson:"createdAt" json:"createdAt"`
|
||||||
|
@ -29,7 +30,7 @@ type GovConfigfTokens struct {
|
||||||
Price float64 `bson:"price" json:"price"`
|
Price float64 `bson:"price" json:"price"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GovStatusPage definition.
|
// GovStatusPage represent a governor status.
|
||||||
type GovStatus struct {
|
type GovStatus struct {
|
||||||
ID string `bson:"_id" json:"id"`
|
ID string `bson:"_id" json:"id"`
|
||||||
CreatedAt *time.Time `bson:"createdAt" json:"createdAt"`
|
CreatedAt *time.Time `bson:"createdAt" json:"createdAt"`
|
||||||
|
@ -50,17 +51,17 @@ type GovStatusChainEmitter struct {
|
||||||
EnqueuedVass interface{} `bson:"enqueuedvaas" json:"enqueuedvaas"`
|
EnqueuedVass interface{} `bson:"enqueuedvaas" json:"enqueuedvaas"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotionalLimit definition.
|
// NotionalLimit represent the notional limit value and maximun tranasction size for a chainID.
|
||||||
type NotionalLimit struct {
|
type NotionalLimit struct {
|
||||||
ChainID vaa.ChainID `bson:"chainid" json:"chainid"`
|
ChainID vaa.ChainID `bson:"chainid" json:"chainid"`
|
||||||
NotionalLimit *int64 `bson:"notionalLimit" json:"notionalLimit"`
|
NotionalLimit *int64 `bson:"notionalLimit" json:"notionalLimit"`
|
||||||
MaxTrasactionSize *int64 `bson:"maxTransactionSize" json:"maxTransactionSize"`
|
MaxTrasactionSize *int64 `bson:"maxTransactionSize" json:"maxTransactionSize"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotionalLimitDetail definition.
|
// NotionalLimitDetail represent a notional limit value
|
||||||
type NotionalLimitDetail struct {
|
type NotionalLimitDetail struct {
|
||||||
ID string `bson:"_id" json:"id"`
|
ID string `bson:"_id" json:"id"`
|
||||||
ChainID vaa.ChainID `bson:"chainid" json:"chainid"`
|
ChainID vaa.ChainID `bson:"chainId" json:"chainId"`
|
||||||
NodeName string `bson:"nodename" json:"nodename"`
|
NodeName string `bson:"nodename" json:"nodename"`
|
||||||
NotionalLimit *int64 `bson:"notionalLimit" json:"notionalLimit"`
|
NotionalLimit *int64 `bson:"notionalLimit" json:"notionalLimit"`
|
||||||
MaxTrasactionSize *int64 `bson:"maxTransactionSize" json:"maxTransactionSize"`
|
MaxTrasactionSize *int64 `bson:"maxTransactionSize" json:"maxTransactionSize"`
|
||||||
|
@ -68,11 +69,13 @@ type NotionalLimitDetail struct {
|
||||||
UpdatedAt *time.Time `bson:"updatedAt" json:"updatedAt"`
|
UpdatedAt *time.Time `bson:"updatedAt" json:"updatedAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotionalAvailable represent the available notional for chainID.
|
||||||
type NotionalAvailable struct {
|
type NotionalAvailable struct {
|
||||||
ChainID vaa.ChainID `bson:"chainid" json:"chainId"`
|
ChainID vaa.ChainID `bson:"chainid" json:"chainId"`
|
||||||
AvailableNotional *int64 `bson:"availableNotional" json:"availableNotional"`
|
AvailableNotional *int64 `bson:"availableNotional" json:"availableNotional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotionalAvailableDetail represent a notional available value.
|
||||||
type NotionalAvailableDetail struct {
|
type NotionalAvailableDetail struct {
|
||||||
ID string `bson:"_id" json:"id"`
|
ID string `bson:"_id" json:"id"`
|
||||||
ChainID vaa.ChainID `bson:"chainId" json:"chainId"`
|
ChainID vaa.ChainID `bson:"chainId" json:"chainId"`
|
||||||
|
@ -108,6 +111,7 @@ type EnqueuedVaa struct {
|
||||||
TxHash string `bson:"txHash" json:"txHash"`
|
TxHash string `bson:"txHash" json:"txHash"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnqueuedVaas definition.
|
||||||
type EnqueuedVaas struct {
|
type EnqueuedVaas struct {
|
||||||
ChainID vaa.ChainID `bson:"chainid" json:"chainId"`
|
ChainID vaa.ChainID `bson:"chainid" json:"chainId"`
|
||||||
EnqueuedVaa []*EnqueuedVaa `bson:"enqueuedVaas" json:"enqueuedVaas"`
|
EnqueuedVaa []*EnqueuedVaa `bson:"enqueuedVaas" json:"enqueuedVaas"`
|
|
@ -1,14 +1,16 @@
|
||||||
|
// Package governor handle the request of governor data from governor endpoint defined in the api.
|
||||||
package governor
|
package governor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/pagination"
|
"github.com/pkg/errors"
|
||||||
|
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
|
||||||
|
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
@ -17,10 +19,7 @@ import (
|
||||||
|
|
||||||
const minGuardianNum = 13
|
const minGuardianNum = 13
|
||||||
|
|
||||||
var (
|
// Repository definition.
|
||||||
ErrWrongQuery = errors.New("MALFORMED_QUERY")
|
|
||||||
)
|
|
||||||
|
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
db *mongo.Database
|
db *mongo.Database
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
|
@ -30,6 +29,7 @@ type Repository struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewRepository create a new Repository.
|
||||||
func NewRepository(db *mongo.Database, logger *zap.Logger) *Repository {
|
func NewRepository(db *mongo.Database, logger *zap.Logger) *Repository {
|
||||||
return &Repository{db: db,
|
return &Repository{db: db,
|
||||||
logger: logger.With(zap.String("module", "GovernorRepository")),
|
logger: logger.With(zap.String("module", "GovernorRepository")),
|
||||||
|
@ -43,21 +43,25 @@ func NewRepository(db *mongo.Database, logger *zap.Logger) *Repository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GovernorQuery respresent a query for the governors mongodb documents.
|
||||||
type GovernorQuery struct {
|
type GovernorQuery struct {
|
||||||
pagination.Pagination
|
pagination.Pagination
|
||||||
id string
|
id string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryGovernor create a new GovernorQuery with default pagination values.
|
||||||
func QueryGovernor() *GovernorQuery {
|
func QueryGovernor() *GovernorQuery {
|
||||||
page := pagination.FirstPage()
|
page := pagination.FirstPage()
|
||||||
return &GovernorQuery{Pagination: *page}
|
return &GovernorQuery{Pagination: *page}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetID set the id field of the GovernorQuery struct.
|
||||||
func (q *GovernorQuery) SetID(id string) *GovernorQuery {
|
func (q *GovernorQuery) SetID(id string) *GovernorQuery {
|
||||||
q.id = id
|
q.id = id
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPagination set the pagination field of the GovernorQuery struct.
|
||||||
func (q *GovernorQuery) SetPagination(p *pagination.Pagination) *GovernorQuery {
|
func (q *GovernorQuery) SetPagination(p *pagination.Pagination) *GovernorQuery {
|
||||||
q.Pagination = *p
|
q.Pagination = *p
|
||||||
return q
|
return q
|
||||||
|
@ -71,6 +75,7 @@ func (q *GovernorQuery) toBSON() *bson.D {
|
||||||
return &r
|
return &r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindGovConfigurations get a list of *GovConfig.
|
||||||
func (r *Repository) FindGovConfigurations(ctx context.Context, q *GovernorQuery) ([]*GovConfig, error) {
|
func (r *Repository) FindGovConfigurations(ctx context.Context, q *GovernorQuery) ([]*GovConfig, error) {
|
||||||
if q == nil {
|
if q == nil {
|
||||||
q = QueryGovernor()
|
q = QueryGovernor()
|
||||||
|
@ -87,19 +92,26 @@ func (r *Repository) FindGovConfigurations(ctx context.Context, q *GovernorQuery
|
||||||
options := options.Find().SetProjection(projection).SetLimit(q.PageSize).SetSkip(q.Offset).SetSort(sort)
|
options := options.Find().SetProjection(projection).SetLimit(q.PageSize).SetSkip(q.Offset).SetSort(sort)
|
||||||
cur, err := r.collections.governorConfig.Find(ctx, q.toBSON(), options)
|
cur, err := r.collections.governorConfig.Find(ctx, q.toBSON(), options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Find command to get governor configurations",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
var govConfigs []*GovConfig
|
var govConfigs []*GovConfig
|
||||||
err = cur.All(ctx, &govConfigs)
|
err = cur.All(ctx, &govConfigs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed decoding cursor to []*GovConfig", zap.Error(err), zap.Any("q", q),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
return govConfigs, err
|
return govConfigs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindGovConfiguration get a *GovConfig. The q parameter define the filter to apply to the query.
|
||||||
func (r *Repository) FindGovConfiguration(ctx context.Context, q *GovernorQuery) (*GovConfig, error) {
|
func (r *Repository) FindGovConfiguration(ctx context.Context, q *GovernorQuery) (*GovConfig, error) {
|
||||||
if q == nil {
|
if q == nil {
|
||||||
return nil, ErrWrongQuery
|
return nil, errs.ErrMalformedQuery
|
||||||
}
|
}
|
||||||
var govConfig GovConfig
|
var govConfig GovConfig
|
||||||
projection := bson.D{
|
projection := bson.D{
|
||||||
|
@ -113,11 +125,18 @@ func (r *Repository) FindGovConfiguration(ctx context.Context, q *GovernorQuery)
|
||||||
options := options.FindOne().SetProjection(projection)
|
options := options.FindOne().SetProjection(projection)
|
||||||
err := r.collections.governorConfig.FindOne(ctx, q.toBSON(), options).Decode(&govConfig)
|
err := r.collections.governorConfig.FindOne(ctx, q.toBSON(), options).Decode(&govConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
if errors.Is(err, mongo.ErrNoDocuments) {
|
||||||
|
return nil, errs.ErrNotFound
|
||||||
|
}
|
||||||
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute FindOne command to get governor configuration",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
return &govConfig, err
|
return &govConfig, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindGovernorStatus get a list of *GovStatus.
|
||||||
func (r *Repository) FindGovernorStatus(ctx context.Context, q *GovernorQuery) ([]*GovStatus, error) {
|
func (r *Repository) FindGovernorStatus(ctx context.Context, q *GovernorQuery) ([]*GovStatus, error) {
|
||||||
if q == nil {
|
if q == nil {
|
||||||
q = QueryGovernor()
|
q = QueryGovernor()
|
||||||
|
@ -132,19 +151,26 @@ func (r *Repository) FindGovernorStatus(ctx context.Context, q *GovernorQuery) (
|
||||||
options := options.Find().SetProjection(projection).SetLimit(q.PageSize).SetSkip(q.Offset).SetSort(sort)
|
options := options.Find().SetProjection(projection).SetLimit(q.PageSize).SetSkip(q.Offset).SetSort(sort)
|
||||||
cur, err := r.collections.governorStatus.Find(ctx, q.toBSON(), options)
|
cur, err := r.collections.governorStatus.Find(ctx, q.toBSON(), options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Find command to get all governor status",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
var govStatus []*GovStatus
|
var govStatus []*GovStatus
|
||||||
err = cur.All(ctx, &govStatus)
|
err = cur.All(ctx, &govStatus)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed decoding cursor to []*GovStatus", zap.Error(err), zap.Any("q", q),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
return govStatus, err
|
return govStatus, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindOneGovernorStatus get a *GovStatus. The q parameter define the filter to apply to the query.
|
||||||
func (r *Repository) FindOneGovernorStatus(ctx context.Context, q *GovernorQuery) (*GovStatus, error) {
|
func (r *Repository) FindOneGovernorStatus(ctx context.Context, q *GovernorQuery) (*GovStatus, error) {
|
||||||
if q == nil {
|
if q == nil {
|
||||||
return nil, ErrWrongQuery
|
return nil, errs.ErrMalformedQuery
|
||||||
}
|
}
|
||||||
var govConfig GovStatus
|
var govConfig GovStatus
|
||||||
projection := bson.D{
|
projection := bson.D{
|
||||||
|
@ -156,37 +182,49 @@ func (r *Repository) FindOneGovernorStatus(ctx context.Context, q *GovernorQuery
|
||||||
options := options.FindOne().SetProjection(projection)
|
options := options.FindOne().SetProjection(projection)
|
||||||
err := r.collections.governorStatus.FindOne(ctx, q.toBSON(), options).Decode(&govConfig)
|
err := r.collections.governorStatus.FindOne(ctx, q.toBSON(), options).Decode(&govConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
if errors.Is(err, mongo.ErrNoDocuments) {
|
||||||
|
return nil, errs.ErrNotFound
|
||||||
|
}
|
||||||
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute FindOne command to get governor status",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
return &govConfig, err
|
return &govConfig, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotionalLimitQuery
|
||||||
type NotionalLimitQuery struct {
|
type NotionalLimitQuery struct {
|
||||||
pagination.Pagination
|
pagination.Pagination
|
||||||
id string
|
id string
|
||||||
chainID vaa.ChainID
|
chainID vaa.ChainID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryNotionalLimit create a new NotionalLimitQuery with default pagination values.
|
||||||
func QueryNotionalLimit() *NotionalLimitQuery {
|
func QueryNotionalLimit() *NotionalLimitQuery {
|
||||||
page := pagination.FirstPage()
|
page := pagination.FirstPage()
|
||||||
return &NotionalLimitQuery{Pagination: *page}
|
return &NotionalLimitQuery{Pagination: *page}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetID set the id field of the NotionalLimitQuery struct.
|
||||||
func (q *NotionalLimitQuery) SetID(id string) *NotionalLimitQuery {
|
func (q *NotionalLimitQuery) SetID(id string) *NotionalLimitQuery {
|
||||||
q.id = id
|
q.id = id
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetChain set the chainID field of the NotionalLimitQuery struct.
|
||||||
func (q *NotionalLimitQuery) SetChain(chainID vaa.ChainID) *NotionalLimitQuery {
|
func (q *NotionalLimitQuery) SetChain(chainID vaa.ChainID) *NotionalLimitQuery {
|
||||||
q.chainID = chainID
|
q.chainID = chainID
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPagination set the Pagination field of the NotionalLimitQuery struct.
|
||||||
func (q *NotionalLimitQuery) SetPagination(p *pagination.Pagination) *NotionalLimitQuery {
|
func (q *NotionalLimitQuery) SetPagination(p *pagination.Pagination) *NotionalLimitQuery {
|
||||||
q.Pagination = *p
|
q.Pagination = *p
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindNotionalLimit get a list *NotionalLimit.
|
||||||
func (r *Repository) FindNotionalLimit(ctx context.Context, q *NotionalLimitQuery) ([]*NotionalLimit, error) {
|
func (r *Repository) FindNotionalLimit(ctx context.Context, q *NotionalLimitQuery) ([]*NotionalLimit, error) {
|
||||||
// agreggation stages to get notionalLimit for each chainID.
|
// agreggation stages to get notionalLimit for each chainID.
|
||||||
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
||||||
|
@ -259,24 +297,31 @@ func (r *Repository) FindNotionalLimit(ctx context.Context, q *NotionalLimitQuer
|
||||||
// execute aggregate operations.
|
// execute aggregate operations.
|
||||||
cur, err := r.collections.governorConfig.Aggregate(ctx, pipeLine)
|
cur, err := r.collections.governorConfig.Aggregate(ctx, pipeLine)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Aggregate command to get notional limit",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decodes to NotionalLimit.
|
// decodes to NotionalLimit.
|
||||||
var notionalLimits []*NotionalLimit
|
var notionalLimits []*NotionalLimit
|
||||||
err = cur.All(ctx, ¬ionalLimits)
|
err = cur.All(ctx, ¬ionalLimits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed decoding cursor to []*NotionalLimit", zap.Error(err), zap.Any("q", q),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check records exists.
|
// check records exists.
|
||||||
if len(notionalLimits) == 0 {
|
if len(notionalLimits) == 0 {
|
||||||
return nil, errors.New("not found")
|
return nil, errs.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
return notionalLimits, nil
|
return notionalLimits, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetNotionalLimitByChainID get a list *NotionalLimitDetail.
|
||||||
func (r *Repository) GetNotionalLimitByChainID(ctx context.Context, q *NotionalLimitQuery) ([]*NotionalLimitDetail, error) {
|
func (r *Repository) GetNotionalLimitByChainID(ctx context.Context, q *NotionalLimitQuery) ([]*NotionalLimitDetail, error) {
|
||||||
// agreggation stages to get notionalLimit by chainID.
|
// agreggation stages to get notionalLimit by chainID.
|
||||||
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
||||||
|
@ -333,19 +378,26 @@ func (r *Repository) GetNotionalLimitByChainID(ctx context.Context, q *NotionalL
|
||||||
// execute aggregate operations.
|
// execute aggregate operations.
|
||||||
cur, err := r.collections.governorConfig.Aggregate(ctx, pipeLine)
|
cur, err := r.collections.governorConfig.Aggregate(ctx, pipeLine)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Aggregate command to get notional limit by chainID",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode to []NotionalLimitRecord.
|
// decode to []NotionalLimitRecord.
|
||||||
var notionalLimits []*NotionalLimitDetail
|
var notionalLimits []*NotionalLimitDetail
|
||||||
err = cur.All(ctx, ¬ionalLimits)
|
err = cur.All(ctx, ¬ionalLimits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed decoding cursor to []*NotionalLimitDetail", zap.Error(err), zap.Any("q", q),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return notionalLimits, nil
|
return notionalLimits, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAvailableNotional get a list of *NotionalAvailable.
|
||||||
func (r *Repository) GetAvailableNotional(ctx context.Context, q *NotionalLimitQuery) ([]*NotionalAvailable, error) {
|
func (r *Repository) GetAvailableNotional(ctx context.Context, q *NotionalLimitQuery) ([]*NotionalAvailable, error) {
|
||||||
// stage.
|
// stage.
|
||||||
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
||||||
|
@ -421,24 +473,31 @@ func (r *Repository) GetAvailableNotional(ctx context.Context, q *NotionalLimitQ
|
||||||
// execute aggregate operations.
|
// execute aggregate operations.
|
||||||
cur, err := r.collections.governorStatus.Aggregate(ctx, pipeLine)
|
cur, err := r.collections.governorStatus.Aggregate(ctx, pipeLine)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Aggregate command to get available notional",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode to []NotionalLimitRecord.
|
// decode to []NotionalLimitRecord.
|
||||||
var notionalAvailables []*NotionalAvailable
|
var notionalAvailables []*NotionalAvailable
|
||||||
err = cur.All(ctx, ¬ionalAvailables)
|
err = cur.All(ctx, ¬ionalAvailables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed decoding cursor to []*NotionalAvailable", zap.Error(err), zap.Any("q", q),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check exists records
|
// check exists records
|
||||||
if len(notionalAvailables) == 0 {
|
if len(notionalAvailables) == 0 {
|
||||||
return nil, errors.New("not found")
|
return nil, errs.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
return notionalAvailables, nil
|
return notionalAvailables, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAvailableNotionalByChainID get a list of *NotionalAvailableDetail.
|
||||||
func (r *Repository) GetAvailableNotionalByChainID(ctx context.Context, q *NotionalLimitQuery) ([]*NotionalAvailableDetail, error) {
|
func (r *Repository) GetAvailableNotionalByChainID(ctx context.Context, q *NotionalLimitQuery) ([]*NotionalAvailableDetail, error) {
|
||||||
// stage definitions.
|
// stage definitions.
|
||||||
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
||||||
|
@ -497,19 +556,26 @@ func (r *Repository) GetAvailableNotionalByChainID(ctx context.Context, q *Notio
|
||||||
// execute aggregate operations.
|
// execute aggregate operations.
|
||||||
cur, err := r.collections.governorStatus.Aggregate(ctx, pipeLine)
|
cur, err := r.collections.governorStatus.Aggregate(ctx, pipeLine)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Aggregate command to get available notional by chainID",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode to []NotionalLimitRecord.
|
// decode to []NotionalLimitRecord.
|
||||||
var notionalAvailability []*NotionalAvailableDetail
|
var notionalAvailability []*NotionalAvailableDetail
|
||||||
err = cur.All(ctx, ¬ionalAvailability)
|
err = cur.All(ctx, ¬ionalAvailability)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed decoding cursor to []*NotionalAvailableDetail", zap.Error(err), zap.Any("q", q),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return notionalAvailability, nil
|
return notionalAvailability, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMaxNotionalAvailableByChainID get a *MaxNotionalAvailableRecord.
|
||||||
func (r *Repository) GetMaxNotionalAvailableByChainID(ctx context.Context, q *NotionalLimitQuery) (*MaxNotionalAvailableRecord, error) {
|
func (r *Repository) GetMaxNotionalAvailableByChainID(ctx context.Context, q *NotionalLimitQuery) (*MaxNotionalAvailableRecord, error) {
|
||||||
// stage definitions.
|
// stage definitions.
|
||||||
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
||||||
|
@ -577,55 +643,67 @@ func (r *Repository) GetMaxNotionalAvailableByChainID(ctx context.Context, q *No
|
||||||
// execute aggregate operations.
|
// execute aggregate operations.
|
||||||
cur, err := r.collections.governorStatus.Aggregate(ctx, pipeLine)
|
cur, err := r.collections.governorStatus.Aggregate(ctx, pipeLine)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Aggregate command to get maximun available notional by chainID",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode to []NotionalLimitRecord.
|
// decode to []NotionalLimitRecord.
|
||||||
var rows []*MaxNotionalAvailableRecord
|
var rows []*MaxNotionalAvailableRecord
|
||||||
err = cur.All(ctx, &rows)
|
err = cur.All(ctx, &rows)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed decoding cursor to []*MaxNotionalAvailableRecord", zap.Error(err), zap.Any("q", q),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check exists records
|
// check exists records
|
||||||
if len(rows) == 0 {
|
if len(rows) == 0 {
|
||||||
return nil, errors.New("not found")
|
return nil, errs.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(rows) < minGuardianNum {
|
if len(rows) < minGuardianNum {
|
||||||
return nil, errors.New("not found")
|
return nil, errs.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
maxNotionalLimit := rows[minGuardianNum-1]
|
maxNotionalLimit := rows[minGuardianNum-1]
|
||||||
return maxNotionalLimit, nil
|
return maxNotionalLimit, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnqueuedVaaQuery respresent a query for enqueuedVaa queries.
|
||||||
type EnqueuedVaaQuery struct {
|
type EnqueuedVaaQuery struct {
|
||||||
pagination.Pagination
|
pagination.Pagination
|
||||||
id string
|
id string
|
||||||
chainID vaa.ChainID
|
chainID vaa.ChainID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryEnqueuedVaa create a new EnqueuedVaaQuery with default pagination values.
|
||||||
func QueryEnqueuedVaa() *EnqueuedVaaQuery {
|
func QueryEnqueuedVaa() *EnqueuedVaaQuery {
|
||||||
page := pagination.FirstPage()
|
page := pagination.FirstPage()
|
||||||
return &EnqueuedVaaQuery{Pagination: *page}
|
return &EnqueuedVaaQuery{Pagination: *page}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetID set the id field of the EnqueuedVaaQuery struct.
|
||||||
func (q *EnqueuedVaaQuery) SetID(id string) *EnqueuedVaaQuery {
|
func (q *EnqueuedVaaQuery) SetID(id string) *EnqueuedVaaQuery {
|
||||||
q.id = id
|
q.id = id
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetChain set the chainID field of the EnqueuedVaaQuery struct.
|
||||||
func (q *EnqueuedVaaQuery) SetChain(chainID vaa.ChainID) *EnqueuedVaaQuery {
|
func (q *EnqueuedVaaQuery) SetChain(chainID vaa.ChainID) *EnqueuedVaaQuery {
|
||||||
q.chainID = chainID
|
q.chainID = chainID
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPagination set the pagination field of the EnqueuedVaaQuery struct.
|
||||||
func (q *EnqueuedVaaQuery) SetPagination(p *pagination.Pagination) *EnqueuedVaaQuery {
|
func (q *EnqueuedVaaQuery) SetPagination(p *pagination.Pagination) *EnqueuedVaaQuery {
|
||||||
q.Pagination = *p
|
q.Pagination = *p
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetEnqueueVass get a list of *EnqueuedVaas.
|
||||||
func (r *Repository) GetEnqueueVass(ctx context.Context, q *EnqueuedVaaQuery) ([]*EnqueuedVaas, error) {
|
func (r *Repository) GetEnqueueVass(ctx context.Context, q *EnqueuedVaaQuery) ([]*EnqueuedVaas, error) {
|
||||||
// match stage.
|
// match stage.
|
||||||
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
||||||
|
@ -678,7 +756,10 @@ func (r *Repository) GetEnqueueVass(ctx context.Context, q *EnqueuedVaaQuery) ([
|
||||||
|
|
||||||
cur, err := r.collections.governorStatus.Aggregate(ctx, pipeLine)
|
cur, err := r.collections.governorStatus.Aggregate(ctx, pipeLine)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Aggregate command to get enqueued vaas",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var rows []struct {
|
var rows []struct {
|
||||||
|
@ -697,11 +778,14 @@ func (r *Repository) GetEnqueueVass(ctx context.Context, q *EnqueuedVaaQuery) ([
|
||||||
// decode query response.
|
// decode query response.
|
||||||
err = cur.All(ctx, &rows)
|
err = cur.All(ctx, &rows)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed decoding cursor to rows", zap.Error(err), zap.Any("q", q),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(rows) == 0 {
|
if len(rows) == 0 {
|
||||||
return nil, errors.New("not found")
|
return nil, errs.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Change this logic to mongo query code.
|
// TODO: Change this logic to mongo query code.
|
||||||
|
@ -732,7 +816,7 @@ func (r *Repository) GetEnqueueVass(ctx context.Context, q *EnqueuedVaaQuery) ([
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(enqueuedVaas) == 0 {
|
if len(enqueuedVaas) == 0 {
|
||||||
return nil, errors.New("not found")
|
return nil, errs.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// group by chainID.
|
// group by chainID.
|
||||||
|
@ -760,6 +844,7 @@ func (r *Repository) GetEnqueueVass(ctx context.Context, q *EnqueuedVaaQuery) ([
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetEnqueueVassByChainID get a list of *EnqueuedVaaDetail by chainID.
|
||||||
func (r *Repository) GetEnqueueVassByChainID(ctx context.Context, q *EnqueuedVaaQuery) ([]*EnqueuedVaaDetail, error) {
|
func (r *Repository) GetEnqueueVassByChainID(ctx context.Context, q *EnqueuedVaaQuery) ([]*EnqueuedVaaDetail, error) {
|
||||||
// stage definitions.
|
// stage definitions.
|
||||||
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
matchStage1 := bson.D{{Key: "$match", Value: bson.D{}}}
|
||||||
|
@ -823,7 +908,10 @@ func (r *Repository) GetEnqueueVassByChainID(ctx context.Context, q *EnqueuedVaa
|
||||||
|
|
||||||
cur, err := r.collections.governorStatus.Aggregate(ctx, pipeline)
|
cur, err := r.collections.governorStatus.Aggregate(ctx, pipeline)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Aggregate command to get enqueued vaas by chainID",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode query response.
|
// decode query response.
|
||||||
|
@ -840,7 +928,10 @@ func (r *Repository) GetEnqueueVassByChainID(ctx context.Context, q *EnqueuedVaa
|
||||||
}
|
}
|
||||||
err = cur.All(ctx, &rows)
|
err = cur.All(ctx, &rows)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed decoding cursor to rows", zap.Error(err), zap.Any("q", q),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Change this logic to mongo query code.
|
// TODO: Change this logic to mongo query code.
|
||||||
|
@ -871,7 +962,7 @@ func (r *Repository) GetEnqueueVassByChainID(ctx context.Context, q *EnqueuedVaa
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(response) == 0 {
|
if len(response) == 0 {
|
||||||
return nil, errors.New("not found")
|
return nil, errs.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort response by sequence.
|
// sort response by sequence.
|
||||||
|
@ -881,6 +972,7 @@ func (r *Repository) GetEnqueueVassByChainID(ctx context.Context, q *EnqueuedVaa
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetGovernorLimit get a list of *GovernorLimit.
|
||||||
func (r *Repository) GetGovernorLimit(ctx context.Context, q *GovernorQuery) ([]*GovernorLimit, error) {
|
func (r *Repository) GetGovernorLimit(ctx context.Context, q *GovernorQuery) ([]*GovernorLimit, error) {
|
||||||
// lookup.
|
// lookup.
|
||||||
lookupStage1 := bson.D{
|
lookupStage1 := bson.D{
|
||||||
|
@ -1017,19 +1109,25 @@ func (r *Repository) GetGovernorLimit(ctx context.Context, q *GovernorQuery) ([]
|
||||||
// execute aggregate operations.
|
// execute aggregate operations.
|
||||||
cur, err := r.collections.governorConfig.Aggregate(ctx, pipeLine)
|
cur, err := r.collections.governorConfig.Aggregate(ctx, pipeLine)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Aggregate command to get governor limit",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decodes to RawDocRecord.
|
// decodes to RawDocRecord.
|
||||||
var governorLimits []*GovernorLimit
|
var governorLimits []*GovernorLimit
|
||||||
err = cur.All(ctx, &governorLimits)
|
err = cur.All(ctx, &governorLimits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed decoding cursor to []*GovernorLimit", zap.Error(err), zap.Any("q", q),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check exists records
|
// check exists records
|
||||||
if len(governorLimits) == 0 {
|
if len(governorLimits) == 0 {
|
||||||
return nil, errors.New("not found")
|
return nil, errs.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
return governorLimits, nil
|
return governorLimits, nil
|
|
@ -1,11 +1,12 @@
|
||||||
|
// Package governor handle the request of governor data from governor endpoint defined in the api.
|
||||||
package governor
|
package governor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/pagination"
|
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/services"
|
"github.com/wormhole-foundation/wormhole-explorer/api/response"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,118 +21,118 @@ func NewService(dao *Repository, logger *zap.Logger) *Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindGovernorConfig get a list of governor configurations.
|
// FindGovernorConfig get a list of governor configurations.
|
||||||
func (s *Service) FindGovernorConfig(ctx context.Context, p *pagination.Pagination) (*services.Response[[]*GovConfig], error) {
|
func (s *Service) FindGovernorConfig(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*GovConfig], error) {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
p = pagination.FirstPage()
|
p = pagination.FirstPage()
|
||||||
}
|
}
|
||||||
query := QueryGovernor().SetPagination(p)
|
query := QueryGovernor().SetPagination(p)
|
||||||
govConfigs, err := s.repo.FindGovConfigurations(ctx, query)
|
govConfigs, err := s.repo.FindGovConfigurations(ctx, query)
|
||||||
res := services.Response[[]*GovConfig]{Data: govConfigs, Error: err}
|
res := response.Response[[]*GovConfig]{Data: govConfigs}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindGovernorConfigByGuardianAddress get a governor configuration by guardianAddress.
|
// FindGovernorConfigByGuardianAddress get a governor configuration by guardianAddress.
|
||||||
func (s *Service) FindGovernorConfigByGuardianAddress(ctx context.Context, guardianAddress string, p *pagination.Pagination) (*services.Response[*GovConfig], error) {
|
func (s *Service) FindGovernorConfigByGuardianAddress(ctx context.Context, guardianAddress string, p *pagination.Pagination) (*response.Response[*GovConfig], error) {
|
||||||
query := QueryGovernor().SetID(guardianAddress).SetPagination(p)
|
query := QueryGovernor().SetID(guardianAddress).SetPagination(p)
|
||||||
govConfig, err := s.repo.FindGovConfiguration(ctx, query)
|
govConfig, err := s.repo.FindGovConfiguration(ctx, query)
|
||||||
res := services.Response[*GovConfig]{Data: govConfig, Error: err}
|
res := response.Response[*GovConfig]{Data: govConfig}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindGovernorStatus get a list of governor status.
|
// FindGovernorStatus get a list of governor status.
|
||||||
func (s *Service) FindGovernorStatus(ctx context.Context, p *pagination.Pagination) (*services.Response[[]*GovStatus], error) {
|
func (s *Service) FindGovernorStatus(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*GovStatus], error) {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
p = pagination.FirstPage()
|
p = pagination.FirstPage()
|
||||||
}
|
}
|
||||||
query := QueryGovernor().SetPagination(p)
|
query := QueryGovernor().SetPagination(p)
|
||||||
govStatus, err := s.repo.FindGovernorStatus(ctx, query)
|
govStatus, err := s.repo.FindGovernorStatus(ctx, query)
|
||||||
res := services.Response[[]*GovStatus]{Data: govStatus, Error: err}
|
res := response.Response[[]*GovStatus]{Data: govStatus}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindGovernorStatusByGuardianAddress get a governor status by guardianAddress.
|
// FindGovernorStatusByGuardianAddress get a governor status by guardianAddress.
|
||||||
func (s *Service) FindGovernorStatusByGuardianAddress(ctx context.Context, guardianAddress string, p *pagination.Pagination) (*services.Response[*GovStatus], error) {
|
func (s *Service) FindGovernorStatusByGuardianAddress(ctx context.Context, guardianAddress string, p *pagination.Pagination) (*response.Response[*GovStatus], error) {
|
||||||
query := QueryGovernor().SetID(guardianAddress).SetPagination(p)
|
query := QueryGovernor().SetID(guardianAddress).SetPagination(p)
|
||||||
govStatus, err := s.repo.FindOneGovernorStatus(ctx, query)
|
govStatus, err := s.repo.FindOneGovernorStatus(ctx, query)
|
||||||
res := services.Response[*GovStatus]{Data: govStatus, Error: err}
|
res := response.Response[*GovStatus]{Data: govStatus}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindNotionalLimit get a notional limit for each chainID.
|
// FindNotionalLimit get a notional limit for each chainID.
|
||||||
func (s *Service) FindNotionalLimit(ctx context.Context, p *pagination.Pagination) (*services.Response[[]*NotionalLimit], error) {
|
func (s *Service) FindNotionalLimit(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*NotionalLimit], error) {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
p = pagination.FirstPage()
|
p = pagination.FirstPage()
|
||||||
}
|
}
|
||||||
query := QueryNotionalLimit().SetPagination(p)
|
query := QueryNotionalLimit().SetPagination(p)
|
||||||
notionalLimit, err := s.repo.FindNotionalLimit(ctx, query)
|
notionalLimit, err := s.repo.FindNotionalLimit(ctx, query)
|
||||||
res := services.Response[[]*NotionalLimit]{Data: notionalLimit, Error: err}
|
res := response.Response[[]*NotionalLimit]{Data: notionalLimit}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNotionalLimitByChainID get a notional limit by chainID.
|
// GetNotionalLimitByChainID get a notional limit by chainID.
|
||||||
func (s *Service) GetNotionalLimitByChainID(ctx context.Context, p *pagination.Pagination, chainID vaa.ChainID) (*services.Response[[]*NotionalLimitDetail], error) {
|
func (s *Service) GetNotionalLimitByChainID(ctx context.Context, p *pagination.Pagination, chainID vaa.ChainID) (*response.Response[[]*NotionalLimitDetail], error) {
|
||||||
query := QueryNotionalLimit().SetPagination(p).SetChain(chainID)
|
query := QueryNotionalLimit().SetPagination(p).SetChain(chainID)
|
||||||
notionalLimit, err := s.repo.GetNotionalLimitByChainID(ctx, query)
|
notionalLimit, err := s.repo.GetNotionalLimitByChainID(ctx, query)
|
||||||
res := services.Response[[]*NotionalLimitDetail]{Data: notionalLimit, Error: err}
|
res := response.Response[[]*NotionalLimitDetail]{Data: notionalLimit}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAvailableNotional get a available notional for each chainID.
|
// GetAvailableNotional get a available notional for each chainID.
|
||||||
func (s *Service) GetAvailableNotional(ctx context.Context, p *pagination.Pagination) (*services.Response[[]*NotionalAvailable], error) {
|
func (s *Service) GetAvailableNotional(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*NotionalAvailable], error) {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
p = pagination.FirstPage()
|
p = pagination.FirstPage()
|
||||||
}
|
}
|
||||||
query := QueryNotionalLimit().SetPagination(p)
|
query := QueryNotionalLimit().SetPagination(p)
|
||||||
notionalAvailability, err := s.repo.GetAvailableNotional(ctx, query)
|
notionalAvailability, err := s.repo.GetAvailableNotional(ctx, query)
|
||||||
res := services.Response[[]*NotionalAvailable]{Data: notionalAvailability, Error: err}
|
res := response.Response[[]*NotionalAvailable]{Data: notionalAvailability}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAvailableNotionalByChainID get a available notional by chainID.
|
// GetAvailableNotionalByChainID get a available notional by chainID.
|
||||||
func (s *Service) GetAvailableNotionalByChainID(ctx context.Context, p *pagination.Pagination, chainID vaa.ChainID) (*services.Response[[]*NotionalAvailableDetail], error) {
|
func (s *Service) GetAvailableNotionalByChainID(ctx context.Context, p *pagination.Pagination, chainID vaa.ChainID) (*response.Response[[]*NotionalAvailableDetail], error) {
|
||||||
query := QueryNotionalLimit().SetPagination(p).SetChain(chainID)
|
query := QueryNotionalLimit().SetPagination(p).SetChain(chainID)
|
||||||
notionaLAvailability, err := s.repo.GetAvailableNotionalByChainID(ctx, query)
|
notionaLAvailability, err := s.repo.GetAvailableNotionalByChainID(ctx, query)
|
||||||
res := services.Response[[]*NotionalAvailableDetail]{Data: notionaLAvailability, Error: err}
|
res := response.Response[[]*NotionalAvailableDetail]{Data: notionaLAvailability}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMaxNotionalAvailableByChainID get a maximun notional value by chainID.
|
// GetMaxNotionalAvailableByChainID get a maximun notional value by chainID.
|
||||||
func (s *Service) GetMaxNotionalAvailableByChainID(ctx context.Context, p *pagination.Pagination, chainID vaa.ChainID) (*services.Response[*MaxNotionalAvailableRecord], error) {
|
func (s *Service) GetMaxNotionalAvailableByChainID(ctx context.Context, p *pagination.Pagination, chainID vaa.ChainID) (*response.Response[*MaxNotionalAvailableRecord], error) {
|
||||||
query := QueryNotionalLimit().SetPagination(p).SetChain(chainID)
|
query := QueryNotionalLimit().SetPagination(p).SetChain(chainID)
|
||||||
maxNotionaLAvailable, err := s.repo.GetMaxNotionalAvailableByChainID(ctx, query)
|
maxNotionaLAvailable, err := s.repo.GetMaxNotionalAvailableByChainID(ctx, query)
|
||||||
res := services.Response[*MaxNotionalAvailableRecord]{Data: maxNotionaLAvailable, Error: err}
|
res := response.Response[*MaxNotionalAvailableRecord]{Data: maxNotionaLAvailable}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEnqueueVass.
|
// GetEnqueueVaas get all the enqueued vaa.
|
||||||
func (s *Service) GetEnqueueVass(ctx context.Context, p *pagination.Pagination) (*services.Response[[]*EnqueuedVaas], error) {
|
func (s *Service) GetEnqueueVass(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*EnqueuedVaas], error) {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
p = pagination.FirstPage()
|
p = pagination.FirstPage()
|
||||||
}
|
}
|
||||||
query := QueryEnqueuedVaa().SetPagination(p)
|
query := QueryEnqueuedVaa().SetPagination(p)
|
||||||
enqueuedVaaResponse, err := s.repo.GetEnqueueVass(ctx, query)
|
enqueuedVaaResponse, err := s.repo.GetEnqueueVass(ctx, query)
|
||||||
res := services.Response[[]*EnqueuedVaas]{Data: enqueuedVaaResponse, Error: err}
|
res := response.Response[[]*EnqueuedVaas]{Data: enqueuedVaaResponse}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEnqueueVassByChainID by chainID.
|
// GetEnqueueVassByChainID get enequeued vaa by chainID.
|
||||||
func (s *Service) GetEnqueueVassByChainID(ctx context.Context, p *pagination.Pagination, chainID vaa.ChainID) (*services.Response[[]*EnqueuedVaaDetail], error) {
|
func (s *Service) GetEnqueueVassByChainID(ctx context.Context, p *pagination.Pagination, chainID vaa.ChainID) (*response.Response[[]*EnqueuedVaaDetail], error) {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
p = pagination.FirstPage()
|
p = pagination.FirstPage()
|
||||||
}
|
}
|
||||||
query := QueryEnqueuedVaa().SetPagination(p).SetChain(chainID)
|
query := QueryEnqueuedVaa().SetPagination(p).SetChain(chainID)
|
||||||
enqueuedVaaRecord, err := s.repo.GetEnqueueVassByChainID(ctx, query)
|
enqueuedVaaRecord, err := s.repo.GetEnqueueVassByChainID(ctx, query)
|
||||||
res := services.Response[[]*EnqueuedVaaDetail]{Data: enqueuedVaaRecord, Error: err}
|
res := response.Response[[]*EnqueuedVaaDetail]{Data: enqueuedVaaRecord}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetGovernorLimit get governor limit.
|
// GetGovernorLimit get governor limit.
|
||||||
func (s *Service) GetGovernorLimit(ctx context.Context, p *pagination.Pagination) (*services.Response[[]*GovernorLimit], error) {
|
func (s *Service) GetGovernorLimit(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*GovernorLimit], error) {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
p = pagination.FirstPage()
|
p = pagination.FirstPage()
|
||||||
}
|
}
|
||||||
query := QueryGovernor().SetPagination(p)
|
query := QueryGovernor().SetPagination(p)
|
||||||
governorLimit, err := s.repo.GetGovernorLimit(ctx, query)
|
governorLimit, err := s.repo.GetGovernorLimit(ctx, query)
|
||||||
res := services.Response[[]*GovernorLimit]{Data: governorLimit, Error: err}
|
res := response.Response[[]*GovernorLimit]{Data: governorLimit}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
|
@ -1,19 +1,19 @@
|
||||||
|
// Package observations handle the request of observations data from governor endpoint defined in the api.
|
||||||
package observations
|
package observations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/errors"
|
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/middleware"
|
"github.com/wormhole-foundation/wormhole-explorer/api/middleware"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/pagination"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Controller definition.
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
srv *Service
|
srv *Service
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewController create a new controler.
|
||||||
func NewController(srv *Service, logger *zap.Logger) *Controller {
|
func NewController(srv *Service, logger *zap.Logger) *Controller {
|
||||||
return &Controller{
|
return &Controller{
|
||||||
srv: srv,
|
srv: srv,
|
||||||
|
@ -21,8 +21,9 @@ func NewController(srv *Service, logger *zap.Logger) *Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindAll handler for the endpoint /observations/.
|
||||||
func (c *Controller) FindAll(ctx *fiber.Ctx) error {
|
func (c *Controller) FindAll(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
obs, err := c.srv.FindAll(ctx.Context(), p)
|
obs, err := c.srv.FindAll(ctx.Context(), p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -30,9 +31,13 @@ func (c *Controller) FindAll(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(obs)
|
return ctx.JSON(obs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindAllByChain handler for the endpoint /observations/:chain.
|
||||||
func (c *Controller) FindAllByChain(ctx *fiber.Ctx) error {
|
func (c *Controller) FindAllByChain(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
chainID, err := middleware.ExtractChainID(ctx)
|
chainID, err := middleware.ExtractChainID(ctx, c.logger)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
obs, err := c.srv.FindByChain(ctx.Context(), chainID, p)
|
obs, err := c.srv.FindByChain(ctx.Context(), chainID, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -40,12 +45,14 @@ func (c *Controller) FindAllByChain(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(obs)
|
return ctx.JSON(obs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindAllByEmitter handler for the endpoint /observations/:chain/:emitter.
|
||||||
func (c *Controller) FindAllByEmitter(ctx *fiber.Ctx) error {
|
func (c *Controller) FindAllByEmitter(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
chainID, addr, _, err := middleware.ExtractVAAParams(ctx)
|
chainID, addr, err := middleware.ExtractVAAChainIDEmitter(ctx, c.logger)
|
||||||
if errors.IsOf(err, middleware.ErrMalformedChain, middleware.ErrMalformedAddr) {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
obs, err := c.srv.FindByEmitter(ctx.Context(), chainID, addr, p)
|
obs, err := c.srv.FindByEmitter(ctx.Context(), chainID, addr, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -53,9 +60,10 @@ func (c *Controller) FindAllByEmitter(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(obs)
|
return ctx.JSON(obs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindAllByVAA handler for the endpoint /observations/:chain/:emitter/:sequence
|
||||||
func (c *Controller) FindAllByVAA(ctx *fiber.Ctx) error {
|
func (c *Controller) FindAllByVAA(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
chainID, addr, seq, err := middleware.ExtractVAAParams(ctx)
|
chainID, addr, seq, err := middleware.ExtractVAAParams(ctx, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -66,18 +74,21 @@ func (c *Controller) FindAllByVAA(ctx *fiber.Ctx) error {
|
||||||
return ctx.JSON(obs)
|
return ctx.JSON(obs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindOne handler for the endpoint /observations/:chain/:emitter/:sequence/:signer/:hash
|
||||||
func (c *Controller) FindOne(ctx *fiber.Ctx) error {
|
func (c *Controller) FindOne(ctx *fiber.Ctx) error {
|
||||||
chainID, addr, seq, err := middleware.ExtractVAAParams(ctx)
|
chainID, addr, seq, err := middleware.ExtractVAAParams(ctx, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
signer := ctx.Params("signer")
|
signerAddr, err := middleware.ExtractObservationSigner(ctx, c.logger)
|
||||||
signerAddr, err := vaa.StringToAddress(signer)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
hash := ctx.Params("hash")
|
hash, err := middleware.ExtractObservationHash(ctx, c.logger)
|
||||||
obs, err := c.srv.FindOne(ctx.Context(), chainID, addr, seq, &signerAddr, []byte(hash))
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
obs, err := c.srv.FindOne(ctx.Context(), chainID, addr, seq, signerAddr, []byte(hash))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
|
@ -1,10 +1,13 @@
|
||||||
|
// Package observations handle the request of observations data from governor endpoint defined in the api.
|
||||||
package observations
|
package observations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ObservationDoc represent an observation document.
|
||||||
type ObservationDoc struct {
|
type ObservationDoc struct {
|
||||||
ID string `bson:"_id" json:"id"`
|
ID string `bson:"_id" json:"id"`
|
||||||
Version uint8 `bson:"version" json:"version"`
|
Version uint8 `bson:"version" json:"version"`
|
||||||
|
@ -15,7 +18,6 @@ type ObservationDoc struct {
|
||||||
TxHash []byte `bson:"txHash" json:"txHash"`
|
TxHash []byte `bson:"txHash" json:"txHash"`
|
||||||
GuardianAddr string `bson:"guardianAddr" json:"guardianAddr"`
|
GuardianAddr string `bson:"guardianAddr" json:"guardianAddr"`
|
||||||
Signature []byte `bson:"signature" json:"signature"`
|
Signature []byte `bson:"signature" json:"signature"`
|
||||||
|
UpdatedAt *time.Time `bson:"updatedAt" json:"updatedAt"`
|
||||||
UpdatedAt *time.Time `bson:"updatedAt" json:"updatedAt"`
|
IndexedAt *time.Time `bson:"indexedAt" json:"indexedAt"`
|
||||||
IndexedAt *time.Time `bson:"indexedAt" json:"indexedAt"`
|
|
||||||
}
|
}
|
|
@ -1,16 +1,21 @@
|
||||||
|
// Package observations handle the request of observations data from governor endpoint defined in the api.
|
||||||
package observations
|
package observations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"fmt"
|
||||||
|
|
||||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/pagination"
|
"github.com/pkg/errors"
|
||||||
|
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
|
||||||
|
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Repository definition.
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
db *mongo.Database
|
db *mongo.Database
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
|
@ -19,6 +24,7 @@ type Repository struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewRepository create a new Repository.
|
||||||
func NewRepository(db *mongo.Database, logger *zap.Logger) *Repository {
|
func NewRepository(db *mongo.Database, logger *zap.Logger) *Repository {
|
||||||
return &Repository{db: db,
|
return &Repository{db: db,
|
||||||
logger: logger.With(zap.String("module", "ObservationsRepository")),
|
logger: logger.With(zap.String("module", "ObservationsRepository")),
|
||||||
|
@ -26,6 +32,8 @@ func NewRepository(db *mongo.Database, logger *zap.Logger) *Repository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find get a list of ObservationDoc pointers.
|
||||||
|
// The input parameter [q *ObservationQuery] define the filters to apply in the query.
|
||||||
func (r *Repository) Find(ctx context.Context, q *ObservationQuery) ([]*ObservationDoc, error) {
|
func (r *Repository) Find(ctx context.Context, q *ObservationQuery) ([]*ObservationDoc, error) {
|
||||||
if q == nil {
|
if q == nil {
|
||||||
q = Query()
|
q = Query()
|
||||||
|
@ -33,32 +41,43 @@ func (r *Repository) Find(ctx context.Context, q *ObservationQuery) ([]*Observat
|
||||||
sort := bson.D{{q.SortBy, q.GetSortInt()}}
|
sort := bson.D{{q.SortBy, q.GetSortInt()}}
|
||||||
cur, err := r.collections.observations.Find(ctx, q.toBSON(), options.Find().SetLimit(q.PageSize).SetSkip(q.Offset).SetSort(sort))
|
cur, err := r.collections.observations.Find(ctx, q.toBSON(), options.Find().SetLimit(q.PageSize).SetSkip(q.Offset).SetSort(sort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Find command to get observations",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
var obs []*ObservationDoc
|
var obs []*ObservationDoc
|
||||||
err = cur.All(ctx, &obs)
|
err = cur.All(ctx, &obs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed decoding cursor to []*ObservationDoc", zap.Error(err), zap.Any("q", q),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
return obs, err
|
return obs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
// Find get ObservationDoc pointer.
|
||||||
ErrWrongQuery = errors.New("MALFORMED_QUERY")
|
// The input parameter [q *ObservationQuery] define the filters to apply in the query.
|
||||||
)
|
|
||||||
|
|
||||||
func (r *Repository) FindOne(ctx context.Context, q *ObservationQuery) (*ObservationDoc, error) {
|
func (r *Repository) FindOne(ctx context.Context, q *ObservationQuery) (*ObservationDoc, error) {
|
||||||
if q == nil {
|
if q == nil {
|
||||||
return nil, ErrWrongQuery
|
return nil, errs.ErrMalformedQuery
|
||||||
}
|
}
|
||||||
var obs ObservationDoc
|
var obs ObservationDoc
|
||||||
err := r.collections.observations.FindOne(ctx, q.toBSON()).Decode(&obs)
|
err := r.collections.observations.FindOne(ctx, q.toBSON()).Decode(&obs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
if errors.Is(err, mongo.ErrNoDocuments) {
|
||||||
|
return nil, errs.ErrNotFound
|
||||||
|
}
|
||||||
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute FindOne command to get observations",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
return &obs, err
|
return &obs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ObservationQuery respresent a query for the observation mongodb document.
|
||||||
type ObservationQuery struct {
|
type ObservationQuery struct {
|
||||||
pagination.Pagination
|
pagination.Pagination
|
||||||
chainId vaa.ChainID
|
chainId vaa.ChainID
|
||||||
|
@ -69,36 +88,43 @@ type ObservationQuery struct {
|
||||||
uint64
|
uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Query create a new ObservationQuery with default pagination vaues.
|
||||||
func Query() *ObservationQuery {
|
func Query() *ObservationQuery {
|
||||||
page := pagination.FirstPage()
|
page := pagination.FirstPage()
|
||||||
return &ObservationQuery{Pagination: *page}
|
return &ObservationQuery{Pagination: *page}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetEmitter set the chainId field of the ObservationQuery struct.
|
||||||
func (q *ObservationQuery) SetChain(chainID vaa.ChainID) *ObservationQuery {
|
func (q *ObservationQuery) SetChain(chainID vaa.ChainID) *ObservationQuery {
|
||||||
q.chainId = chainID
|
q.chainId = chainID
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetEmitter set the emitter field of the ObservationQuery struct.
|
||||||
func (q *ObservationQuery) SetEmitter(emitter string) *ObservationQuery {
|
func (q *ObservationQuery) SetEmitter(emitter string) *ObservationQuery {
|
||||||
q.emitter = emitter
|
q.emitter = emitter
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSequence set the sequence field of the ObservationQuery struct.
|
||||||
func (q *ObservationQuery) SetSequence(seq uint64) *ObservationQuery {
|
func (q *ObservationQuery) SetSequence(seq uint64) *ObservationQuery {
|
||||||
q.sequence = seq
|
q.sequence = seq
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetGuardianAddr set the guardianAddr field of the ObservationQuery struct.
|
||||||
func (q *ObservationQuery) SetGuardianAddr(guardianAddr string) *ObservationQuery {
|
func (q *ObservationQuery) SetGuardianAddr(guardianAddr string) *ObservationQuery {
|
||||||
q.guardianAddr = guardianAddr
|
q.guardianAddr = guardianAddr
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetHash set the hash field of the ObservationQuery struct.
|
||||||
func (q *ObservationQuery) SetHash(hash []byte) *ObservationQuery {
|
func (q *ObservationQuery) SetHash(hash []byte) *ObservationQuery {
|
||||||
q.hash = hash
|
q.hash = hash
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPagination set the pagination field of the ObservationQuery struct.
|
||||||
func (q *ObservationQuery) SetPagination(p *pagination.Pagination) *ObservationQuery {
|
func (q *ObservationQuery) SetPagination(p *pagination.Pagination) *ObservationQuery {
|
||||||
q.Pagination = *p
|
q.Pagination = *p
|
||||||
return q
|
return q
|
|
@ -1,40 +1,49 @@
|
||||||
|
// Package observations handle the request of observations data from governor endpoint defined in the api.
|
||||||
package observations
|
package observations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/pagination"
|
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Service definition.
|
||||||
type Service struct {
|
type Service struct {
|
||||||
repo *Repository
|
repo *Repository
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewService create a new Service.
|
||||||
func NewService(dao *Repository, logger *zap.Logger) *Service {
|
func NewService(dao *Repository, logger *zap.Logger) *Service {
|
||||||
return &Service{repo: dao, logger: logger.With(zap.String("module", "ObservationsService"))}
|
return &Service{repo: dao, logger: logger.With(zap.String("module", "ObservationsService"))}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindAll get all the observations.
|
||||||
func (s *Service) FindAll(ctx context.Context, p *pagination.Pagination) ([]*ObservationDoc, error) {
|
func (s *Service) FindAll(ctx context.Context, p *pagination.Pagination) ([]*ObservationDoc, error) {
|
||||||
return s.repo.Find(ctx, Query().SetPagination(p))
|
return s.repo.Find(ctx, Query().SetPagination(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindByChain get all the observations by chainID.
|
||||||
func (s *Service) FindByChain(ctx context.Context, chain vaa.ChainID, p *pagination.Pagination) ([]*ObservationDoc, error) {
|
func (s *Service) FindByChain(ctx context.Context, chain vaa.ChainID, p *pagination.Pagination) ([]*ObservationDoc, error) {
|
||||||
query := Query().SetChain(chain).SetPagination(p)
|
query := Query().SetChain(chain).SetPagination(p)
|
||||||
return s.repo.Find(ctx, query)
|
return s.repo.Find(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindByEmitter get all the observations by chainID and emitter address.
|
||||||
func (s *Service) FindByEmitter(ctx context.Context, chain vaa.ChainID, emitter *vaa.Address, p *pagination.Pagination) ([]*ObservationDoc, error) {
|
func (s *Service) FindByEmitter(ctx context.Context, chain vaa.ChainID, emitter *vaa.Address, p *pagination.Pagination) ([]*ObservationDoc, error) {
|
||||||
query := Query().SetChain(chain).SetEmitter(emitter.String()).SetPagination(p)
|
query := Query().SetChain(chain).SetEmitter(emitter.String()).SetPagination(p)
|
||||||
return s.repo.Find(ctx, query)
|
return s.repo.Find(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindByVAA get all the observations for a VAA (chainID, emitter addrress and sequence number).
|
||||||
func (s *Service) FindByVAA(ctx context.Context, chain vaa.ChainID, emitter *vaa.Address, seq uint64, p *pagination.Pagination) ([]*ObservationDoc, error) {
|
func (s *Service) FindByVAA(ctx context.Context, chain vaa.ChainID, emitter *vaa.Address, seq uint64, p *pagination.Pagination) ([]*ObservationDoc, error) {
|
||||||
query := Query().SetChain(chain).SetEmitter(emitter.String()).SetSequence(seq).SetPagination(p)
|
query := Query().SetChain(chain).SetEmitter(emitter.String()).SetSequence(seq).SetPagination(p)
|
||||||
return s.repo.Find(ctx, query)
|
return s.repo.Find(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindOne get a observation by chainID, emitter address, sequence, signer address and hash.
|
||||||
func (s *Service) FindOne(ctx context.Context, chainID vaa.ChainID, emitterAddr *vaa.Address, seq uint64, signerAddr *vaa.Address, hash []byte) (*ObservationDoc, error) {
|
func (s *Service) FindOne(ctx context.Context, chainID vaa.ChainID, emitterAddr *vaa.Address, seq uint64, signerAddr *vaa.Address, hash []byte) (*ObservationDoc, error) {
|
||||||
query := Query().SetChain(chainID).SetEmitter(emitterAddr.String()).SetSequence(seq).SetGuardianAddr(signerAddr.String()).SetHash(hash)
|
query := Query().SetChain(chainID).SetEmitter(emitterAddr.String()).SetSequence(seq).SetGuardianAddr(signerAddr.String()).SetHash(hash)
|
||||||
return s.repo.FindOne(ctx, query)
|
return s.repo.FindOne(ctx, query)
|
|
@ -1,83 +1,86 @@
|
||||||
|
// Package observations handle the request of VAA data from governor endpoint defined in the api.
|
||||||
package vaa
|
package vaa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/errors"
|
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/middleware"
|
"github.com/wormhole-foundation/wormhole-explorer/api/middleware"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/pagination"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Controller definition.
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
srv *Service
|
srv *Service
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewController create a new controler.
|
||||||
func NewController(serv *Service, logger *zap.Logger) *Controller {
|
func NewController(serv *Service, logger *zap.Logger) *Controller {
|
||||||
return &Controller{srv: serv, logger: logger.With(zap.String("module", "VaaController"))}
|
return &Controller{srv: serv, logger: logger.With(zap.String("module", "VaaController"))}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindAll handler for the endpoint /vaas/.
|
||||||
func (c *Controller) FindAll(ctx *fiber.Ctx) error {
|
func (c *Controller) FindAll(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
vaas, err := c.srv.FindAll(ctx.Context(), p)
|
vaas, err := c.srv.FindAll(ctx.Context(), p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("error finding vaas: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
return ctx.JSON(vaas)
|
return ctx.JSON(vaas)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindByChain handler for the endpoint /vaas/:chain.
|
||||||
func (c *Controller) FindByChain(ctx *fiber.Ctx) error {
|
func (c *Controller) FindByChain(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
|
||||||
chainID, err := middleware.ExtractChainID(ctx)
|
fmt.Println(ctx.Locals("requestid"))
|
||||||
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
|
chainID, err := middleware.ExtractChainID(ctx, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
vaas, err := c.srv.FindByChain(ctx.Context(), chainID, p)
|
vaas, err := c.srv.FindByChain(ctx.Context(), chainID, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("error finding vaas: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
return ctx.JSON(vaas)
|
return ctx.JSON(vaas)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindByEmitter handler for the endpoint /vaas/:chain/:emitter.
|
||||||
func (c *Controller) FindByEmitter(ctx *fiber.Ctx) error {
|
func (c *Controller) FindByEmitter(ctx *fiber.Ctx) error {
|
||||||
p := pagination.GetFromContext(ctx)
|
p := middleware.GetPaginationFromContext(ctx)
|
||||||
chainID, emitter, _, err := middleware.ExtractVAAParams(ctx)
|
chainID, emitter, err := middleware.ExtractVAAChainIDEmitter(ctx, c.logger)
|
||||||
if errors.IsOf(err, middleware.ErrMalformedChain, middleware.ErrMalformedAddr) {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
vaas, err := c.srv.FindByEmitter(ctx.Context(), chainID, *emitter, p)
|
vaas, err := c.srv.FindByEmitter(ctx.Context(), chainID, *emitter, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//TODO logging
|
return err
|
||||||
fmt.Printf("error finding vaas: %v", err)
|
|
||||||
}
|
}
|
||||||
return ctx.JSON(vaas)
|
return ctx.JSON(vaas)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindById handler for the endpoint /vaas/:chain/:emitter/:sequence/:signer/:hash.
|
||||||
func (c *Controller) FindById(ctx *fiber.Ctx) error {
|
func (c *Controller) FindById(ctx *fiber.Ctx) error {
|
||||||
chainID, emitter, seq, err := middleware.ExtractVAAParams(ctx)
|
chainID, emitter, seq, err := middleware.ExtractVAAParams(ctx, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
vaa, err := c.srv.FindById(ctx.Context(), chainID, *emitter, seq)
|
vaa, err := c.srv.FindById(ctx.Context(), chainID, *emitter, seq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//TODO logging
|
return err
|
||||||
fmt.Printf("error finding vaa: %v", err)
|
|
||||||
}
|
}
|
||||||
return ctx.JSON(vaa)
|
return ctx.JSON(vaa)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindSignedVAAByID get a signedVAA []byte from a chainID, emitter address and sequence.
|
// FindSignedVAAByID get a signedVAA []byte from a chainID, emitter address and sequence.
|
||||||
func (c *Controller) FindSignedVAAByID(ctx *fiber.Ctx) error {
|
func (c *Controller) FindSignedVAAByID(ctx *fiber.Ctx) error {
|
||||||
chainID, emitter, seq, err := middleware.ExtractVAAParams(ctx)
|
chainID, emitter, seq, err := middleware.ExtractVAAParams(ctx, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: Handle InvalidArgument code (3) in the response.
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
vaa, err := c.srv.FindById(ctx.Context(), chainID, *emitter, seq)
|
vaa, err := c.srv.FindById(ctx.Context(), chainID, *emitter, seq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: handle not found(5) and internal(13) response code.
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response := struct {
|
response := struct {
|
|
@ -1,10 +1,12 @@
|
||||||
package vaa
|
package vaa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// VaaDoc represent an vaa document.
|
||||||
type VaaDoc struct {
|
type VaaDoc struct {
|
||||||
ID string `bson:"_id" json:"id"`
|
ID string `bson:"_id" json:"id"`
|
||||||
Version uint8 `bson:"version" json:"version"`
|
Version uint8 `bson:"version" json:"version"`
|
|
@ -2,15 +2,19 @@ package vaa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/pagination"
|
"github.com/pkg/errors"
|
||||||
|
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
|
||||||
|
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Repository definition
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
db *mongo.Database
|
db *mongo.Database
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
|
@ -20,6 +24,7 @@ type Repository struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewRepository create a new Repository.
|
||||||
func NewRepository(db *mongo.Database, logger *zap.Logger) *Repository {
|
func NewRepository(db *mongo.Database, logger *zap.Logger) *Repository {
|
||||||
return &Repository{db: db,
|
return &Repository{db: db,
|
||||||
logger: logger.With(zap.String("module", "VaaRepository")),
|
logger: logger.With(zap.String("module", "VaaRepository")),
|
||||||
|
@ -29,6 +34,8 @@ func NewRepository(db *mongo.Database, logger *zap.Logger) *Repository {
|
||||||
}{vaas: db.Collection("vaas"), invalidVaas: db.Collection("invalid_vaas")}}
|
}{vaas: db.Collection("vaas"), invalidVaas: db.Collection("invalid_vaas")}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find get a list of *VaaDoc.
|
||||||
|
// The input parameter [q *VaaQuery] define the filters to apply in the query.
|
||||||
func (r *Repository) Find(ctx context.Context, q *VaaQuery) ([]*VaaDoc, error) {
|
func (r *Repository) Find(ctx context.Context, q *VaaQuery) ([]*VaaDoc, error) {
|
||||||
if q == nil {
|
if q == nil {
|
||||||
q = Query()
|
q = Query()
|
||||||
|
@ -36,22 +43,37 @@ func (r *Repository) Find(ctx context.Context, q *VaaQuery) ([]*VaaDoc, error) {
|
||||||
sort := bson.D{{q.SortBy, q.GetSortInt()}}
|
sort := bson.D{{q.SortBy, q.GetSortInt()}}
|
||||||
cur, err := r.collections.vaas.Find(ctx, q.toBSON(), options.Find().SetLimit(q.PageSize).SetSkip(q.Offset).SetSort(sort))
|
cur, err := r.collections.vaas.Find(ctx, q.toBSON(), options.Find().SetLimit(q.PageSize).SetSkip(q.Offset).SetSort(sort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Find command to get vaas",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
var vaas []*VaaDoc
|
var vaas []*VaaDoc
|
||||||
err = cur.All(ctx, &vaas)
|
err = cur.All(ctx, &vaas)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed decoding cursor to []*VaaDoc", zap.Error(err), zap.Any("q", q),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
return vaas, err
|
return vaas, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindOne get *VaaDoc.
|
||||||
|
// The input parameter [q *VaaQuery] define the filters to apply in the query.
|
||||||
func (r *Repository) FindOne(ctx context.Context, q *VaaQuery) (*VaaDoc, error) {
|
func (r *Repository) FindOne(ctx context.Context, q *VaaQuery) (*VaaDoc, error) {
|
||||||
var vaaDoc VaaDoc
|
var vaaDoc VaaDoc
|
||||||
err := r.collections.vaas.FindOne(ctx, q.toBSON()).Decode(&vaaDoc)
|
err := r.collections.vaas.FindOne(ctx, q.toBSON()).Decode(&vaaDoc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
if errors.Is(err, mongo.ErrNoDocuments) {
|
||||||
|
return nil, errs.ErrNotFound
|
||||||
|
}
|
||||||
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute FindOne command to get vaas",
|
||||||
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &vaaDoc, err
|
return &vaaDoc, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +86,9 @@ func (r *Repository) FindStats(ctx context.Context) ([]*VaaStats, error) {
|
||||||
}
|
}
|
||||||
c, err := r.collections.vaas.Aggregate(ctx, mongo.Pipeline{group})
|
c, err := r.collections.vaas.Aggregate(ctx, mongo.Pipeline{group})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
|
r.logger.Error("failed execute Aggregate command to get vaa stats",
|
||||||
|
zap.Error(err), zap.String("requestID", requestID))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var stats []*VaaStats
|
var stats []*VaaStats
|
||||||
|
@ -71,6 +96,7 @@ func (r *Repository) FindStats(ctx context.Context) ([]*VaaStats, error) {
|
||||||
return stats, err
|
return stats, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VaaQuery respresent a query for the vaa mongodb document.
|
||||||
type VaaQuery struct {
|
type VaaQuery struct {
|
||||||
pagination.Pagination
|
pagination.Pagination
|
||||||
chainId vaa.ChainID
|
chainId vaa.ChainID
|
||||||
|
@ -78,26 +104,31 @@ type VaaQuery struct {
|
||||||
sequence uint64
|
sequence uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Query create a new VaaQuery with default pagination vaues.
|
||||||
func Query() *VaaQuery {
|
func Query() *VaaQuery {
|
||||||
page := pagination.FirstPage()
|
page := pagination.FirstPage()
|
||||||
return &VaaQuery{Pagination: *page}
|
return &VaaQuery{Pagination: *page}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetChain set the chainId field of the VaaQuery struct.
|
||||||
func (q *VaaQuery) SetChain(chainID vaa.ChainID) *VaaQuery {
|
func (q *VaaQuery) SetChain(chainID vaa.ChainID) *VaaQuery {
|
||||||
q.chainId = chainID
|
q.chainId = chainID
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetEmitter set the emitter field of the VaaQuery struct.
|
||||||
func (q *VaaQuery) SetEmitter(emitter string) *VaaQuery {
|
func (q *VaaQuery) SetEmitter(emitter string) *VaaQuery {
|
||||||
q.emitter = emitter
|
q.emitter = emitter
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSequence set the sequence field of the VaaQuery struct.
|
||||||
func (q *VaaQuery) SetSequence(seq uint64) *VaaQuery {
|
func (q *VaaQuery) SetSequence(seq uint64) *VaaQuery {
|
||||||
q.sequence = seq
|
q.sequence = seq
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPagination set the pagination field of the VaaQuery struct.
|
||||||
func (q *VaaQuery) SetPagination(p *pagination.Pagination) *VaaQuery {
|
func (q *VaaQuery) SetPagination(p *pagination.Pagination) *VaaQuery {
|
||||||
q.Pagination = *p
|
q.Pagination = *p
|
||||||
return q
|
return q
|
|
@ -4,54 +4,60 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/pagination"
|
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/services"
|
"github.com/wormhole-foundation/wormhole-explorer/api/response"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Service definition.
|
||||||
type Service struct {
|
type Service struct {
|
||||||
repo *Repository
|
repo *Repository
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewService create a new Service.
|
||||||
func NewService(r *Repository, logger *zap.Logger) *Service {
|
func NewService(r *Repository, logger *zap.Logger) *Service {
|
||||||
return &Service{repo: r, logger: logger.With(zap.String("module", "VaaService"))}
|
return &Service{repo: r, logger: logger.With(zap.String("module", "VaaService"))}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) FindAll(ctx context.Context, p *pagination.Pagination) (*services.Response[[]*VaaDoc], error) {
|
// FindAll get all the the vaa.
|
||||||
|
func (s *Service) FindAll(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*VaaDoc], error) {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
p = pagination.FirstPage()
|
p = pagination.FirstPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
query := Query().SetPagination(p)
|
query := Query().SetPagination(p)
|
||||||
vaas, err := s.repo.Find(ctx, query)
|
vaas, err := s.repo.Find(ctx, query)
|
||||||
res := services.Response[[]*VaaDoc]{Data: vaas, Error: err}
|
res := response.Response[[]*VaaDoc]{Data: vaas}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) FindByChain(ctx context.Context, chain vaa.ChainID, p *pagination.Pagination) (*services.Response[[]*VaaDoc], error) {
|
// FindByChain get all the vaa by chainID.
|
||||||
|
func (s *Service) FindByChain(ctx context.Context, chain vaa.ChainID, p *pagination.Pagination) (*response.Response[[]*VaaDoc], error) {
|
||||||
query := Query().SetChain(chain).SetPagination(p)
|
query := Query().SetChain(chain).SetPagination(p)
|
||||||
vaas, err := s.repo.Find(ctx, query)
|
vaas, err := s.repo.Find(ctx, query)
|
||||||
res := services.Response[[]*VaaDoc]{Data: vaas, Error: err}
|
res := response.Response[[]*VaaDoc]{Data: vaas}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) FindByEmitter(ctx context.Context, chain vaa.ChainID, emitter vaa.Address, p *pagination.Pagination) (*services.Response[[]*VaaDoc], error) {
|
// FindByEmitter get all the vaa by chainID and emitter address.
|
||||||
|
func (s *Service) FindByEmitter(ctx context.Context, chain vaa.ChainID, emitter vaa.Address, p *pagination.Pagination) (*response.Response[[]*VaaDoc], error) {
|
||||||
query := Query().SetChain(chain).SetEmitter(emitter.String()).SetPagination(p)
|
query := Query().SetChain(chain).SetEmitter(emitter.String()).SetPagination(p)
|
||||||
vaas, err := s.repo.Find(ctx, query)
|
vaas, err := s.repo.Find(ctx, query)
|
||||||
res := services.Response[[]*VaaDoc]{Data: vaas, Error: err}
|
res := response.Response[[]*VaaDoc]{Data: vaas}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) FindById(ctx context.Context, chain vaa.ChainID, emitter vaa.Address, seq uint64) (*services.Response[*VaaDoc], error) {
|
// FindById get a vaa by chainID, emitter address and sequence number.
|
||||||
|
func (s *Service) FindById(ctx context.Context, chain vaa.ChainID, emitter vaa.Address, seq uint64) (*response.Response[*VaaDoc], error) {
|
||||||
query := Query().SetChain(chain).SetEmitter(emitter.String()).SetSequence(seq)
|
query := Query().SetChain(chain).SetEmitter(emitter.String()).SetSequence(seq)
|
||||||
vaas, err := s.repo.FindOne(ctx, query)
|
vaas, err := s.repo.FindOne(ctx, query)
|
||||||
res := services.Response[*VaaDoc]{Data: vaas, Error: err}
|
res := response.Response[*VaaDoc]{Data: vaas}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) GetVAAStats(ctx context.Context) (*services.Response[[]*VaaStats], error) {
|
func (s *Service) GetVAAStats(ctx context.Context) (*response.Response[[]*VaaStats], error) {
|
||||||
stats, err := s.repo.FindStats(ctx)
|
stats, err := s.repo.FindStats(ctx)
|
||||||
res := services.Response[[]*VaaStats]{Data: stats, Error: err}
|
res := response.Response[[]*VaaStats]{Data: stats}
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
|
@ -1,13 +1,23 @@
|
||||||
|
// Package config implement a simple configuration package.
|
||||||
|
// It define a type [AppConfig] that represent the aplication configuration and
|
||||||
|
// use viper [https://github.com/spf13/viper] to load the configuration.
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
|
||||||
ipfslog "github.com/ipfs/go-log/v2"
|
ipfslog "github.com/ipfs/go-log/v2"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RunModeProduction = "PRODUCTION"
|
||||||
|
RunModeDevelopmernt = "DEVELOPMENT"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AppConfig defines the configuration for the app.
|
||||||
type AppConfig struct {
|
type AppConfig struct {
|
||||||
DB struct {
|
DB struct {
|
||||||
URL string
|
URL string
|
||||||
|
@ -15,11 +25,12 @@ type AppConfig struct {
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
PORT int
|
PORT int
|
||||||
|
|
||||||
LogLevel string
|
LogLevel string
|
||||||
|
RunMode string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLogLevel get zapcore.Level define in the configuraion.
|
||||||
func (cfg *AppConfig) GetLogLevel() (ipfslog.LogLevel, error) {
|
func (cfg *AppConfig) GetLogLevel() (ipfslog.LogLevel, error) {
|
||||||
return ipfslog.LevelFromString(cfg.LogLevel)
|
return ipfslog.LevelFromString(cfg.LogLevel)
|
||||||
}
|
}
|
||||||
|
@ -27,6 +38,8 @@ func (cfg *AppConfig) GetLogLevel() (ipfslog.LogLevel, error) {
|
||||||
func init() {
|
func init() {
|
||||||
viper.SetDefault("port", 8000)
|
viper.SetDefault("port", 8000)
|
||||||
viper.SetDefault("loglevel", "INFO")
|
viper.SetDefault("loglevel", "INFO")
|
||||||
|
viper.SetDefault("runmode", "PRODUCTION")
|
||||||
|
|
||||||
// Consider environment variables in unmarshall doesn't work unless doing this: https://github.com/spf13/viper/issues/188#issuecomment-1168898503
|
// Consider environment variables in unmarshall doesn't work unless doing this: https://github.com/spf13/viper/issues/188#issuecomment-1168898503
|
||||||
b, err := json.Marshal(AppConfig{})
|
b, err := json.Marshal(AppConfig{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -50,6 +63,7 @@ func init() {
|
||||||
viper.AutomaticEnv()
|
viper.AutomaticEnv()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get returns the app configuration.
|
||||||
func Get() (*AppConfig, error) {
|
func Get() (*AppConfig, error) {
|
||||||
var cfg AppConfig
|
var cfg AppConfig
|
||||||
err := viper.Unmarshal(&cfg)
|
err := viper.Unmarshal(&cfg)
|
|
@ -1,11 +1,14 @@
|
||||||
|
// Package db handle mongodb connections.
|
||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Connect create a new mongo db client for the options defined in the input param url.
|
||||||
func Connect(ctx context.Context, url string) (*mongo.Client, error) {
|
func Connect(ctx context.Context, url string) (*mongo.Client, error) {
|
||||||
cli, err := mongo.NewClient(options.Client().ApplyURI(url))
|
cli, err := mongo.NewClient(options.Client().ApplyURI(url))
|
||||||
if err != nil {
|
if err != nil {
|
|
@ -0,0 +1,10 @@
|
||||||
|
package errors
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
// Error definitions to use in service and repository layers.
|
||||||
|
var (
|
||||||
|
ErrMalformedQuery = errors.New("MALFORMED_QUERY")
|
||||||
|
ErrNotFound = errors.New("NOT FOUND")
|
||||||
|
ErrInternalError = errors.New("INTERNAL ERROR")
|
||||||
|
)
|
|
@ -1,5 +1,6 @@
|
||||||
package pagination
|
package pagination
|
||||||
|
|
||||||
|
// Pagination definition.
|
||||||
type Pagination struct {
|
type Pagination struct {
|
||||||
Offset int64
|
Offset int64
|
||||||
PageSize int64
|
PageSize int64
|
||||||
|
@ -7,41 +8,49 @@ type Pagination struct {
|
||||||
SortBy string
|
SortBy string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FirstPage return a *Pagination with default values offset and page size.
|
||||||
func FirstPage() *Pagination {
|
func FirstPage() *Pagination {
|
||||||
return &Pagination{Offset: 0, PageSize: 50}
|
return &Pagination{Offset: 0, PageSize: 50}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildPagination create a new *Pagination.
|
||||||
func BuildPagination(page, pageSize int64, sortOrder, sortBy string) *Pagination {
|
func BuildPagination(page, pageSize int64, sortOrder, sortBy string) *Pagination {
|
||||||
p := Pagination{}
|
p := Pagination{}
|
||||||
p.SetPage(page).SetPageSize(pageSize).SetSortOrder(sortOrder).SetSortBy(sortBy)
|
p.SetPage(page).SetPageSize(pageSize).SetSortOrder(sortOrder).SetSortBy(sortBy)
|
||||||
return &p
|
return &p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPageSize set the PageSize field of the Pagination struct.
|
||||||
func (p *Pagination) SetPageSize(limit int64) *Pagination {
|
func (p *Pagination) SetPageSize(limit int64) *Pagination {
|
||||||
p.PageSize = limit
|
p.PageSize = limit
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetOffset set the Offset field of the Pagination struct.
|
||||||
func (p *Pagination) SetOffset(offset int64) *Pagination {
|
func (p *Pagination) SetOffset(offset int64) *Pagination {
|
||||||
p.Offset = offset
|
p.Offset = offset
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPage set the Page field of the Pagination struct.
|
||||||
func (p *Pagination) SetPage(page int64) *Pagination {
|
func (p *Pagination) SetPage(page int64) *Pagination {
|
||||||
p.Offset = page * p.PageSize
|
p.Offset = page * p.PageSize
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSortOrder set the SortOrder field of the Pagination struct.
|
||||||
func (p *Pagination) SetSortOrder(order string) *Pagination {
|
func (p *Pagination) SetSortOrder(order string) *Pagination {
|
||||||
p.SortOrder = order
|
p.SortOrder = order
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSortBy set the SortBy field of the Pagination struct.
|
||||||
func (p *Pagination) SetSortBy(by string) *Pagination {
|
func (p *Pagination) SetSortBy(by string) *Pagination {
|
||||||
p.SortBy = by
|
p.SortBy = by
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSortInt mapping to mongodb sort values.
|
||||||
func (p *Pagination) GetSortInt() int {
|
func (p *Pagination) GetSortInt() int {
|
||||||
if p.SortOrder == "ASC" {
|
if p.SortOrder == "ASC" {
|
||||||
return 1
|
return 1
|
18
api/main.go
18
api/main.go
|
@ -14,12 +14,13 @@ import (
|
||||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||||
"github.com/gofiber/fiber/v2/middleware/requestid"
|
"github.com/gofiber/fiber/v2/middleware/requestid"
|
||||||
ipfslog "github.com/ipfs/go-log/v2"
|
ipfslog "github.com/ipfs/go-log/v2"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/config"
|
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/governor"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/db"
|
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/observations"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/governor"
|
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/vaa"
|
||||||
|
"github.com/wormhole-foundation/wormhole-explorer/api/internal/config"
|
||||||
|
"github.com/wormhole-foundation/wormhole-explorer/api/internal/db"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/middleware"
|
"github.com/wormhole-foundation/wormhole-explorer/api/middleware"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/observations"
|
"github.com/wormhole-foundation/wormhole-explorer/api/response"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/vaa"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var cacheConfig = cache.Config{
|
var cacheConfig = cache.Config{
|
||||||
|
@ -54,7 +55,7 @@ func main() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rootLogger := ipfslog.Logger("wormhole-spy").Desugar()
|
rootLogger := ipfslog.Logger("wormhole-api").Desugar()
|
||||||
ipfslog.SetAllLoggers(lvl)
|
ipfslog.SetAllLoggers(lvl)
|
||||||
|
|
||||||
// Setup DB
|
// Setup DB
|
||||||
|
@ -79,8 +80,9 @@ func main() {
|
||||||
observationsCtrl := observations.NewController(obsService, rootLogger)
|
observationsCtrl := observations.NewController(obsService, rootLogger)
|
||||||
governorCtrl := governor.NewController(governorService, rootLogger)
|
governorCtrl := governor.NewController(governorService, rootLogger)
|
||||||
|
|
||||||
// Setup API
|
// Setup app with custom error handling.
|
||||||
app := fiber.New()
|
response.SetEnableStackTrace(*cfg)
|
||||||
|
app := fiber.New(fiber.Config{ErrorHandler: middleware.ErrorHandler})
|
||||||
|
|
||||||
// Middleware
|
// Middleware
|
||||||
prometheus := fiberprometheus.New("wormscan")
|
prometheus := fiberprometheus.New("wormscan")
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
// package middleare contains all the middleware function to use in the API.
|
||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
|
||||||
|
"github.com/wormhole-foundation/wormhole-explorer/api/response"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrorHandler define a fiber custom error handler. This function process all errors
|
||||||
|
// returned from any handlers in the stack.
|
||||||
|
//
|
||||||
|
// To setup this function we must set the ErrorHandler field of the fiber.Config struct
|
||||||
|
// with this function and create a new fiber with this config.
|
||||||
|
//
|
||||||
|
// example: fiber.New(fiber.Config{ErrorHandler: errs.APIErrorHandler}
|
||||||
|
func ErrorHandler(ctx *fiber.Ctx, err error) error {
|
||||||
|
var apiError response.APIError
|
||||||
|
switch {
|
||||||
|
case errors.As(err, &apiError):
|
||||||
|
ctx.Status(apiError.StatusCode).JSON(apiError)
|
||||||
|
case errors.Is(err, errs.ErrNotFound):
|
||||||
|
apiError = response.NewNotFoundError(ctx)
|
||||||
|
ctx.Status(fiber.StatusNotFound).JSON(apiError)
|
||||||
|
default:
|
||||||
|
apiError = response.NewInternalError(ctx, err)
|
||||||
|
ctx.Status(fiber.StatusInternalServerError).JSON(apiError)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,15 +1,50 @@
|
||||||
|
// package middleare contains all the middleware function to use in the API.
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gofiber/fiber/v2"
|
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/pagination"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ExtractPagination middleware invoke pagination.ExtractPagination.
|
||||||
func ExtractPagination(c *fiber.Ctx) error {
|
func ExtractPagination(c *fiber.Ctx) error {
|
||||||
if c.Method() != http.MethodGet {
|
if c.Method() != http.MethodGet {
|
||||||
return c.Next()
|
return c.Next()
|
||||||
}
|
}
|
||||||
pagination.ExtractPagination(c)
|
extractPagination(c)
|
||||||
return c.Next()
|
return c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extractPagination get pagination query params and build a *Pagination.
|
||||||
|
func extractPagination(ctx *fiber.Ctx) (*pagination.Pagination, error) {
|
||||||
|
pageNumberStr := ctx.Query("page", "0")
|
||||||
|
pageNumber, err := strconv.ParseInt(pageNumberStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pageSizeStr := ctx.Query("pageSize", "50")
|
||||||
|
pageSize, err := strconv.ParseInt(pageSizeStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sortOrder := ctx.Query("sortOrder", "DESC")
|
||||||
|
sortBy := ctx.Query("sortBy", "indexedAt")
|
||||||
|
|
||||||
|
p := pagination.BuildPagination(pageNumber, pageSize, sortOrder, sortBy)
|
||||||
|
ctx.Locals("pagination", p)
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPaginationFromContext get pagination from context.
|
||||||
|
func GetPaginationFromContext(ctx *fiber.Ctx) *pagination.Pagination {
|
||||||
|
p := ctx.Locals("pagination")
|
||||||
|
if p == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return p.(*pagination.Pagination)
|
||||||
|
}
|
||||||
|
|
|
@ -1,67 +1,114 @@
|
||||||
|
// package middleare contains all the middleware function to use in the API.
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/wormhole-foundation/wormhole-explorer/api/response"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// ExtractChainID get chain parameter from route path.
|
||||||
ErrMalformedChain = errors.New("WRONG_CHAIN_ID")
|
func ExtractChainID(c *fiber.Ctx, l *zap.Logger) (vaa.ChainID, error) {
|
||||||
ErrMalformedAddr = errors.New("MALFORMED_EMITTER_ADDR")
|
|
||||||
ErrMalformedSequence = errors.New("MALFORMED_SEQUENCE_NUMBER")
|
|
||||||
ErrMalFormedGuardianAddress = errors.New("MALFORMED_GUARDIAN_ADDR")
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExtractChainID(c *fiber.Ctx) (vaa.ChainID, error) {
|
|
||||||
chain, err := c.ParamsInt("chain")
|
chain, err := c.ParamsInt("chain")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return vaa.ChainIDUnset, ErrMalformedChain
|
requestID := fmt.Sprintf("%v", c.Locals("requestid"))
|
||||||
|
l.Error("failed to get chain parameter", zap.Error(err), zap.Int("chain", chain),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
|
||||||
|
return vaa.ChainIDUnset, response.NewInvalidParamError(c, "WRONG CHAIN ID", errors.WithStack(err))
|
||||||
}
|
}
|
||||||
return vaa.ChainID(chain), nil
|
return vaa.ChainID(chain), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractEmitterAddr(c *fiber.Ctx) (*vaa.Address, error) {
|
// ExtractEmitterAddr get emitter parameter from route path.
|
||||||
|
func ExtractEmitterAddr(c *fiber.Ctx, l *zap.Logger) (*vaa.Address, error) {
|
||||||
emitterStr := c.Params("emitter")
|
emitterStr := c.Params("emitter")
|
||||||
emitter, err := vaa.StringToAddress(emitterStr)
|
emitter, err := vaa.StringToAddress(emitterStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ErrMalformedAddr
|
requestID := fmt.Sprintf("%v", c.Locals("requestid"))
|
||||||
|
l.Error("failed to covert emitter to address", zap.Error(err), zap.String("emitterStr", emitterStr),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, response.NewInvalidParamError(c, "MALFORMED EMITTER_ADDR", errors.WithStack(err))
|
||||||
}
|
}
|
||||||
return &emitter, nil
|
return &emitter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractSequence(c *fiber.Ctx) (uint64, error) {
|
// ExtractSequence get sequence parameter from route path.
|
||||||
|
func ExtractSequence(c *fiber.Ctx, l *zap.Logger) (uint64, error) {
|
||||||
sequence := c.Params("sequence")
|
sequence := c.Params("sequence")
|
||||||
seq, err := strconv.ParseUint(sequence, 10, 64)
|
seq, err := strconv.ParseUint(sequence, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
requestID := fmt.Sprintf("%v", c.Locals("requestid"))
|
||||||
|
l.Error("failed to get sequence parameter", zap.Error(err), zap.String("sequence", sequence),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return 0, response.NewInvalidParamError(c, "MALFORMED SEQUENCE NUMBER", errors.WithStack(err))
|
||||||
}
|
}
|
||||||
return seq, nil
|
return seq, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractGuardianAddress(c *fiber.Ctx) (string, error) {
|
// ExtractGuardianAddress get guardian address from route path.
|
||||||
|
func ExtractGuardianAddress(c *fiber.Ctx, l *zap.Logger) (string, error) {
|
||||||
//TODO: check guardianAddress [vaa.StringToAddress(emitterStr)]
|
//TODO: check guardianAddress [vaa.StringToAddress(emitterStr)]
|
||||||
guardianAddress := c.Params("guardian_address")
|
guardianAddress := c.Params("guardian_address")
|
||||||
if guardianAddress == "" {
|
if guardianAddress == "" {
|
||||||
return "", ErrMalFormedGuardianAddress
|
return "", response.NewInvalidParamError(c, "MALFORMED GUARDIAN ADDR", nil)
|
||||||
}
|
}
|
||||||
return guardianAddress, nil
|
return guardianAddress, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractVAAParams(c *fiber.Ctx) (vaa.ChainID, *vaa.Address, uint64, error) {
|
// ExtractVAAParams get VAA chain, address from route path.
|
||||||
chainID, err := ExtractChainID(c)
|
func ExtractVAAChainIDEmitter(c *fiber.Ctx, l *zap.Logger) (vaa.ChainID, *vaa.Address, error) {
|
||||||
|
chainID, err := ExtractChainID(c, l)
|
||||||
|
if err != nil {
|
||||||
|
return vaa.ChainIDUnset, nil, err
|
||||||
|
}
|
||||||
|
address, err := ExtractEmitterAddr(c, l)
|
||||||
|
if err != nil {
|
||||||
|
return chainID, nil, err
|
||||||
|
}
|
||||||
|
return chainID, address, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractVAAParams get VAAA chain, address and sequence from route path.
|
||||||
|
func ExtractVAAParams(c *fiber.Ctx, l *zap.Logger) (vaa.ChainID, *vaa.Address, uint64, error) {
|
||||||
|
chainID, err := ExtractChainID(c, l)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return vaa.ChainIDUnset, nil, 0, err
|
return vaa.ChainIDUnset, nil, 0, err
|
||||||
}
|
}
|
||||||
address, err := ExtractEmitterAddr(c)
|
address, err := ExtractEmitterAddr(c, l)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return chainID, nil, 0, err
|
return chainID, nil, 0, err
|
||||||
}
|
}
|
||||||
seq, err := ExtractSequence(c)
|
seq, err := ExtractSequence(c, l)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return chainID, address, 0, err
|
return chainID, address, 0, err
|
||||||
}
|
}
|
||||||
return chainID, address, seq, nil
|
return chainID, address, seq, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExtractObservationSigner get signer from route path.
|
||||||
|
func ExtractObservationSigner(c *fiber.Ctx, l *zap.Logger) (*vaa.Address, error) {
|
||||||
|
signer := c.Params("signer")
|
||||||
|
signerAddr, err := vaa.StringToAddress(signer)
|
||||||
|
if err != nil {
|
||||||
|
requestID := fmt.Sprintf("%v", c.Locals("requestid"))
|
||||||
|
l.Error("failed to covert signer to address", zap.Error(err), zap.String("signer", signer),
|
||||||
|
zap.String("requestID", requestID))
|
||||||
|
return nil, response.NewInvalidParamError(c, "MALFORMED SIGNER", errors.WithStack(err))
|
||||||
|
}
|
||||||
|
return &signerAddr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractObservationHash get a hash from route path.
|
||||||
|
func ExtractObservationHash(c *fiber.Ctx, l *zap.Logger) (string, error) {
|
||||||
|
hash := c.Params("hash")
|
||||||
|
if hash == "" {
|
||||||
|
return "", response.NewInvalidParamError(c, "MALFORMED HASH", nil)
|
||||||
|
}
|
||||||
|
return hash, nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
package pagination
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gofiber/fiber/v2"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExtractPagination(ctx *fiber.Ctx) (*Pagination, error) {
|
|
||||||
pageNumberStr := ctx.Query("page", "0")
|
|
||||||
pageNumber, err := strconv.ParseInt(pageNumberStr, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pageSizeStr := ctx.Query("pageSize", "50")
|
|
||||||
pageSize, err := strconv.ParseInt(pageSizeStr, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sortOrder := ctx.Query("sortOrder", "DESC")
|
|
||||||
sortBy := ctx.Query("sortBy", "indexedAt")
|
|
||||||
|
|
||||||
p := BuildPagination(pageNumber, pageSize, sortOrder, sortBy)
|
|
||||||
ctx.Locals("pagination", p)
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetFromContext(ctx *fiber.Ctx) *Pagination {
|
|
||||||
p := ctx.Locals("pagination")
|
|
||||||
if p == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return p.(*Pagination)
|
|
||||||
}
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
// The response package defines the success and error response type.
|
||||||
|
// It define a type [AppError] that represent the api error response.
|
||||||
|
// Its define a custom error handling for the api.
|
||||||
|
package response
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/wormhole-foundation/wormhole-explorer/api/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
// API error codes. These error code are the same used in guardian API.
|
||||||
|
const (
|
||||||
|
InvalidParam = 3
|
||||||
|
NotFound = 5
|
||||||
|
Internal = 13
|
||||||
|
)
|
||||||
|
|
||||||
|
var enableStackTrace bool
|
||||||
|
|
||||||
|
// SetEnableStackTrace enable/disable send the stacktrace field in the response.
|
||||||
|
func SetEnableStackTrace(cfg config.AppConfig) {
|
||||||
|
if cfg.RunMode == config.RunModeDevelopmernt {
|
||||||
|
enableStackTrace = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
enableStackTrace = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIError api error response.
|
||||||
|
// This structure is defined to be aligned with the way the guardian API handles the error response.
|
||||||
|
type APIError struct {
|
||||||
|
StatusCode int `json:"-"`
|
||||||
|
Code int `json:"code"` // support to guardian-api code.
|
||||||
|
Message string `json:"message"`
|
||||||
|
Details []ErrorDetail `json:"details"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorDetail definition.
|
||||||
|
// This structure contains the requestID and the stacktrace of the error.
|
||||||
|
type ErrorDetail struct {
|
||||||
|
RequestID string `json:"request_id"`
|
||||||
|
StackTrace string `json:"stack_trace,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error interface implementation.
|
||||||
|
func (a APIError) Error() string {
|
||||||
|
return fmt.Sprintf("code: %d, message: %s, details: %v", a.Code, a.Message, a.Details)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewApiError create a new api response.
|
||||||
|
func NewApiError(ctx *fiber.Ctx, statusCode, code int, message string, err error) APIError {
|
||||||
|
detail := ErrorDetail{
|
||||||
|
RequestID: fmt.Sprintf("%v", ctx.Locals("requestid")),
|
||||||
|
}
|
||||||
|
if enableStackTrace && err != nil {
|
||||||
|
detail.StackTrace = fmt.Sprintf("%+v\n", err)
|
||||||
|
}
|
||||||
|
return APIError{
|
||||||
|
StatusCode: fiber.StatusBadRequest,
|
||||||
|
Code: InvalidParam,
|
||||||
|
Message: message,
|
||||||
|
Details: []ErrorDetail{detail},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInvalidParamError create a invalid param Error.
|
||||||
|
func NewInvalidParamError(ctx *fiber.Ctx, message string, err error) APIError {
|
||||||
|
if message == "" {
|
||||||
|
message = "INVALID PARAM"
|
||||||
|
}
|
||||||
|
detail := ErrorDetail{
|
||||||
|
RequestID: fmt.Sprintf("%v", ctx.Locals("requestid")),
|
||||||
|
}
|
||||||
|
if enableStackTrace && err != nil {
|
||||||
|
detail.StackTrace = fmt.Sprintf("%+v\n", err)
|
||||||
|
}
|
||||||
|
return APIError{
|
||||||
|
StatusCode: fiber.StatusBadRequest,
|
||||||
|
Code: InvalidParam,
|
||||||
|
Message: message,
|
||||||
|
Details: []ErrorDetail{detail},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInternalError create a new APIError for Internal Errors.
|
||||||
|
func NewInternalError(ctx *fiber.Ctx, err error) APIError {
|
||||||
|
detail := ErrorDetail{
|
||||||
|
RequestID: fmt.Sprintf("%v", ctx.Locals("requestid")),
|
||||||
|
}
|
||||||
|
if enableStackTrace && err != nil {
|
||||||
|
detail.StackTrace = fmt.Sprintf("%+v\n", err)
|
||||||
|
}
|
||||||
|
return APIError{
|
||||||
|
StatusCode: fiber.StatusInternalServerError,
|
||||||
|
Code: Internal,
|
||||||
|
Message: "INTERNAL ERROR",
|
||||||
|
Details: []ErrorDetail{detail},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNotFoundError create a new APIError for Not Found errors.
|
||||||
|
func NewNotFoundError(ctx *fiber.Ctx) APIError {
|
||||||
|
return APIError{
|
||||||
|
StatusCode: fiber.StatusNotFound,
|
||||||
|
Code: NotFound,
|
||||||
|
Message: "NOT FOUND",
|
||||||
|
Details: []ErrorDetail{{
|
||||||
|
RequestID: fmt.Sprintf("%v", ctx.Locals("requestid")),
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,13 @@
|
||||||
package services
|
// The response package defines the success and error response type.
|
||||||
|
package response
|
||||||
|
|
||||||
|
// ResponsePagination definition.
|
||||||
type ResponsePagination struct {
|
type ResponsePagination struct {
|
||||||
Next string `json:"next"`
|
Next string `json:"next"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Response represent a success API response.
|
||||||
type Response[T any] struct {
|
type Response[T any] struct {
|
||||||
Data T `json:"data"`
|
Data T `json:"data"`
|
||||||
Error error `json:"error"`
|
|
||||||
Pagination ResponsePagination `json:"pagination"`
|
Pagination ResponsePagination `json:"pagination"`
|
||||||
}
|
}
|
Loading…
Reference in New Issue