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:
ftocal 2023-03-15 16:52:50 -03:00 committed by GitHub
parent 86f1e12f1c
commit 824ba3c7f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 2018 additions and 123 deletions

View File

@ -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

View File

@ -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"
]
},

View File

@ -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"
]
},

View File

@ -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.

View File

@ -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

View File

@ -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=

View File

@ -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

View File

@ -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"
)
@ -40,15 +44,24 @@ from(bucket: "%s")
`
type Repository struct {
influxCli influxdb2.Client
queryAPI api.QueryAPI
bucket string
logger *zap.Logger
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
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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")

View File

@ -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)
}

View File

@ -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
}

1
contract-watcher/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.env

View File

@ -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"]

17
contract-watcher/Makefile Normal file
View File

@ -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

View File

View File

@ -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
}

View File

@ -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
}

66
contract-watcher/go.mod Normal file
View File

@ -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

228
contract-watcher/go.sum Normal file
View File

@ -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=

View File

@ -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"})
}

View File

@ -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()
}

View File

@ -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
}

View File

@ -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"`
}

View File

@ -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)
}

View File

@ -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()
}
}

View File

@ -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"`
}

View File

@ -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
}

View File

@ -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()
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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 }}

View File

@ -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=

12
deploy/contract-watcher/env/staging.env vendored Normal file
View File

@ -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=

12
deploy/contract-watcher/env/test.env vendored Normal file
View File

@ -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=

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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")

View File

@ -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
}

View File

@ -4,6 +4,7 @@ use (
./analytic
./api
./common
./contract-watcher
./fly
./parser
./pipeline

View File

@ -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 {

View File

@ -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)