Add contract watcher component (#190)
* init contract-watcher * Add processor and blockain watchers * Add pagination and save last blocknumber procesed by chain * Add processing by blocks * Add contract-watcher deploy manifest * Add endpoint to get globalTransactions by Id * Add originTX to get globalTransactionById endpoint * Add wait time for new blocks * Add initial block for evm watcher * Add rate limit for evm watcher * Handle testnet environment and small fixes * Update wormhole dependencies * Fix api documentation for swagger --------- Co-authored-by: Agustin Pazos <agpazos85@gmail.com>
This commit is contained in:
parent
86f1e12f1c
commit
824ba3c7f9
2
Makefile
2
Makefile
|
@ -13,6 +13,7 @@ build:
|
|||
make -C spy/ build
|
||||
make -C parser/ build
|
||||
make -C tx-tracker/ build
|
||||
make -C contract-watcher/ build
|
||||
|
||||
doc:
|
||||
swag init -pd
|
||||
|
@ -23,5 +24,6 @@ test:
|
|||
cd spy && go test -v -cover ./...
|
||||
cd parser && go test -v -cover ./...
|
||||
cd tx-tracker && go test -v -cover ./...
|
||||
cd contract-watcher && go test -v -cover ./...
|
||||
|
||||
.PHONY: build doc test
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Code generated by swaggo/swag. DO NOT EDIT
|
||||
// Package docs GENERATED BY SWAG; DO NOT EDIT
|
||||
// This file was generated by swaggo/swag
|
||||
package docs
|
||||
|
||||
import "github.com/swaggo/swag"
|
||||
|
@ -24,6 +25,52 @@ const docTemplate = `{
|
|||
"host": "{{.Host}}",
|
||||
"basePath": "{{.BasePath}}",
|
||||
"paths": {
|
||||
"/api/v1/global-tx/{chain_id}/{emitter}/{seq}": {
|
||||
"get": {
|
||||
"description": "Find a global transaction by ID.",
|
||||
"tags": [
|
||||
"Wormscan"
|
||||
],
|
||||
"operationId": "find-global-transaction-by-id",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "id of the blockchain",
|
||||
"name": "chain_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "address of the emitter",
|
||||
"name": "emitter",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "sequence of the VAA",
|
||||
"name": "seq",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/transactions.Tx"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request"
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/governor/config": {
|
||||
"get": {
|
||||
"description": "Returns governor configuration for all guardians.",
|
||||
|
@ -2252,6 +2299,7 @@ const docTemplate = `{
|
|||
26,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
3104
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
|
@ -2282,6 +2330,7 @@ const docTemplate = `{
|
|||
"ChainIDPythNet",
|
||||
"ChainIDXpla",
|
||||
"ChainIDBtc",
|
||||
"ChainIDBase",
|
||||
"ChainIDWormchain"
|
||||
]
|
||||
},
|
||||
|
|
|
@ -17,6 +17,52 @@
|
|||
},
|
||||
"basePath": "/v1",
|
||||
"paths": {
|
||||
"/api/v1/global-tx/{chain_id}/{emitter}/{seq}": {
|
||||
"get": {
|
||||
"description": "Find a global transaction by ID.",
|
||||
"tags": [
|
||||
"Wormscan"
|
||||
],
|
||||
"operationId": "find-global-transaction-by-id",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "id of the blockchain",
|
||||
"name": "chain_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "address of the emitter",
|
||||
"name": "emitter",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "sequence of the VAA",
|
||||
"name": "seq",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/transactions.Tx"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request"
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/governor/config": {
|
||||
"get": {
|
||||
"description": "Returns governor configuration for all guardians.",
|
||||
|
@ -2245,6 +2291,7 @@
|
|||
26,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
3104
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
|
@ -2275,6 +2322,7 @@
|
|||
"ChainIDPythNet",
|
||||
"ChainIDXpla",
|
||||
"ChainIDBtc",
|
||||
"ChainIDBase",
|
||||
"ChainIDWormchain"
|
||||
]
|
||||
},
|
||||
|
|
|
@ -517,6 +517,7 @@ definitions:
|
|||
- 26
|
||||
- 28
|
||||
- 29
|
||||
- 30
|
||||
- 3104
|
||||
type: integer
|
||||
x-enum-varnames:
|
||||
|
@ -547,6 +548,7 @@ definitions:
|
|||
- ChainIDPythNet
|
||||
- ChainIDXpla
|
||||
- ChainIDBtc
|
||||
- ChainIDBase
|
||||
- ChainIDWormchain
|
||||
vaa.VaaDoc:
|
||||
properties:
|
||||
|
@ -607,6 +609,37 @@ info:
|
|||
title: Wormhole Guardian API
|
||||
version: "1.0"
|
||||
paths:
|
||||
/api/v1/global-tx/{chain_id}/{emitter}/{seq}:
|
||||
get:
|
||||
description: Find a global transaction by ID.
|
||||
operationId: find-global-transaction-by-id
|
||||
parameters:
|
||||
- description: id of the blockchain
|
||||
in: path
|
||||
name: chain_id
|
||||
required: true
|
||||
type: integer
|
||||
- description: address of the emitter
|
||||
in: path
|
||||
name: emitter
|
||||
required: true
|
||||
type: string
|
||||
- description: sequence of the VAA
|
||||
in: path
|
||||
name: seq
|
||||
required: true
|
||||
type: integer
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/transactions.Tx'
|
||||
"400":
|
||||
description: Bad Request
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
tags:
|
||||
- Wormscan
|
||||
/api/v1/governor/config:
|
||||
get:
|
||||
description: Returns governor configuration for all guardians.
|
||||
|
|
13
api/go.mod
13
api/go.mod
|
@ -4,7 +4,7 @@ go 1.19
|
|||
|
||||
require (
|
||||
github.com/ansrivas/fiberprometheus/v2 v2.4.1
|
||||
github.com/certusone/wormhole/node v0.0.0-20230120141536-53d554d93b02
|
||||
github.com/certusone/wormhole/node v0.0.0-20230315165931-62bef9ffb441
|
||||
github.com/ethereum/go-ethereum v1.10.21
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/gofiber/adaptor/v2 v2.1.29
|
||||
|
@ -13,9 +13,9 @@ require (
|
|||
github.com/ipfs/go-log/v2 v2.5.1
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/spf13/viper v1.13.0
|
||||
github.com/spf13/viper v1.14.0
|
||||
github.com/swaggo/swag v1.8.9
|
||||
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20221118153622-cddfe74b6787
|
||||
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20230315165931-62bef9ffb441
|
||||
go.mongodb.org/mongo-driver v1.10.3
|
||||
go.uber.org/zap v1.23.0
|
||||
google.golang.org/grpc v1.50.1
|
||||
|
@ -36,7 +36,7 @@ require (
|
|||
github.com/deepmap/oapi-codegen v1.8.2 // indirect
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
github.com/go-openapi/spec v0.20.4 // indirect
|
||||
|
@ -48,6 +48,7 @@ require (
|
|||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/holiman/uint256 v1.2.1 // indirect
|
||||
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect
|
||||
github.com/ipfs/go-cid v0.2.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
|
@ -75,7 +76,7 @@ require (
|
|||
github.com/multiformats/go-varint v0.0.6 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||
github.com/prometheus/client_golang v1.13.0 // indirect
|
||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
|
@ -83,7 +84,7 @@ require (
|
|||
github.com/rs/cors v1.8.2 // indirect
|
||||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/spf13/afero v1.8.2 // indirect
|
||||
github.com/spf13/afero v1.9.2 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
|
|
30
api/go.sum
30
api/go.sum
|
@ -85,8 +85,8 @@ github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInq
|
|||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/certusone/wormhole/node v0.0.0-20230120141536-53d554d93b02 h1:7hRUpbg41a3GGnW8YVz2cyE3GY2WyLP+nN0EbSU9Blg=
|
||||
github.com/certusone/wormhole/node v0.0.0-20230120141536-53d554d93b02/go.mod h1:Lcz1OWZlnR1bBfyWH9BlKGwH+eIfMkYkqkRZM26u3Vw=
|
||||
github.com/certusone/wormhole/node v0.0.0-20230315165931-62bef9ffb441 h1:GA0tsKbkA2jz4lQUGV0PyWTJ02GIsTvSwq7xjjv3GN0=
|
||||
github.com/certusone/wormhole/node v0.0.0-20230315165931-62bef9ffb441/go.mod h1:U/qHGQY1vAw//UlPYVQKSL9b3C2nL6YakCYorMEz3GY=
|
||||
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/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
|
@ -141,8 +141,8 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB
|
|||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
|
||||
github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
|
@ -306,6 +306,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
|
|||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/holiman/uint256 v1.2.1 h1:XRtyuda/zw2l+Bq/38n5XUoEF72aSOu/77Thd9pPp2o=
|
||||
github.com/holiman/uint256 v1.2.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
|
@ -463,7 +465,7 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
|||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
|
||||
github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
|
@ -500,8 +502,8 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP
|
|||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=
|
||||
github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
|
||||
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
|
||||
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
|
@ -559,8 +561,8 @@ github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+
|
|||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
|
||||
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
|
||||
github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw=
|
||||
github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
|
@ -569,8 +571,8 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0
|
|||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU=
|
||||
github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw=
|
||||
github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU=
|
||||
github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
|
@ -609,8 +611,8 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU
|
|||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20221118153622-cddfe74b6787 h1:DTlEqjjlMddN3py3sGtuqOOtxvhXiFIH9N9nhawC7t4=
|
||||
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20221118153622-cddfe74b6787/go.mod h1:Vg7Cbb370S+JihB+of1rWm9Aaxzf0GPPvKszPeSb7AE=
|
||||
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20230315165931-62bef9ffb441 h1:ZSB93rvaWarOv/TTJp1wicIygQLNx6fZhgsmxDBAnO0=
|
||||
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20230315165931-62bef9ffb441/go.mod h1:dE12DOucCq23gjGGGhtbyx41FBxuHxjpPvG+ArO+8t0=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
|
||||
|
@ -849,10 +851,10 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/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-20220704084225-05e143d24a9e/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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
|
|
|
@ -1,6 +1,61 @@
|
|||
package transactions
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
)
|
||||
|
||||
type GlobalTransactionDoc struct {
|
||||
ID string `bson:"_id" json:"id"`
|
||||
OriginTx *OriginTx `bson:"originTx" json:"originTx"`
|
||||
DestinationTx *DestinationTx `bson:"destinationTx" json:"destinationTx"`
|
||||
}
|
||||
|
||||
// OriginTx representa a origin transaction.
|
||||
type OriginTx struct {
|
||||
ChainID vaa.ChainID `bson:"chainId" json:"chainId"`
|
||||
TxHash string `bson:"txHash" json:"txHash"`
|
||||
Status string `bson:"status" json:"status"`
|
||||
Timestamp *time.Time `bson:"timestamp" json:"timestamp"`
|
||||
Signer *string `bson:"signer" json:"signer"`
|
||||
}
|
||||
|
||||
// DestinationTx representa a destination transaction.
|
||||
type DestinationTx struct {
|
||||
ChainID vaa.ChainID `bson:"chainId" json:"chainId"`
|
||||
Status string `bson:"status" json:"status"`
|
||||
Method string `bson:"method" json:"method"`
|
||||
TxHash string `bson:"txHash" json:"txHash"`
|
||||
From string `bson:"from" json:"from"`
|
||||
To string `bson:"to" json:"to"`
|
||||
BlockNumber string `bson:"blockNumber" json:"blockNumber"`
|
||||
Timestamp string `bson:"timestamp" json:"timestamp"`
|
||||
UpdatedAt *time.Time `bson:"updatedAt" json:"updatedAt"`
|
||||
}
|
||||
|
||||
// TransactionUpdate represents a transaction document.
|
||||
type TransactionUpdate struct {
|
||||
}
|
||||
|
||||
// GlobalTransactionQuery respresent a query for the globalTransactions mongodb document.
|
||||
type GlobalTransactionQuery struct {
|
||||
pagination.Pagination
|
||||
id string
|
||||
}
|
||||
|
||||
// Query create a new VaaQuery with default pagination vaues.
|
||||
func Query() *GlobalTransactionQuery {
|
||||
p := pagination.Default()
|
||||
return &GlobalTransactionQuery{Pagination: *p}
|
||||
}
|
||||
|
||||
// SetId set the chainId field of the VaaQuery struct.
|
||||
func (q *GlobalTransactionQuery) SetId(id string) *GlobalTransactionQuery {
|
||||
q.id = id
|
||||
return q
|
||||
}
|
||||
|
||||
type TransactionCountQuery struct {
|
||||
TimeSpan string
|
||||
|
|
|
@ -9,6 +9,10 @@ import (
|
|||
influxdb2 "github.com/influxdata/influxdb-client-go/v2"
|
||||
"github.com/influxdata/influxdb-client-go/v2/api"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/pkg/errors"
|
||||
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -43,12 +47,21 @@ type Repository struct {
|
|||
influxCli influxdb2.Client
|
||||
queryAPI api.QueryAPI
|
||||
bucket string
|
||||
db *mongo.Database
|
||||
collections struct {
|
||||
globalTransactions *mongo.Collection
|
||||
}
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewRepository(client influxdb2.Client, org, bucket string, logger *zap.Logger) *Repository {
|
||||
func NewRepository(client influxdb2.Client, org, bucket string, db *mongo.Database, logger *zap.Logger) *Repository {
|
||||
queryAPI := client.QueryAPI(org)
|
||||
return &Repository{influxCli: client, queryAPI: queryAPI, bucket: bucket, logger: logger}
|
||||
return &Repository{influxCli: client,
|
||||
queryAPI: queryAPI,
|
||||
bucket: bucket,
|
||||
db: db,
|
||||
collections: struct{ globalTransactions *mongo.Collection }{globalTransactions: db.Collection("globalTransactions")},
|
||||
logger: logger}
|
||||
}
|
||||
|
||||
func (r *Repository) FindChainActivity(ctx context.Context, q *ChainActivityQuery) ([]ChainActivityResult, error) {
|
||||
|
@ -111,3 +124,18 @@ func (r *Repository) GetTransactionCount(ctx context.Context, q *TransactionCoun
|
|||
func (r *Repository) buildLastTrxQuery(q *TransactionCountQuery) string {
|
||||
return fmt.Sprintf(queryTemplateVaaCount, r.bucket, q.TimeSpan, q.SampleRate)
|
||||
}
|
||||
|
||||
func (r *Repository) FindGlobalTransactionByID(ctx context.Context, q GlobalTransactionQuery) (*GlobalTransactionDoc, error) {
|
||||
var globalTranstaction GlobalTransactionDoc
|
||||
err := r.db.Collection("globalTransactions").FindOne(ctx, bson.M{"_id": q.id}).Decode(&globalTranstaction)
|
||||
if err != nil {
|
||||
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 global transaction",
|
||||
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
return &globalTranstaction, nil
|
||||
}
|
||||
|
|
|
@ -2,7 +2,10 @@ package transactions
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/types"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -25,3 +28,11 @@ func (s *Service) GetTransactionCount(ctx context.Context, q *TransactionCountQu
|
|||
func (s *Service) GetChainActivity(ctx context.Context, q *ChainActivityQuery) ([]ChainActivityResult, error) {
|
||||
return s.repo.FindChainActivity(ctx, q)
|
||||
}
|
||||
|
||||
// FindGlobalTransactionByID find a global transaction by id.
|
||||
func (s *Service) FindGlobalTransactionByID(ctx context.Context, chainID vaa.ChainID, emitter *types.Address, seq string) (*GlobalTransactionDoc, error) {
|
||||
key := fmt.Sprintf("%d/%s/%s", chainID, emitter.ShortHex(), seq)
|
||||
q := GlobalTransactionQuery{
|
||||
id: key}
|
||||
return s.repo.FindGlobalTransactionByID(ctx, q)
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ func main() {
|
|||
governorRepo := governor.NewRepository(db, rootLogger)
|
||||
infrastructureRepo := infrastructure.NewRepository(db, rootLogger)
|
||||
heartbeatsRepo := heartbeats.NewRepository(db, rootLogger)
|
||||
transactionsRepo := transactions.NewRepository(influxCli, cfg.Influx.Organization, cfg.Influx.Bucket, rootLogger)
|
||||
transactionsRepo := transactions.NewRepository(influxCli, cfg.Influx.Organization, cfg.Influx.Bucket, db, rootLogger)
|
||||
|
||||
// Set up services
|
||||
vaaService := vaa.NewService(vaaRepo, cacheGetFunc, rootLogger)
|
||||
|
|
|
@ -58,6 +58,7 @@ func RegisterRoutes(
|
|||
// analytics
|
||||
api.Get("/last-txs", transactionCtrl.GetLastTransactions)
|
||||
api.Get("/x-chain-activity", transactionCtrl.GetChainActivity)
|
||||
api.Get("/global-tx/:chain/:emitter/:sequence", transactionCtrl.FindGlobalTransactionByID)
|
||||
|
||||
// vaas resource
|
||||
vaas := api.Group("/vaas")
|
||||
|
|
|
@ -144,3 +144,28 @@ func (c *Controller) GetChainActivity(ctx *fiber.Ctx) error {
|
|||
|
||||
return ctx.JSON(ChainActivity{Txs: txs})
|
||||
}
|
||||
|
||||
// FindGlobalTransactionByID godoc
|
||||
// @Description Find a global transaction by ID.
|
||||
// @Tags Wormscan
|
||||
// @ID find-global-transaction-by-id
|
||||
// @Param chain_id path integer true "id of the blockchain"
|
||||
// @Param emitter path string true "address of the emitter"
|
||||
// @Param seq path integer true "sequence of the VAA"
|
||||
// @Success 200 {object} Tx
|
||||
// @Failure 400
|
||||
// @Failure 500
|
||||
// @Router /api/v1/global-tx/{chain_id}/{emitter}/{seq} [get]
|
||||
func (c *Controller) FindGlobalTransactionByID(ctx *fiber.Ctx) error {
|
||||
chainID, emitter, seq, err := middleware.ExtractVAAParams(ctx, c.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
globalTransaction, err := c.srv.FindGlobalTransactionByID(ctx.Context(), chainID, emitter, strconv.FormatUint(seq, 10))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ctx.JSON(globalTransaction)
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ type Server struct {
|
|||
|
||||
// NewServer creates a GRPC server.
|
||||
func NewServer(h *Handler, logger *zap.Logger) *grpc.Server {
|
||||
grpcServer := common.NewInstrumentedGRPCServer(logger)
|
||||
grpcServer := common.NewInstrumentedGRPCServer(logger, common.GrpcLogDetailMinimal)
|
||||
publicrpcv1.RegisterPublicRPCServiceServer(grpcServer, h)
|
||||
return grpcServer
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
.env
|
|
@ -0,0 +1,21 @@
|
|||
# syntax=docker.io/docker/dockerfile:1.3@sha256:42399d4635eddd7a9b8a24be879d2f9a930d0ed040a61324cfdf59ef1357b3b2
|
||||
FROM --platform=linux/amd64 docker.io/golang:1.19.2@sha256:0467d7d12d170ed8d998a2dae4a09aa13d0aa56e6d23c4ec2b1e4faacf86a813 AS build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY contract-watcher contract-watcher
|
||||
COPY common common
|
||||
|
||||
# Build the Go app
|
||||
RUN cd contract-watcher && CGO_ENABLED=0 GOOS=linux go build -o "./contract-watcher" cmd/main.go
|
||||
|
||||
############################
|
||||
# STEP 2 build a small image
|
||||
############################
|
||||
FROM alpine
|
||||
#Copy certificates
|
||||
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||
# Copy our static executable.
|
||||
COPY --from=build "/app/contract-watcher/contract-watcher" "/contract-watcher"
|
||||
# Run the binary.
|
||||
ENTRYPOINT ["/contract-watcher"]
|
|
@ -0,0 +1,17 @@
|
|||
SHELL := /bin/bash
|
||||
|
||||
|
||||
## help: print this help message
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo 'Usage:'
|
||||
@sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /'
|
||||
|
||||
build:
|
||||
go build -o contract-watcher cmd/main.go
|
||||
|
||||
test:
|
||||
go test -v -cover ./...
|
||||
|
||||
|
||||
.PHONY: build doc test
|
|
@ -0,0 +1,158 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
ipfslog "github.com/ipfs/go-log/v2"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/common/domain"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/common/health"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/config"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/http/infrastructure"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/internal/ankr"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/internal/db"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/processor"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/storage"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/watcher"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
type exitCode int
|
||||
|
||||
func handleExit() {
|
||||
if r := recover(); r != nil {
|
||||
if e, ok := r.(exitCode); ok {
|
||||
os.Exit(int(e))
|
||||
}
|
||||
panic(r) // not an Exit, bubble up
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
defer handleExit()
|
||||
rootCtx, rootCtxCancel := context.WithCancel(context.Background())
|
||||
|
||||
config, err := config.New(rootCtx)
|
||||
if err != nil {
|
||||
log.Fatal("Error creating config", err)
|
||||
}
|
||||
|
||||
level, err := ipfslog.LevelFromString(config.LogLevel)
|
||||
if err != nil {
|
||||
log.Fatal("Invalid log level", err)
|
||||
}
|
||||
|
||||
logger := ipfslog.Logger("wormhole-explorer-contract-watcher").Desugar()
|
||||
ipfslog.SetAllLoggers(level)
|
||||
|
||||
logger.Info("Starting wormhole-explorer-contract-watcher ...")
|
||||
|
||||
//setup DB connection
|
||||
db, err := db.New(rootCtx, logger, config.MongoURI, config.MongoDatabase)
|
||||
if err != nil {
|
||||
logger.Fatal("failed to connect MongoDB", zap.Error(err))
|
||||
}
|
||||
|
||||
// get health check functions.
|
||||
healthChecks, err := newHealthChecks(rootCtx, db.Database)
|
||||
if err != nil {
|
||||
logger.Fatal("failed to create health checks", zap.Error(err))
|
||||
}
|
||||
|
||||
// create repositories
|
||||
repo := storage.NewRepository(db.Database, logger)
|
||||
|
||||
// create watchers
|
||||
watchers := newWatchers(config.P2pNetwork, config.AnkrUrl, repo, logger)
|
||||
|
||||
//create processor
|
||||
processor := processor.NewProcessor(watchers, logger)
|
||||
processor.Start(rootCtx)
|
||||
|
||||
// create and start server.
|
||||
server := infrastructure.NewServer(logger, config.Port, config.PprofEnabled, healthChecks...)
|
||||
server.Start()
|
||||
|
||||
logger.Info("Started wormhole-explorer-contract-watcher")
|
||||
|
||||
// Waiting for signal
|
||||
sigterm := make(chan os.Signal, 1)
|
||||
signal.Notify(sigterm, syscall.SIGINT, syscall.SIGTERM)
|
||||
select {
|
||||
case <-rootCtx.Done():
|
||||
logger.Warn("Terminating with root context cancelled.")
|
||||
case signal := <-sigterm:
|
||||
logger.Info("Terminating with signal.", zap.String("signal", signal.String()))
|
||||
}
|
||||
|
||||
logger.Info("root context cancelled, exiting...")
|
||||
rootCtxCancel()
|
||||
|
||||
logger.Info("Closing processor ...")
|
||||
processor.Close()
|
||||
logger.Info("Closing database connections ...")
|
||||
db.Close()
|
||||
logger.Info("Closing Http server ...")
|
||||
server.Stop()
|
||||
logger.Info("Finished wormhole-explorer-contract-watcher")
|
||||
}
|
||||
|
||||
func newHealthChecks(ctx context.Context, db *mongo.Database) ([]health.Check, error) {
|
||||
return []health.Check{health.Mongo(db)}, nil
|
||||
}
|
||||
|
||||
type watcherBlockchain struct {
|
||||
chainID vaa.ChainID
|
||||
name string
|
||||
address string
|
||||
sizeBlocks uint8
|
||||
waitSeconds uint16
|
||||
initialBlock int64
|
||||
}
|
||||
|
||||
func newWatchers(p2pNetwork, ankUrl string, repo *storage.Repository, logger *zap.Logger) []watcher.ContractWatcher {
|
||||
var watchers []watcherBlockchain
|
||||
var maxRequestPerSecond int
|
||||
switch p2pNetwork {
|
||||
case domain.P2pMainNet:
|
||||
watchers, maxRequestPerSecond = newWatchersForMainnet()
|
||||
case domain.P2pTestNet:
|
||||
watchers, maxRequestPerSecond = newWatchersForTestnet()
|
||||
default:
|
||||
watchers = []watcherBlockchain{}
|
||||
}
|
||||
result := make([]watcher.ContractWatcher, 0)
|
||||
limiter := rate.NewLimiter(rate.Every(time.Second/time.Duration(maxRequestPerSecond)), maxRequestPerSecond)
|
||||
client := ankr.NewAnkrSDK(ankUrl, limiter)
|
||||
for _, w := range watchers {
|
||||
params := watcher.EVMParams{ChainID: w.chainID, Blockchain: w.name, ContractAddress: w.address,
|
||||
SizeBlocks: w.sizeBlocks, WaitSeconds: w.waitSeconds, InitialBlock: w.initialBlock}
|
||||
result = append(result, watcher.NewEVMWatcher(client, repo, params, logger))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func newWatchersForMainnet() ([]watcherBlockchain, int) {
|
||||
return []watcherBlockchain{
|
||||
{vaa.ChainIDEthereum, "eth", "0x3ee18B2214AFF97000D974cf647E7C347E8fa585", 100, 10, 16820790},
|
||||
{vaa.ChainIDPolygon, "polygon", "0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE", 100, 10, 40307020},
|
||||
{vaa.ChainIDBSC, "bsc", "0xB6F6D86a8f9879A9c87f643768d9efc38c1Da6E7", 100, 10, 26436320},
|
||||
{vaa.ChainIDFantom, "fantom", "0x7C9Fc5741288cDFdD83CeB07f3ea7e22618D79D2", 100, 10, 57525624},
|
||||
}, 1000
|
||||
}
|
||||
|
||||
func newWatchersForTestnet() ([]watcherBlockchain, int) {
|
||||
return []watcherBlockchain{
|
||||
{vaa.ChainIDEthereum, "eth_goerli", "0xF890982f9310df57d00f659cf4fd87e65adEd8d7", 100, 10, 8660321},
|
||||
{vaa.ChainIDPolygon, "polygon_mumbai", "0x377D55a7928c046E18eEbb61977e714d2a76472a", 100, 10, 33151522},
|
||||
{vaa.ChainIDBSC, "bsc_testnet_chapel", "0x9dcF9D205C9De35334D646BeE44b2D2859712A09", 100, 10, 28071327},
|
||||
{vaa.ChainIDFantom, "fantom_testnet", "0x599CEa2204B4FaECd584Ab1F2b6aCA137a0afbE8", 100, 10, 14524466},
|
||||
}, 100
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/sethvargo/go-envconfig"
|
||||
)
|
||||
|
||||
// Configuration represents the application configuration with the default values.
|
||||
type Configuration struct {
|
||||
Env string `env:"ENV,default=development"`
|
||||
LogLevel string `env:"LOG_LEVEL,default=INFO"`
|
||||
Port string `env:"PORT,default=8000"`
|
||||
MongoURI string `env:"MONGODB_URI,required"`
|
||||
MongoDatabase string `env:"MONGODB_DATABASE,required"`
|
||||
AnkrUrl string `env:"ANKR_URL,required"`
|
||||
PprofEnabled bool `env:"PPROF_ENABLED,default=false"`
|
||||
P2pNetwork string `env:"P2P_NETWORK,required"`
|
||||
}
|
||||
|
||||
// New creates a configuration with the values from .env file and environment variables.
|
||||
func New(ctx context.Context) (*Configuration, error) {
|
||||
_ = godotenv.Load(".env", "../.env")
|
||||
|
||||
var configuration Configuration
|
||||
if err := envconfig.Process(ctx, &configuration); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &configuration, nil
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
module github.com/wormhole-foundation/wormhole-explorer/contract-watcher
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/gofiber/fiber/v2 v2.42.0
|
||||
github.com/ipfs/go-log/v2 v2.5.1
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/sethvargo/go-envconfig v0.9.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/wormhole-foundation/wormhole-explorer/common v0.0.0-20230307192542-867f1c29626a
|
||||
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20230308163036-9b3458a90997
|
||||
go.mongodb.org/mongo-driver v1.11.2
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.20.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.20.4 // indirect
|
||||
github.com/aws/smithy-go v1.13.5 // indirect
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
|
||||
github.com/deepmap/oapi-codegen v1.12.4 // indirect
|
||||
github.com/ethereum/go-ethereum v1.11.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/holiman/uint256 v1.2.1 // indirect
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.12.2 // indirect
|
||||
github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf // indirect
|
||||
github.com/klauspost/compress v1.16.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/montanaflynn/stats v0.7.0 // indirect
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 // indirect
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect
|
||||
github.com/tinylib/msgp v1.1.8 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.44.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
golang.org/x/crypto v0.7.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
replace github.com/wormhole-foundation/wormhole-explorer/common => ../common
|
|
@ -0,0 +1,228 @@
|
|||
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.5 h1:TzCUW1Nq4H8Xscph5M/skINUitxM5UBAyvm2s7XBzL4=
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.5/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29 h1:9/aKwwus0TQxppPXFmf010DFrE+ssSbzroLVYINA+xE=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29/go.mod h1:Dip3sIGv485+xerzVv24emnjX5Sg88utCL8fwGmCeWg=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23 h1:b/Vn141DBuLVgXbhRWIrl9g+ww7G+ScV5SzniWR13jQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23/go.mod h1:mr6c4cHC+S/MMkrjtSlG4QA36kOznDep+0fga5L/fGQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.20.4 h1:WrHiTFASw/Q0lGX2kEKvzMobxsMno/WuPXJyZyEGKEg=
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.20.4/go.mod h1:e1fyQ5uQWkMKrxMXF/B5YwgKHXIbdVsU3Ttb0XqnMQg=
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.20.4 h1:8bI15PB1gxNcW53Dx3DVPZltmRiNQbtEsCtHXabNYMc=
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.20.4/go.mod h1:DVY5QFIndM5hWkrO+9lK4EN7mJUrttvpbbYcu2/id1Y=
|
||||
github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8=
|
||||
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc=
|
||||
github.com/deepmap/oapi-codegen v1.12.4 h1:pPmn6qI9MuOtCz82WY2Xaw46EQjgvxednXXrP7g5Q2s=
|
||||
github.com/deepmap/oapi-codegen v1.12.4/go.mod h1:3lgHGMu6myQ2vqbbTXH2H1o4eXFTGnFiDaOaKKl5yas=
|
||||
github.com/ethereum/go-ethereum v1.11.3 h1:uuBkYUJW9aY5JYi3+sqLHz+XWyo5fmn/ab9XcbtVDTU=
|
||||
github.com/ethereum/go-ethereum v1.11.3/go.mod h1:rBUvAl5cdVrAei9q5lgOU7RSEuPJk1nlBDnS/YSoKQE=
|
||||
github.com/gofiber/fiber/v2 v2.42.0 h1:Fnp7ybWvS+sjNQsFvkhf4G8OhXswvB6Vee8hM/LyS+8=
|
||||
github.com/gofiber/fiber/v2 v2.42.0/go.mod h1:3+SGNjqMh5VQH5Vz2Wdi43zTIV16ktlFd3x3R6O1Zlc=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw=
|
||||
github.com/holiman/uint256 v1.2.1 h1:XRtyuda/zw2l+Bq/38n5XUoEF72aSOu/77Thd9pPp2o=
|
||||
github.com/holiman/uint256 v1.2.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.12.2 h1:uYABKdrEKlYm+++qfKdbgaHKBPmoWR5wpbmj6MBB/2g=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.12.2/go.mod h1:YteV91FiQxRdccyJ2cHvj2f/5sq4y4Njqu1fQzsQCOU=
|
||||
github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf h1:7JTmneyiNEwVBOHSjoMxiWAqB992atOeepeFYegn5RU=
|
||||
github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
|
||||
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/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4=
|
||||
github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/montanaflynn/stats v0.7.0 h1:r3y12KyNxj/Sb/iOE46ws+3mS1+MZca1wlHQFPsY/JU=
|
||||
github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
|
||||
github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 h1:rmMl4fXJhKMNWl+K+r/fq4FbbKI+Ia2m9hYBLm2h4G4=
|
||||
github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94/go.mod h1:90zrgN3D/WJsDd1iXHT96alCoN2KJo6/4x1DZC3wZs8=
|
||||
github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4=
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk=
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g=
|
||||
github.com/sethvargo/go-envconfig v0.9.0 h1:Q6FQ6hVEeTECULvkJZakq3dZMeBQ3JUpcKMfPQbKMDE=
|
||||
github.com/sethvargo/go-envconfig v0.9.0/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YIlt8GMUX6yyNFs0=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw=
|
||||
github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
|
||||
github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw=
|
||||
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/fasthttp v1.44.0 h1:R+gLUhldIsfg1HokMuQjdQ5bh9nuXHPIfvkYUu9eR5Q=
|
||||
github.com/valyala/fasthttp v1.44.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20230308163036-9b3458a90997 h1:K9P4tfL0Q9MuoJjIKMNzwvLJeYHHSoVrIL7CxJfIz8w=
|
||||
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20230308163036-9b3458a90997/go.mod h1:dE12DOucCq23gjGGGhtbyx41FBxuHxjpPvG+ArO+8t0=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk=
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.mongodb.org/mongo-driver v1.11.2 h1:+1v2rDQUWNcGW7/7E0Jvdz51V38XXxJfhzbV17aNHCw=
|
||||
go.mongodb.org/mongo-driver v1.11.2/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8=
|
||||
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/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 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
@ -0,0 +1,46 @@
|
|||
package infrastructure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
health "github.com/wormhole-foundation/wormhole-explorer/common/health"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Controller definition.
|
||||
type Controller struct {
|
||||
checks []health.Check
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewController creates a Controller instance.
|
||||
func NewController(checks []health.Check, logger *zap.Logger) *Controller {
|
||||
return &Controller{checks: checks, logger: logger}
|
||||
}
|
||||
|
||||
// HealthCheck handler for the endpoint /health.
|
||||
func (c *Controller) HealthCheck(ctx *fiber.Ctx) error {
|
||||
return ctx.JSON(struct {
|
||||
Status string `json:"status"`
|
||||
}{Status: "OK"})
|
||||
}
|
||||
|
||||
// ReadyCheck handler for the endpoint /ready.
|
||||
func (c *Controller) ReadyCheck(ctx *fiber.Ctx) error {
|
||||
rctx := ctx.Context()
|
||||
requestID := fmt.Sprintf("%v", rctx.Value("requestid"))
|
||||
for _, check := range c.checks {
|
||||
if err := check(rctx); err != nil {
|
||||
c.logger.Error("Ready check failed", zap.Error(err), zap.String("requestID", requestID))
|
||||
return ctx.Status(fiber.StatusInternalServerError).JSON(struct {
|
||||
Ready string `json:"ready"`
|
||||
Error string `json:"error"`
|
||||
}{Ready: "NO", Error: err.Error()})
|
||||
}
|
||||
}
|
||||
return ctx.Status(fiber.StatusOK).JSON(struct {
|
||||
Ready string `json:"ready"`
|
||||
}{Ready: "OK"})
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package infrastructure
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/pprof"
|
||||
health "github.com/wormhole-foundation/wormhole-explorer/common/health"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
app *fiber.App
|
||||
port string
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewServer(logger *zap.Logger, port string, pprofEnabled bool, checks ...health.Check) *Server {
|
||||
app := fiber.New(fiber.Config{DisableStartupMessage: true})
|
||||
|
||||
// config use of middlware.
|
||||
if pprofEnabled {
|
||||
app.Use(pprof.New())
|
||||
}
|
||||
|
||||
ctrl := NewController(checks, logger)
|
||||
api := app.Group("/api")
|
||||
api.Get("/health", ctrl.HealthCheck)
|
||||
api.Get("/ready", ctrl.ReadyCheck)
|
||||
|
||||
return &Server{
|
||||
app: app,
|
||||
port: port,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// Start listen serves HTTP requests from addr.
|
||||
func (s *Server) Start() {
|
||||
addr := ":" + s.port
|
||||
s.logger.Info("Listening on " + addr)
|
||||
go func() {
|
||||
s.app.Listen(addr)
|
||||
}()
|
||||
}
|
||||
|
||||
// Stop gracefull server.
|
||||
func (s *Server) Stop() {
|
||||
_ = s.app.Shutdown()
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package ankr
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
type AnkrSDK struct {
|
||||
url string
|
||||
client *http.Client
|
||||
rl *rate.Limiter
|
||||
}
|
||||
|
||||
func NewAnkrSDK(url string, rl *rate.Limiter) *AnkrSDK {
|
||||
return &AnkrSDK{
|
||||
url: url,
|
||||
rl: rl,
|
||||
client: &http.Client{},
|
||||
}
|
||||
}
|
||||
|
||||
func (s AnkrSDK) GetTransactionsByAddress(ctx context.Context, request TransactionsByAddressRequest) (*TransactionsByAddressResponse, error) {
|
||||
payload, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", s.url, bytes.NewReader(payload))
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
|
||||
s.rl.Wait(ctx)
|
||||
|
||||
res, err := s.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response TransactionsByAddressResponse
|
||||
err = json.Unmarshal(body, &response)
|
||||
|
||||
return &response, err
|
||||
|
||||
}
|
||||
|
||||
func (s AnkrSDK) GetBlockchainStats(ctx context.Context, blockchain string) (*BlockchainStatsResponse, error) {
|
||||
request := TransactionsByAddressRequest{
|
||||
ID: rand.Int63(),
|
||||
Jsonrpc: "2.0",
|
||||
Method: "ankr_getBlockchainStats",
|
||||
RequestParams: RequestParams{
|
||||
Blockchain: blockchain,
|
||||
},
|
||||
}
|
||||
|
||||
payload, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := http.NewRequest("POST", s.url, bytes.NewReader(payload))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
|
||||
s.rl.Wait(ctx)
|
||||
|
||||
res, err := s.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response BlockchainStatsResponse
|
||||
err = json.Unmarshal(body, &response)
|
||||
|
||||
return &response, err
|
||||
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package ankr
|
||||
|
||||
type MaultichainOption func(*TransactionsByAddressRequest)
|
||||
|
||||
type TransactionsByAddressRequest struct {
|
||||
ID int64 `json:"id"`
|
||||
Jsonrpc string `json:"jsonrpc"`
|
||||
Method string `json:"method"`
|
||||
RequestParams RequestParams `json:"params"`
|
||||
}
|
||||
|
||||
func WithBlochchain(blockchain string) MaultichainOption {
|
||||
return func(h *TransactionsByAddressRequest) {
|
||||
h.RequestParams.Blockchain = blockchain
|
||||
}
|
||||
}
|
||||
|
||||
func WithContract(address string) MaultichainOption {
|
||||
return func(h *TransactionsByAddressRequest) {
|
||||
h.RequestParams.Address = address
|
||||
}
|
||||
}
|
||||
|
||||
func WithBlocks(fromBlock int64, toBlock int64) MaultichainOption {
|
||||
return func(h *TransactionsByAddressRequest) {
|
||||
h.RequestParams.FromBlock = fromBlock
|
||||
h.RequestParams.ToBlock = toBlock
|
||||
}
|
||||
}
|
||||
|
||||
func WithPageToken(pageToken string) MaultichainOption {
|
||||
return func(h *TransactionsByAddressRequest) {
|
||||
h.RequestParams.PageToken = pageToken
|
||||
}
|
||||
}
|
||||
|
||||
func NewTransactionsByAddressRequest(opts ...MaultichainOption) *TransactionsByAddressRequest {
|
||||
const (
|
||||
defaultMethod = "ankr_getTransactionsByAddress"
|
||||
)
|
||||
|
||||
h := &TransactionsByAddressRequest{
|
||||
ID: 1,
|
||||
Jsonrpc: "2.0",
|
||||
Method: defaultMethod,
|
||||
RequestParams: RequestParams{
|
||||
DescOrder: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(h)
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
type RequestParams struct {
|
||||
Address string `json:"address"`
|
||||
Blockchain string `json:"blockchain"`
|
||||
FromBlock int64 `json:"fromBlock,omitempty"`
|
||||
ToBlock int64 `json:"toBlock,omitempty"`
|
||||
FromTimestamp int64 `json:"fromTimestamp,omitempty"`
|
||||
ToTimestamp int64 `json:"toTimestamp,omitempty"`
|
||||
IncludeLogs bool `json:"includeLogs,omitempty"`
|
||||
DescOrder bool `json:"descOrder,omitempty"`
|
||||
PageSize int64 `json:"pageSize,omitempty"`
|
||||
PageToken string `json:"pageToken,omitempty"`
|
||||
}
|
||||
|
||||
type TransactionsByAddressResponse struct {
|
||||
ID int64 `json:"id"`
|
||||
Jsonrpc string `json:"jsonrpc"`
|
||||
Result struct {
|
||||
NextPageToken string `json:"nextPageToken"`
|
||||
Transactions []struct {
|
||||
BlockHash string `json:"blockHash"`
|
||||
BlockNumber string `json:"blockNumber"`
|
||||
Blockchain string `json:"blockchain"`
|
||||
CumulativeGasUsed string `json:"cumulativeGasUsed"`
|
||||
From string `json:"from"`
|
||||
Gas string `json:"gas"`
|
||||
GasPrice string `json:"gasPrice"`
|
||||
GasUsed string `json:"gasUsed"`
|
||||
Hash string `json:"hash"`
|
||||
Input string `json:"input"`
|
||||
Logs []struct {
|
||||
Address string `json:"address"`
|
||||
BlockHash string `json:"blockHash"`
|
||||
BlockNumber string `json:"blockNumber"`
|
||||
Blockchain string `json:"blockchain"`
|
||||
Data string `json:"data"`
|
||||
LogIndex string `json:"logIndex"`
|
||||
Removed bool `json:"removed"`
|
||||
Topics []string `json:"topics"`
|
||||
TransactionHash string `json:"transactionHash"`
|
||||
TransactionIndex string `json:"transactionIndex"`
|
||||
} `json:"logs"`
|
||||
Nonce string `json:"nonce"`
|
||||
R string `json:"r"`
|
||||
S string `json:"s"`
|
||||
Status string `json:"status"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
To string `json:"to"`
|
||||
TransactionIndex string `json:"transactionIndex"`
|
||||
Type string `json:"type"`
|
||||
V string `json:"v"`
|
||||
Value string `json:"value"`
|
||||
} `json:"transactions"`
|
||||
} `json:"result"`
|
||||
}
|
||||
|
||||
type BlockchainStatsResponse struct {
|
||||
ID int64 `json:"id"`
|
||||
Jsonrpc string `json:"jsonrpc"`
|
||||
Result struct {
|
||||
Stats []struct {
|
||||
BlockTimeMs int64 `json:"blockTimeMs"`
|
||||
Blockchain string `json:"blockchain"`
|
||||
LatestBlockNumber int64 `json:"latestBlockNumber"`
|
||||
NativeCoinUsdPrice string `json:"nativeCoinUsdPrice"`
|
||||
TotalEventsCount int64 `json:"totalEventsCount"`
|
||||
TotalTransactionsCount int64 `json:"totalTransactionsCount"`
|
||||
} `json:"stats"`
|
||||
} `json:"result"`
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Database definition.
|
||||
type Database struct {
|
||||
Database *mongo.Database
|
||||
client *mongo.Client
|
||||
}
|
||||
|
||||
// New connects to DB and returns a client that will disconnect when the passed in context is cancelled.
|
||||
func New(appCtx context.Context, log *zap.Logger, uri, databaseName string) (*Database, error) {
|
||||
cli, err := mongo.Connect(appCtx, options.Client().ApplyURI(uri))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Database{client: cli, Database: cli.Database(databaseName)}, err
|
||||
}
|
||||
|
||||
// Close closes the database connections.
|
||||
func (d *Database) Close() error {
|
||||
ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(30*time.Second))
|
||||
return d.client.Disconnect(ctx)
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package processor
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/watcher"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type Processor struct {
|
||||
watchers []watcher.ContractWatcher
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewProcessor(watchers []watcher.ContractWatcher, logger *zap.Logger) *Processor {
|
||||
return &Processor{watchers: watchers, logger: logger}
|
||||
}
|
||||
|
||||
func (p *Processor) Start(ctx context.Context) {
|
||||
for _, watcher := range p.watchers {
|
||||
go watcher.Start(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Processor) Close() {
|
||||
for _, watcher := range p.watchers {
|
||||
watcher.Close()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
)
|
||||
|
||||
// DestinationTx representa a destination transaction.
|
||||
type DestinationTx struct {
|
||||
ChainID vaa.ChainID `bson:"chainId"`
|
||||
Status string `bson:"status"`
|
||||
Method string `bson:"method"`
|
||||
TxHash string `bson:"txHash"`
|
||||
From string `bson:"from"`
|
||||
To string `bson:"to"`
|
||||
BlockNumber string `bson:"blockNumber"`
|
||||
Timestamp *time.Time `bson:"timestamp"`
|
||||
UpdatedAt *time.Time `bson:"updatedAt"`
|
||||
}
|
||||
|
||||
type IndexingTimestamps struct {
|
||||
IndexedAt time.Time `bson:"indexedAt"`
|
||||
}
|
||||
|
||||
// TransactionUpdate represents a transaction document.
|
||||
type TransactionUpdate struct {
|
||||
ID string `bson:"_id"`
|
||||
Destination DestinationTx `bson:"destinationTx"`
|
||||
}
|
||||
|
||||
type WatcherBlock struct {
|
||||
ID string `bson:"_id"`
|
||||
BlockNumber int64 `bson:"blockNumber"`
|
||||
UpdatedAt time.Time `bson:"updatedAt"`
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// repository errors
|
||||
var ErrDocNotFound = errors.New("NOT FOUND")
|
||||
|
||||
// Repository definitions.
|
||||
type Repository struct {
|
||||
db *mongo.Database
|
||||
log *zap.Logger
|
||||
collections struct {
|
||||
watcherBlock *mongo.Collection
|
||||
globalTransactions *mongo.Collection
|
||||
}
|
||||
}
|
||||
|
||||
// NewRepository create a new respository instance.
|
||||
func NewRepository(db *mongo.Database, log *zap.Logger) *Repository {
|
||||
return &Repository{db, log, struct {
|
||||
watcherBlock *mongo.Collection
|
||||
globalTransactions *mongo.Collection
|
||||
}{
|
||||
watcherBlock: db.Collection("watcherBlock"),
|
||||
globalTransactions: db.Collection("globalTransactions"),
|
||||
}}
|
||||
}
|
||||
|
||||
func indexedAt(t time.Time) IndexingTimestamps {
|
||||
return IndexingTimestamps{
|
||||
IndexedAt: t,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Repository) UpsertGlobalTransaction(ctx context.Context, globalTransactions TransactionUpdate) error {
|
||||
update := bson.M{
|
||||
"$set": globalTransactions,
|
||||
"$setOnInsert": indexedAt(time.Now()),
|
||||
"$inc": bson.D{{Key: "revision", Value: 1}},
|
||||
}
|
||||
|
||||
_, err := s.collections.globalTransactions.UpdateByID(ctx, globalTransactions.ID, update, options.Update().SetUpsert(true))
|
||||
if err != nil {
|
||||
s.log.Error("Error inserting global transaction", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
func (s *Repository) UpdateWatcherBlock(ctx context.Context, watcherBlock WatcherBlock) error {
|
||||
update := bson.M{
|
||||
"$set": watcherBlock,
|
||||
"$setOnInsert": indexedAt(time.Now()),
|
||||
}
|
||||
_, err := s.collections.watcherBlock.UpdateByID(ctx, watcherBlock.ID, update, options.Update().SetUpsert(true))
|
||||
if err != nil {
|
||||
s.log.Error("Error inserting watcher block", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Repository) GetCurrentBlock(ctx context.Context, blockchain string, defaultBlock int64) (int64, error) {
|
||||
var block WatcherBlock
|
||||
err := s.collections.watcherBlock.FindOne(ctx, bson.M{"_id": blockchain}).Decode(&block)
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return defaultBlock, nil
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
return block.BlockNumber, nil
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package watcher
|
||||
|
||||
import "context"
|
||||
|
||||
// ContractTracker is an interface for tracking contracts
|
||||
// It Tracks contract operations and persist the tx data
|
||||
// BackfillContract is used to backfill the contract data from the past
|
||||
type ContractWatcher interface {
|
||||
Start(ctx context.Context) error
|
||||
Close()
|
||||
}
|
|
@ -0,0 +1,311 @@
|
|||
package watcher
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/internal/ankr"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/storage"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const (
|
||||
MethodCompleteTransfer = "completeTransfer"
|
||||
MethodWrapAndTransfer = "wrapAndTransfer"
|
||||
MethodTransferTokens = "transferTokens"
|
||||
MethodAttestToken = "attestToken"
|
||||
MethodCompleteAndUnwrapETH = "completeAndUnwrapETH"
|
||||
MethodCreateWrapped = "createWrapped"
|
||||
MethodUpdateWrapped = "updateWrapped"
|
||||
MethodUnkown = "unknown"
|
||||
)
|
||||
|
||||
const (
|
||||
MethodIDCompleteTransfer = "0xc6878519"
|
||||
MethodIDWrapAndTransfer = "0x9981509f"
|
||||
MethodIDTransferTokens = "0x0f5287b0"
|
||||
MethodIDAttestToken = "0xc48fa115"
|
||||
MethodIDCompleteAndUnwrapETH = "0xff200cde"
|
||||
MethodIDCreateWrapped = "0xe8059810"
|
||||
MethodIDUpdateWrapped = "0xf768441f"
|
||||
)
|
||||
|
||||
const (
|
||||
TxStatusSuccess = "0x1"
|
||||
TxStatusFailReverted = "0x0"
|
||||
)
|
||||
|
||||
const (
|
||||
TxStatusFailedToProcess = "failed"
|
||||
TxStatusConfirmed = "completed"
|
||||
TxStatusUnkonwn = "unknown"
|
||||
)
|
||||
|
||||
type EVMWatcher struct {
|
||||
client *ankr.AnkrSDK
|
||||
chainID vaa.ChainID
|
||||
blockchain string
|
||||
contractAddress string
|
||||
sizeBlocks uint8
|
||||
waitSeconds uint16
|
||||
initialBlock int64
|
||||
repository *storage.Repository
|
||||
logger *zap.Logger
|
||||
close chan bool
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
type EVMParams struct {
|
||||
ChainID vaa.ChainID
|
||||
Blockchain string
|
||||
ContractAddress string
|
||||
SizeBlocks uint8
|
||||
WaitSeconds uint16
|
||||
InitialBlock int64
|
||||
}
|
||||
|
||||
func NewEVMWatcher(client *ankr.AnkrSDK, repo *storage.Repository, params EVMParams, logger *zap.Logger) *EVMWatcher {
|
||||
return &EVMWatcher{
|
||||
client: client,
|
||||
chainID: params.ChainID,
|
||||
blockchain: params.Blockchain,
|
||||
contractAddress: params.ContractAddress,
|
||||
sizeBlocks: params.SizeBlocks,
|
||||
waitSeconds: params.WaitSeconds,
|
||||
initialBlock: params.InitialBlock,
|
||||
repository: repo,
|
||||
logger: logger.With(zap.String("blockchain", params.Blockchain), zap.Uint16("chainId", uint16(params.ChainID))),
|
||||
}
|
||||
}
|
||||
|
||||
func (w *EVMWatcher) Start(ctx context.Context) error {
|
||||
// get the current block for the chain.
|
||||
currentBlock, err := w.repository.GetCurrentBlock(ctx, w.blockchain, w.initialBlock)
|
||||
if err != nil {
|
||||
w.logger.Error("cannot get current block", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
w.wg.Add(1)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
w.logger.Info("clossing watcher by context")
|
||||
w.wg.Done()
|
||||
return nil
|
||||
case <-w.close:
|
||||
w.logger.Info("clossing watcher")
|
||||
w.wg.Done()
|
||||
return nil
|
||||
default:
|
||||
// get the latest block for the chain.
|
||||
stats, err := w.client.GetBlockchainStats(ctx, w.blockchain)
|
||||
if err != nil {
|
||||
w.logger.Error("cannot get blockchain stats", zap.Error(err))
|
||||
}
|
||||
if len(stats.Result.Stats) == 0 {
|
||||
return fmt.Errorf("no stats for blockchain %s", w.blockchain)
|
||||
}
|
||||
|
||||
maxBlocks := int64(w.sizeBlocks)
|
||||
lastBlock := stats.Result.Stats[0].LatestBlockNumber
|
||||
if currentBlock < lastBlock {
|
||||
totalBlocks := (lastBlock-currentBlock)/maxBlocks + 1
|
||||
for i := 0; i < int(totalBlocks); i++ {
|
||||
fromBlock := currentBlock + int64(i)*maxBlocks
|
||||
toBlock := fromBlock + maxBlocks - 1
|
||||
if toBlock > lastBlock {
|
||||
toBlock = lastBlock
|
||||
}
|
||||
w.logger.Info("processing blocks", zap.Int64("from", fromBlock), zap.Int64("to", toBlock))
|
||||
w.processBlock(ctx, fromBlock, toBlock)
|
||||
w.logger.Info("blocks processed", zap.Int64("from", fromBlock), zap.Int64("to", toBlock))
|
||||
}
|
||||
// process all the blocks between current and last block.
|
||||
} else {
|
||||
w.logger.Info("waiting for new blocks")
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
w.wg.Done()
|
||||
return nil
|
||||
case <-time.After(time.Duration(w.waitSeconds) * time.Second):
|
||||
}
|
||||
}
|
||||
currentBlock = lastBlock
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (w *EVMWatcher) processBlock(ctx context.Context, currentBlock int64, lastBlock int64) {
|
||||
pageToken := ""
|
||||
hasPage := true
|
||||
|
||||
for hasPage {
|
||||
// get the transactions
|
||||
request := ankr.NewTransactionsByAddressRequest(
|
||||
ankr.WithBlochchain(w.blockchain),
|
||||
ankr.WithContract(w.contractAddress),
|
||||
ankr.WithBlocks(currentBlock, lastBlock),
|
||||
ankr.WithPageToken(pageToken),
|
||||
)
|
||||
|
||||
// get transaction data by address with pagination.
|
||||
r, err := w.client.GetTransactionsByAddress(ctx, *request)
|
||||
if err != nil {
|
||||
w.logger.Error("cannot get transactions by address", zap.Error(err))
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
|
||||
var lastBlockNumberHex string
|
||||
for _, tx := range r.Result.Transactions {
|
||||
w.logger.Debug("new tx", zap.String("tx", tx.Hash), zap.String("method", w.getMethodByInput(tx.Input)))
|
||||
method := w.getMethodByInput(tx.Input)
|
||||
switch method {
|
||||
case MethodCompleteTransfer, MethodCompleteAndUnwrapETH, MethodCreateWrapped, MethodUpdateWrapped:
|
||||
// parse the VAA
|
||||
vaa, err := w.parseInput(tx.Input)
|
||||
if err != nil {
|
||||
w.logger.Error("cannot parse VAA", zap.Error(err), zap.String("tx", tx.Hash))
|
||||
continue
|
||||
}
|
||||
|
||||
// get the timestamp.
|
||||
unixTime, err := strconv.ParseInt(remove0x(tx.Timestamp), 16, 64)
|
||||
var timestamp *time.Time
|
||||
if err != nil {
|
||||
w.logger.Error("cannot convert to timestamp", zap.Error(err), zap.String("tx", tx.Hash))
|
||||
} else {
|
||||
tm := time.Unix(unixTime, 0)
|
||||
timestamp = &tm
|
||||
}
|
||||
|
||||
// create global transaction.
|
||||
updatedAt := time.Now()
|
||||
globalTx := storage.TransactionUpdate{
|
||||
ID: vaa.MessageID(),
|
||||
Destination: storage.DestinationTx{
|
||||
ChainID: w.chainID,
|
||||
Status: w.getTxStatus(tx.Status),
|
||||
Method: w.getMethodByInput(tx.Input),
|
||||
TxHash: remove0x(tx.Hash),
|
||||
To: tx.To,
|
||||
From: tx.From,
|
||||
BlockNumber: tx.BlockNumber,
|
||||
Timestamp: timestamp,
|
||||
UpdatedAt: &updatedAt,
|
||||
},
|
||||
}
|
||||
err = w.repository.UpsertGlobalTransaction(ctx, globalTx)
|
||||
if err != nil {
|
||||
w.logger.Error("cannot save redeemed tx", zap.Error(err))
|
||||
}
|
||||
case MethodUnkown:
|
||||
w.logger.Warn("method unkown", zap.String("tx", tx.Hash))
|
||||
}
|
||||
lastBlockNumberHex = tx.BlockNumber
|
||||
}
|
||||
|
||||
newBlockNumber := int64(-1)
|
||||
if len(r.Result.Transactions) == 0 {
|
||||
newBlockNumber = lastBlock
|
||||
} else {
|
||||
lastBlockNumber := strings.Replace(lastBlockNumberHex, "0x", "", -1)
|
||||
newBlockNumber, err = strconv.ParseInt(lastBlockNumber, 16, 64)
|
||||
if err != nil {
|
||||
w.logger.Error("error parsing block number", zap.Error(err), zap.String("blockNumber", lastBlockNumber))
|
||||
}
|
||||
}
|
||||
|
||||
w.logger.Debug("new block",
|
||||
zap.Int64("currentBlock", currentBlock),
|
||||
zap.Int64("lastBlock", lastBlock),
|
||||
zap.Int64("newBlockNumber", newBlockNumber),
|
||||
zap.String("lastBlockNumberHex", lastBlockNumberHex))
|
||||
|
||||
if newBlockNumber != -1 {
|
||||
watcherBlock := storage.WatcherBlock{
|
||||
ID: w.blockchain,
|
||||
BlockNumber: newBlockNumber,
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
w.repository.UpdateWatcherBlock(ctx, watcherBlock)
|
||||
}
|
||||
|
||||
pageToken = r.Result.NextPageToken
|
||||
if pageToken == "" {
|
||||
hasPage = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *EVMWatcher) Close() {
|
||||
close(w.close)
|
||||
w.wg.Wait()
|
||||
}
|
||||
|
||||
// get transaction status
|
||||
func (w *EVMWatcher) getTxStatus(status string) string {
|
||||
switch status {
|
||||
case TxStatusSuccess:
|
||||
return TxStatusConfirmed
|
||||
case TxStatusFailReverted:
|
||||
return TxStatusFailedToProcess
|
||||
default:
|
||||
return fmt.Sprintf("%s: %s", TxStatusUnkonwn, status)
|
||||
}
|
||||
}
|
||||
|
||||
// get executed method by input
|
||||
// completeTransfer, completeAndUnwrapETH, createWrapped receive a VAA as input
|
||||
func (w *EVMWatcher) getMethodByInput(input string) string {
|
||||
if len(input) < 10 {
|
||||
return MethodUnkown
|
||||
}
|
||||
method := input[0:10]
|
||||
switch method {
|
||||
case MethodIDCompleteTransfer:
|
||||
return MethodCompleteTransfer
|
||||
case MethodIDWrapAndTransfer:
|
||||
return MethodWrapAndTransfer
|
||||
case MethodIDTransferTokens:
|
||||
return MethodTransferTokens
|
||||
case MethodIDAttestToken:
|
||||
return MethodAttestToken
|
||||
case MethodIDCompleteAndUnwrapETH:
|
||||
return MethodCompleteAndUnwrapETH
|
||||
case MethodIDCreateWrapped:
|
||||
return MethodCreateWrapped
|
||||
case MethodIDUpdateWrapped:
|
||||
return MethodUpdateWrapped
|
||||
default:
|
||||
return MethodUnkown
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// get the input and extract the method signature and VAA
|
||||
func (w *EVMWatcher) parseInput(input string) (*vaa.VAA, error) {
|
||||
// remove the first 64 characters plus 0x
|
||||
input = input[138:]
|
||||
vaaBytes, err := hex.DecodeString(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vaa, err := vaa.Unmarshal(vaaBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vaa, nil
|
||||
}
|
||||
|
||||
func remove0x(input string) string {
|
||||
return strings.Replace(input, "0x", "", -1)
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package watcher
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func Test_parseInput(t *testing.T) {
|
||||
logger := zap.NewExample()
|
||||
|
||||
w := NewEVMWatcher(nil, nil, EVMParams{}, logger)
|
||||
|
||||
_, err := w.parseInput("0xc68785190000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000041801000000030d001752692f4c9833d07d300d083af2485690244e432c8874577735982f7f5222d77a27ee7703bf15263be091cf76d5e7f614d1b273228aabe022779e803e731a7e0001a9aa6115f959f70d20b0c5d48db0c8bd5ab646fde61b3a8260f1afe77bae5dc11e48d43275ee32107f52f8eec12b0a454218d74a74073fec861f250bc8472e6d0006671461db8795cba03f7f0990875319171314d3182b1273805a521f240917be65634b9f2118dafe5845aeda5e7051de4284013802de32ccf8666f3d5a1a4b6ae901070c56fea7f99f1709ac593bf86a115b5adc0b865c3a832c21457fa8445b273cd714994c1dfeeece9aa36b7ca06914cfc7cffaf8b69afcf2f3fb8161f193c6231d0008a4b00cf265c31a5d5a93feebb75e2a32b69d0797d74a48d64529335cd9eb9c3368f45a57fbf03f149726bce3f0c5e95bf1affa8f73c8b6337a8d6b7bf7d56eaa010958c78eafaa1dbb7584dfb1f1336a9c0336b08e81b2c38e1f874d5a3596608f901959b3f43b453c14a35e0d801eb6aee9f63f3e302436780733926f83cf0186b9000a7ee0949495ae6d7b4a9c9669289c69d94b984dc3f7a5ad7d2e0c64b587db2d393eb6b791acc359c809bc04b78a3d7da1e71bc568eaf158da9e8a39ca58fe2a5d000b49b0beb343015b1fff9520f0749a89ecf4582a8a064b0dcc26afd8d6a6cad5f96ed990c9098df0cbe0cbded34608066942e0d8b3295a2fe81ececbc843d18379010c80a5bbb3504afd60cf290b6a7dd5b79fb39b082864aa0ae049e3ee939830730913ac155431479796b8f704abf65caa89cafa90b6c0c8a732cdb5a24b21661698000d523336c7038d5079b8107507dc659a6ffc7e975a036024f322159e40126708405f90c8ee86ec766a6fae9c25fb62f88f4a03a27a8f4972f083bd9d9287668aa7011079ebe7ed680ed5ca973f68ba93b7ea01cadf2e0b6686083c2bb8ed04a0cbf9356b198588d9fbcdd4eb519b63416aecf1924bd826c9ad277209c173408d16a65d0011f8e3eb4770c9e4e3ce2592970126037caee2f3121e78301edb3eed86645e54db0e4d14b093d526f154c9e0cbb2744eadd91970e506167b9e7730177aa22015b00012ef1e55545b5b4b1ed2cf18c1012838a1c02e586b015a1ec996bdbaa7ce6026f31ee78cfcb125cc732f58adbd5604998cac3f9deb4d07205e0fdfc94a18e98e780064053c510000247f0001ec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f50000000000043924200100000000000000000000000000000000000000000000000000000021596de513000000000000000000000000bba39fd2935d5769116ce38d46a71bde9cf030990002000000000000000000000000cc35f4c022992cdb0ab7b19fb45d4173a34fde02000200000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
||||
|
||||
assert.Nil(t, err)
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .NAME }}
|
||||
namespace: {{ .NAMESPACE }}
|
||||
spec:
|
||||
replicas: {{ .REPLICAS }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app: {{ .NAME }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: {{ .NAME }}
|
||||
spec:
|
||||
restartPolicy: Always
|
||||
terminationGracePeriodSeconds: 40
|
||||
containers:
|
||||
- name: {{ .NAME }}
|
||||
image: {{ .IMAGE_NAME }}
|
||||
imagePullPolicy: Always
|
||||
readinessProbe:
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 20
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /api/ready
|
||||
port: 8000
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /api/health
|
||||
port: 8000
|
||||
env:
|
||||
- name: ENV
|
||||
value: "PRODUCTION"
|
||||
- name: PORT
|
||||
value: "8000"
|
||||
- name: LOG_LEVEL
|
||||
value: "INFO"
|
||||
- name: MONGODB_URI
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mongodb
|
||||
key: mongo-uri
|
||||
- name: MONGODB_DATABASE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: config
|
||||
key: mongo-database
|
||||
- name: PPROF_ENABLED
|
||||
value: "{{ .PPROF_ENABLED }}"
|
||||
- name: P2P_NETWORK
|
||||
value: {{ .P2P_NETWORK }}
|
||||
- name: ANKR_URL
|
||||
value: {{ .ANKR_URL }}
|
||||
resources:
|
||||
limits:
|
||||
memory: {{ .RESOURCES_LIMITS_MEMORY }}
|
||||
cpu: {{ .RESOURCES_LIMITS_CPU }}
|
||||
requests:
|
||||
memory: {{ .RESOURCES_REQUESTS_MEMORY }}
|
||||
cpu: {{ .RESOURCES_REQUESTS_CPU }}
|
|
@ -0,0 +1,12 @@
|
|||
ENVIRONMENT=production
|
||||
NAMESPACE=wormscan
|
||||
NAME=wormscan-contract-watcher
|
||||
REPLICAS=1
|
||||
IMAGE_NAME=
|
||||
RESOURCES_LIMITS_MEMORY=256Mi
|
||||
RESOURCES_LIMITS_CPU=500m
|
||||
RESOURCES_REQUESTS_MEMORY=128Mi
|
||||
RESOURCES_REQUESTS_CPU=250m
|
||||
P2P_NETWORK=mainnet
|
||||
PPROF_ENABLED=false
|
||||
ANKR_URL=
|
|
@ -0,0 +1,12 @@
|
|||
ENVIRONMENT=staging
|
||||
NAMESPACE=wormscan
|
||||
NAME=wormscan-contract-watcher
|
||||
REPLICAS=1
|
||||
IMAGE_NAME=
|
||||
RESOURCES_LIMITS_MEMORY=128Mi
|
||||
RESOURCES_LIMITS_CPU=500m
|
||||
RESOURCES_REQUESTS_MEMORY=64Mi
|
||||
RESOURCES_REQUESTS_CPU=250m
|
||||
P2P_NETWORK=mainnet
|
||||
PPROF_ENABLED=true
|
||||
ANKR_URL=
|
|
@ -0,0 +1,12 @@
|
|||
ENVIRONMENT=test
|
||||
NAMESPACE=wormscan-testnet
|
||||
NAME=wormscan-contract-watcher
|
||||
REPLICAS=1
|
||||
IMAGE_NAME=
|
||||
RESOURCES_LIMITS_MEMORY=128Mi
|
||||
RESOURCES_LIMITS_CPU=200m
|
||||
RESOURCES_REQUESTS_MEMORY=64Mi
|
||||
RESOURCES_REQUESTS_CPU=100m
|
||||
P2P_NETWORK=testnet
|
||||
PPROF_ENABLED=false
|
||||
ANKR_URL=
|
43
fly/go.mod
43
fly/go.mod
|
@ -4,7 +4,7 @@ go 1.19
|
|||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go v1.44.133
|
||||
github.com/certusone/wormhole/node v0.0.0-20230120141536-53d554d93b02
|
||||
github.com/certusone/wormhole/node v0.0.0-20230315165931-62bef9ffb441
|
||||
github.com/dgraph-io/ristretto v0.1.1
|
||||
github.com/eko/gocache/v3 v3.1.2
|
||||
github.com/ethereum/go-ethereum v1.10.21
|
||||
|
@ -15,23 +15,19 @@ require (
|
|||
github.com/libp2p/go-libp2p-core v0.20.0
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20230123141139-45b3d18d80b2
|
||||
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20230315165931-62bef9ffb441
|
||||
go.mongodb.org/mongo-driver v1.11.2
|
||||
go.uber.org/zap v1.23.0
|
||||
google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
github.com/go-openapi/spec v0.20.4 // indirect
|
||||
github.com/go-openapi/swag v0.19.15 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/swaggo/swag v1.8.10 // indirect
|
||||
github.com/cosmos/cosmos-proto v1.0.0-alpha8 // indirect
|
||||
github.com/cosmos/gogoproto v1.4.3 // indirect
|
||||
github.com/cosmos/ibc-go/v4 v4.2.0 // indirect
|
||||
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||
github.com/holiman/uint256 v1.2.1 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -39,9 +35,8 @@ require (
|
|||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
|
||||
github.com/99designs/keyring v1.2.1 // indirect
|
||||
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect
|
||||
github.com/CosmWasm/wasmd v0.28.0 // indirect
|
||||
github.com/CosmWasm/wasmvm v1.0.0 // indirect
|
||||
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||
github.com/CosmWasm/wasmd v0.30.0 // indirect
|
||||
github.com/CosmWasm/wasmvm v1.1.1 // indirect
|
||||
github.com/Workiva/go-datastructures v1.0.53 // indirect
|
||||
github.com/XiaoMi/pegasus-go-client v0.0.0-20210427083443-f3b6b08bc4c2 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
|
@ -63,11 +58,10 @@ require (
|
|||
github.com/containerd/cgroups v1.0.4 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 // indirect
|
||||
github.com/cosmos/btcutil v1.0.5 // indirect
|
||||
github.com/cosmos/cosmos-sdk v0.45.9 // indirect
|
||||
github.com/cosmos/cosmos-sdk v0.45.11 // indirect
|
||||
github.com/cosmos/go-bip39 v1.0.0 // indirect
|
||||
github.com/cosmos/gorocksdb v1.2.0 // indirect
|
||||
github.com/cosmos/iavl v0.19.3 // indirect
|
||||
github.com/cosmos/ibc-go/v3 v3.3.0 // indirect
|
||||
github.com/cosmos/iavl v0.19.4 // indirect
|
||||
github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect
|
||||
github.com/creachadair/taskgroup v0.3.2 // indirect
|
||||
github.com/danieljoos/wincred v1.1.2 // indirect
|
||||
|
@ -86,7 +80,7 @@ require (
|
|||
github.com/felixge/httpsnoop v1.0.2 // indirect
|
||||
github.com/flynn/noise v1.0.0 // indirect
|
||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-kit/kit v0.12.0 // indirect
|
||||
github.com/go-kit/log v0.2.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
|
@ -99,7 +93,7 @@ require (
|
|||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/flatbuffers v1.12.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/gopacket v1.1.19 // indirect
|
||||
|
@ -213,12 +207,12 @@ require (
|
|||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/spf13/afero v1.8.2 // indirect
|
||||
github.com/spf13/afero v1.9.2 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/cobra v1.6.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.13.0 // indirect
|
||||
github.com/spf13/viper v1.14.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.1 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
|
||||
github.com/tendermint/btcd v0.1.1 // indirect
|
||||
|
@ -272,7 +266,6 @@ require (
|
|||
|
||||
require (
|
||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
||||
github.com/schollz/progressbar v1.0.0
|
||||
github.com/wormhole-foundation/wormhole-explorer/common v0.0.0-20230301134427-b3ec0bcc9eda
|
||||
)
|
||||
|
||||
|
@ -280,8 +273,8 @@ require (
|
|||
// https://github.com/cosmos/cosmos-sdk/issues/10925 for more details.
|
||||
replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
|
||||
|
||||
replace github.com/wormhole-foundation/wormchain => github.com/certusone/wormhole/wormchain v0.0.0-20230120141536-53d554d93b02
|
||||
replace github.com/wormhole-foundation/wormchain => github.com/certusone/wormhole/wormchain v0.0.0-20230315165931-62bef9ffb441
|
||||
|
||||
replace github.com/CosmWasm/wasmd v0.28.0 => github.com/wormhole-foundation/wasmd v0.28.0-wormhole-2
|
||||
replace github.com/CosmWasm/wasmd v0.30.0 => github.com/wormhole-foundation/wasmd v0.30.0-wormchain-1
|
||||
|
||||
replace github.com/cosmos/cosmos-sdk => github.com/wormhole-foundation/cosmos-sdk v0.45.9-wormhole
|
||||
|
|
304
fly/go.sum
304
fly/go.sum
File diff suppressed because it is too large
Load Diff
|
@ -32,7 +32,7 @@ func (h *GuardianSetHistory) Verify(vaa *sdk.VAA) error {
|
|||
}
|
||||
|
||||
// Verify guardian signatures
|
||||
if sdk.VerifySignatures(vaa.SigningMsg().Bytes(), vaa.Signatures, h.guardianSetsByIndex[idx].Keys) {
|
||||
if vaa.VerifySignatures(h.guardianSetsByIndex[idx].Keys) {
|
||||
return nil
|
||||
} else {
|
||||
return errors.New("VAA contains invalid signatures")
|
||||
|
|
|
@ -403,7 +403,7 @@ func main() {
|
|||
// Run supervisor.
|
||||
supervisor.New(rootCtx, logger, func(ctx context.Context) error {
|
||||
if err := supervisor.Run(ctx, "p2p",
|
||||
p2p.Run(obsvC, obsvReqC, nil, sendC, signedInC, priv, nil, gst, p2pNetworkConfig.P2pPort, p2pNetworkConfig.P2pNetworkID, p2pNetworkConfig.P2pBootstrap, "", false, rootCtxCancel, nil, nil, govConfigC, govStatusC)); err != nil {
|
||||
p2p.Run(obsvC, obsvReqC, nil, sendC, signedInC, priv, nil, gst, p2pNetworkConfig.P2pNetworkID, p2pNetworkConfig.P2pBootstrap, "", false, rootCtxCancel, nil, nil, govConfigC, govStatusC, nil)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
1
go.work
1
go.work
|
@ -4,6 +4,7 @@ use (
|
|||
./analytic
|
||||
./api
|
||||
./common
|
||||
./contract-watcher
|
||||
./fly
|
||||
./parser
|
||||
./pipeline
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
|
||||
func createGRPCServer(handler *Handler, logger *zap.Logger) (context.Context, *grpc.ClientConn, spyv1.SpyRPCServiceClient) {
|
||||
listen := bufconn.Listen(1024 * 1024)
|
||||
grpcServer := common.NewInstrumentedGRPCServer(logger)
|
||||
grpcServer := common.NewInstrumentedGRPCServer(logger, common.GrpcLogDetailMinimal)
|
||||
spyv1.RegisterSpyRPCServiceServer(grpcServer, handler)
|
||||
go func() {
|
||||
if err := grpcServer.Serve(listen); err != nil {
|
||||
|
|
|
@ -25,7 +25,7 @@ func NewServer(h *Handler, logger *zap.Logger, listenAddr string) (*Server, erro
|
|||
|
||||
logger.Info("spy server listening", zap.String("addr", l.Addr().String()))
|
||||
|
||||
grpcServer := common.NewInstrumentedGRPCServer(logger)
|
||||
grpcServer := common.NewInstrumentedGRPCServer(logger, common.GrpcLogDetailMinimal)
|
||||
spyv1.RegisterSpyRPCServiceServer(grpcServer, h)
|
||||
|
||||
runnale := supervisor.GRPCServer(grpcServer, l, false)
|
||||
|
|
Loading…
Reference in New Issue