node/pkg/db: store signed VAAs in database
Bug: certusone/wormhole#282 Change-Id: Iecd4ff74a1e73655ac3240991a4dc36e572cdb15
This commit is contained in:
parent
b2495ca43e
commit
7e0bbdbe6e
|
@ -3,11 +3,13 @@ package guardiand
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/certusone/wormhole/bridge/pkg/db"
|
||||
"github.com/gagliardetto/solana-go/rpc"
|
||||
"log"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"path"
|
||||
"syscall"
|
||||
|
||||
solana_types "github.com/gagliardetto/solana-go"
|
||||
|
@ -322,6 +324,17 @@ func runBridge(cmd *cobra.Command, args []string) {
|
|||
}
|
||||
}
|
||||
|
||||
// Database
|
||||
dbPath := path.Join(*dataDir, "db")
|
||||
if err := os.MkdirAll(dbPath, 0700); err != nil {
|
||||
logger.Fatal("failed to create database directory", zap.Error(err))
|
||||
}
|
||||
db, err := db.Open(dbPath)
|
||||
if err != nil {
|
||||
logger.Fatal("failed to open database", zap.Error(err))
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// Guardian key
|
||||
gk, err := loadGuardianKey(*bridgeKeyPath)
|
||||
if err != nil {
|
||||
|
@ -417,6 +430,7 @@ func runBridge(cmd *cobra.Command, args []string) {
|
|||
|
||||
// TODO: this thing has way too many arguments at this point - make it an options struct
|
||||
p := processor.NewProcessor(ctx,
|
||||
db,
|
||||
lockC,
|
||||
setC,
|
||||
sendC,
|
||||
|
|
|
@ -5,6 +5,7 @@ go 1.16
|
|||
require (
|
||||
github.com/cenkalti/backoff/v4 v4.1.1
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/dgraph-io/badger/v3 v3.2103.1
|
||||
github.com/ethereum/go-ethereum v1.10.6
|
||||
github.com/gagliardetto/solana-go v0.3.5-0.20210727215348-0cf016734976
|
||||
github.com/gorilla/mux v1.7.4
|
||||
|
|
|
@ -65,6 +65,7 @@ github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo
|
|||
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
|
@ -228,17 +229,24 @@ github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70/go.mod h1:EoK/8RF
|
|||
github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ=
|
||||
github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
|
||||
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
|
||||
github.com/dgraph-io/badger v1.6.1 h1:w9pSFNSdq/JPM1N12Fz/F/bzo993Is1W+Q7HjPzi7yg=
|
||||
github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU=
|
||||
github.com/dgraph-io/badger/v3 v3.2103.1 h1:zaX53IRg7ycxVlkd5pYdCeFp1FynD6qBGQoQql3R3Hk=
|
||||
github.com/dgraph-io/badger/v3 v3.2103.1/go.mod h1:dULbq6ehJ5K0cGW/1TQ9iSfUk0gbSiToDWmWmTsJ53E=
|
||||
github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
|
||||
github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI=
|
||||
github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ=
|
||||
github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a h1:mq+R6XEM6lJX5VlLyZIrUSP8tSuJp82xTK89hvBwJbU=
|
||||
github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM=
|
||||
|
@ -320,6 +328,7 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
|||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
|
@ -363,6 +372,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
|
|||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/flatbuffers v1.12.0 h1:/PtAHvnBY4Kqnx/xCQ3OIV9uYcSFGScBsWI3Oogeh6w=
|
||||
github.com/google/flatbuffers v1.12.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
|
@ -587,6 +598,7 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
|||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/compress v1.13.1 h1:wXr2uRxZTJXHLly6qhJabee5JqIhTRoLBhDOA74hDEQ=
|
||||
github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio=
|
||||
|
@ -1173,6 +1185,7 @@ github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7A
|
|||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU=
|
||||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
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.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M=
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/certusone/wormhole/bridge/pkg/vaa"
|
||||
"github.com/dgraph-io/badger/v3"
|
||||
)
|
||||
|
||||
type Database struct {
|
||||
db *badger.DB
|
||||
}
|
||||
|
||||
type VAAID struct {
|
||||
EmitterChain vaa.ChainID
|
||||
EmitterAddress vaa.Address
|
||||
Sequence uint64
|
||||
}
|
||||
|
||||
func vaaIDFromVAA(v *vaa.VAA) *VAAID {
|
||||
return &VAAID{
|
||||
EmitterChain: v.EmitterChain,
|
||||
EmitterAddress: v.EmitterAddress,
|
||||
Sequence: v.Sequence,
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
ErrVAANotFound = errors.New("requested VAA not found in store")
|
||||
)
|
||||
|
||||
func (i *VAAID) Bytes() []byte {
|
||||
return []byte(fmt.Sprintf("signed/%d/%s/%d", i.EmitterChain, i.EmitterAddress, i.Sequence))
|
||||
}
|
||||
|
||||
func Open(path string) (*Database, error) {
|
||||
db, err := badger.Open(badger.DefaultOptions(path))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open database: %w", err)
|
||||
}
|
||||
return &Database{
|
||||
db: db,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Database) Close() error {
|
||||
return d.db.Close()
|
||||
}
|
||||
|
||||
func (d *Database) StoreSignedVAA(v *vaa.VAA) error {
|
||||
if len(v.Signatures) == 0 {
|
||||
panic("StoreSignedVAA called for unsigned VAA")
|
||||
}
|
||||
|
||||
b, _ := v.Marshal()
|
||||
|
||||
err := d.db.Update(func(txn *badger.Txn) error {
|
||||
if err := txn.Set(vaaIDFromVAA(v).Bytes(), b); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to commit tx: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Database) GetSignedVAABytes(id VAAID) (b []byte, err error) {
|
||||
if err := d.db.View(func(txn *badger.Txn) error {
|
||||
item, err := txn.Get(id.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := item.ValueCopy(b); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
|
@ -226,13 +226,15 @@ func (p *Processor) handleObservation(ctx context.Context, m *gossipv1.SignedObs
|
|||
panic(err)
|
||||
}
|
||||
|
||||
// Submit every VAA to Solana for data availability.
|
||||
// Store signed VAA in database.
|
||||
p.logger.Info("signed VAA with quorum",
|
||||
zap.String("digest", hash),
|
||||
zap.Any("vaa", signed),
|
||||
zap.String("bytes", hex.EncodeToString(vaaBytes)))
|
||||
|
||||
// TODO: broadcast on p2p and persist
|
||||
if err := p.db.StoreSignedVAA(signed); err != nil {
|
||||
p.logger.Error("failed to store signed VAA", zap.Error(err))
|
||||
}
|
||||
p.state.vaaSignatures[hash].submitted = true
|
||||
} else {
|
||||
p.logger.Info("quorum not met or already submitted, doing nothing",
|
||||
|
|
|
@ -3,6 +3,7 @@ package processor
|
|||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"github.com/certusone/wormhole/bridge/pkg/db"
|
||||
"time"
|
||||
|
||||
ethcommon "github.com/ethereum/go-ethereum/common"
|
||||
|
@ -76,6 +77,8 @@ type Processor struct {
|
|||
|
||||
logger *zap.Logger
|
||||
|
||||
db *db.Database
|
||||
|
||||
// Runtime state
|
||||
|
||||
// gs is the currently valid guardian set
|
||||
|
@ -90,6 +93,7 @@ type Processor struct {
|
|||
|
||||
func NewProcessor(
|
||||
ctx context.Context,
|
||||
db *db.Database,
|
||||
lockC chan *common.MessagePublication,
|
||||
setC chan *common.GuardianSet,
|
||||
sendC chan []byte,
|
||||
|
@ -113,6 +117,7 @@ func NewProcessor(
|
|||
devnetMode: devnetMode,
|
||||
devnetNumGuardians: devnetNumGuardians,
|
||||
devnetEthRPC: devnetEthRPC,
|
||||
db: db,
|
||||
|
||||
terraLCD: terraLCD,
|
||||
terraChainID: terraChainID,
|
||||
|
|
Loading…
Reference in New Issue