diff --git a/Tiltfile b/Tiltfile index 3d007858..8029a47d 100644 --- a/Tiltfile +++ b/Tiltfile @@ -146,3 +146,12 @@ k8s_yaml("devnet/web.yaml") k8s_resource("web", port_forwards=[ port_forward(3000, name="Experimental Web UI [:3000]") ]) + +# terra devnet + +k8s_yaml("devnet/terra-devnet.yaml") + +k8s_resource("terra-lcd", port_forwards=[ + port_forward(1317, name="Terra LCD interface [:1317]") +]) +k8s_resource("terra-terrad") \ No newline at end of file diff --git a/bridge/cmd/guardiand/bridge.go b/bridge/cmd/guardiand/bridge.go index 67eb7c0b..1c703901 100644 --- a/bridge/cmd/guardiand/bridge.go +++ b/bridge/cmd/guardiand/bridge.go @@ -25,6 +25,8 @@ import ( "github.com/certusone/wormhole/bridge/pkg/supervisor" "github.com/certusone/wormhole/bridge/pkg/vaa" + "github.com/certusone/wormhole/bridge/pkg/terra" + ipfslog "github.com/ipfs/go-log/v2" ) @@ -39,6 +41,13 @@ var ( ethContract *string ethConfirmations *uint64 + terraSupport *bool + terraWS *string + terraLCD *string + terraChaidID *string + terraContract *string + terraFeePayer *string + agentRPC *string logLevel *string @@ -59,6 +68,13 @@ func init() { ethContract = BridgeCmd.Flags().String("ethContract", "", "Ethereum bridge contract address") ethConfirmations = BridgeCmd.Flags().Uint64("ethConfirmations", 15, "Ethereum confirmation count requirement") + terraSupport = BridgeCmd.Flags().Bool("terra", false, "Turn on support for Terra") + terraWS = BridgeCmd.Flags().String("terraWS", "", "Path to terrad root for websocket connection") + terraLCD = BridgeCmd.Flags().String("terraLCD", "", "Path to LCD service root for http calls") + terraChaidID = BridgeCmd.Flags().String("terraChainID", "", "Terra chain ID, used in LCD client initialization") + terraContract = BridgeCmd.Flags().String("terraContract", "", "Wormhole contract address on Terra blockhain") + terraFeePayer = BridgeCmd.Flags().String("terraFeePayer", "", "Mnemonic to account paying gas for submitting transactions to Terra") + agentRPC = BridgeCmd.Flags().String("agentRPC", "", "Solana agent sidecar gRPC address") logLevel = BridgeCmd.Flags().String("logLevel", "info", "Logging level (debug, info, warn, error, dpanic, panic, fatal)") @@ -180,6 +196,23 @@ func runBridge(cmd *cobra.Command, args []string) { if *nodeName == "" { logger.Fatal("Please specify -nodeName") } + if *terraSupport { + if *terraWS == "" { + logger.Fatal("Please specify -terraWS") + } + if *terraLCD == "" { + logger.Fatal("Please specify -terraLCD") + } + if *terraChaidID == "" { + logger.Fatal("Please specify -terraChaidID") + } + if *terraContract == "" { + logger.Fatal("Please specify -terraContract") + } + if *terraFeePayer == "" { + logger.Fatal("Please specify -terraFeePayer") + } + } ethContractAddr := eth_common.HexToAddress(*ethContract) @@ -232,12 +265,21 @@ func runBridge(cmd *cobra.Command, args []string) { return err } + // Start Terra watcher only if configured + if *terraSupport { + logger.Info("Starting Terra watcher") + if err := supervisor.Run(ctx, "terrawatch", + terra.NewTerraBridgeWatcher(*terraWS, *terraLCD, *terraContract, lockC, setC).Run); err != nil { + return err + } + } + if err := supervisor.Run(ctx, "solwatch", solana.NewSolanaBridgeWatcher(*agentRPC, lockC, solanaVaaC).Run); err != nil { return err } - p := processor.NewProcessor(ctx, lockC, setC, sendC, obsvC, solanaVaaC, gk, *unsafeDevMode, *devNumGuardians, *ethRPC) + p := processor.NewProcessor(ctx, lockC, setC, sendC, obsvC, solanaVaaC, gk, *unsafeDevMode, *devNumGuardians, *ethRPC, *terraLCD, *terraChaidID, *terraContract, *terraFeePayer) if err := supervisor.Run(ctx, "processor", p.Run); err != nil { return err } diff --git a/bridge/cmd/vaa-test/main.go b/bridge/cmd/vaa-test/main.go index b37e1d1a..c4e3eb9e 100644 --- a/bridge/cmd/vaa-test/main.go +++ b/bridge/cmd/vaa-test/main.go @@ -5,12 +5,13 @@ import ( "crypto/ecdsa" "encoding/hex" "fmt" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" "math/big" "math/rand" "time" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/certusone/wormhole/bridge/pkg/devnet" "github.com/certusone/wormhole/bridge/pkg/vaa" ) diff --git a/bridge/go.mod b/bridge/go.mod index c0c04853..e0144905 100644 --- a/bridge/go.mod +++ b/bridge/go.mod @@ -7,6 +7,8 @@ require ( github.com/aristanetworks/goarista v0.0.0-20201012165903-2cb20defcd66 // indirect github.com/btcsuite/btcd v0.21.0-beta // indirect github.com/cenkalti/backoff/v4 v4.1.0 + github.com/cosmos/cosmos-sdk v0.39.1 + github.com/cosmos/go-bip39 v0.0.0-20200817134856-d632e0d11689 github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/deckarep/golang-set v1.7.1 // indirect github.com/ethereum/go-ethereum v1.9.23 @@ -14,6 +16,7 @@ require ( github.com/go-ole/go-ole v1.2.4 // indirect github.com/golang/protobuf v1.4.3 github.com/golang/snappy v0.0.2 // indirect + github.com/gorilla/websocket v1.4.2 github.com/hashicorp/errwrap v1.1.0 // indirect github.com/ipfs/go-log/v2 v2.1.1 github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect @@ -40,12 +43,17 @@ require ( github.com/olekukonko/tablewriter v0.0.4 // indirect github.com/pborman/uuid v1.2.1 // indirect github.com/peterh/liner v1.2.0 // indirect + github.com/prometheus/common v0.9.1 github.com/prometheus/tsdb v0.10.0 // indirect github.com/shirou/gopsutil v2.20.9+incompatible // indirect - github.com/spf13/cobra v0.0.5 - github.com/spf13/viper v1.3.2 + github.com/spf13/cobra v1.0.0 + github.com/spf13/viper v1.6.3 github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 // indirect github.com/stretchr/testify v1.6.1 + github.com/tendermint/tendermint v0.33.8 + github.com/terra-project/terra.go v1.0.1-0.20201113170042-b3bffdc6fd06 + github.com/tidwall/gjson v1.6.3 + github.com/tidwall/match v1.0.2 // indirect github.com/tyler-smith/go-bip39 v1.0.2 // indirect go.opencensus.io v0.22.5 // indirect go.uber.org/multierr v1.6.0 // indirect diff --git a/bridge/go.sum b/bridge/go.sum index f85f5496..5d3bd112 100644 --- a/bridge/go.sum +++ b/bridge/go.sum @@ -7,6 +7,8 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +github.com/99designs/keyring v1.1.3 h1:mEV3iyZWjkxQ7R8ia8GcG97vCX5zQQ7n4o8R2BylwQY= +github.com/99designs/keyring v1.1.3/go.mod h1:657DQuMrBZRtuL/voxVyiyb6zpMehlm5vLB9Qwrv904= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= @@ -25,9 +27,13 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +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/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs= github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= @@ -37,16 +43,23 @@ github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUW github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw= github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks= github.com/aristanetworks/glog v0.0.0-20180419172825-c15b03b3054f/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA= github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA= @@ -56,16 +69,28 @@ github.com/aristanetworks/goarista v0.0.0-20190912214011-b54698eaaca6/go.mod h1: github.com/aristanetworks/goarista v0.0.0-20201012165903-2cb20defcd66 h1:bylzF2sl5pWmmHcdwEku/BPHp5wYjcdjmOnW4siw688= github.com/aristanetworks/goarista v0.0.0-20201012165903-2cb20defcd66/go.mod h1:QZe5Yh80Hp1b6JxQdpfSEEe8X7hTyTEZSosSrFf/oJE= github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d/go.mod h1:icNx/6QdFblhsEjZehARqbNumymUT/ydwlLojFdv7Sk= github.com/benbjohnson/clock v1.0.2/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= +github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= @@ -74,6 +99,7 @@ github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13P github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= @@ -87,10 +113,14 @@ github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.0 h1:c8LkOFQTzuO0WBM/ae5HdGQuZPfPxp7lqBRwQRm4fSc= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certusone/wormhole v0.0.0-20201025075704-8d7a35683e63 h1:3UgjvZJVnrX0c4ZsiSiCYM3aKQFza2Y8WbNN75gPCSw= +github.com/certusone/wormhole v0.0.0-20201029145145-47ce56749883 h1:HMpUQtatDbrg2Y5AojJPWLmMjJUMxoCUg6v/E1kGZQ8= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= @@ -99,18 +129,37 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cosmos/cosmos-sdk v0.39.1 h1:vhjf9PZh9ph8btAj9aBpHoVITgVVjNBpM3x5Gl/Vwac= +github.com/cosmos/cosmos-sdk v0.39.1/go.mod h1:ry2ROl5n+f2/QXpKJo3rdWNJwll00z7KhIVcxNcl16M= +github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= +github.com/cosmos/go-bip39 v0.0.0-20200817134856-d632e0d11689 h1:LApiux6F9SuXR5wVKBplzLJli1wm/wrlH5KYFMicCfQ= +github.com/cosmos/go-bip39 v0.0.0-20200817134856-d632e0d11689/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= +github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= +github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= @@ -136,7 +185,10 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 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/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= github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= @@ -147,6 +199,7 @@ github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -154,7 +207,11 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/ethereum/go-ethereum v1.9.5/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= github.com/ethereum/go-ethereum v1.9.23 h1:SIKhg/z4Q7AbvqcxuPYvMxf36che/Rq/Pp0IdYEkbtw= github.com/ethereum/go-ethereum v1.9.23/go.mod h1:JIfVb6esrqALTExdz9hRYvrP0xBDf6wCncIu1hNwHpM= +github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= +github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc h1:jtW8jbpkO4YirRSyepBOH8E+2HEw6/hKkBvFPwhUN8c= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= @@ -163,6 +220,8 @@ github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -181,22 +240,32 @@ github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= @@ -204,6 +273,7 @@ github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4er github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= @@ -229,6 +299,8 @@ github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26/go.mod h1:/XxbfmMg github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 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= @@ -238,6 +310,7 @@ github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= @@ -254,23 +327,53 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= +github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= +github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -278,9 +381,14 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +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.1.1 h1:4JywC80b+/hSfljFlEBLHrrh+CIONLDz9NuFl0af4Mw= github.com/holiman/uint256 v1.1.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/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= @@ -354,11 +462,15 @@ github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0 github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= @@ -367,6 +479,8 @@ github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 h1:I/yrLt2WilKxlQKCM5 github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 h1:ZHuwnjpP8LsVsUYqTqeVAI+GfDfJ6UNPrExZF+vX/DQ= github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM= +github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -596,11 +710,16 @@ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h github.com/libp2p/go-yamux v1.3.9/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.0 h1:7nqe0T95T2CWh40IdJ/tp8RMor4ubc9/wYZpB2a/Hx0= github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys= github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/qpack v0.2.0/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= @@ -616,34 +735,49 @@ github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0X github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miguelmota/go-ethereum-hdwallet v0.0.0-20200123000308-a60dcd172b4c h1:cbhK2JT4nl7k8frmCN98ttRdSGP75x9mDxDhlQ1kHQQ= github.com/miguelmota/go-ethereum-hdwallet v0.0.0-20200123000308-a60dcd172b4c/go.mod h1:Z4zI+CdJB1fyrZ1jfevFH6flNV9izrLZnQAeuD6Wkjk= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -712,11 +846,21 @@ github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c h1:1RHs3tNxjXGHeul8z2t6H2N2TlAqpKe5yryJztRx4Jk= github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= @@ -739,13 +883,22 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc= github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw= +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= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= @@ -753,11 +906,16 @@ github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= +github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/peterh/liner v1.2.0 h1:w/UPXyl5GfahFxcTOz2j9wCIHNI+pUPr2laqpojKNCg= github.com/peterh/liner v1.2.0/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -766,35 +924,56 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= 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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA= +github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= 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= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.0.10 h1:QJQN3jYQhkamO4mhfUWqdDH2asK7ONOI9MTWjyAxNKM= github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150 h1:ZeU+auZj1iNzN8iVhff6M38Mfu73FQiJve/GEXYJBjE= github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= +github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= @@ -803,7 +982,10 @@ github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubr github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v2.20.5+incompatible h1:tYH07UPoQt0OCQdgWWMgYHy3/a9bcxNpBIysykNIP7I= github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= @@ -833,8 +1015,14 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= +github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= @@ -845,16 +1033,29 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M= +github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/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.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.6.3 h1:pDDu1OyEDTKzpJwdq4TiuLyMsUgRa/BT5cn5O62NoHs= +github.com/spf13/viper v1.6.3/go.mod h1:jUMtyi0/lB5yZH/FjyGAoH7IMNrIhlBf6pXZmbMDvzw= github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= @@ -864,30 +1065,71 @@ github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1 github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM= github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= +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= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/goleveldb v0.0.0-20180621010148-0d5a0ceb10cf/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= +github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= +github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= +github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= +github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= +github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso= +github.com/tendermint/go-amino v0.15.1 h1:D2uk35eT4iTsvJd9jWIetzthE5C0/k2QmMFkCN+4JgQ= +github.com/tendermint/go-amino v0.15.1/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= +github.com/tendermint/iavl v0.14.0/go.mod h1:QmfViflFiXzxKLQE4tAUuWQHq+RSuQFxablW5oJZ6sE= +github.com/tendermint/tendermint v0.33.5/go.mod h1:0yUs9eIuuDq07nQql9BmI30FtYGcEC60Tu5JzB5IezM= +github.com/tendermint/tendermint v0.33.7/go.mod h1:0yUs9eIuuDq07nQql9BmI30FtYGcEC60Tu5JzB5IezM= +github.com/tendermint/tendermint v0.33.8 h1:Xxu4QhpqcomSE0iQDw1MqLgfsa8fqtPtWFJK6zZOVso= +github.com/tendermint/tendermint v0.33.8/go.mod h1:0yUs9eIuuDq07nQql9BmI30FtYGcEC60Tu5JzB5IezM= +github.com/tendermint/tm-db v0.5.1 h1:H9HDq8UEA7Eeg13kdYckkgwwkQLBnJGgX4PgLJRhieY= +github.com/tendermint/tm-db v0.5.1/go.mod h1:g92zWjHpCYlEvQXvy9M168Su8V1IBEeawpXVVBaK4f4= +github.com/terra-project/terra.go v0.0.0-20201112132816-3eb55b358ed6 h1:P3aCNycSUafF3ctydWIrMvI9AmIdQZwBEqIcaVd29uc= +github.com/terra-project/terra.go v0.0.0-20201112132816-3eb55b358ed6/go.mod h1:w+V/aEgQEeMuxV9ZnA3J0FUGjg1qBNi3WOr8/yphh/U= +github.com/terra-project/terra.go v1.0.0 h1:TR2b3x8yrljXhrs9a3KORRCQ6BGr+bCTp0ZwTrG/i3c= +github.com/terra-project/terra.go v1.0.0/go.mod h1:w+V/aEgQEeMuxV9ZnA3J0FUGjg1qBNi3WOr8/yphh/U= +github.com/terra-project/terra.go v1.0.1-0.20201113170042-b3bffdc6fd06 h1:TAhaL+7VYJe44qBEKqjlj3wD0CRjJN1JZfz8p+L6FGY= +github.com/terra-project/terra.go v1.0.1-0.20201113170042-b3bffdc6fd06/go.mod h1:elzj1F6B9Sel3c4QFNeR3yR4E9tu+c1xBP+ZZYPlSq8= +github.com/tidwall/gjson v1.6.3 h1:aHoiiem0dr7GHkW001T1SMTJ7X5PvyekH5WX0whWGnI= +github.com/tidwall/gjson v1.6.3/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0= +github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= +github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= +github.com/tidwall/match v1.0.2 h1:uuqvHuBGSedK7awZ2YoAtpnimfwBGFjHuWLuLqQj+bU= +github.com/tidwall/match v1.0.2/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= +github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU= +github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc= github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip39 v0.0.0-20180618194314-52158e4697b8/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8= github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= @@ -906,11 +1148,18 @@ github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+m github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xtaci/kcp-go v5.4.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= +github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -919,7 +1168,9 @@ go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= @@ -927,6 +1178,7 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo= go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= @@ -934,6 +1186,7 @@ go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9i go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= @@ -943,6 +1196,7 @@ go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1 golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -955,17 +1209,22 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -975,6 +1234,7 @@ golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+o golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -990,22 +1250,31 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -1027,14 +1296,18 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1047,13 +1320,18 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1090,6 +1368,8 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -1099,6 +1379,7 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69 h1:yBHHx+XZqXJBm6Exke3N7V9gnlsyXxoCPEb1yVenjfk= golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd h1:hHkvGJK23seRCflePJnVa9IMv8fsuavSCWKd11kDQFs= @@ -1112,6 +1393,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1123,6 +1405,7 @@ google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= @@ -1133,13 +1416,19 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.0 h1:IBKSUNL2uBS2DkJBncPP+TwT0sp9tgA8A75NjHt6umg= google.golang.org/grpc v1.33.0/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1161,10 +1450,14 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fatih/set.v0 v0.2.1/go.mod h1:5eLWEndGL4zGGemXWrKuts+wTJR0y+w+auqUJZbmyBg= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= @@ -1177,12 +1470,15 @@ gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHN gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 h1:a6cXbcDDUkSBlpnkWV1bJ+vv3mOgQEltEJ2rPxroVu0= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1202,5 +1498,7 @@ honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXe honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/bridge/pkg/devnet/constants.go b/bridge/pkg/devnet/constants.go index 1551837c..06e02c99 100644 --- a/bridge/pkg/devnet/constants.go +++ b/bridge/pkg/devnet/constants.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" - "github.com/miguelmota/go-ethereum-hdwallet" + hdwallet "github.com/miguelmota/go-ethereum-hdwallet" ) var ( diff --git a/bridge/pkg/processor/observation.go b/bridge/pkg/processor/observation.go index 894f5433..7c39e237 100644 --- a/bridge/pkg/processor/observation.go +++ b/bridge/pkg/processor/observation.go @@ -7,12 +7,14 @@ import ( "strings" "time" + "github.com/certusone/wormhole/bridge/pkg/terra" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "go.uber.org/zap" "github.com/certusone/wormhole/bridge/pkg/devnet" - "github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1" + gossipv1 "github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1" "github.com/certusone/wormhole/bridge/pkg/vaa" ) @@ -137,19 +139,25 @@ func (p *Processor) handleObservation(ctx context.Context, m *gossipv1.LockupObs } if t, ok := v.Payload.(*vaa.BodyTransfer); ok { - switch { - case t.TargetChain == vaa.ChainIDEthereum: - // Check whether we run in devmode and submit the VAA ourselves, if so. - p.devnetVAASubmission(ctx, signed, hash) - // Cross-submit to Solana for data availability - fallthrough - case t.TargetChain == vaa.ChainIDSolana: + switch t.TargetChain { + case vaa.ChainIDEthereum, + vaa.ChainIDSolana, + vaa.ChainIDTerra: + // Submit to Solana if target is Solana, but also cross-submit all other targets to Solana for data availability p.logger.Info("submitting signed VAA to Solana", zap.String("digest", hash), zap.Any("vaa", signed), zap.String("bytes", hex.EncodeToString(vaaBytes))) + switch t.TargetChain { + case vaa.ChainIDEthereum: + // Check whether we run in devmode and submit the VAA ourselves, if so. + p.devnetVAASubmission(ctx, signed, hash) + case vaa.ChainIDTerra: + p.terraVAASubmission(ctx, signed, hash) + } + p.vaaC <- signed default: p.logger.Error("we don't know how to submit this VAA", @@ -190,3 +198,19 @@ func (p *Processor) devnetVAASubmission(ctx context.Context, signed *vaa.VAA, ha p.logger.Info("lockup submitted to Ethereum", zap.Any("tx", tx), zap.String("digest", hash)) } } + +// Submit VAA to Terra +func (p *Processor) terraVAASubmission(ctx context.Context, signed *vaa.VAA, hash string) { + tx, err := terra.SubmitVAA(ctx, p.terraLCD, p.terraChaidID, p.terraContract, p.terraFeePayer, signed) + if err != nil { + if strings.Contains(err.Error(), "VaaAlreadyExecuted") { + p.logger.Info("lockup already submitted to Terra by another node, ignoring", + zap.Error(err), zap.String("digest", hash)) + } else { + p.logger.Error("failed to submit lockup to Terra", + zap.Error(err), zap.String("digest", hash)) + } + return + } + p.logger.Info("lockup submitted to Terra", zap.Any("tx", tx), zap.String("digest", hash)) +} diff --git a/bridge/pkg/processor/processor.go b/bridge/pkg/processor/processor.go index 4b867850..9782a5d9 100644 --- a/bridge/pkg/processor/processor.go +++ b/bridge/pkg/processor/processor.go @@ -58,6 +58,11 @@ type Processor struct { devnetNumGuardians uint devnetEthRPC string + terraLCD string + terraChaidID string + terraContract string + terraFeePayer string + logger *zap.Logger // Runtime state @@ -82,7 +87,11 @@ func NewProcessor( gk *ecdsa.PrivateKey, devnetMode bool, devnetNumGuardians uint, - devnetEthRPC string) *Processor { + devnetEthRPC string, + terraLCD string, + terraChaidID string, + terraContract string, + terraFeePayer string) *Processor { return &Processor{ lockC: lockC, @@ -95,6 +104,11 @@ func NewProcessor( devnetNumGuardians: devnetNumGuardians, devnetEthRPC: devnetEthRPC, + terraLCD: terraLCD, + terraChaidID: terraChaidID, + terraContract: terraContract, + terraFeePayer: terraFeePayer, + logger: supervisor.Logger(ctx), state: &aggregationState{vaaMap{}}, ourAddr: crypto.PubkeyToAddress(gk.PublicKey), @@ -139,12 +153,12 @@ func (p *Processor) checkDevModeGuardianSetUpdate(ctx context.Context) error { timeout, cancel := context.WithTimeout(ctx, 15*time.Second) defer cancel() - tx, err := devnet.SubmitVAA(timeout, p.devnetEthRPC, v) + trx, err := devnet.SubmitVAA(timeout, p.devnetEthRPC, v) if err != nil { return fmt.Errorf("failed to submit devnet guardian set change: %v", err) } - p.logger.Info("devnet guardian set change submitted to Ethereum", zap.Any("tx", tx), zap.Any("vaa", v)) + p.logger.Info("devnet guardian set change submitted to Ethereum", zap.Any("trx", trx), zap.Any("vaa", v)) // Submit VAA to Solana as well. This is asynchronous and can fail, leading to inconsistent devnet state. p.vaaC <- v diff --git a/bridge/pkg/terra/sender.go b/bridge/pkg/terra/sender.go new file mode 100644 index 00000000..3002c863 --- /dev/null +++ b/bridge/pkg/terra/sender.go @@ -0,0 +1,101 @@ +package terra + +import ( + "context" + "encoding/json" + "fmt" + "strings" + "time" + + "github.com/certusone/wormhole/bridge/pkg/vaa" + "github.com/terra-project/terra.go/client" + "github.com/terra-project/terra.go/key" + "github.com/terra-project/terra.go/msg" + "github.com/terra-project/terra.go/tx" +) + +type JSONArraySlice []uint8 + +func (u JSONArraySlice) MarshalJSON() ([]uint8, error) { + var result string + if u == nil { + result = "null" + } else { + result = strings.Join(strings.Fields(fmt.Sprintf("%d", u)), ",") + } + return []byte(result), nil +} + +type SubmitVAAMsg struct { + Params SubmitVAAParams `json:"submit_v_a_a"` +} + +type SubmitVAAParams struct { + VAA JSONArraySlice `json:"vaa"` +} + +// SubmitVAA prepares transaction with signed VAA and sends it to the Terra blockchain +func SubmitVAA(ctx context.Context, urlLCD string, chainID string, contractAddress string, feePayer string, signed *vaa.VAA) (*client.TxResponse, error) { + + // Serialize VAA + vaaBytes, err := signed.Marshal() + if err != nil { + return nil, err + } + + // Derive Raw Private Key + privKey, err := key.DerivePrivKey(feePayer, key.CreateHDPath(0, 0)) + if err != nil { + return nil, err + } + + // Generate StdPrivKey + tmKey, err := key.StdPrivKeyGen(privKey) + if err != nil { + return nil, err + } + + // Generate Address from Public Key + addr := msg.AccAddress(tmKey.PubKey().Address()) + + // Create LCDClient + LCDClient := client.NewLCDClient( + urlLCD, + chainID, + msg.NewDecCoinFromDec("uusd", msg.NewDecFromIntWithPrec(msg.NewInt(15), 2)), // 0.15uusd + msg.NewDecFromIntWithPrec(msg.NewInt(15), 1), tmKey, time.Second*15, + ) + + contract, err := msg.AccAddressFromBech32(contractAddress) + if err != nil { + return nil, err + } + + // Create tx + contractCall, err := json.Marshal(SubmitVAAMsg{ + Params: SubmitVAAParams{ + VAA: vaaBytes, + }}) + + if err != nil { + return nil, err + } + + executeContract := msg.NewExecuteContract(addr, contract, contractCall, msg.NewCoins()) + + transaction, err := LCDClient.CreateAndSignTx(ctx, client.CreateTxOptions{ + Msgs: []msg.Msg{ + executeContract, + }, + Fee: tx.StdFee{ + Gas: msg.NewInt(0), + Amount: msg.NewCoins(), + }, + }) + if err != nil { + return nil, err + } + + // Broadcast + return LCDClient.Broadcast(ctx, transaction) +} diff --git a/bridge/pkg/terra/watcher.go b/bridge/pkg/terra/watcher.go new file mode 100644 index 00000000..de4524d4 --- /dev/null +++ b/bridge/pkg/terra/watcher.go @@ -0,0 +1,227 @@ +package terra + +import ( + "context" + "encoding/hex" + "fmt" + "io/ioutil" + "math/big" + "net/http" + "time" + + eth_common "github.com/ethereum/go-ethereum/common" + + "github.com/certusone/wormhole/bridge/pkg/common" + "github.com/certusone/wormhole/bridge/pkg/supervisor" + "github.com/certusone/wormhole/bridge/pkg/vaa" + "github.com/gorilla/websocket" + "github.com/tidwall/gjson" + "go.uber.org/zap" +) + +type ( + // BridgeWatcher is responsible for looking over Terra blockchain and reporting new transactions to the bridge + BridgeWatcher struct { + urlWS string + urlLCD string + bridge string + + lockChan chan *common.ChainLock + setChan chan *common.GuardianSet + } +) + +type clientRequest struct { + JSONRPC string `json:"jsonrpc"` + // A String containing the name of the method to be invoked. + Method string `json:"method"` + // Object to pass as request parameter to the method. + Params [1]string `json:"params"` + // The request id. This can be of any type. It is used to match the + // response with the request that it is replying to. + ID uint64 `json:"id"` +} + +// NewTerraBridgeWatcher creates a new terra bridge watcher +func NewTerraBridgeWatcher(urlWS string, urlLCD string, bridge string, lockEvents chan *common.ChainLock, setEvents chan *common.GuardianSet) *BridgeWatcher { + return &BridgeWatcher{urlWS: urlWS, urlLCD: urlLCD, bridge: bridge, lockChan: lockEvents, setChan: setEvents} +} + +// Run is the main Terra Bridge run cycle +func (e *BridgeWatcher) Run(ctx context.Context) error { + errC := make(chan error) + logger := supervisor.Logger(ctx) + + logger.Info("connecting to", zap.String("url", e.urlLCD)) + + c, _, err := websocket.DefaultDialer.DialContext(ctx, e.urlLCD, nil) + if err != nil { + return fmt.Errorf("socket dial failed: %w", err) + } + defer c.Close() + + // Subscribe to smart contract transactions + params := [...]string{fmt.Sprintf("tm.event='Tx' AND execute_contract.contract_address='%s'", e.bridge)} + command := &clientRequest{ + JSONRPC: "2.0", + Method: "subscribe", + Params: params, + ID: 1, + } + err = c.WriteJSON(command) + if err != nil { + return fmt.Errorf("websocket subscription failed: %w", err) + } + + // Wait for the success response + _, _, err = c.ReadMessage() + if err != nil { + return fmt.Errorf("event subscription failed: %w", err) + } + logger.Info("Subscribed to new transaction events") + + go func() { + defer close(errC) + + for { + _, message, err := c.ReadMessage() + if err != nil { + logger.Error("error reading channel", zap.Error(err)) + errC <- err + return + } + + // Received a message from the blockchain + json := string(message) + targetChain := gjson.Get(json, "result.events.from_contract\\.locked\\.target_chain.0") + tokenChain := gjson.Get(json, "result.events.from_contract\\.locked\\.token_chain.0") + tokenDecimals := gjson.Get(json, "result.events.from_contract\\.locked\\.token_decimals.0") + token := gjson.Get(json, "result.events.from_contract\\.locked\\.token.0") + sender := gjson.Get(json, "result.events.from_contract\\.locked\\.sender.0") + recipient := gjson.Get(json, "result.events.from_contract\\.locked\\.recipient.0") + amount := gjson.Get(json, "result.events.from_contract\\.locked\\.amount.0") + nonce := gjson.Get(json, "result.events.from_contract\\.locked\\.nonce.0") + txHash := gjson.Get(json, "result.events.tx\\.hash.0") + + if targetChain.Exists() && tokenChain.Exists() && tokenDecimals.Exists() && token.Exists() && + sender.Exists() && recipient.Exists() && amount.Exists() && amount.Exists() && nonce.Exists() && txHash.Exists() { + + logger.Info("Token lock detected on Terra: ", + zap.String("txHash", txHash.String()), + zap.String("targetChain", targetChain.String()), + zap.String("tokenChain", tokenChain.String()), + zap.String("tokenDecimals", tokenDecimals.String()), + zap.String("token", token.String()), + zap.String("sender", sender.String()), + zap.String("recipient", recipient.String()), + zap.String("amount", amount.String()), + zap.String("nonce", nonce.String())) + + senderAddress, err := StringToAddress(sender.String()) + if err != nil { + logger.Error("cannot decode hex ", zap.String("value", sender.String())) + continue + } + recipientAddress, err := StringToAddress(recipient.String()) + if err != nil { + logger.Error("cannot decode hex ", zap.String("value", recipient.String())) + continue + } + tokenAddress, err := StringToAddress(token.String()) + if err != nil { + logger.Error("cannot decode hex ", zap.String("value", token.String())) + continue + } + txHashValue, err := StringToHash(txHash.String()) + if err != nil { + logger.Error("cannot decode hex ", zap.String("value", txHash.String())) + continue + } + lock := &common.ChainLock{ + TxHash: txHashValue, + Timestamp: time.Now(), // No timestamp available, consider adding it into transaction logs or request additionally from the blockchain + Nonce: uint32(nonce.Uint()), + SourceAddress: senderAddress, + TargetAddress: recipientAddress, + SourceChain: vaa.ChainIDTerra, + TargetChain: vaa.ChainID(uint8(targetChain.Uint())), + TokenChain: vaa.ChainID(uint8(tokenChain.Uint())), + TokenAddress: tokenAddress, + TokenDecimals: uint8(tokenDecimals.Uint()), + Amount: new(big.Int).SetUint64(amount.Uint()), + } + e.lockChan <- lock + } + + // Query and report guardian set status + requestURL := fmt.Sprintf("%s/wasm/contracts/%s/store?query_msg={\"guardian_set_info\":{}}", e.urlLCD, e.bridge) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, requestURL, nil) + if err != nil { + logger.Error("query guardian set request error", zap.Error(err)) + errC <- err + return + } + client := &http.Client{ + Timeout: time.Second * 15, + } + resp, err := client.Do(req) + if err != nil { + logger.Error("query guardian set response error", zap.Error(err)) + errC <- err + return + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + logger.Error("query guardian set error", zap.Error(err)) + errC <- err + resp.Body.Close() + return + } + json = string(body) + guardianSetIndex := gjson.Get(json, "result.guardian_set_index") + addresses := gjson.Get(json, "result.addresses.#.bytes") + + logger.Debug("Current guardian set on Terra: ", + zap.Any("guardianSetIndex", guardianSetIndex), + zap.Any("addresses", addresses)) + + resp.Body.Close() + + // Do not report it since ETH guardians are the source of truth + } + }() + + select { + case <-ctx.Done(): + err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) + if err != nil { + logger.Error("error on closing socket ", zap.Error(err)) + } + return ctx.Err() + case err := <-errC: + return err + } +} + +// StringToAddress convert string into address +func StringToAddress(value string) (vaa.Address, error) { + var address vaa.Address + res, err := hex.DecodeString(value) + if err != nil { + return address, err + } + copy(address[:], res) + return address, nil +} + +// StringToHash convert string into transaction hash +func StringToHash(value string) (eth_common.Hash, error) { + var hash eth_common.Hash + res, err := hex.DecodeString(value) + if err != nil { + return hash, err + } + copy(hash[:], res) + return hash, nil +} diff --git a/bridge/pkg/vaa/structs.go b/bridge/pkg/vaa/structs.go index a354e8e8..bcc6f25d 100644 --- a/bridge/pkg/vaa/structs.go +++ b/bridge/pkg/vaa/structs.go @@ -110,6 +110,8 @@ const ( ChainIDSolana = 1 // ChainIDEthereum is the ChainID of Ethereum ChainIDEthereum = 2 + // ChainIDTerra is the ChainID of Terra + ChainIDTerra = 3 minVAALength = 1 + 4 + 52 + 4 + 1 + 1 SupportedVAAVersion = 0x01 diff --git a/devnet/bridge.yaml b/devnet/bridge.yaml index 3081094b..8eeacbfe 100644 --- a/devnet/bridge.yaml +++ b/devnet/bridge.yaml @@ -41,6 +41,9 @@ spec: containers: - name: guardiand image: guardiand-image + env: + - name: TERRA_FEE_PAYER + value: "notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius" command: # Uncomment this to enable in-place debugging using dlv # (not suitable for regular development since the process will no longer restart on its own) @@ -57,6 +60,17 @@ spec: - bridge - --ethRPC - ws://eth-devnet:8545 + - --terra + - --terraWS + - ws://terra-terrad:26657/websocket + - --terraLCD + - http://terra-lcd:1317 + - --terraChainID + - localterra + - --terraContract + - terra174kgn5rtw4kf6f938wm7kwh70h2v4vcfd26jlc + - --terraFeePayer + - $(TERRA_FEE_PAYER) - --agentRPC - localhost:9000 - --ethConfirmations diff --git a/devnet/terra-devnet.yaml b/devnet/terra-devnet.yaml new file mode 100644 index 00000000..f0e8a719 --- /dev/null +++ b/devnet/terra-devnet.yaml @@ -0,0 +1,2183 @@ +apiVersion: v1 +data: + addrbook.json: "{\n\t\"key\": \"42a010b29b4d74efd44c4694\",\n\t\"addrs\": []\n}" + app.toml: | + # This is a TOML config file. + # For more information, see https://github.com/toml-lang/toml + + ##### main base config options ##### + + # The minimum gas prices a validator is willing to accept for processing a + # transaction. A transaction's fees must meet the minimum of any denomination + # specified in this config (e.g. 0.25token1;0.0001token2). + minimum-gas-prices = "0.00506uluna,0.0015uusd,0.00102usdr,1.7805ukrw,4.31626umnt" + + # default: the last 100 states are kept in addition to every 500th state; pruning at 10 block intervals + # nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node) + # everything: all saved states will be deleted, storing only the current state; pruning at 10 block intervals + # custom: allow pruning options to be manually specified through 'pruning-keep-recent', 'pruning-keep-every', and 'pruning-interval' + pruning = "default" + + # These are applied if and only if the pruning strategy is custom. + pruning-keep-recent = "0" + pruning-keep-every = "0" + pruning-interval = "0" + + # HaltHeight contains a non-zero block height at which a node will gracefully + # halt and shutdown that can be used to assist upgrades and testing. + # + # Note: Commitment of state will be attempted on the corresponding block. + halt-height = 0 + + # HaltTime contains a non-zero minimum block time (in Unix seconds) at which + # a node will gracefully halt and shutdown that can be used to assist upgrades + # and testing. + # + # Note: Commitment of state will be attempted on the corresponding block. + halt-time = 0 + + # InterBlockCache enables inter-block caching. + inter-block-cache = true + config.toml: | + # This is a TOML config file. + # For more information, see https://github.com/toml-lang/toml + + # NOTE: Any path below can be absolute (e.g. "/var/myawesomeapp/data") or + # relative to the home directory (e.g. "data"). The home directory is + # "$HOME/.tendermint" by default, but could be changed via $TMHOME env variable + # or --home cmd flag. + + ##### main base config options ##### + + # TCP or UNIX socket address of the ABCI application, + # or the name of an ABCI application compiled in with the Tendermint binary + proxy_app = "tcp://127.0.0.1:26656" + + # A custom human readable name for this node + moniker = "localterra" + + # If this node is many blocks behind the tip of the chain, FastSync + # allows them to catchup quickly by downloading blocks in parallel + # and verifying their commits + fast_sync = true + + # Database backend: goleveldb | cleveldb | boltdb | rocksdb + # * goleveldb (github.com/syndtr/goleveldb - most popular implementation) + # - pure go + # - stable + # * cleveldb (uses levigo wrapper) + # - fast + # - requires gcc + # - use cleveldb build tag (go build -tags cleveldb) + # * boltdb (uses etcd's fork of bolt - github.com/etcd-io/bbolt) + # - EXPERIMENTAL + # - may be faster is some use-cases (random reads - indexer) + # - use boltdb build tag (go build -tags boltdb) + # * rocksdb (uses github.com/tecbot/gorocksdb) + # - EXPERIMENTAL + # - requires gcc + # - use rocksdb build tag (go build -tags rocksdb) + db_backend = "goleveldb" + + # Database directory + db_dir = "data" + + # Output level for logging, including package level options + log_level = "main:info,state:info,*:error" + + # Output format: 'plain' (colored text) or 'json' + log_format = "plain" + + ##### additional base config options ##### + + # Path to the JSON file containing the initial validator set and other meta data + genesis_file = "config/genesis.json" + + # Path to the JSON file containing the private key to use as a validator in the consensus protocol + priv_validator_key_file = "config/priv_validator_key.json" + + # Path to the JSON file containing the last sign state of a validator + priv_validator_state_file = "data/priv_validator_state.json" + + # TCP or UNIX socket address for Tendermint to listen on for + # connections from an external PrivValidator process + priv_validator_laddr = "" + + # Path to the JSON file containing the private key to use for node authentication in the p2p protocol + node_key_file = "config/node_key.json" + + # Mechanism to connect to the ABCI application: socket | grpc + abci = "socket" + + # TCP or UNIX socket address for the profiling server to listen on + prof_laddr = "localhost:6060" + + # If true, query the ABCI app on connecting to a new peer + # so the app can decide if we should keep the connection or not + filter_peers = false + + ##### advanced configuration options ##### + + ##### rpc server configuration options ##### + [rpc] + + # TCP or UNIX socket address for the RPC server to listen on + laddr = "tcp://0.0.0.0:26657" + + # A list of origins a cross-domain request can be executed from + # Default value '[]' disables cors support + # Use '["*"]' to allow any origin + cors_allowed_origins = [] + + # A list of methods the client is allowed to use with cross-domain requests + cors_allowed_methods = ["HEAD", "GET", "POST", ] + + # A list of non simple headers the client is allowed to use with cross-domain requests + cors_allowed_headers = ["Origin", "Accept", "Content-Type", "X-Requested-With", "X-Server-Time", ] + + # TCP or UNIX socket address for the gRPC server to listen on + # NOTE: This server only supports /broadcast_tx_commit + grpc_laddr = "" + + # Maximum number of simultaneous connections. + # Does not include RPC (HTTP&WebSocket) connections. See max_open_connections + # If you want to accept a larger number than the default, make sure + # you increase your OS limits. + # 0 - unlimited. + # Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} + # 1024 - 40 - 10 - 50 = 924 = ~900 + grpc_max_open_connections = 900 + + # Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool + unsafe = false + + # Maximum number of simultaneous connections (including WebSocket). + # Does not include gRPC connections. See grpc_max_open_connections + # If you want to accept a larger number than the default, make sure + # you increase your OS limits. + # 0 - unlimited. + # Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} + # 1024 - 40 - 10 - 50 = 924 = ~900 + max_open_connections = 900 + + # Maximum number of unique clientIDs that can /subscribe + # If you're using /broadcast_tx_commit, set to the estimated maximum number + # of broadcast_tx_commit calls per block. + max_subscription_clients = 100 + + # Maximum number of unique queries a given client can /subscribe to + # If you're using GRPC (or Local RPC client) and /broadcast_tx_commit, set to + # the estimated # maximum number of broadcast_tx_commit calls per block. + max_subscriptions_per_client = 5 + + # How long to wait for a tx to be committed during /broadcast_tx_commit. + # WARNING: Using a value larger than 10s will result in increasing the + # global HTTP write timeout, which applies to all connections and endpoints. + # See https://github.com/tendermint/tendermint/issues/3435 + timeout_broadcast_tx_commit = "10s" + + # Maximum size of request body, in bytes + max_body_bytes = 10000000 + + # Maximum size of request header, in bytes + max_header_bytes = 1048576 + + # The path to a file containing certificate that is used to create the HTTPS server. + # Migth be either absolute path or path related to tendermint's config directory. + # If the certificate is signed by a certificate authority, + # the certFile should be the concatenation of the server's certificate, any intermediates, + # and the CA's certificate. + # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. + # Otherwise, HTTP server is run. + tls_cert_file = "" + + # The path to a file containing matching private key that is used to create the HTTPS server. + # Migth be either absolute path or path related to tendermint's config directory. + # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. + # Otherwise, HTTP server is run. + tls_key_file = "" + + ##### peer to peer configuration options ##### + [p2p] + + # Address to listen for incoming connections + laddr = "tcp://0.0.0.0:26660" + + # Address to advertise to peers for them to dial + # If empty, will use the same port as the laddr, + # and will introspect on the listener or use UPnP + # to figure out the address. + external_address = "" + + # Comma separated list of seed nodes to connect to + seeds = "" + + # Comma separated list of nodes to keep persistent connections to + persistent_peers = "" + + # UPNP port forwarding + upnp = false + + # Path to address book + addr_book_file = "config/addrbook.json" + + # Set true for strict address routability rules + # Set false for private or local networks + addr_book_strict = true + + # Maximum number of inbound peers + max_num_inbound_peers = 40 + + # Maximum number of outbound peers to connect to, excluding persistent peers + max_num_outbound_peers = 10 + + # List of node IDs, to which a connection will be (re)established ignoring any existing limits + unconditional_peer_ids = "" + + # Maximum pause when redialing a persistent peer (if zero, exponential backoff is used) + persistent_peers_max_dial_period = "0s" + + # Time to wait before flushing messages out on the connection + flush_throttle_timeout = "100ms" + + # Maximum size of a message packet payload, in bytes + max_packet_msg_payload_size = 1024 + + # Rate at which packets can be sent, in bytes/second + send_rate = 5120000 + + # Rate at which packets can be received, in bytes/second + recv_rate = 5120000 + + # Set true to enable the peer-exchange reactor + pex = true + + # Seed mode, in which node constantly crawls the network and looks for + # peers. If another node asks it for addresses, it responds and disconnects. + # + # Does not work if the peer-exchange reactor is disabled. + seed_mode = false + + # Comma separated list of peer IDs to keep private (will not be gossiped to other peers) + private_peer_ids = "" + + # Toggle to disable guard against peers connecting from the same ip. + allow_duplicate_ip = false + + # Peer connection configuration. + handshake_timeout = "20s" + dial_timeout = "3s" + + ##### mempool configuration options ##### + [mempool] + + recheck = true + broadcast = true + wal_dir = "" + + # Maximum number of transactions in the mempool + size = 5000 + + # Limit the total size of all txs in the mempool. + # This only accounts for raw transactions (e.g. given 1MB transactions and + # max_txs_bytes=5MB, mempool will only accept 5 transactions). + max_txs_bytes = 1073741824 + + # Size of the cache (used to filter transactions we saw earlier) in transactions + cache_size = 10000 + + # Maximum size of a single transaction. + # NOTE: the max size of a tx transmitted over the network is {max_tx_bytes} + {amino overhead}. + max_tx_bytes = 1048576 + + ##### fast sync configuration options ##### + [fastsync] + + # Fast Sync version to use: + # 1) "v0" (default) - the legacy fast sync implementation + # 2) "v1" - refactor of v0 version for better testability + # 3) "v2" - refactor of v1 version for better usability + version = "v0" + + ##### consensus configuration options ##### + [consensus] + + wal_file = "data/cs.wal/wal" + + timeout_propose = "3s" + timeout_propose_delta = "500ms" + timeout_prevote = "1s" + timeout_prevote_delta = "500ms" + timeout_precommit = "1s" + timeout_precommit_delta = "500ms" + timeout_commit = "5s" + + # Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) + skip_timeout_commit = false + + # EmptyBlocks mode and possible interval between empty blocks + create_empty_blocks = true + create_empty_blocks_interval = "0s" + + # Reactor sleep duration parameters + peer_gossip_sleep_duration = "100ms" + peer_query_maj23_sleep_duration = "2s" + + ##### transactions indexer configuration options ##### + [tx_index] + + # What indexer to use for transactions + # + # Options: + # 1) "null" + # 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). + indexer = "kv" + + # Comma-separated list of compositeKeys to index (by default the only key is "tx.hash") + # Remember that Event has the following structure: type.key + # type: [ + # key: value, + # ... + # ] + # + # You can also index transactions by height by adding "tx.height" key here. + # + # It's recommended to index only a subset of keys due to possible memory + # bloat. This is, of course, depends on the indexer's DB and the volume of + # transactions. + index_keys = "tx.hash,tx.height,message.action,message.sender,submit_proposal.proposal_id,proposal_vote.proposal_id,proposal_deposit.proposal_id" + + # When set to true, tells indexer to index all compositeKeys (predefined keys: + # "tx.hash", "tx.height" and all keys from DeliverTx responses). + # + # Note this may be not desirable (see the comment above). IndexKeys has a + # precedence over IndexAllKeys (i.e. when given both, IndexKeys will be + # indexed). + index_all_keys = false + + ##### instrumentation configuration options ##### + [instrumentation] + + # When true, Prometheus metrics are served under /metrics on + # PrometheusListenAddr. + # Check out the documentation for the list of available metrics. + prometheus = false + + # Address to listen for Prometheus collector(s) connections + prometheus_listen_addr = ":26660" + + # Maximum number of simultaneous connections. + # If you want to accept a larger number than the default, make sure + # you increase your OS limits. + # 0 - unlimited. + max_open_connections = 3 + + # Instrumentation namespace + namespace = "tendermint" + genesis.json: | + { + "genesis_time": "2020-08-24T08:43:02.336889Z", + "chain_id": "localterra", + "consensus_params": { + "block": { + "max_bytes": "22020096", + "max_gas": "-1", + "time_iota_ms": "1000" + }, + "evidence": { + "max_age_num_blocks": "100000", + "max_age_duration": "172800000000000" + }, + "validator": { + "pub_key_types": [ + "ed25519" + ] + } + }, + "app_hash": "", + "app_state": { + "auth": { + "params": { + "max_memo_characters": "256", + "tx_sig_limit": "7", + "tx_size_cost_per_byte": "10", + "sig_verify_cost_ed25519": "590", + "sig_verify_cost_secp256k1": "1000" + }, + "accounts": [ + { + "type": "core/Account", + "value": { + "address": "terra1dcegyrekltswvyy0xy69ydgxn9x8x32zdtapd8", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra17lmam6zguazs5q5u6z5mmx76uj63gldnse2pdp", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra1757tkx08n0cqrw7p86ny9lnxsqeth0wgp0em95", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra199vw7724lzkwz6lf2hsx04lrxfkz09tg8dlp6r", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra18wlvftxzj6zt0xugy2lr9nxzu402690ltaf4ss", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra1e8ryd9ezefuucd4mje33zdms9m2s90m57878v9", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra17tv2hvwpg0ukqgd2y5ct2w54fyan7z0zxrm2f9", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra1lkccuqgj6sjwjn8gsa9xlklqv4pmrqg9dx2fxc", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra1333veey879eeqcff8j3gfcgwt8cfrg9mq20v6f", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra1fmcjjt6yc9wqup2r06urnrd928jhrde6gcld6n", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + } + ] + }, + "params": null, + "distribution": { + "params": { + "community_tax": "0.020000000000000000", + "base_proposer_reward": "0.010000000000000000", + "bonus_proposer_reward": "0.040000000000000000", + "withdraw_addr_enabled": true + }, + "fee_pool": { + "community_pool": [] + }, + "delegator_withdraw_infos": [], + "previous_proposer": "", + "outstanding_rewards": [], + "validator_accumulated_commissions": [], + "validator_historical_rewards": [], + "validator_current_rewards": [], + "delegator_starting_infos": [], + "validator_slash_events": [] + }, + "msgauth": { + "authorization_entries": [] + }, + "wasm": { + "params": { + "max_contract_size": "512000", + "max_contract_gas": "100000000", + "max_contract_msg_size": "1024" + }, + "last_code_id": "0", + "last_instance_id": "0", + "codes": [], + "contracts": [] + }, + "mint": { + "minter": { + "inflation": "0.130000000000000000", + "annual_provisions": "0.000000000000000000" + }, + "params": { + "mint_denom": "uluna", + "inflation_rate_change": "0.130000000000000000", + "inflation_max": "0.200000000000000000", + "inflation_min": "0.070000000000000000", + "goal_bonded": "0.670000000000000000", + "blocks_per_year": "6311520" + } + }, + "upgrade": {}, + "bank": { + "send_enabled": true + }, + "gov": { + "starting_proposal_id": "1", + "deposits": null, + "votes": null, + "proposals": null, + "deposit_params": { + "min_deposit": [ + { + "denom": "uluna", + "amount": "10000000" + } + ], + "max_deposit_period": "172800000000000" + }, + "voting_params": { + "voting_period": "300000000000" + }, + "tally_params": { + "quorum": "0.334000000000000000", + "threshold": "0.500000000000000000", + "veto": "0.334000000000000000" + } + }, + "staking": { + "params": { + "unbonding_time": "1814400000000000", + "max_validators": 100, + "max_entries": 100, + "historical_entries": 0, + "bond_denom": "uluna" + }, + "last_total_power": "0", + "last_validator_powers": null, + "validators": null, + "delegations": null, + "unbonding_delegations": null, + "redelegations": null, + "exported": false + }, + "supply": { + "supply": [] + }, + "treasury": { + "params": { + "tax_policy": { + "rate_min": "0.000500000000000000", + "rate_max": "0.010000000000000000", + "cap": { + "denom": "usdr", + "amount": "1000000" + }, + "change_max": "0.000250000000000000" + }, + "reward_policy": { + "rate_min": "0.050000000000000000", + "rate_max": "0.500000000000000000", + "cap": { + "denom": "unused", + "amount": "0" + }, + "change_max": "0.025000000000000000" + }, + "seigniorage_burden_target": "0.670000000000000000", + "mining_increment": "1.070000000000000000", + "window_short": "4", + "window_long": "52", + "window_probation": "12" + }, + "tax_rate": "0.001000000000000000", + "reward_weight": "0.050000000000000000", + "tax_caps": {}, + "tax_proceed": [], + "epoch_initial_issuance": [], + "cumulated_height": "0", + "TRs": [], + "SRs": [], + "TSLs": [] + }, + "genutil": { + "gentxs": [ + { + "type": "core/StdTx", + "value": { + "msg": [ + { + "type": "staking/MsgCreateValidator", + "value": { + "description": { + "moniker": "localterra", + "identity": "", + "website": "https://github.com/terra-project/LocalTerra", + "security_contact": "", + "details": "" + }, + "commission": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "min_self_delegation": "1", + "delegator_address": "terra1dcegyrekltswvyy0xy69ydgxn9x8x32zdtapd8", + "validator_address": "terravaloper1dcegyrekltswvyy0xy69ydgxn9x8x32zdy3ua5", + "pubkey": "terravalconspub1zcjduepqn7ju9nnv6fl0l6a24ha3a52s8nm948athu5fy3e05vjpapw3rhksszjl92", + "value": { + "denom": "uluna", + "amount": "1000000000" + } + } + } + ], + "fee": { + "amount": [], + "gas": "200000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "An4JQUJX6KTbh6CvqmDLPhe6knWdqfKYjDvkCl2QE1oc" + }, + "signature": "mj0RNoIqzPCfTjWwA0R7jcUBA5Yr820vgk5sFiN98Vx4ifKTU6qtVRCpXExR6B9pDHZ/1PXyGXMp8DEGZQ/Vxg==" + } + ], + "memo": "e9059223d8b9a9539394a05f996f63ce7bb3a405@10.10.20.74:26656" + } + } + ] + }, + "crisis": { + "constant_fee": { + "denom": "uluna", + "amount": "1000" + } + }, + "slashing": { + "params": { + "signed_blocks_window": "100", + "min_signed_per_window": "0.500000000000000000", + "downtime_jail_duration": "600000000000", + "slash_fraction_double_sign": "0.050000000000000000", + "slash_fraction_downtime": "0.010000000000000000" + }, + "signing_infos": {}, + "missed_blocks": {} + }, + "oracle": { + "params": { + "vote_period": "5", + "vote_threshold": "0.500000000000000000", + "reward_band": "0.020000000000000000", + "reward_distribution_window": "5256000", + "whitelist": [ + { + "name": "ukrw", + "tobin_tax": "0.002500000000000000" + }, + { + "name": "usdr", + "tobin_tax": "0.002500000000000000" + }, + { + "name": "uusd", + "tobin_tax": "0.002500000000000000" + }, + { + "name": "umnt", + "tobin_tax": "0.020000000000000000" + } + ], + "slash_fraction": "0.000100000000000000", + "slash_window": "100800", + "min_valid_per_window": "0.000000000000000000" + }, + "feeder_delegations": {}, + "exchange_rates": {}, + "exchange_rate_prevotes": [], + "exchange_rate_votes": [], + "miss_counters": {}, + "aggregate_exchange_rate_prevotes": [], + "aggregate_exchange_rate_votes": [], + "tobin_taxes": {} + }, + "market": { + "terra_pool_delta": "0.000000000000000000", + "params": { + "base_pool": "625000000000", + "pool_recovery_period": "14400", + "min_spread": "0.005" + } + }, + "evidence": { + "params": { + "max_evidence_age": "120000000000" + }, + "evidence": [] + } + } + } + node_key.json: '{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"4XSNmmjHbNiAnP0qrXwJ1otOzZuObJXXvg+ASKlxjVwdP4Tlh4TA6iSpQ/5EF9aFpDGUqcTnJY8u3/FfHiIl2A=="}}' + priv_validator_key.json: |- + { + "address": "411E0995BFCA0250FC442B8B330786F6ACA56D9D", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "n6XCzmzSfv/rqq37HtFQPPZan6u/KJJHL6MkHoXRHe0=" + }, + "priv_key": { + "type": "tendermint/PrivKeyEd25519", + "value": "GYmv6DOzsd8kVS3JU1TkZr6MOr0CFCBzTCxNYquyDK2fpcLObNJ+/+uqrfse0VA89lqfq78okkcvoyQehdEd7Q==" + } + } + terrad.toml: | + # This is a TOML config file. + # For more information, see https://github.com/toml-lang/toml + + ##### main base config options ##### + + # The minimum gas prices a validator is willing to accept for processing a + # transaction. A transaction's fees must meet the minimum of any denomination + # specified in this config (e.g. 0.25token1;0.0001token2). + minimum-gas-prices = "" + wasm.toml: "# This is a TOML config file.\n# For more information, see https://github.com/toml-lang/toml\n\n##### + main base config options #####\n\n# The maximum gas amount can be spent for contract + query.\n# The contract query will invoke contract execution vm,\n# so we need + to restrict the max usage to prevent DoS attack\ncontract-query-gas-limit = \"3000000\"\n\n# + Storing instances in the LRU will have no effect on the results \n# (still deterministic), + but should lower execution time at \n# the cost of increased memory usage. We + cannot pick universal \n# parameters for this, so we should allow node operators + to set it.\nlru-size = \"0\"\n" +kind: ConfigMap +metadata: + labels: + app: terra-lcd + name: terra-lcd-cm0 +--- +apiVersion: v1 +data: + addrbook.json: "{\n\t\"key\": \"42a010b29b4d74efd44c4694\",\n\t\"addrs\": []\n}" + app.toml: | + # This is a TOML config file. + # For more information, see https://github.com/toml-lang/toml + + ##### main base config options ##### + + # The minimum gas prices a validator is willing to accept for processing a + # transaction. A transaction's fees must meet the minimum of any denomination + # specified in this config (e.g. 0.25token1;0.0001token2). + minimum-gas-prices = "0.00506uluna,0.0015uusd,0.00102usdr,1.7805ukrw,4.31626umnt" + + # default: the last 100 states are kept in addition to every 500th state; pruning at 10 block intervals + # nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node) + # everything: all saved states will be deleted, storing only the current state; pruning at 10 block intervals + # custom: allow pruning options to be manually specified through 'pruning-keep-recent', 'pruning-keep-every', and 'pruning-interval' + pruning = "default" + + # These are applied if and only if the pruning strategy is custom. + pruning-keep-recent = "0" + pruning-keep-every = "0" + pruning-interval = "0" + + # HaltHeight contains a non-zero block height at which a node will gracefully + # halt and shutdown that can be used to assist upgrades and testing. + # + # Note: Commitment of state will be attempted on the corresponding block. + halt-height = 0 + + # HaltTime contains a non-zero minimum block time (in Unix seconds) at which + # a node will gracefully halt and shutdown that can be used to assist upgrades + # and testing. + # + # Note: Commitment of state will be attempted on the corresponding block. + halt-time = 0 + + # InterBlockCache enables inter-block caching. + inter-block-cache = true + config.toml: | + # This is a TOML config file. + # For more information, see https://github.com/toml-lang/toml + + # NOTE: Any path below can be absolute (e.g. "/var/myawesomeapp/data") or + # relative to the home directory (e.g. "data"). The home directory is + # "$HOME/.tendermint" by default, but could be changed via $TMHOME env variable + # or --home cmd flag. + + ##### main base config options ##### + + # TCP or UNIX socket address of the ABCI application, + # or the name of an ABCI application compiled in with the Tendermint binary + proxy_app = "tcp://127.0.0.1:26656" + + # A custom human readable name for this node + moniker = "localterra" + + # If this node is many blocks behind the tip of the chain, FastSync + # allows them to catchup quickly by downloading blocks in parallel + # and verifying their commits + fast_sync = true + + # Database backend: goleveldb | cleveldb | boltdb | rocksdb + # * goleveldb (github.com/syndtr/goleveldb - most popular implementation) + # - pure go + # - stable + # * cleveldb (uses levigo wrapper) + # - fast + # - requires gcc + # - use cleveldb build tag (go build -tags cleveldb) + # * boltdb (uses etcd's fork of bolt - github.com/etcd-io/bbolt) + # - EXPERIMENTAL + # - may be faster is some use-cases (random reads - indexer) + # - use boltdb build tag (go build -tags boltdb) + # * rocksdb (uses github.com/tecbot/gorocksdb) + # - EXPERIMENTAL + # - requires gcc + # - use rocksdb build tag (go build -tags rocksdb) + db_backend = "goleveldb" + + # Database directory + db_dir = "data" + + # Output level for logging, including package level options + log_level = "main:info,state:info,*:error" + + # Output format: 'plain' (colored text) or 'json' + log_format = "plain" + + ##### additional base config options ##### + + # Path to the JSON file containing the initial validator set and other meta data + genesis_file = "config/genesis.json" + + # Path to the JSON file containing the private key to use as a validator in the consensus protocol + priv_validator_key_file = "config/priv_validator_key.json" + + # Path to the JSON file containing the last sign state of a validator + priv_validator_state_file = "data/priv_validator_state.json" + + # TCP or UNIX socket address for Tendermint to listen on for + # connections from an external PrivValidator process + priv_validator_laddr = "" + + # Path to the JSON file containing the private key to use for node authentication in the p2p protocol + node_key_file = "config/node_key.json" + + # Mechanism to connect to the ABCI application: socket | grpc + abci = "socket" + + # TCP or UNIX socket address for the profiling server to listen on + prof_laddr = "localhost:6060" + + # If true, query the ABCI app on connecting to a new peer + # so the app can decide if we should keep the connection or not + filter_peers = false + + ##### advanced configuration options ##### + + ##### rpc server configuration options ##### + [rpc] + + # TCP or UNIX socket address for the RPC server to listen on + laddr = "tcp://0.0.0.0:26657" + + # A list of origins a cross-domain request can be executed from + # Default value '[]' disables cors support + # Use '["*"]' to allow any origin + cors_allowed_origins = [] + + # A list of methods the client is allowed to use with cross-domain requests + cors_allowed_methods = ["HEAD", "GET", "POST", ] + + # A list of non simple headers the client is allowed to use with cross-domain requests + cors_allowed_headers = ["Origin", "Accept", "Content-Type", "X-Requested-With", "X-Server-Time", ] + + # TCP or UNIX socket address for the gRPC server to listen on + # NOTE: This server only supports /broadcast_tx_commit + grpc_laddr = "" + + # Maximum number of simultaneous connections. + # Does not include RPC (HTTP&WebSocket) connections. See max_open_connections + # If you want to accept a larger number than the default, make sure + # you increase your OS limits. + # 0 - unlimited. + # Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} + # 1024 - 40 - 10 - 50 = 924 = ~900 + grpc_max_open_connections = 900 + + # Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool + unsafe = false + + # Maximum number of simultaneous connections (including WebSocket). + # Does not include gRPC connections. See grpc_max_open_connections + # If you want to accept a larger number than the default, make sure + # you increase your OS limits. + # 0 - unlimited. + # Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} + # 1024 - 40 - 10 - 50 = 924 = ~900 + max_open_connections = 900 + + # Maximum number of unique clientIDs that can /subscribe + # If you're using /broadcast_tx_commit, set to the estimated maximum number + # of broadcast_tx_commit calls per block. + max_subscription_clients = 100 + + # Maximum number of unique queries a given client can /subscribe to + # If you're using GRPC (or Local RPC client) and /broadcast_tx_commit, set to + # the estimated # maximum number of broadcast_tx_commit calls per block. + max_subscriptions_per_client = 5 + + # How long to wait for a tx to be committed during /broadcast_tx_commit. + # WARNING: Using a value larger than 10s will result in increasing the + # global HTTP write timeout, which applies to all connections and endpoints. + # See https://github.com/tendermint/tendermint/issues/3435 + timeout_broadcast_tx_commit = "10s" + + # Maximum size of request body, in bytes + max_body_bytes = 10000000 + + # Maximum size of request header, in bytes + max_header_bytes = 1048576 + + # The path to a file containing certificate that is used to create the HTTPS server. + # Migth be either absolute path or path related to tendermint's config directory. + # If the certificate is signed by a certificate authority, + # the certFile should be the concatenation of the server's certificate, any intermediates, + # and the CA's certificate. + # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. + # Otherwise, HTTP server is run. + tls_cert_file = "" + + # The path to a file containing matching private key that is used to create the HTTPS server. + # Migth be either absolute path or path related to tendermint's config directory. + # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. + # Otherwise, HTTP server is run. + tls_key_file = "" + + ##### peer to peer configuration options ##### + [p2p] + + # Address to listen for incoming connections + laddr = "tcp://0.0.0.0:26660" + + # Address to advertise to peers for them to dial + # If empty, will use the same port as the laddr, + # and will introspect on the listener or use UPnP + # to figure out the address. + external_address = "" + + # Comma separated list of seed nodes to connect to + seeds = "" + + # Comma separated list of nodes to keep persistent connections to + persistent_peers = "" + + # UPNP port forwarding + upnp = false + + # Path to address book + addr_book_file = "config/addrbook.json" + + # Set true for strict address routability rules + # Set false for private or local networks + addr_book_strict = true + + # Maximum number of inbound peers + max_num_inbound_peers = 40 + + # Maximum number of outbound peers to connect to, excluding persistent peers + max_num_outbound_peers = 10 + + # List of node IDs, to which a connection will be (re)established ignoring any existing limits + unconditional_peer_ids = "" + + # Maximum pause when redialing a persistent peer (if zero, exponential backoff is used) + persistent_peers_max_dial_period = "0s" + + # Time to wait before flushing messages out on the connection + flush_throttle_timeout = "100ms" + + # Maximum size of a message packet payload, in bytes + max_packet_msg_payload_size = 1024 + + # Rate at which packets can be sent, in bytes/second + send_rate = 5120000 + + # Rate at which packets can be received, in bytes/second + recv_rate = 5120000 + + # Set true to enable the peer-exchange reactor + pex = true + + # Seed mode, in which node constantly crawls the network and looks for + # peers. If another node asks it for addresses, it responds and disconnects. + # + # Does not work if the peer-exchange reactor is disabled. + seed_mode = false + + # Comma separated list of peer IDs to keep private (will not be gossiped to other peers) + private_peer_ids = "" + + # Toggle to disable guard against peers connecting from the same ip. + allow_duplicate_ip = false + + # Peer connection configuration. + handshake_timeout = "20s" + dial_timeout = "3s" + + ##### mempool configuration options ##### + [mempool] + + recheck = true + broadcast = true + wal_dir = "" + + # Maximum number of transactions in the mempool + size = 5000 + + # Limit the total size of all txs in the mempool. + # This only accounts for raw transactions (e.g. given 1MB transactions and + # max_txs_bytes=5MB, mempool will only accept 5 transactions). + max_txs_bytes = 1073741824 + + # Size of the cache (used to filter transactions we saw earlier) in transactions + cache_size = 10000 + + # Maximum size of a single transaction. + # NOTE: the max size of a tx transmitted over the network is {max_tx_bytes} + {amino overhead}. + max_tx_bytes = 1048576 + + ##### fast sync configuration options ##### + [fastsync] + + # Fast Sync version to use: + # 1) "v0" (default) - the legacy fast sync implementation + # 2) "v1" - refactor of v0 version for better testability + # 3) "v2" - refactor of v1 version for better usability + version = "v0" + + ##### consensus configuration options ##### + [consensus] + + wal_file = "data/cs.wal/wal" + + timeout_propose = "3s" + timeout_propose_delta = "500ms" + timeout_prevote = "1s" + timeout_prevote_delta = "500ms" + timeout_precommit = "1s" + timeout_precommit_delta = "500ms" + timeout_commit = "5s" + + # Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) + skip_timeout_commit = false + + # EmptyBlocks mode and possible interval between empty blocks + create_empty_blocks = true + create_empty_blocks_interval = "0s" + + # Reactor sleep duration parameters + peer_gossip_sleep_duration = "100ms" + peer_query_maj23_sleep_duration = "2s" + + ##### transactions indexer configuration options ##### + [tx_index] + + # What indexer to use for transactions + # + # Options: + # 1) "null" + # 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). + indexer = "kv" + + # Comma-separated list of compositeKeys to index (by default the only key is "tx.hash") + # Remember that Event has the following structure: type.key + # type: [ + # key: value, + # ... + # ] + # + # You can also index transactions by height by adding "tx.height" key here. + # + # It's recommended to index only a subset of keys due to possible memory + # bloat. This is, of course, depends on the indexer's DB and the volume of + # transactions. + index_keys = "tx.hash,tx.height,message.action,message.sender,submit_proposal.proposal_id,proposal_vote.proposal_id,proposal_deposit.proposal_id" + + # When set to true, tells indexer to index all compositeKeys (predefined keys: + # "tx.hash", "tx.height" and all keys from DeliverTx responses). + # + # Note this may be not desirable (see the comment above). IndexKeys has a + # precedence over IndexAllKeys (i.e. when given both, IndexKeys will be + # indexed). + index_all_keys = false + + ##### instrumentation configuration options ##### + [instrumentation] + + # When true, Prometheus metrics are served under /metrics on + # PrometheusListenAddr. + # Check out the documentation for the list of available metrics. + prometheus = false + + # Address to listen for Prometheus collector(s) connections + prometheus_listen_addr = ":26660" + + # Maximum number of simultaneous connections. + # If you want to accept a larger number than the default, make sure + # you increase your OS limits. + # 0 - unlimited. + max_open_connections = 3 + + # Instrumentation namespace + namespace = "tendermint" + genesis.json: | + { + "genesis_time": "2020-08-24T08:43:02.336889Z", + "chain_id": "localterra", + "consensus_params": { + "block": { + "max_bytes": "22020096", + "max_gas": "-1", + "time_iota_ms": "1000" + }, + "evidence": { + "max_age_num_blocks": "100000", + "max_age_duration": "172800000000000" + }, + "validator": { + "pub_key_types": [ + "ed25519" + ] + } + }, + "app_hash": "", + "app_state": { + "auth": { + "params": { + "max_memo_characters": "256", + "tx_sig_limit": "7", + "tx_size_cost_per_byte": "10", + "sig_verify_cost_ed25519": "590", + "sig_verify_cost_secp256k1": "1000" + }, + "accounts": [ + { + "type": "core/Account", + "value": { + "address": "terra1dcegyrekltswvyy0xy69ydgxn9x8x32zdtapd8", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra17lmam6zguazs5q5u6z5mmx76uj63gldnse2pdp", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra1757tkx08n0cqrw7p86ny9lnxsqeth0wgp0em95", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra199vw7724lzkwz6lf2hsx04lrxfkz09tg8dlp6r", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra18wlvftxzj6zt0xugy2lr9nxzu402690ltaf4ss", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra1e8ryd9ezefuucd4mje33zdms9m2s90m57878v9", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra17tv2hvwpg0ukqgd2y5ct2w54fyan7z0zxrm2f9", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra1lkccuqgj6sjwjn8gsa9xlklqv4pmrqg9dx2fxc", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra1333veey879eeqcff8j3gfcgwt8cfrg9mq20v6f", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + }, + { + "type": "core/Account", + "value": { + "address": "terra1fmcjjt6yc9wqup2r06urnrd928jhrde6gcld6n", + "coins": [ + { + "denom": "ukrw", + "amount": "1000000000000000000" + }, + { + "denom": "uluna", + "amount": "1000000000000000" + }, + { + "denom": "umnt", + "amount": "1000000000000000000" + }, + { + "denom": "usdr", + "amount": "1000000000000000" + }, + { + "denom": "uusd", + "amount": "10000000000000000" + } + ], + "public_key": null, + "account_number": "0", + "sequence": "0" + } + } + ] + }, + "params": null, + "distribution": { + "params": { + "community_tax": "0.020000000000000000", + "base_proposer_reward": "0.010000000000000000", + "bonus_proposer_reward": "0.040000000000000000", + "withdraw_addr_enabled": true + }, + "fee_pool": { + "community_pool": [] + }, + "delegator_withdraw_infos": [], + "previous_proposer": "", + "outstanding_rewards": [], + "validator_accumulated_commissions": [], + "validator_historical_rewards": [], + "validator_current_rewards": [], + "delegator_starting_infos": [], + "validator_slash_events": [] + }, + "msgauth": { + "authorization_entries": [] + }, + "wasm": { + "params": { + "max_contract_size": "512000", + "max_contract_gas": "100000000", + "max_contract_msg_size": "1024" + }, + "last_code_id": "0", + "last_instance_id": "0", + "codes": [], + "contracts": [] + }, + "mint": { + "minter": { + "inflation": "0.130000000000000000", + "annual_provisions": "0.000000000000000000" + }, + "params": { + "mint_denom": "uluna", + "inflation_rate_change": "0.130000000000000000", + "inflation_max": "0.200000000000000000", + "inflation_min": "0.070000000000000000", + "goal_bonded": "0.670000000000000000", + "blocks_per_year": "6311520" + } + }, + "upgrade": {}, + "bank": { + "send_enabled": true + }, + "gov": { + "starting_proposal_id": "1", + "deposits": null, + "votes": null, + "proposals": null, + "deposit_params": { + "min_deposit": [ + { + "denom": "uluna", + "amount": "10000000" + } + ], + "max_deposit_period": "172800000000000" + }, + "voting_params": { + "voting_period": "300000000000" + }, + "tally_params": { + "quorum": "0.334000000000000000", + "threshold": "0.500000000000000000", + "veto": "0.334000000000000000" + } + }, + "staking": { + "params": { + "unbonding_time": "1814400000000000", + "max_validators": 100, + "max_entries": 100, + "historical_entries": 0, + "bond_denom": "uluna" + }, + "last_total_power": "0", + "last_validator_powers": null, + "validators": null, + "delegations": null, + "unbonding_delegations": null, + "redelegations": null, + "exported": false + }, + "supply": { + "supply": [] + }, + "treasury": { + "params": { + "tax_policy": { + "rate_min": "0.000500000000000000", + "rate_max": "0.010000000000000000", + "cap": { + "denom": "usdr", + "amount": "1000000" + }, + "change_max": "0.000250000000000000" + }, + "reward_policy": { + "rate_min": "0.050000000000000000", + "rate_max": "0.500000000000000000", + "cap": { + "denom": "unused", + "amount": "0" + }, + "change_max": "0.025000000000000000" + }, + "seigniorage_burden_target": "0.670000000000000000", + "mining_increment": "1.070000000000000000", + "window_short": "4", + "window_long": "52", + "window_probation": "12" + }, + "tax_rate": "0.001000000000000000", + "reward_weight": "0.050000000000000000", + "tax_caps": {}, + "tax_proceed": [], + "epoch_initial_issuance": [], + "cumulated_height": "0", + "TRs": [], + "SRs": [], + "TSLs": [] + }, + "genutil": { + "gentxs": [ + { + "type": "core/StdTx", + "value": { + "msg": [ + { + "type": "staking/MsgCreateValidator", + "value": { + "description": { + "moniker": "localterra", + "identity": "", + "website": "https://github.com/terra-project/LocalTerra", + "security_contact": "", + "details": "" + }, + "commission": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "min_self_delegation": "1", + "delegator_address": "terra1dcegyrekltswvyy0xy69ydgxn9x8x32zdtapd8", + "validator_address": "terravaloper1dcegyrekltswvyy0xy69ydgxn9x8x32zdy3ua5", + "pubkey": "terravalconspub1zcjduepqn7ju9nnv6fl0l6a24ha3a52s8nm948athu5fy3e05vjpapw3rhksszjl92", + "value": { + "denom": "uluna", + "amount": "1000000000" + } + } + } + ], + "fee": { + "amount": [], + "gas": "200000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "An4JQUJX6KTbh6CvqmDLPhe6knWdqfKYjDvkCl2QE1oc" + }, + "signature": "mj0RNoIqzPCfTjWwA0R7jcUBA5Yr820vgk5sFiN98Vx4ifKTU6qtVRCpXExR6B9pDHZ/1PXyGXMp8DEGZQ/Vxg==" + } + ], + "memo": "e9059223d8b9a9539394a05f996f63ce7bb3a405@10.10.20.74:26656" + } + } + ] + }, + "crisis": { + "constant_fee": { + "denom": "uluna", + "amount": "1000" + } + }, + "slashing": { + "params": { + "signed_blocks_window": "100", + "min_signed_per_window": "0.500000000000000000", + "downtime_jail_duration": "600000000000", + "slash_fraction_double_sign": "0.050000000000000000", + "slash_fraction_downtime": "0.010000000000000000" + }, + "signing_infos": {}, + "missed_blocks": {} + }, + "oracle": { + "params": { + "vote_period": "5", + "vote_threshold": "0.500000000000000000", + "reward_band": "0.020000000000000000", + "reward_distribution_window": "5256000", + "whitelist": [ + { + "name": "ukrw", + "tobin_tax": "0.002500000000000000" + }, + { + "name": "usdr", + "tobin_tax": "0.002500000000000000" + }, + { + "name": "uusd", + "tobin_tax": "0.002500000000000000" + }, + { + "name": "umnt", + "tobin_tax": "0.020000000000000000" + } + ], + "slash_fraction": "0.000100000000000000", + "slash_window": "100800", + "min_valid_per_window": "0.050000000000000000" + }, + "feeder_delegations": {}, + "exchange_rates": {}, + "exchange_rate_prevotes": [], + "exchange_rate_votes": [], + "miss_counters": {}, + "aggregate_exchange_rate_prevotes": [], + "aggregate_exchange_rate_votes": [], + "tobin_taxes": {} + }, + "market": { + "terra_pool_delta": "0.000000000000000000", + "params": { + "base_pool": "625000000000", + "pool_recovery_period": "14400", + "min_spread": "0.005" + } + }, + "evidence": { + "params": { + "max_evidence_age": "120000000000" + }, + "evidence": [] + } + } + } + node_key.json: '{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"4XSNmmjHbNiAnP0qrXwJ1otOzZuObJXXvg+ASKlxjVwdP4Tlh4TA6iSpQ/5EF9aFpDGUqcTnJY8u3/FfHiIl2A=="}}' + priv_validator_key.json: |- + { + "address": "411E0995BFCA0250FC442B8B330786F6ACA56D9D", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "n6XCzmzSfv/rqq37HtFQPPZan6u/KJJHL6MkHoXRHe0=" + }, + "priv_key": { + "type": "tendermint/PrivKeyEd25519", + "value": "GYmv6DOzsd8kVS3JU1TkZr6MOr0CFCBzTCxNYquyDK2fpcLObNJ+/+uqrfse0VA89lqfq78okkcvoyQehdEd7Q==" + } + } + terrad.toml: | + # This is a TOML config file. + # For more information, see https://github.com/toml-lang/toml + + ##### main base config options ##### + + # The minimum gas prices a validator is willing to accept for processing a + # transaction. A transaction's fees must meet the minimum of any denomination + # specified in this config (e.g. 0.25token1;0.0001token2). + minimum-gas-prices = "" + wasm.toml: "# This is a TOML config file.\n# For more information, see https://github.com/toml-lang/toml\n\n##### + main base config options #####\n\n# The maximum gas amount can be spent for contract + query.\n# The contract query will invoke contract execution vm,\n# so we need + to restrict the max usage to prevent DoS attack\ncontract-query-gas-limit = \"3000000\"\n\n# + Storing instances in the LRU will have no effect on the results \n# (still deterministic), + but should lower execution time at \n# the cost of increased memory usage. We + cannot pick universal \n# parameters for this, so we should allow node operators + to set it.\nlru-size = \"0\"\n" +kind: ConfigMap +metadata: + labels: + app: terra-terrad + name: terra-terrad-cm0 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: terra-lcd + name: terra-lcd +spec: + ports: + - name: "1317" + port: 1317 + targetPort: 1317 + selector: + app: terra-lcd +status: + loadBalancer: {} +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: terra-terrad + name: terra-terrad +spec: + ports: + - name: "26657" + port: 26657 + targetPort: 26657 + selector: + app: terra-terrad +status: + loadBalancer: {} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app: terra-lcd + name: terra-lcd +spec: + replicas: 1 + selector: + matchLabels: + app: terra-lcd + strategy: + type: Recreate + template: + metadata: + labels: + app: terra-lcd + spec: + containers: + - args: + - terracli + - rest-server + - --laddr=tcp://0.0.0.0:1317 + - --node=tcp://terra-terrad:26657 + - --trust-node=true + - --unsafe-cors + image: terramoney/localterra-core:0.4.5 + name: terra-lcd + ports: + - containerPort: 1317 + resources: {} + volumeMounts: + - mountPath: /root/.terrad/config + name: terra-lcd-cm0 + restartPolicy: Always + volumes: + - configMap: + name: terra-lcd-cm0 + name: terra-lcd-cm0 +status: {} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app: terra-terrad + name: terra-terrad +spec: + replicas: 1 + selector: + matchLabels: + app: terra-terrad + strategy: + type: Recreate + template: + metadata: + labels: + app: terra-terrad + spec: + containers: + - args: + - terrad + - start + image: terramoney/localterra-core:0.4.5 + name: terra-terrad + ports: + - containerPort: 26657 + resources: {} + volumeMounts: + - mountPath: /root/.terrad/config + name: terra-terrad-cm0 + restartPolicy: Always + volumes: + - configMap: + name: terra-terrad-cm0 + name: terra-terrad-cm0 +status: {} diff --git a/terra/Cargo.lock b/terra/Cargo.lock new file mode 100644 index 00000000..e62c1549 --- /dev/null +++ b/terra/Cargo.lock @@ -0,0 +1,1243 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "addr2line" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gimli 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "adler" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "backtrace" +version = "0.3.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "addr2line 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "object 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "base64" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bincode" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitvec" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "funty 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "radium 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wyz 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "blake3" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-mac 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-padding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cc" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cosmwasm-std" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "schemars 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", + "serde-json-wasm 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "snafu 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cosmwasm-storage" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cosmwasm-std 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cosmwasm-vm" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cosmwasm-std 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hex 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", + "schemars 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "snafu 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-clif-backend 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-middleware-common 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-runtime-core 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cpuid-bool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cranelift-bforest" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cranelift-entity 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cranelift-codegen" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-bforest 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-codegen-meta 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-codegen-shared 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-entity 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gimli 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "target-lexicon 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cranelift-codegen-shared 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-entity 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cranelift-entity" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cranelift-native" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cranelift-codegen 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "raw-cpuid 7.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "target-lexicon 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-channel" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-deque" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crypto-mac" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cw0" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cosmwasm-std 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "schemars 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cw2" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cosmwasm-std 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cosmwasm-storage 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "schemars 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cw20" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cosmwasm-std 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cw0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "schemars 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cw20-base" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cosmwasm-std 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cosmwasm-storage 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cw0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cw2 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cw20 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "schemars 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", + "snafu 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cw20-wrapped" +version = "0.1.0" +dependencies = [ + "cosmwasm-std 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cosmwasm-storage 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cosmwasm-vm 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cw20 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cw20-base 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "schemars 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ecdsa" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "elliptic-curve 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "hmac 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "signature 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "elliptic-curve" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitvec 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ff 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)", + "group 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "errno" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ff" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitvec 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "funty" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gimli" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gimli" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "group" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ff 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hermit-abi" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hex" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hmac" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crypto-mac 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "indexmap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "itoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "k256" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ecdsa 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", + "elliptic-curve 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memoffset" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "adler 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nix" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hermit-abi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "object" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "page_size" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parity-wasm" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "parking_lot" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "radium" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "raw-cpuid" +version = "7.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon-core" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-channel 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-demangle" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "schemars" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "schemars_derive 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "schemars_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde_derive 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde-bench" +version = "0.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde-json-wasm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_bytes" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive_internals" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sha2" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-buffer 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cpuid-bool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-buffer 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "signature" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "smallvec" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "snafu" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)", + "doc-comment 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "snafu-derive 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "snafu-derive" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "subtle" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "syn" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "target-lexicon" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "thiserror" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "thiserror-impl 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "wasmer-clif-backend" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-codegen 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-entity 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-native 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", + "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", + "target-lexicon 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-clif-fork-frontend 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-clif-fork-wasm 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-runtime-core 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-win-exception-handler 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmparser 0.51.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasmer-clif-fork-frontend" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cranelift-codegen 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "target-lexicon 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasmer-clif-fork-wasm" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cranelift-codegen 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-entity 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-clif-fork-frontend 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmparser 0.51.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasmer-middleware-common" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "wasmer-runtime-core 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasmer-runtime-core" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bincode 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "blake3 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "errno 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "hex 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "page_size 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", + "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "target-lexicon 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmparser 0.51.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasmer-win-exception-handler" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-runtime-core 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasmparser" +version = "0.51.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "wormhole" +version = "0.1.0" +dependencies = [ + "cosmwasm-std 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cosmwasm-storage 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cosmwasm-vm 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cw20 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cw20-base 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cw20-wrapped 0.1.0", + "hex 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "k256 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "schemars 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)", + "sha3 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "zeroize" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum addr2line 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" +"checksum adler 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" +"checksum arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" +"checksum autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +"checksum backtrace 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)" = "ec1931848a574faa8f7c71a12ea00453ff5effbb5f51afe7f77d7a48cace6ac1" +"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" +"checksum bincode 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d" +"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +"checksum bitvec 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1d2838fdd79e8776dbe07a106c784b0f8dda571a21b2750a092cc4cbaa653c8e" +"checksum blake3 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e9ff35b701f3914bdb8fad3368d822c766ef2858b2583198e41639b936f09d3f" +"checksum block-buffer 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +"checksum block-padding 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +"checksum cc 1.0.61 (registry+https://github.com/rust-lang/crates.io-index)" = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d" +"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +"checksum cosmwasm-std 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f85908a2696117c8f2c1b3ce201d34a1aa9a6b3c1583a65cfb794ec66e1cfde4" +"checksum cosmwasm-storage 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e103531a2ce636e86b7639cec25d348c4d360832ab8e0e7f9a6e00f08aac1379" +"checksum cosmwasm-vm 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12d56a7ad7bbbf04b94a782f25fe50a9372067737f661931acf9d30668003efd" +"checksum cpuid-bool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" +"checksum cranelift-bforest 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45a9c21f8042b9857bda93f6c1910b9f9f24100187a3d3d52f214a34e3dc5818" +"checksum cranelift-codegen 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7853f77a6e4a33c67a69c40f5e1bb982bd2dc5c4a22e17e67b65bbccf9b33b2e" +"checksum cranelift-codegen-meta 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)" = "084cd6d5fb0d1da28acd72c199471bfb09acc703ec8f3bf07b1699584272a3b9" +"checksum cranelift-codegen-shared 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)" = "701b599783305a58c25027a4d73f2d6b599b2d8ef3f26677275f480b4d51e05d" +"checksum cranelift-entity 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b88e792b28e1ebbc0187b72ba5ba880dad083abe9231a99d19604d10c9e73f38" +"checksum cranelift-native 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32daf082da21c0c05d93394ff4842c2ab7c4991b1f3186a1d952f8ac660edd0b" +"checksum crossbeam-channel 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +"checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" +"checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +"checksum crypto-mac 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +"checksum crypto-mac 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "58bcd97a54c7ca5ce2f6eb16f6bede5b0ab5f0055fedc17d2f0b4466e21671ca" +"checksum cw0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd55b1bb0bb419fe065d80d9ac5a4a0512d9fecf08ad9796f8aa29c7dbe63618" +"checksum cw2 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2b7d5d7ea75a5eb53bfa4db60112bef22cdb56a8d612b67aab5c70edd2fbf34e" +"checksum cw20 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c4e74e78cc957826bb20c21e75244b2a3a7e0e12799f0710e318726406bed37b" +"checksum cw20-base 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e33af71eb8e2746fc7843b096fee77451ca96b78bc32b3c88b4bf744048fc07a" +"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +"checksum digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +"checksum doc-comment 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +"checksum ecdsa 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87bf8bfb05ea8a6f74ddf48c7d1774851ba77bbe51ac984fdfa6c30310e1ff5f" +"checksum either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +"checksum elliptic-curve 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "396db09c483e7fca5d4fdb9112685632b3e76c9a607a2649c1bf904404a01366" +"checksum errno 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6eab5ee3df98a279d9b316b1af6ac95422127b1290317e6d18c1743c99418b01" +"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067" +"checksum ff 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01646e077d4ebda82b73f1bca002ea1e91561a77df2431a9e79729bcc31950ef" +"checksum funty 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8" +"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" +"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +"checksum generic-array 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +"checksum gimli 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81dd6190aad0f05ddbbf3245c54ed14ca4aa6dd32f22312b70d8f168c3e3e633" +"checksum gimli 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" +"checksum group 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc11f9f5fbf1943b48ae7c2bf6846e7d827a512d1be4f23af708f5ca5d01dde1" +"checksum hashbrown 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +"checksum hermit-abi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" +"checksum hex 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" +"checksum hmac 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "deae6d9dbb35ec2c502d62b8f7b1c000a0822c3b0794ba36b3149c0a1c840dff" +"checksum indexmap 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" +"checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +"checksum k256 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c2967b7caf19e57f5d01ac0893551b0aaae1a8e2e2b2a28996e12c9c51b3b486" +"checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +"checksum libc 0.2.79 (registry+https://github.com/rust-lang/crates.io-index)" = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743" +"checksum lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +"checksum memoffset 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +"checksum miniz_oxide 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9" +"checksum nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229" +"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +"checksum object 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" +"checksum opaque-debug 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +"checksum page_size 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eebde548fbbf1ea81a99b128872779c437752fb99f217c45245e1a61dcd9edcd" +"checksum parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" +"checksum parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +"checksum parking_lot_core 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +"checksum proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +"checksum radium 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64de9a0c5361e034f1aefc9f71a86871ec870e766fe31a009734a989b329286a" +"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +"checksum raw-cpuid 7.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4a349ca83373cfa5d6dbb66fd76e58b2cca08da71a5f6400de0a0a6a9bceeaf" +"checksum rayon 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf6960dc9a5b4ee8d3e4c5787b4a112a8818e0290a42ff664ad60692fdf2032" +"checksum rayon-core 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e8c4fec834fb6e6d2dd5eece3c7b432a52f0ba887cf40e595190c4107edc08bf" +"checksum redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)" = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +"checksum schemars 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "be77ed66abed6954aabf6a3e31a84706bedbf93750d267e92ef4a6d90bbd6a61" +"checksum schemars_derive 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "11af7a475c9ee266cfaa9e303a47c830ebe072bf3101ab907a7b7b9d816fa01d" +"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)" = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +"checksum serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d733da87e79faaac25616e33d26299a41143fd4cd42746cbb0e91d8feea243fd" +"checksum serde-json-wasm 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7294d94d390f1d2334697c065ea591d7074c676e2d20aa6f1df752fced29823f" +"checksum serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)" = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" +"checksum serde_derive 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)" = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +"checksum serde_derive_internals 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" +"checksum serde_json 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)" = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4" +"checksum sha2 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" +"checksum sha3 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +"checksum signature 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210" +"checksum smallvec 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" +"checksum snafu 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9c4e6046e4691afe918fd1b603fd6e515bcda5388a1092a9edbada307d159f09" +"checksum snafu-derive 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "7073448732a89f2f3e6581989106067f403d378faeafb4a50812eb814170d3e5" +"checksum subtle 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd" +"checksum syn 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)" = "9c51d92969d209b54a98397e1b91c8ae82d8c87a7bb87df0b29aa2ad81454228" +"checksum target-lexicon 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d" +"checksum thiserror 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "318234ffa22e0920fe9a40d7b8369b5f649d490980cf7aadcf1eb91594869b42" +"checksum thiserror-impl 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cae2447b6282786c3493999f40a9be2a6ad20cb8bd268b0a0dbf5a065535c0ab" +"checksum typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +"checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum wasmer-clif-backend 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "691ea323652d540a10722066dbf049936f4367bb22a96f8992a262a942a8b11b" +"checksum wasmer-clif-fork-frontend 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c23f2824f354a00a77e4b040eef6e1d4c595a8a3e9013bad65199cc8dade9a5a" +"checksum wasmer-clif-fork-wasm 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a35e21d3aebc51cc6ebc0e830cf8458a9891c3482fb3c65ad18d408102929ae5" +"checksum wasmer-middleware-common 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd94068186b25fbe5213442648ffe0fa65ee77389bed020404486fd22056cc87" +"checksum wasmer-runtime-core 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45d4253f097502423d8b19d54cb18745f61b984b9dbce32424cba7945cfef367" +"checksum wasmer-win-exception-handler 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf22ce6dc66d893099aac853d451bf9443fa8f5443f5bf4fc63f3aebd7b592b1" +"checksum wasmparser 0.51.4 (registry+https://github.com/rust-lang/crates.io-index)" = "aeb1956b19469d1c5e63e459d29e7b5aa0f558d9f16fcef09736f8a265e6c10a" +"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum wyz 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" +"checksum zeroize 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05f33972566adbd2d3588b0491eb94b98b43695c4ef897903470ede4f3f5a28a" diff --git a/terra/Cargo.toml b/terra/Cargo.toml new file mode 100644 index 00000000..58642782 --- /dev/null +++ b/terra/Cargo.toml @@ -0,0 +1,13 @@ +[workspace] +members = ["contracts/cw20-wrapped", "contracts/wormhole"] + +[profile.release] +opt-level = 3 +debug = false +rpath = false +lto = true +debug-assertions = false +codegen-units = 1 +panic = 'abort' +incremental = false +overflow-checks = true \ No newline at end of file diff --git a/terra/Tiltfile b/terra/Tiltfile new file mode 100644 index 00000000..d7ca8a6c --- /dev/null +++ b/terra/Tiltfile @@ -0,0 +1,6 @@ +# Smaller environment only with terra and no bridge + +k8s_yaml("../devnet/terra-devnet.yaml") + +k8s_resource("terra-lcd") +k8s_resource("terra-terrad") \ No newline at end of file diff --git a/terra/artifacts/cw20_base.wasm b/terra/artifacts/cw20_base.wasm new file mode 100644 index 00000000..ed4cd3fd Binary files /dev/null and b/terra/artifacts/cw20_base.wasm differ diff --git a/terra/contracts/cw20-wrapped/.cargo/config b/terra/contracts/cw20-wrapped/.cargo/config new file mode 100644 index 00000000..2d5cce4e --- /dev/null +++ b/terra/contracts/cw20-wrapped/.cargo/config @@ -0,0 +1,5 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +wasm-debug = "build --target wasm32-unknown-unknown" +unit-test = "test --lib --features backtraces" +integration-test = "test --test integration" \ No newline at end of file diff --git a/terra/contracts/cw20-wrapped/Cargo.toml b/terra/contracts/cw20-wrapped/Cargo.toml new file mode 100644 index 00000000..6b153b06 --- /dev/null +++ b/terra/contracts/cw20-wrapped/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "cw20-wrapped" +version = "0.1.0" +authors = ["Yuriy Savchenko "] +edition = "2018" +description = "Wrapped CW20 token contract" + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all init/handle/query exports +library = [] + +[dependencies] +cosmwasm-std = { version = "0.10.0" } +cosmwasm-storage = { version = "0.10.0" } +schemars = "0.7" +serde = { version = "1.0.103", default-features = false, features = ["derive"] } +cw20 = "0.2.0" +cw20-base = { version = "0.2.0", features = ["library"] } +thiserror = { version = "1.0.20" } + +[dev-dependencies] +cosmwasm-vm = { version = "0.10.0", default-features = false, features = ["default-cranelift"] } \ No newline at end of file diff --git a/terra/contracts/cw20-wrapped/src/contract.rs b/terra/contracts/cw20-wrapped/src/contract.rs new file mode 100644 index 00000000..a641d655 --- /dev/null +++ b/terra/contracts/cw20-wrapped/src/contract.rs @@ -0,0 +1,396 @@ +use cosmwasm_std::{ + log, to_binary, Api, Binary, CosmosMsg, Env, Extern, HandleResponse, HumanAddr, InitResponse, + Querier, StdError, StdResult, Storage, Uint128, WasmMsg, +}; + +use cw20_base::allowances::{ + handle_burn_from, handle_decrease_allowance, handle_increase_allowance, handle_send_from, + handle_transfer_from, query_allowance, +}; +use cw20_base::contract::{ + handle_mint, handle_send, handle_transfer, query_balance, query_token_info, +}; +use cw20_base::state::{balances, token_info, MinterData, TokenInfo}; + +use crate::msg::{HandleMsg, InitMsg, QueryMsg, WrappedAssetInfoResponse}; +use crate::state::{wrapped_asset_info, wrapped_asset_info_read, WrappedAssetInfo}; +use std::string::String; + +pub fn init( + deps: &mut Extern, + env: Env, + msg: InitMsg, +) -> StdResult { + // store token info using cw20-base format + let data = TokenInfo { + name: String::from("Wormhole Wrapped"), + symbol: String::from("WWT"), + decimals: msg.decimals, + total_supply: Uint128(0), + // set creator as minter + mint: Some(MinterData { + minter: deps.api.canonical_address(&env.message.sender)?, + cap: None, + }), + }; + token_info(&mut deps.storage).save(&data)?; + + // save wrapped asset info + let data = WrappedAssetInfo { + asset_chain: msg.asset_chain, + asset_address: msg.asset_address, + bridge: deps.api.canonical_address(&env.message.sender)?, + }; + wrapped_asset_info(&mut deps.storage).save(&data)?; + + if let Some(mint_info) = msg.mint { + handle_mint(deps, env, mint_info.recipient, mint_info.amount)?; + } + + if let Some(hook) = msg.init_hook { + Ok(InitResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: hook.contract_addr, + msg: hook.msg, + send: vec![], + })], + log: vec![], + }) + } else { + Ok(InitResponse::default()) + } +} + +pub fn handle( + deps: &mut Extern, + env: Env, + msg: HandleMsg, +) -> StdResult { + match msg { + // these all come from cw20-base to implement the cw20 standard + HandleMsg::Transfer { recipient, amount } => { + Ok(handle_transfer(deps, env, recipient, amount)?) + } + HandleMsg::Burn { account, amount } => Ok(handle_burn_wrapped(deps, env, account, amount)?), + HandleMsg::Send { + contract, + amount, + msg, + } => Ok(handle_send(deps, env, contract, amount, msg)?), + HandleMsg::Mint { recipient, amount } => handle_mint_wrapped(deps, env, recipient, amount), + HandleMsg::IncreaseAllowance { + spender, + amount, + expires, + } => Ok(handle_increase_allowance( + deps, env, spender, amount, expires, + )?), + HandleMsg::DecreaseAllowance { + spender, + amount, + expires, + } => Ok(handle_decrease_allowance( + deps, env, spender, amount, expires, + )?), + HandleMsg::TransferFrom { + owner, + recipient, + amount, + } => Ok(handle_transfer_from(deps, env, owner, recipient, amount)?), + HandleMsg::BurnFrom { owner, amount } => Ok(handle_burn_from(deps, env, owner, amount)?), + HandleMsg::SendFrom { + owner, + contract, + amount, + msg, + } => Ok(handle_send_from(deps, env, owner, contract, amount, msg)?), + } +} + +fn handle_burn_wrapped( + deps: &mut Extern, + env: Env, + account: HumanAddr, + amount: Uint128, +) -> StdResult { + // Only bridge can burn + let wrapped_info = wrapped_asset_info_read(&deps.storage).load()?; + if wrapped_info.bridge != deps.api.canonical_address(&env.message.sender)? { + return Err(StdError::unauthorized()); + } + + // Copy of CW20-base handle_burn, but burning from account sent with parameters, not from sender + if amount == Uint128::zero() { + return Err(StdError::generic_err("Invalid zero amount")); + } + + let burn_from_raw = deps.api.canonical_address(&account)?; + + // lower balance + let mut accounts = balances(&mut deps.storage); + accounts.update(burn_from_raw.as_slice(), |balance: Option| { + balance.unwrap_or_default() - amount + })?; + // reduce total_supply + token_info(&mut deps.storage).update(|mut info| { + info.total_supply = (info.total_supply - amount)?; + Ok(info) + })?; + + let res = HandleResponse { + messages: vec![], + log: vec![ + log("action", "burn"), + log("from", account), + log("amount", amount), + ], + data: None, + }; + Ok(res) +} + +fn handle_mint_wrapped( + deps: &mut Extern, + env: Env, + recipient: HumanAddr, + amount: Uint128, +) -> StdResult { + // Only bridge can mint + let wrapped_info = wrapped_asset_info_read(&deps.storage).load()?; + if wrapped_info.bridge != deps.api.canonical_address(&env.message.sender)? { + return Err(StdError::unauthorized()); + } + + return Ok(handle_mint(deps, env, recipient, amount)?); +} + +pub fn query( + deps: &Extern, + msg: QueryMsg, +) -> StdResult { + match msg { + QueryMsg::WrappedAssetInfo {} => to_binary(&query_wrapped_asset_info(deps)?), + // inherited from cw20-base + QueryMsg::TokenInfo {} => to_binary(&query_token_info(deps)?), + QueryMsg::Balance { address } => to_binary(&query_balance(deps, address)?), + QueryMsg::Allowance { owner, spender } => { + to_binary(&query_allowance(deps, owner, spender)?) + } + } +} + +pub fn query_wrapped_asset_info( + deps: &Extern, +) -> StdResult { + let info = wrapped_asset_info_read(&deps.storage).load()?; + let res = WrappedAssetInfoResponse { + asset_chain: info.asset_chain, + asset_address: info.asset_address, + bridge: deps.api.human_address(&info.bridge)?, + }; + Ok(res) +} + +#[cfg(test)] +mod tests { + use super::*; + use cosmwasm_std::testing::{mock_dependencies, mock_env}; + use cosmwasm_std::HumanAddr; + use cw20::TokenInfoResponse; + + const CANONICAL_LENGTH: usize = 20; + + fn get_balance>( + deps: &Extern, + address: T, + ) -> Uint128 { + query_balance(&deps, address.into()).unwrap().balance + } + + fn do_init(deps: &mut Extern, creator: &HumanAddr) { + let init_msg = InitMsg { + asset_chain: 1, + asset_address: vec![1; 32], + decimals: 10, + mint: None, + init_hook: None, + }; + let env = mock_env(creator, &[]); + let res = init(deps, env, init_msg).unwrap(); + assert_eq!(0, res.messages.len()); + + assert_eq!( + query_token_info(&deps).unwrap(), + TokenInfoResponse { + name: "Wormhole Wrapped".to_string(), + symbol: "WWT".to_string(), + decimals: 10, + total_supply: Uint128::from(0u128), + } + ); + + assert_eq!( + query_wrapped_asset_info(&deps).unwrap(), + WrappedAssetInfoResponse { + asset_chain: 1, + asset_address: vec![1; 32], + bridge: creator.clone(), + } + ); + } + + fn do_init_and_mint( + deps: &mut Extern, + creator: &HumanAddr, + mint_to: &HumanAddr, + amount: Uint128, + ) { + do_init(deps, creator); + + let msg = HandleMsg::Mint { + recipient: mint_to.clone(), + amount, + }; + + let env = mock_env(&creator, &[]); + let res = handle(deps, env, msg.clone()).unwrap(); + assert_eq!(0, res.messages.len()); + assert_eq!(get_balance(deps, mint_to), amount); + + assert_eq!( + query_token_info(&deps).unwrap(), + TokenInfoResponse { + name: "Wormhole Wrapped".to_string(), + symbol: "WWT".to_string(), + decimals: 10, + total_supply: amount, + } + ); + } + + #[test] + fn can_mint_by_minter() { + let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); + let minter = HumanAddr::from("minter"); + let recipient = HumanAddr::from("recipient"); + let amount = Uint128(222_222_222); + do_init_and_mint(&mut deps, &minter, &recipient, amount); + } + + #[test] + fn others_cannot_mint() { + let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); + let minter = HumanAddr::from("minter"); + let recipient = HumanAddr::from("recipient"); + do_init(&mut deps, &minter); + + let amount = Uint128(222_222_222); + let msg = HandleMsg::Mint { + recipient: recipient.clone(), + amount, + }; + + let other_address = HumanAddr::from("other"); + let env = mock_env(&other_address, &[]); + let res = handle(&mut deps, env, msg); + assert_eq!( + format!("{}", res.unwrap_err()), + format!("{}", crate::error::ContractError::Unauthorized {}) + ); + } + + #[test] + fn can_burn_by_minter() { + let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); + let minter = HumanAddr::from("minter"); + let recipient = HumanAddr::from("recipient"); + let amount = Uint128(222_222_222); + do_init_and_mint(&mut deps, &minter, &recipient, amount); + + let amount_to_burn = Uint128(222_222_221); + let msg = HandleMsg::Burn { + account: recipient.clone(), + amount: amount_to_burn, + }; + + let env = mock_env(&minter, &[]); + let res = handle(&mut deps, env, msg.clone()).unwrap(); + assert_eq!(0, res.messages.len()); + assert_eq!(get_balance(&deps, recipient), Uint128(1)); + + assert_eq!( + query_token_info(&deps).unwrap(), + TokenInfoResponse { + name: "Wormhole Wrapped".to_string(), + symbol: "WWT".to_string(), + decimals: 10, + total_supply: Uint128(1), + } + ); + } + + #[test] + fn others_cannot_burn() { + let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); + let minter = HumanAddr::from("minter"); + let recipient = HumanAddr::from("recipient"); + let amount = Uint128(222_222_222); + do_init_and_mint(&mut deps, &minter, &recipient, amount); + + let amount_to_burn = Uint128(222_222_221); + let msg = HandleMsg::Burn { + account: recipient.clone(), + amount: amount_to_burn, + }; + + let env = mock_env(&recipient, &[]); + let res = handle(&mut deps, env, msg.clone()); + assert_eq!( + format!("{}", res.unwrap_err()), + format!("{}", crate::error::ContractError::Unauthorized {}) + ); + } + + #[test] + fn transfer_balance_success() { + let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); + let minter = HumanAddr::from("minter"); + let owner = HumanAddr::from("owner"); + let amount_initial = Uint128(222_222_222); + do_init_and_mint(&mut deps, &minter, &owner, amount_initial); + + // Transfer + let recipient = HumanAddr::from("recipient"); + let amount_transfer = Uint128(222_222); + let msg = HandleMsg::Transfer { + recipient: recipient.clone(), + amount: amount_transfer, + }; + + let env = mock_env(&owner, &[]); + let res = handle(&mut deps, env, msg.clone()).unwrap(); + assert_eq!(0, res.messages.len()); + assert_eq!(get_balance(&deps, owner), Uint128(222_000_000)); + assert_eq!(get_balance(&deps, recipient), amount_transfer); + } + + #[test] + fn transfer_balance_not_enough() { + let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); + let minter = HumanAddr::from("minter"); + let owner = HumanAddr::from("owner"); + let amount_initial = Uint128(222_221); + do_init_and_mint(&mut deps, &minter, &owner, amount_initial); + + // Transfer + let recipient = HumanAddr::from("recipient"); + let amount_transfer = Uint128(222_222); + let msg = HandleMsg::Transfer { + recipient: recipient.clone(), + amount: amount_transfer, + }; + + let env = mock_env(&owner, &[]); + let _ = handle(&mut deps, env, msg.clone()).unwrap_err(); // Will panic if no error + } +} diff --git a/terra/contracts/cw20-wrapped/src/error.rs b/terra/contracts/cw20-wrapped/src/error.rs new file mode 100644 index 00000000..95eba93c --- /dev/null +++ b/terra/contracts/cw20-wrapped/src/error.rs @@ -0,0 +1,27 @@ +use cosmwasm_std::StdError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ContractError { + // CW20 errors + #[error("{0}")] + Std(#[from] StdError), + + #[error("Unauthorized")] + Unauthorized {}, + + #[error("Cannot set to own account")] + CannotSetOwnAccount {}, + + #[error("Invalid zero amount")] + InvalidZeroAmount {}, + + #[error("Allowance is expired")] + Expired {}, + + #[error("No allowance for this account")] + NoAllowance {}, + + #[error("Minting cannot exceed the cap")] + CannotExceedCap {}, +} diff --git a/terra/contracts/cw20-wrapped/src/lib.rs b/terra/contracts/cw20-wrapped/src/lib.rs new file mode 100644 index 00000000..e8a83276 --- /dev/null +++ b/terra/contracts/cw20-wrapped/src/lib.rs @@ -0,0 +1,9 @@ +pub mod contract; +mod error; +pub mod msg; +pub mod state; + +pub use crate::error::ContractError; + +#[cfg(all(target_arch = "wasm32", not(feature = "library")))] +cosmwasm_std::create_entry_points!(contract); diff --git a/terra/contracts/cw20-wrapped/src/msg.rs b/terra/contracts/cw20-wrapped/src/msg.rs new file mode 100644 index 00000000..cf043c57 --- /dev/null +++ b/terra/contracts/cw20-wrapped/src/msg.rs @@ -0,0 +1,110 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use cosmwasm_std::{Binary, HumanAddr, Uint128}; +use cw20::Expiration; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct InitMsg { + pub asset_chain: u8, + pub asset_address: Vec, + pub decimals: u8, + pub mint: Option, + pub init_hook: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct InitHook { + pub msg: Binary, + pub contract_addr: HumanAddr, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct InitMint { + pub recipient: HumanAddr, + pub amount: Uint128, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + /// Implements CW20. Transfer is a base message to move tokens to another account without triggering actions + Transfer { + recipient: HumanAddr, + amount: Uint128, + }, + /// Slightly different than CW20. Burn is a base message to destroy tokens forever + Burn { account: HumanAddr, amount: Uint128 }, + /// Implements CW20. Send is a base message to transfer tokens to a contract and trigger an action + /// on the receiving contract. + Send { + contract: HumanAddr, + amount: Uint128, + msg: Option, + }, + /// Implements CW20 "mintable" extension. If authorized, creates amount new tokens + /// and adds to the recipient balance. + Mint { + recipient: HumanAddr, + amount: Uint128, + }, + /// Implements CW20 "approval" extension. Allows spender to access an additional amount tokens + /// from the owner's (env.sender) account. If expires is Some(), overwrites current allowance + /// expiration with this one. + IncreaseAllowance { + spender: HumanAddr, + amount: Uint128, + expires: Option, + }, + /// Implements CW20 "approval" extension. Lowers the spender's access of tokens + /// from the owner's (env.sender) account by amount. If expires is Some(), overwrites current + /// allowance expiration with this one. + DecreaseAllowance { + spender: HumanAddr, + amount: Uint128, + expires: Option, + }, + /// Implements CW20 "approval" extension. Transfers amount tokens from owner -> recipient + /// if `env.sender` has sufficient pre-approval. + TransferFrom { + owner: HumanAddr, + recipient: HumanAddr, + amount: Uint128, + }, + /// Implements CW20 "approval" extension. Sends amount tokens from owner -> contract + /// if `env.sender` has sufficient pre-approval. + SendFrom { + owner: HumanAddr, + contract: HumanAddr, + amount: Uint128, + msg: Option, + }, + /// Implements CW20 "approval" extension. Destroys tokens forever + BurnFrom { owner: HumanAddr, amount: Uint128 }, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg { + // Generic information about the wrapped asset + WrappedAssetInfo {}, + /// Implements CW20. Returns the current balance of the given address, 0 if unset. + Balance { + address: HumanAddr, + }, + /// Implements CW20. Returns metadata on the contract - name, decimals, supply, etc. + TokenInfo {}, + /// Implements CW20 "allowance" extension. + /// Returns how much spender can use from owner account, 0 if unset. + Allowance { + owner: HumanAddr, + spender: HumanAddr, + }, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct WrappedAssetInfoResponse { + pub asset_chain: u8, // Asset chain id + pub asset_address: Vec, // Asset smart contract address in the original chain + pub bridge: HumanAddr, // Bridge address, authorized to mint and burn wrapped tokens +} diff --git a/terra/contracts/cw20-wrapped/src/state.rs b/terra/contracts/cw20-wrapped/src/state.rs new file mode 100644 index 00000000..22be1c55 --- /dev/null +++ b/terra/contracts/cw20-wrapped/src/state.rs @@ -0,0 +1,25 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use cosmwasm_std::{CanonicalAddr, ReadonlyStorage, Storage}; +use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton}; + +pub const KEY_WRAPPED_ASSET: &[u8] = b"wrappedAsset"; + +// Created at initialization and reference original asset and bridge address +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct WrappedAssetInfo { + pub asset_chain: u8, // Asset chain id + pub asset_address: Vec, // Asset smart contract address on the original chain + pub bridge: CanonicalAddr, // Bridge address, authorized to mint and burn wrapped tokens +} + +pub fn wrapped_asset_info(storage: &mut S) -> Singleton { + singleton(storage, KEY_WRAPPED_ASSET) +} + +pub fn wrapped_asset_info_read( + storage: &S, +) -> ReadonlySingleton { + singleton_read(storage, KEY_WRAPPED_ASSET) +} diff --git a/terra/contracts/cw20-wrapped/tests/integration.rs b/terra/contracts/cw20-wrapped/tests/integration.rs new file mode 100644 index 00000000..e33b66bc --- /dev/null +++ b/terra/contracts/cw20-wrapped/tests/integration.rs @@ -0,0 +1,308 @@ +static WASM: &[u8] = + include_bytes!("../../../target/wasm32-unknown-unknown/release/cw20_wrapped.wasm"); + +use cosmwasm_std::{ + from_slice, Env, HandleResponse, HandleResult, HumanAddr, InitResponse, Uint128, +}; +use cosmwasm_storage::to_length_prefixed; +use cosmwasm_vm::testing::{ + handle, init, mock_env, mock_instance, query, MockApi, MockQuerier, MockStorage, +}; +use cosmwasm_vm::{Api, Instance, Storage}; +use cw20_wrapped::msg::{HandleMsg, InitMsg, QueryMsg}; +use cw20_wrapped::state::WrappedAssetInfo; +use cw20_wrapped::state::KEY_WRAPPED_ASSET; +use cw20_wrapped::ContractError; + +enum TestAddress { + INITIALIZER, + RECIPIENT, + SENDER, +} + +impl TestAddress { + fn value(&self) -> HumanAddr { + match self { + TestAddress::INITIALIZER => HumanAddr::from("addr0000"), + TestAddress::RECIPIENT => HumanAddr::from("addr2222"), + TestAddress::SENDER => HumanAddr::from("addr3333"), + } + } +} + +fn mock_env_height(signer: &HumanAddr, height: u64, time: u64) -> Env { + let mut env = mock_env(signer, &[]); + env.block.height = height; + env.block.time = time; + env +} + +fn get_wrapped_asset_info(storage: &S) -> WrappedAssetInfo { + let key = to_length_prefixed(KEY_WRAPPED_ASSET); + let data = storage + .get(&key) + .0 + .expect("error getting data") + .expect("data should exist"); + from_slice(&data).expect("invalid data") +} + +fn do_init(height: u64) -> Instance { + let mut deps = mock_instance(WASM, &[]); + let init_msg = InitMsg { + asset_chain: 1, + asset_address: vec![1; 32], + decimals: 10, + mint: None, + init_hook: None, + }; + let env = mock_env_height(&TestAddress::INITIALIZER.value(), height, 0); + let res: InitResponse = init(&mut deps, env, init_msg).unwrap(); + assert_eq!(0, res.messages.len()); + + // query the store directly + let api = deps.api; + deps.with_storage(|storage| { + assert_eq!( + get_wrapped_asset_info(storage), + WrappedAssetInfo { + asset_chain: 1, + asset_address: vec![1; 32], + bridge: api.canonical_address(&TestAddress::INITIALIZER.value()).0?, + } + ); + Ok(()) + }) + .unwrap(); + deps +} + +fn do_mint( + deps: &mut Instance, + height: u64, + recipient: &HumanAddr, + amount: &Uint128, +) { + let mint_msg = HandleMsg::Mint { + recipient: recipient.clone(), + amount: amount.clone(), + }; + let env = mock_env_height(&TestAddress::INITIALIZER.value(), height, 0); + let handle_response: HandleResponse = handle(deps, env, mint_msg).unwrap(); + assert_eq!(0, handle_response.messages.len()); +} + +fn do_transfer( + deps: &mut Instance, + height: u64, + sender: &HumanAddr, + recipient: &HumanAddr, + amount: &Uint128, +) { + let transfer_msg = HandleMsg::Transfer { + recipient: recipient.clone(), + amount: amount.clone(), + }; + let env = mock_env_height(sender, height, 0); + let handle_response: HandleResponse = handle(deps, env, transfer_msg).unwrap(); + assert_eq!(0, handle_response.messages.len()); +} + +fn check_balance( + deps: &mut Instance, + address: &HumanAddr, + amount: &Uint128, +) { + let query_response = query( + deps, + QueryMsg::Balance { + address: address.clone(), + }, + ) + .unwrap(); + assert_eq!( + query_response.as_slice(), + format!("{{\"balance\":\"{}\"}}", amount.u128()).as_bytes() + ); +} + +fn check_token_details(deps: &mut Instance, supply: &Uint128) { + let query_response = query(deps, QueryMsg::TokenInfo {}).unwrap(); + assert_eq!( + query_response.as_slice(), + format!( + "{{\"name\":\"Wormhole Wrapped\",\ + \"symbol\":\"WWT\",\ + \"decimals\":10,\ + \"total_supply\":\"{}\"}}", + supply.u128() + ) + .as_bytes() + ); +} + +fn format_array(data: &Vec) -> String { + let mut result = String::new(); + + for num in &data[0..data.len() - 1] { + result.push_str(&num.to_string()); + result.push_str(","); + } + result.push_str(&data[data.len() - 1].to_string()); + + result +} + +#[test] +fn init_works() { + let mut deps = do_init(111); + check_token_details(&mut deps, &Uint128(0)); +} + +#[test] +fn query_works() { + let mut deps = do_init(111); + + let query_response = query(&mut deps, QueryMsg::WrappedAssetInfo {}).unwrap(); + assert_eq!( + query_response.as_slice(), + format!( + "{{\"asset_chain\":1,\ + \"asset_address\":[{}],\ + \"bridge\":\"{}\"}}", + format_array(&vec![1; 32]), + TestAddress::INITIALIZER.value().as_str() + ) + .as_bytes() + ); +} + +#[test] +fn mint_works() { + let mut deps = do_init(111); + + do_mint( + &mut deps, + 112, + &TestAddress::RECIPIENT.value(), + &Uint128(123_123_123), + ); + + check_balance( + &mut deps, + &TestAddress::RECIPIENT.value(), + &Uint128(123_123_123), + ); + check_token_details(&mut deps, &Uint128(123_123_123)); +} + +#[test] +fn others_cannot_mint() { + let mut deps = do_init(111); + + let mint_msg = HandleMsg::Mint { + recipient: TestAddress::RECIPIENT.value(), + amount: Uint128(123_123_123), + }; + let env = mock_env_height(&TestAddress::RECIPIENT.value(), 112, 0); + let handle_result: HandleResult = handle(&mut deps, env, mint_msg); + assert_eq!( + format!("{}", handle_result.unwrap_err()), + format!("{}", ContractError::Unauthorized {}) + ); +} + +#[test] +fn transfer_works() { + let mut deps = do_init(111); + + do_mint( + &mut deps, + 112, + &TestAddress::SENDER.value(), + &Uint128(123_123_123), + ); + do_transfer( + &mut deps, + 113, + &TestAddress::SENDER.value(), + &TestAddress::RECIPIENT.value(), + &Uint128(123_123_000), + ); + + check_balance(&mut deps, &TestAddress::SENDER.value(), &Uint128(123)); + check_balance( + &mut deps, + &TestAddress::RECIPIENT.value(), + &Uint128(123_123_000), + ); +} + +#[test] +fn burn_works() { + let mut deps = do_init(111); + + do_mint( + &mut deps, + 112, + &TestAddress::RECIPIENT.value(), + &Uint128(123_123_123), + ); + + let burn_msg = HandleMsg::Burn { + account: TestAddress::RECIPIENT.value(), + amount: Uint128(123_123_000), + }; + let env = mock_env_height(&TestAddress::INITIALIZER.value(), 113, 0); + let handle_response: HandleResponse = handle(&mut deps, env, burn_msg).unwrap(); + assert_eq!(0, handle_response.messages.len()); + + check_balance(&mut deps, &TestAddress::RECIPIENT.value(), &Uint128(123)); + check_token_details(&mut deps, &Uint128(123)); +} + +#[test] +fn others_cannot_burn() { + let mut deps = do_init(111); + + do_mint( + &mut deps, + 112, + &TestAddress::RECIPIENT.value(), + &Uint128(123_123_123), + ); + + let burn_msg = HandleMsg::Burn { + account: TestAddress::RECIPIENT.value(), + amount: Uint128(123_123_000), + }; + let env = mock_env_height(&TestAddress::RECIPIENT.value(), 113, 0); + let handle_result: HandleResult = handle(&mut deps, env, burn_msg); + assert_eq!( + format!("{}", handle_result.unwrap_err()), + format!("{}", ContractError::Unauthorized {}) + ); +} + +#[test] +fn cannot_burn_more_than_available() { + let mut deps = do_init(111); + + do_mint( + &mut deps, + 112, + &TestAddress::RECIPIENT.value(), + &Uint128(123_123_123), + ); + + let burn_msg = HandleMsg::Burn { + account: TestAddress::RECIPIENT.value(), + amount: Uint128(123_123_124), + }; + let env = mock_env_height(&TestAddress::INITIALIZER.value(), 113, 0); + let handle_result: HandleResult = handle(&mut deps, env, burn_msg); + assert_eq!( + format!("{}", handle_result.unwrap_err()), + "Cannot subtract 123123124 from 123123123" + ); +} diff --git a/terra/contracts/wormhole/.cargo/config b/terra/contracts/wormhole/.cargo/config new file mode 100644 index 00000000..2d5cce4e --- /dev/null +++ b/terra/contracts/wormhole/.cargo/config @@ -0,0 +1,5 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +wasm-debug = "build --target wasm32-unknown-unknown" +unit-test = "test --lib --features backtraces" +integration-test = "test --test integration" \ No newline at end of file diff --git a/terra/contracts/wormhole/Cargo.toml b/terra/contracts/wormhole/Cargo.toml new file mode 100644 index 00000000..dd0cc317 --- /dev/null +++ b/terra/contracts/wormhole/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "wormhole" +version = "0.1.0" +authors = ["Yuriy Savchenko "] +edition = "2018" +description = "Wormhole contract" + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all init/handle/query exports +library = [] + +[dependencies] +cosmwasm-std = { version = "0.10.0" } +cosmwasm-storage = { version = "0.10.0" } +schemars = "0.7" +serde = { version = "1.0.103", default-features = false, features = ["derive"] } +cw20 = "0.2.2" +cw20-base = { version = "0.2.2", features = ["library"] } +cw20-wrapped = { path = "../cw20-wrapped", features = ["library"] } +thiserror = { version = "1.0.20" } +k256 = { version = "0.5.9", default-features = false, features = ["ecdsa"] } +sha3 = { version = "0.9.1", default-features = false } +hex = "0.4.2" + +[dev-dependencies] +cosmwasm-vm = { version = "0.10.0", default-features = false, features = ["default-cranelift"] } \ No newline at end of file diff --git a/terra/contracts/wormhole/src/byte_utils.rs b/terra/contracts/wormhole/src/byte_utils.rs new file mode 100644 index 00000000..850dbccf --- /dev/null +++ b/terra/contracts/wormhole/src/byte_utils.rs @@ -0,0 +1,43 @@ +use cosmwasm_std::CanonicalAddr; + +pub trait ByteUtils { + fn get_u8(&self, index: usize) -> u8; + fn get_u32(&self, index: usize) -> u32; + fn get_u128_be(&self, index: usize) -> u128; + /// High 128 then low 128 + fn get_u256(&self, index: usize) -> (u128, u128); + fn get_address(&self, index: usize) -> CanonicalAddr; + fn get_bytes32(&self, index: usize) -> &[u8]; +} + +impl ByteUtils for &[u8] { + fn get_u8(&self, index: usize) -> u8 { + self[index] + } + fn get_u32(&self, index: usize) -> u32 { + let mut bytes: [u8; 32 / 8] = [0; 32 / 8]; + bytes.copy_from_slice(&self[index..index + 4]); + u32::from_be_bytes(bytes) + } + fn get_u128_be(&self, index: usize) -> u128 { + let mut bytes: [u8; 128 / 8] = [0; 128 / 8]; + bytes.copy_from_slice(&self[index..index + 128 / 8]); + u128::from_be_bytes(bytes) + } + fn get_u256(&self, index: usize) -> (u128, u128) { + (self.get_u128_be(index), self.get_u128_be(index + 128 / 8)) + } + fn get_address(&self, index: usize) -> CanonicalAddr { + // 32 bytes are reserved for addresses, but only the last 20 bytes are taken by the actual address + CanonicalAddr::from(&self[index + 32 - 20..index + 32]) + } + fn get_bytes32(&self, index: usize) -> &[u8] { + &self[index..index + 32] + } +} + +pub fn extend_address_to_32(addr: &CanonicalAddr) -> Vec { + let mut result: Vec = vec![0; 12]; + result.extend(addr.as_slice()); + result +} diff --git a/terra/contracts/wormhole/src/contract.rs b/terra/contracts/wormhole/src/contract.rs new file mode 100644 index 00000000..17680127 --- /dev/null +++ b/terra/contracts/wormhole/src/contract.rs @@ -0,0 +1,723 @@ +use cosmwasm_std::{ + log, to_binary, Api, Binary, CanonicalAddr, CosmosMsg, Env, Extern, HandleResponse, HumanAddr, + InitResponse, Querier, QueryRequest, StdResult, Storage, Uint128, WasmMsg, WasmQuery, +}; + +use crate::byte_utils::extend_address_to_32; +use crate::byte_utils::ByteUtils; +use crate::error::ContractError; +use crate::msg::{GuardianSetInfoResponse, HandleMsg, InitMsg, QueryMsg}; +use crate::state::{ + config, config_read, guardian_set_get, guardian_set_set, vaa_archive_add, vaa_archive_check, + wrapped_asset, wrapped_asset_address, wrapped_asset_address_read, wrapped_asset_read, + ConfigInfo, GuardianAddress, GuardianSetInfo, +}; + +use cw20_base::msg::HandleMsg as TokenMsg; +use cw20_base::msg::QueryMsg as TokenQuery; + +use cw20::TokenInfoResponse; + +use hex; + +use cw20_wrapped::msg::HandleMsg as WrappedMsg; +use cw20_wrapped::msg::InitMsg as WrappedInit; +use cw20_wrapped::msg::QueryMsg as WrappedQuery; +use cw20_wrapped::msg::{InitHook, InitMint, WrappedAssetInfoResponse}; + +use k256::ecdsa::recoverable::Id as RecoverableId; +use k256::ecdsa::recoverable::Signature as RecoverableSignature; +use k256::ecdsa::Signature; +use k256::ecdsa::VerifyKey; +use k256::EncodedPoint; +use sha3::{Digest, Keccak256}; + +use std::convert::TryFrom; + +// Chain ID of Terra +const CHAIN_ID: u8 = 3; + +pub fn init( + deps: &mut Extern, + env: Env, + msg: InitMsg, +) -> StdResult { + // Save general wormhole info + let state = ConfigInfo { + guardian_set_index: 0, + guardian_set_expirity: msg.guardian_set_expirity, + wrapped_asset_code_id: msg.wrapped_asset_code_id, + owner: deps.api.canonical_address(&env.message.sender)?, + is_active: true, + }; + config(&mut deps.storage).save(&state)?; + + // Add initial guardian set to storage + guardian_set_set( + &mut deps.storage, + state.guardian_set_index, + &msg.initial_guardian_set, + )?; + + Ok(InitResponse::default()) +} + +pub fn handle( + deps: &mut Extern, + env: Env, + msg: HandleMsg, +) -> StdResult { + match msg { + HandleMsg::SubmitVAA { vaa } => handle_submit_vaa(deps, env, &vaa), + HandleMsg::RegisterAssetHook { asset_id } => handle_register_asset(deps, env, &asset_id), + HandleMsg::LockAssets { + asset, + recipient, + amount, + target_chain, + nonce, + } => handle_lock_assets(deps, env, asset, amount, recipient, target_chain, nonce), + HandleMsg::TokensLocked { + target_chain, + token_chain, + token_decimals, + token, + sender, + recipient, + amount, + nonce, + } => handle_tokens_locked( + target_chain, + token_chain, + token_decimals, + token, + sender, + recipient, + amount, + nonce, + ), + HandleMsg::SetActive { is_active } => handle_set_active(deps, env, is_active), + } +} + +/// Process VAA message signed by quardians +fn handle_submit_vaa( + deps: &mut Extern, + env: Env, + data: &[u8], +) -> StdResult { + + let state = config_read(&deps.storage).load()?; + if !state.is_active { + return ContractError::ContractInactive.std_err(); + } + + /* VAA format: + + header (length 6): + 0 uint8 version (0x01) + 1 uint32 guardian set index + 5 uint8 len signatures + + per signature (length 66): + 0 uint8 index of the signer (in guardian keys) + 1 [65]uint8 signature + + body: + 0 uint32 unix seconds + 4 uint8 action + 5 [payload_size]uint8 payload */ + + const HEADER_LEN: usize = 6; + const SIGNATURE_LEN: usize = 66; + + let version = data.get_u8(0); + if version != 1 { + return ContractError::InvalidVersion.std_err(); + } + + // Load 4 bytes starting from index 1 + let vaa_guardian_set_index: u32 = data.get_u32(1); + let len_signers = data.get_u8(5) as usize; + let body_offset: usize = 6 + SIGNATURE_LEN * len_signers as usize; + + // Hash the body + let body = &data[body_offset..]; + let mut hasher = Keccak256::new(); + hasher.update(body); + let hash = hasher.finalize(); + + // Check if VAA with this hash was already accepted + if vaa_archive_check(&deps.storage, &hash) { + return ContractError::VaaAlreadyExecuted.std_err(); + } + vaa_archive_add(&mut deps.storage, &hash)?; + + // Load and check guardian set + let guardian_set = guardian_set_get(&deps.storage, vaa_guardian_set_index); + let guardian_set: GuardianSetInfo = + guardian_set.or(ContractError::InvalidGuardianSetIndex.std_err())?; + + if guardian_set.expiration_time == 0 || guardian_set.expiration_time > env.block.time { + return ContractError::GuardianSetExpired.std_err(); + } + if len_signers < (guardian_set.addresses.len() / 4) * 3 + 1 { + return ContractError::NoQuorum.std_err(); + } + + // Verify guardian signatures + let mut last_index: i32 = -1; + let mut pos = HEADER_LEN; + for _ in 0..len_signers { + let index = data.get_u8(pos) as i32; + if index <= last_index { + return Err(ContractError::WrongGuardianIndexOrder.std()); + } + last_index = index; + + let signature = Signature::try_from(&data[pos + 1..pos + 1 + 64]) + .or(ContractError::CannotDecodeSignature.std_err())?; + let id = RecoverableId::new(data.get_u8(pos + 1 + 64)) + .or(ContractError::CannotDecodeSignature.std_err())?; + let recoverable_signature = RecoverableSignature::new(&signature, id) + .or(ContractError::CannotDecodeSignature.std_err())?; + + let verify_key = recoverable_signature + .recover_verify_key_from_digest_bytes(&hash) + .or(ContractError::CannotRecoverKey.std_err())?; + if !keys_equal(&verify_key, &guardian_set.addresses[index as usize]) { + return ContractError::GuardianSignatureError.std_err(); + } + pos += SIGNATURE_LEN; + } + + // Signatures valid, apply VAA + let action = data.get_u8(body_offset + 4); + let payload = &data[body_offset + 5..]; + + match action { + 0x01 => { + if vaa_guardian_set_index != state.guardian_set_index { + return ContractError::NotCurrentGuardianSet.std_err(); + } + vaa_update_guardian_set(deps, env, payload) + } + 0x10 => vaa_transfer(deps, env, payload), + _ => ContractError::InvalidVAAAction.std_err(), + } +} + +/// Handle wrapped asset registration messages +fn handle_register_asset( + deps: &mut Extern, + env: Env, + asset_id: &[u8], +) -> StdResult { + let mut bucket = wrapped_asset(&mut deps.storage); + let result = bucket.load(asset_id); + match result { + Ok(_) => { + // Asset already registered, return error + return ContractError::AssetAlreadyRegistered.std_err(); + } + Err(_) => { + bucket.save(asset_id, &env.message.sender)?; + + let contract_address: CanonicalAddr = + deps.api.canonical_address(&env.message.sender)?; + wrapped_asset_address(&mut deps.storage) + .save(contract_address.as_slice(), &asset_id.to_vec())?; + + Ok(HandleResponse { + messages: vec![], + log: vec![ + log("action", "register_asset"), + log("asset_id", format!("{:?}", asset_id)), + log("contract_addr", env.message.sender), + ], + data: None, + }) + } + } +} + +fn vaa_update_guardian_set( + deps: &mut Extern, + env: Env, + data: &[u8], +) -> StdResult { + /* Payload format + 0 uint32 new_index + 4 uint8 len(keys) + 5 [][20]uint8 guardian addresses + */ + + let mut state = config_read(&deps.storage).load()?; + + let new_guardian_set_index = data.get_u32(0); + + if new_guardian_set_index != state.guardian_set_index + 1 { + return ContractError::GuardianSetIndexIncreaseError.std_err(); + } + let len = data.get_u8(4); + + let mut new_guardian_set = GuardianSetInfo { + addresses: vec![], + expiration_time: 0, + }; + let mut pos = 5; + for _ in 0..len { + new_guardian_set.addresses.push(GuardianAddress { + bytes: data[pos..pos + 20].to_vec(), + }); + pos += 20; + } + + let old_guardian_set_index = state.guardian_set_index; + state.guardian_set_index = new_guardian_set_index; + + guardian_set_set( + &mut deps.storage, + state.guardian_set_index, + &new_guardian_set, + )?; + config(&mut deps.storage).save(&state)?; + + let mut old_guardian_set = guardian_set_get(&deps.storage, old_guardian_set_index)?; + old_guardian_set.expiration_time = env.block.time + state.guardian_set_expirity; + guardian_set_set(&mut deps.storage, old_guardian_set_index, &old_guardian_set)?; + + // TODO: Apply new guardian set + Ok(HandleResponse { + messages: vec![], + log: vec![ + log("action", "guardian_set_change"), + log("old", old_guardian_set_index), + log("new", state.guardian_set_index), + ], + data: None, + }) +} + +fn vaa_transfer( + deps: &mut Extern, + env: Env, + data: &[u8], +) -> StdResult { + /* Payload format: + 0 uint32 nonce + 4 uint8 source_chain + 5 uint8 target_chain + 6 [32]uint8 source_address + 38 [32]uint8 target_address + 70 uint8 token_chain + 71 [32]uint8 token_address + 103 uint8 decimals + 104 uint256 amount */ + + let source_chain = data.get_u8(4); + let target_chain = data.get_u8(5); + + let target_address = data.get_address(38); + + let token_chain = data.get_u8(70); + let (not_supported_amount, amount) = data.get_u256(104); + + // Check high 128 bit of amount value to be empty + if not_supported_amount != 0 { + return ContractError::AmountTooHigh.std_err(); + } + + // Check if source and target chains are different + if source_chain == target_chain { + return ContractError::SameSourceAndTarget.std_err(); + } + + // Check if transfer is incoming + if target_chain != CHAIN_ID { + return ContractError::WrongTargetChain.std_err(); + } + + if token_chain != CHAIN_ID { + let mut asset_id: Vec = vec![]; + asset_id.push(token_chain); + let asset_address = data.get_bytes32(71); + asset_id.extend_from_slice(asset_address); + + let mut hasher = Keccak256::new(); + hasher.update(asset_id); + let asset_id = hasher.finalize(); + + let mut messages: Vec = vec![]; + + // Check if this asset is already deployed + match wrapped_asset_read(&deps.storage).load(&asset_id) { + Ok(contract_addr) => { + // Asset already deployed, just mint + messages.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr, + msg: to_binary(&WrappedMsg::Mint { + recipient: deps.api.human_address(&target_address)?, + amount: Uint128::from(amount), + })?, + send: vec![], + })); + } + Err(_) => { + // Asset is not deployed yet, deploy and mint + let state = config_read(&deps.storage).load()?; + messages.push(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id: state.wrapped_asset_code_id, + msg: to_binary(&WrappedInit { + asset_chain: token_chain, + asset_address: asset_address.to_vec(), + decimals: data.get_u8(103), + mint: Some(InitMint { + recipient: deps.api.human_address(&target_address)?, + amount: Uint128::from(amount), + }), + init_hook: Some(InitHook { + contract_addr: env.contract.address, + msg: to_binary(&HandleMsg::RegisterAssetHook { + asset_id: asset_id.to_vec(), + })?, + }), + })?, + send: vec![], + label: None, + })); + } + } + + Ok(HandleResponse { + messages, + log: vec![], + data: None, + }) + } else { + let token_address = data.get_address(71); + + Ok(HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: deps.api.human_address(&token_address)?, + msg: to_binary(&TokenMsg::Transfer { + recipient: deps.api.human_address(&target_address)?, + amount: Uint128::from(amount), + })?, + send: vec![], + })], + log: vec![], // TODO: Add log entries + data: None, + }) + } +} + +fn handle_lock_assets( + deps: &mut Extern, + env: Env, + asset: HumanAddr, + amount: Uint128, + recipient: Vec, + target_chain: u8, + nonce: u32, +) -> StdResult { + if target_chain == CHAIN_ID { + return ContractError::SameSourceAndTarget.std_err(); + } + + if amount.is_zero() { + return ContractError::AmountTooLow.std_err(); + } + + let state = config_read(&deps.storage).load()?; + if !state.is_active { + return ContractError::ContractInactive.std_err(); + } + + let asset_chain: u8; + let asset_address: Vec; + + // Query asset details + let request = QueryRequest::<()>::Wasm(WasmQuery::Smart { + contract_addr: asset.clone(), + msg: to_binary(&TokenQuery::TokenInfo {})?, + }); + let token_info: TokenInfoResponse = deps.querier.custom_query(&request)?; + + let decimals: u8 = token_info.decimals; + + let asset_canonical: CanonicalAddr = deps.api.canonical_address(&asset)?; + + let mut messages: Vec = vec![]; + + match wrapped_asset_address_read(&deps.storage).load(asset_canonical.as_slice()) { + Ok(_) => { + // This is a deployed wrapped asset, burn it + messages.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: asset.clone(), + msg: to_binary(&WrappedMsg::Burn { + account: env.message.sender.clone(), + amount: Uint128::from(amount), + })?, + send: vec![], + })); + let request = QueryRequest::<()>::Wasm(WasmQuery::Smart { + contract_addr: asset, + msg: to_binary(&WrappedQuery::WrappedAssetInfo {})?, + }); + let wrapped_token_info: WrappedAssetInfoResponse = + deps.querier.custom_query(&request)?; + asset_chain = wrapped_token_info.asset_chain; + asset_address = wrapped_token_info.asset_address; + } + Err(_) => { + // This is a regular asset, transfer its balance + messages.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: asset.clone(), + msg: to_binary(&TokenMsg::TransferFrom { + owner: env.message.sender.clone(), + recipient: env.contract.address.clone(), + amount: Uint128::from(amount), + })?, + send: vec![], + })); + asset_address = extend_address_to_32(&asset_canonical); + asset_chain = CHAIN_ID; + } + }; + + messages.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: env.contract.address, + msg: to_binary(&HandleMsg::TokensLocked { + target_chain, + token_chain: asset_chain, + token_decimals: decimals, + token: asset_address, + sender: extend_address_to_32(&deps.api.canonical_address(&env.message.sender)?), + recipient, + amount, + nonce, + })?, + send: vec![], + })); + + Ok(HandleResponse { + messages, + log: vec![], + data: None, + }) +} + +fn handle_tokens_locked( + target_chain: u8, + token_chain: u8, + token_decimals: u8, + token: Vec, + sender: Vec, + recipient: Vec, + amount: Uint128, + nonce: u32, +) -> StdResult { + // Dummy handler to record token lock as transaction + Ok(HandleResponse { + messages: vec![], + log: vec![ + log("locked.target_chain", target_chain), + log("locked.token_chain", token_chain), + log("locked.token_decimals", token_decimals), + log("locked.token", hex::encode(token)), + log("locked.sender", hex::encode(sender)), + log("locked.recipient", hex::encode(recipient)), + log("locked.amount", amount), + log("locked.nonce", nonce), + ], + data: None, + }) +} + +pub fn handle_set_active( + deps: &mut Extern, + env: Env, + is_active: bool, +) -> StdResult { + let mut state = config_read(&deps.storage).load()?; + + if deps.api.canonical_address(&env.message.sender)? != state.owner { + return ContractError::PermissionDenied.std_err(); + } + + state.is_active = is_active; + + config(&mut deps.storage).save(&state)?; + + Ok(HandleResponse { + messages: vec![], + log: vec![], + data: None, + }) +} + +pub fn query( + deps: &Extern, + msg: QueryMsg, +) -> StdResult { + match msg { + QueryMsg::GuardianSetInfo {} => to_binary(&query_query_guardian_set_info(deps)?), + } +} + +pub fn query_query_guardian_set_info( + deps: &Extern, +) -> StdResult { + let state = config_read(&deps.storage).load()?; + let guardian_set = guardian_set_get(&deps.storage, state.guardian_set_index)?; + let res = GuardianSetInfoResponse { + guardian_set_index: state.guardian_set_index, + addresses: guardian_set.addresses, + }; + Ok(res) +} + +fn keys_equal(a: &VerifyKey, b: &GuardianAddress) -> bool { + let mut hasher = Keccak256::new(); + + let point: EncodedPoint = EncodedPoint::from(a); + let point = point.decompress(); + if bool::from(point.is_none()) { + return false; + } + let point = point.unwrap(); + + hasher.update(&point.as_bytes()[1..]); + let a = &hasher.finalize()[12..]; + + let b = &b.bytes; + if a.len() != b.len() { + return false; + } + for (ai, bi) in a.iter().zip(b.iter()) { + if ai != bi { + return false; + } + } + true +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::state::GuardianSetInfo; + use cosmwasm_std::testing::{mock_dependencies, mock_env}; + use cosmwasm_std::HumanAddr; + + const ADDR_1: &str = "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe"; + const ADDR_2: &str = "8575Df9b3c97B4E267Deb92d93137844A97A0132"; + + const VAA_VALID_TRANSFER: &str = "010000000001005468beb21caff68710b2af2d60a986245bf85099509b6babe990a6c32456b44b3e2e9493e3056b7d5892957e14beab24be02dab77ed6c8915000e4a1267f78f400000007d01000000038018002010400000000000000000000000000000000000000000000000000000000000101010101010101010101010101010101010101000000000000000000000000010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000"; + const VAA_VALID_GUARDIAN_SET_CHANGE: &str = "01000000000100d90d6f9cbc0458599cbe4d267bc9221b54955b94cb5cb338aeb845bdc9dd275f558871ea479de9cc0b44cfb2a07344431a3adbd2f98aa86f4e12ff4aba061b7f00000007d00100000001018575df9b3c97b4e267deb92d93137844a97a0132"; + + const CANONICAL_LENGTH: usize = 20; + + fn do_init_default_guardians(deps: &mut Extern) { + do_init(deps, &vec![GuardianAddress::from(ADDR_1)]); + } + + fn do_init( + deps: &mut Extern, + guardians: &Vec, + ) { + let init_msg = InitMsg { + initial_guardian_set: GuardianSetInfo { + addresses: guardians.clone(), + expiration_time: 100, + }, + guardian_set_expirity: 50, + wrapped_asset_code_id: 999, + }; + let env = mock_env(&HumanAddr::from("creator"), &[]); + let res = init(deps, env, init_msg).unwrap(); + assert_eq!(0, res.messages.len()); + + // TODO: Query and check contract state and guardians storage + } + + fn submit_vaa( + deps: &mut Extern, + vaa: &str, + ) -> StdResult { + let msg = HandleMsg::SubmitVAA { + vaa: hex::decode(vaa).expect("Decoding failed"), + }; + let env = mock_env(&HumanAddr::from("creator"), &[]); + + handle(deps, env, msg) + } + + #[test] + fn can_init() { + let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); + do_init_default_guardians(&mut deps); + } + + #[test] + fn valid_vaa_token_transfer() { + let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); + do_init_default_guardians(&mut deps); + + let messages = submit_vaa(&mut deps, VAA_VALID_TRANSFER).unwrap().messages; + assert_eq!(1, messages.len()); + let msg = &messages[0]; + match msg { + CosmosMsg::Wasm(wasm_msg) => match wasm_msg { + WasmMsg::Instantiate { + code_id, + msg: _, + send, + label, + } => { + assert_eq!(*code_id, 999); + assert_eq!(*label, None); + assert_eq!(*send, vec![]); + } + _ => panic!("Wrong message type"), + }, + _ => panic!("Wrong message type"), + } + } + + #[test] + fn same_vaa_twice_error() { + let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); + do_init_default_guardians(&mut deps); + + let _ = submit_vaa(&mut deps, VAA_VALID_TRANSFER).unwrap(); + let e = submit_vaa(&mut deps, VAA_VALID_TRANSFER).unwrap_err(); + assert_eq!(e, ContractError::VaaAlreadyExecuted.std()); + } + + #[test] + fn valid_vaa_guardian_set_change() { + let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); + do_init_default_guardians(&mut deps); + + let messages = submit_vaa(&mut deps, VAA_VALID_GUARDIAN_SET_CHANGE) + .unwrap() + .messages; + assert_eq!(0, messages.len()); + + // Check storage + let state = config_read(&deps.storage) + .load() + .expect("Cannot load config storage"); + assert_eq!(state.guardian_set_index, 1); + let guardian_set_info = guardian_set_get(&deps.storage, state.guardian_set_index) + .expect("Cannot find guardian set"); + assert_eq!( + guardian_set_info, + GuardianSetInfo { + addresses: vec![GuardianAddress::from(ADDR_2)], + expiration_time: 0 + } + ); + } +} diff --git a/terra/contracts/wormhole/src/error.rs b/terra/contracts/wormhole/src/error.rs new file mode 100644 index 00000000..b5286ff8 --- /dev/null +++ b/terra/contracts/wormhole/src/error.rs @@ -0,0 +1,94 @@ +use cosmwasm_std::StdError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ContractError { + /// Invalid VAA version + #[error("InvalidVersion")] + InvalidVersion, + + /// Guardian set with this index does not exist + #[error("InvalidGuardianSetIndex")] + InvalidGuardianSetIndex, + + /// Guardian set expiration date is zero or in the past + #[error("GuardianSetExpired")] + GuardianSetExpired, + + /// Not enough signers on the VAA + #[error("NoQuorum")] + NoQuorum, + + /// Wrong guardian index order, order must be ascending + #[error("WrongGuardianIndexOrder")] + WrongGuardianIndexOrder, + + /// Some problem with signature decoding from bytes + #[error("CannotDecodeSignature")] + CannotDecodeSignature, + + /// Some problem with public key recovery from the signature + #[error("CannotRecoverKey")] + CannotRecoverKey, + + /// Recovered pubkey from signature does not match guardian address + #[error("GuardianSignatureError")] + GuardianSignatureError, + + /// VAA action code not recognized + #[error("InvalidVAAAction")] + InvalidVAAAction, + + /// VAA guardian set is not current + #[error("NotCurrentGuardianSet")] + NotCurrentGuardianSet, + + /// Only 128-bit amounts are supported + #[error("AmountTooHigh")] + AmountTooHigh, + + /// Amount should be higher than zero + #[error("AmountTooLow")] + AmountTooLow, + + /// Source and target chain ids must be different + #[error("SameSourceAndTarget")] + SameSourceAndTarget, + + /// Target chain id must be the same as the current CHAIN_ID + #[error("WrongTargetChain")] + WrongTargetChain, + + /// Wrapped asset init hook sent twice for the same asset id + #[error("AssetAlreadyRegistered")] + AssetAlreadyRegistered, + + /// Guardian set must increase in steps of 1 + #[error("GuardianSetIndexIncreaseError")] + GuardianSetIndexIncreaseError, + + /// VAA was already executed + #[error("VaaAlreadyExecuted")] + VaaAlreadyExecuted, + + /// Message sender not permitted to execute this operation + #[error("PermissionDenied")] + PermissionDenied, + + /// Attempt to execute contract action while it is inactive + #[error("ContractInactive")] + ContractInactive, +} + +impl ContractError { + pub fn std(&self) -> StdError { + StdError::GenericErr { + msg: format!("{}", self), + backtrace: None, + } + } + + pub fn std_err(&self) -> Result { + Err(self.std()) + } +} diff --git a/terra/contracts/wormhole/src/lib.rs b/terra/contracts/wormhole/src/lib.rs new file mode 100644 index 00000000..bb529705 --- /dev/null +++ b/terra/contracts/wormhole/src/lib.rs @@ -0,0 +1,10 @@ +mod byte_utils; +pub mod contract; +mod error; +pub mod msg; +pub mod state; + +pub use crate::error::ContractError; + +#[cfg(all(target_arch = "wasm32", not(feature = "library")))] +cosmwasm_std::create_entry_points!(contract); diff --git a/terra/contracts/wormhole/src/msg.rs b/terra/contracts/wormhole/src/msg.rs new file mode 100644 index 00000000..33d943cb --- /dev/null +++ b/terra/contracts/wormhole/src/msg.rs @@ -0,0 +1,55 @@ +use cosmwasm_std::{HumanAddr, Uint128}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::state::{GuardianAddress, GuardianSetInfo}; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct InitMsg { + pub initial_guardian_set: GuardianSetInfo, + pub guardian_set_expirity: u64, + pub wrapped_asset_code_id: u64, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + SubmitVAA { + vaa: Vec, + }, + RegisterAssetHook { + asset_id: Vec, + }, + LockAssets { + asset: HumanAddr, + amount: Uint128, + recipient: Vec, + target_chain: u8, + nonce: u32, + }, + TokensLocked { + target_chain: u8, + token_chain: u8, + token_decimals: u8, + token: Vec, + sender: Vec, + recipient: Vec, + amount: Uint128, + nonce: u32, + }, + SetActive { + is_active: bool, + }, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg { + GuardianSetInfo {}, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct GuardianSetInfoResponse { + pub guardian_set_index: u32, // Current guardian set index + pub addresses: Vec, // List of querdian addresses +} diff --git a/terra/contracts/wormhole/src/state.rs b/terra/contracts/wormhole/src/state.rs new file mode 100644 index 00000000..5b928813 --- /dev/null +++ b/terra/contracts/wormhole/src/state.rs @@ -0,0 +1,110 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use cosmwasm_std::{CanonicalAddr, HumanAddr, StdResult, Storage}; +use cosmwasm_storage::{ + bucket, bucket_read, singleton, singleton_read, Bucket, ReadonlyBucket, ReadonlySingleton, + Singleton, +}; + +pub static CONFIG_KEY: &[u8] = b"config"; +pub static GUARDIAN_SET_KEY: &[u8] = b"guardian_set"; +pub static WRAPPED_ASSET_KEY: &[u8] = b"wrapped_asset"; +pub static WRAPPED_ASSET_ADDRESS_KEY: &[u8] = b"wrapped_asset_address"; + +// Guardian set information +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct ConfigInfo { + // Current active guardian set + pub guardian_set_index: u32, + + // Period for which a guardian set stays active after it has been replaced + pub guardian_set_expirity: u64, + + // Code id for wrapped asset contract + pub wrapped_asset_code_id: u64, + + // Contract owner address, it can make contract active/inactive + pub owner: CanonicalAddr, + + // If true the contract is active and functioning + pub is_active: bool, +} + +// Guardian address +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct GuardianAddress { + pub bytes: Vec, // 20-byte addresses +} + +#[cfg(test)] +use hex; +#[cfg(test)] +impl GuardianAddress { + pub fn from(string: &str) -> GuardianAddress { + GuardianAddress { + bytes: hex::decode(string).expect("Decoding failed"), + } + } +} + +// Guardian set information +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct GuardianSetInfo { + pub addresses: Vec, // List of guardian addresses + pub expiration_time: u64, // Guardian set expiration time +} + +// Wormhole contract generic information +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct WormholeInfo { + // Period for which a guardian set stays active after it has been replaced + pub guardian_set_expirity: u64, +} + +pub fn config(storage: &mut S) -> Singleton { + singleton(storage, CONFIG_KEY) +} + +pub fn config_read(storage: &S) -> ReadonlySingleton { + singleton_read(storage, CONFIG_KEY) +} + +pub fn guardian_set_set( + storage: &mut S, + index: u32, + data: &GuardianSetInfo, +) -> StdResult<()> { + bucket(GUARDIAN_SET_KEY, storage).save(&index.to_le_bytes(), data) +} + +pub fn guardian_set_get(storage: &S, index: u32) -> StdResult { + bucket_read(GUARDIAN_SET_KEY, storage).load(&index.to_le_bytes()) +} + +pub fn vaa_archive_add(storage: &mut S, hash: &[u8]) -> StdResult<()> { + bucket(GUARDIAN_SET_KEY, storage).save(hash, &true) +} + +pub fn vaa_archive_check(storage: &S, hash: &[u8]) -> bool { + bucket_read(GUARDIAN_SET_KEY, storage) + .load(&hash) + .or::(Ok(false)) + .unwrap() +} + +pub fn wrapped_asset(storage: &mut S) -> Bucket { + bucket(WRAPPED_ASSET_KEY, storage) +} + +pub fn wrapped_asset_read(storage: &S) -> ReadonlyBucket { + bucket_read(WRAPPED_ASSET_KEY, storage) +} + +pub fn wrapped_asset_address(storage: &mut S) -> Bucket> { + bucket(WRAPPED_ASSET_ADDRESS_KEY, storage) +} + +pub fn wrapped_asset_address_read(storage: &S) -> ReadonlyBucket> { + bucket_read(WRAPPED_ASSET_ADDRESS_KEY, storage) +} diff --git a/terra/contracts/wormhole/tests/integration.rs b/terra/contracts/wormhole/tests/integration.rs new file mode 100644 index 00000000..29fff624 --- /dev/null +++ b/terra/contracts/wormhole/tests/integration.rs @@ -0,0 +1,84 @@ +static WASM: &[u8] = include_bytes!("../../../target/wasm32-unknown-unknown/release/wormhole.wasm"); + +use cosmwasm_std::{from_slice, Env, HumanAddr, InitResponse}; +use cosmwasm_storage::to_length_prefixed; +use cosmwasm_vm::testing::{init, mock_env, mock_instance, MockApi, MockQuerier, MockStorage}; +use cosmwasm_vm::{Instance, Storage, Api}; + +use wormhole::msg::InitMsg; +use wormhole::state::{ConfigInfo, GuardianAddress, GuardianSetInfo, CONFIG_KEY}; + +use hex; + +enum TestAddress { + INITIALIZER, +} + +impl TestAddress { + fn value(&self) -> HumanAddr { + match self { + TestAddress::INITIALIZER => HumanAddr::from("initializer"), + } + } +} + +fn mock_env_height(signer: &HumanAddr, height: u64, time: u64) -> Env { + let mut env = mock_env(signer, &[]); + env.block.height = height; + env.block.time = time; + env +} + +fn get_config_info(storage: &S) -> ConfigInfo { + let key = to_length_prefixed(CONFIG_KEY); + let data = storage + .get(&key) + .0 + .expect("error getting data") + .expect("data should exist"); + from_slice(&data).expect("invalid data") +} + +fn do_init( + height: u64, + guardians: &Vec, +) -> Instance { + let mut deps = mock_instance(WASM, &[]); + let init_msg = InitMsg { + initial_guardian_set: GuardianSetInfo { + addresses: guardians.clone(), + expiration_time: 100, + }, + guardian_set_expirity: 50, + wrapped_asset_code_id: 999, + }; + let env = mock_env_height(&TestAddress::INITIALIZER.value(), height, 0); + let owner = deps.api.canonical_address(&TestAddress::INITIALIZER.value()).0.unwrap(); + let res: InitResponse = init(&mut deps, env, init_msg).unwrap(); + assert_eq!(0, res.messages.len()); + + // query the store directly + deps.with_storage(|storage| { + assert_eq!( + get_config_info(storage), + ConfigInfo { + guardian_set_index: 0, + guardian_set_expirity: 50, + wrapped_asset_code_id: 999, + owner, + is_active: true, + } + ); + Ok(()) + }) + .unwrap(); + deps +} + +#[test] +fn init_works() { + let guardians = vec![GuardianAddress::from(GuardianAddress { + bytes: hex::decode("beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe").expect("Decoding failed"), + })]; + let _deps = do_init(111, &guardians); +} diff --git a/terra/docs/testing.md b/terra/docs/testing.md new file mode 100644 index 00000000..0bb280b6 --- /dev/null +++ b/terra/docs/testing.md @@ -0,0 +1,24 @@ +# Wormhole + Terra local test environment + +For the list of dependencies please follow [DEVELOP.md](../../DEVELOP.md) + +Additional dependencies: +- [Node.js](https://nodejs.org/) >= 14.x, [ts-node](https://www.npmjs.com/package/ts-node) >= 8.x + +Start Tilt from the project root: + + tilt up + +Afterwards use test scripts in `terra/tools` folder: + + npm install + npm run prepare-token + npm run prepare-wormhole + +These commands will give you two important addresses: test token address and Wormhole contract address on Terra. Now you need to change guardian configuration to monitor the right contract. Copy Wormhole contract address and replace existing address in file `devnet/bridge-terra.yaml` (line 67). Save the changes and monitor Tilt dashboard until guardian services restart. + +Now use both token address and Wormhole contract address to issue tocken lock transaction: + + npm run lock-tocken -- TOKEN_CONTRACT WORMHOLE_CONTRACT 1000 + +Where 1000 is a sample amount to transfer. After this command is issued monitor Guardian service in Tilt dashboard to see its effects propagated to the destination blockchain (in this case it is Ethereum). \ No newline at end of file diff --git a/terra/tools/lock-token.ts b/terra/tools/lock-token.ts new file mode 100644 index 00000000..a5151e43 --- /dev/null +++ b/terra/tools/lock-token.ts @@ -0,0 +1,25 @@ +import { execute_contract, query_contract } from './utils'; + +async function script() { + if (process.argv.length < 5) { + console.log('Required 3 params TOKEN_CONTRACT, WORMHOLE_CONTRACT, integer AMOUNT'); + } + let token_contract = process.argv[2]; + let wormhole_contract = process.argv[3]; + let amount = process.argv[4]; + + let allowanceResult = await execute_contract(token_contract, {increase_allowance: {spender: wormhole_contract, amount}}); + if (allowanceResult == null) return; + console.log('Allowance increased'); + let lockResult = await execute_contract(wormhole_contract, {lock_assets: { + asset: token_contract, + amount, + recipient: [...Buffer.from('00000000000000000000000019a4437E2BA06bF1FA42C56Fb269Ca0d30f60716', 'hex')], + target_chain: 2, // Ethereum + nonce: Date.now() % 1000000 + }}); + if (lockResult == null) return; + console.log('Tokens locked'); +} + +script(); \ No newline at end of file diff --git a/terra/tools/package-lock.json b/terra/tools/package-lock.json new file mode 100644 index 00000000..d7806fe9 --- /dev/null +++ b/terra/tools/package-lock.json @@ -0,0 +1,438 @@ +{ + "name": "terra-contract-tools", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@terra-money/terra.js": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-0.5.12.tgz", + "integrity": "sha512-3UZWMT3Tu+MOQrHZ8uEtHL+hurKbe1QVm8x+qWOe4+IOeY3eWdVeBIkHflhGI8NU31v/r5eznbTuy7kEMA4CMQ==", + "requires": { + "axios": "^0.20.0", + "bech32": "^1.1.4", + "bip32": "^2.0.6", + "bip39": "^3.0.2", + "bufferutil": "^4.0.1", + "crypto-js": "3.3.0", + "decimal.js": "^10.2.1", + "post-message-stream": "^3.0.0", + "secp256k1": "^4.0.2", + "utf-8-validate": "^5.0.2", + "ws": "^7.3.1" + } + }, + "@types/node": { + "version": "14.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz", + "integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==" + }, + "axios": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", + "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip32": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz", + "integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==", + "requires": { + "@types/node": "10.12.18", + "bs58check": "^2.1.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "tiny-secp256k1": "^1.1.3", + "typeforce": "^1.11.5", + "wif": "^2.0.6" + }, + "dependencies": { + "@types/node": { + "version": "10.12.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", + "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" + } + } + }, + "bip39": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz", + "integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==", + "requires": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + }, + "dependencies": { + "@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" + } + } + }, + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "bufferutil": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.2.tgz", + "integrity": "sha512-AtnG3W6M8B2n4xDQ5R+70EXvOpnXsFYg/AK2yTZd+HQ/oxAdz+GI+DvjmhBw3L0ole+LJ0ngqY4JMbDzkfNzhA==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "crypto-js": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", + "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==" + }, + "decimal.js": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" + }, + "elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "follow-redirects": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, + "pbkdf2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "post-message-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/post-message-stream/-/post-message-stream-3.0.0.tgz", + "integrity": "sha1-kNn1S9IJ5rb110eVuHWIIFtUcEg=", + "requires": { + "readable-stream": "^2.1.4" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "tiny-secp256k1": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.5.tgz", + "integrity": "sha512-duE2hSLSQIpHGzmK48OgRrGTi+4OTkXLC6aa86uOYQ6LLCYZSarVKIAvEtY7MoXjoL6bOXMSerEGMzrvW4SkDw==", + "requires": { + "bindings": "^1.3.0", + "bn.js": "^4.11.8", + "create-hmac": "^1.1.7", + "elliptic": "^6.4.0", + "nan": "^2.13.2" + } + }, + "typeforce": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", + "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" + }, + "utf-8-validate": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.3.tgz", + "integrity": "sha512-jtJM6fpGv8C1SoH4PtG22pGto6x+Y8uPprW0tw3//gGFhDDTiuksgradgFN6yRayDP4SyZZa6ZMGHLIa17+M8A==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "wif": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", + "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=", + "requires": { + "bs58check": "<3.0.0" + } + }, + "ws": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==" + } + } +} diff --git a/terra/tools/package.json b/terra/tools/package.json new file mode 100644 index 00000000..fab82a3f --- /dev/null +++ b/terra/tools/package.json @@ -0,0 +1,20 @@ +{ + "name": "terra-contract-tools", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build-contracts": "( cd .. && docker run --rm -v \"$(pwd)\":/code --mount type=volume,source=\"$(basename \"$(pwd)\")_cache\",target=/code/target --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry cosmwasm/workspace-optimizer:0.10.4 )", + "prepare-token": "ts-node prepare-token.ts", + "prepare-wormhole": "ts-node prepare-wormhole.ts", + "lock-token": "ts-node lock-token.ts", + "submit-vaa": "ts-node submit-vaa.ts" + }, + "author": "", + "license": "ISC", + "type": "module", + "dependencies": { + "@terra-money/terra.js": "^0.5.12", + "@types/node": "^14.14.6" + } +} diff --git a/terra/tools/prepare-token.ts b/terra/tools/prepare-token.ts new file mode 100644 index 00000000..006a707c --- /dev/null +++ b/terra/tools/prepare-token.ts @@ -0,0 +1,26 @@ +import { deploy_contract, instantiate_contract, query_contract } from './utils'; + +async function script() { + const TEST_ADDRESS: string = 'terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v'; + // cw20_base.wasm is build from https://github.com/CosmWasm/cosmwasm-plus repository, v.0.2.0 and is a standard base cw20 contract + let code_id = await deploy_contract('../artifacts/cw20_base.wasm'); + if (code_id == -1) return; + console.log(`Program deployed with code id ${code_id}`); + let contract_address = await instantiate_contract(code_id, { + name: 'Test token', + symbol: 'TST', + decimals: 8, + initial_balances: [{ + address: TEST_ADDRESS, + amount: '100000000000000', + }], + mint: null, + }); + console.log(`Contract instance created at ${contract_address}`); + + // Verify if token was minted to the test address + let result = await query_contract(contract_address, {balance: { address : TEST_ADDRESS}}); + console.log(`${TEST_ADDRESS} balance is ${result.balance}`); +} + +script(); \ No newline at end of file diff --git a/terra/tools/prepare-wormhole.ts b/terra/tools/prepare-wormhole.ts new file mode 100644 index 00000000..e3cc9c77 --- /dev/null +++ b/terra/tools/prepare-wormhole.ts @@ -0,0 +1,26 @@ +import { deploy_contract, instantiate_contract, query_contract } from './utils'; + +async function script() { + // Deploy cw20-wrapped + let wrapped_code_id = await deploy_contract('../artifacts/cw20_wrapped.wasm'); + if (wrapped_code_id == -1) return; + console.log(`CW20 Wrapped program deployed with code id ${wrapped_code_id}`); + // Deploy wormhole + let wormhole_code_id = await deploy_contract('../artifacts/wormhole.wasm'); + if (wormhole_code_id == -1) return; + console.log(`Wormhole program deployed with code id ${wormhole_code_id}`); + // Instantiate wormhole + let contract_address = await instantiate_contract(wormhole_code_id, { + initial_guardian_set: { + addresses: [ + { bytes: [0xbe, 0xfa, 0x42, 0x9d, 0x57, 0xcd, 0x18, 0xb7, 0xf8, 0xa4, 0xd9, 0x1a, 0x2d, 0xa9, 0xab, 0x4a, 0xf0, 0x5d, 0x0f, 0xbe] } + ], + expiration_time: 1000 * 60 * 60 + }, + guardian_set_expirity: 0, + wrapped_asset_code_id: wrapped_code_id, + }); + console.log(`Wormhole instance created at ${contract_address}`); +} + +script(); \ No newline at end of file diff --git a/terra/tools/submit-vaa.ts b/terra/tools/submit-vaa.ts new file mode 100644 index 00000000..0311016e --- /dev/null +++ b/terra/tools/submit-vaa.ts @@ -0,0 +1,17 @@ +import { execute_contract } from './utils'; + +async function script() { + if (process.argv.length < 3) { + console.log('Required 1 param WORMHOLE_CONTRACT'); + } + let wormhole_contract = process.argv[2]; + + // Test VAA built using bridge/cmd/vaa-test + let vaaResult = await execute_contract(wormhole_contract, {submit_v_a_a: { + vaa: [...Buffer.from('010000000001005468beb21caff68710b2af2d60a986245bf85099509b6babe990a6c32456b44b3e2e9493e3056b7d5892957e14beab24be02dab77ed6c8915000e4a1267f78f400000007d01000000038018002010400000000000000000000000000000000000000000000000000000000000101010101010101010101010101010101010101000000000000000000000000010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000', 'hex')] + }}); + if (vaaResult == null) return; + console.log('Vaa submitted'); +} + +script(); \ No newline at end of file diff --git a/terra/tools/tsconfig.json b/terra/tools/tsconfig.json new file mode 100644 index 00000000..51de44ad --- /dev/null +++ b/terra/tools/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "module": "commonjs", + "esModuleInterop": true, + "target": "es2017", + "moduleResolution": "node", + "sourceMap": true, + "outDir": "dist" + }, + "lib": ["es2017"] + } \ No newline at end of file diff --git a/terra/tools/utils.ts b/terra/tools/utils.ts new file mode 100644 index 00000000..f487dbf7 --- /dev/null +++ b/terra/tools/utils.ts @@ -0,0 +1,115 @@ +import { LCDClient, MsgStoreCode, MsgInstantiateContract, MsgExecuteContract, MnemonicKey, isTxError } from '@terra-money/terra.js'; +import * as fs from 'fs'; + +// test1 key from localterra accounts +const mk = new MnemonicKey({ + mnemonic: 'notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius' +}) + +// connect to localterra +const terra = new LCDClient({ + URL: 'http://localhost:1317', + chainID: 'localterra' +}); +const wallet = terra.wallet(mk); + +export async function deploy_contract(wasm_file) : Promise { + + const storeCode = new MsgStoreCode( + wallet.key.accAddress, + fs.readFileSync(wasm_file).toString('base64') + ); + try { + const storeCodeTx = await wallet.createAndSignTx({ + msgs: [storeCode], + }); + const storeCodeTxResult = await terra.tx.broadcast(storeCodeTx); + + //console.log(storeCodeTxResult); + + if (isTxError(storeCodeTxResult)) { + throw new Error( + `store code failed. code: ${storeCodeTxResult.code}, codespace: ${storeCodeTxResult.codespace}, raw_log: ${storeCodeTxResult.raw_log}` + ); + } + + const { + store_code: { code_id }, + } = storeCodeTxResult.logs[0].eventsByType; + + return parseInt(code_id[0], 10); + } catch (err) { + console.log(`Error ${err}`); + if (err.response) { + console.log(err.response.data); + } + return -1; + } +} + +export async function instantiate_contract(code_id: number, initMsg: object) : Promise { + try { + const instantiate = new MsgInstantiateContract( + wallet.key.accAddress, + code_id, + initMsg, + {}, + false + ); + + const instantiateTx = await wallet.createAndSignTx({ + msgs: [instantiate], + }); + const instantiateTxResult = await terra.tx.broadcast(instantiateTx); + + if (isTxError(instantiateTxResult)) { + throw new Error( + `instantiate failed. code: ${instantiateTxResult.code}, codespace: ${instantiateTxResult.codespace}, raw_log: ${instantiateTxResult.raw_log}` + ); + return null; + } + + const { + instantiate_contract: { contract_address }, + } = instantiateTxResult.logs[0].eventsByType; + + return contract_address[0]; + + } catch (err) { + console.log(`Error ${err}`); + if (err.response) { + console.log(err.response.data); + } + return null; + } +} + +export async function execute_contract(contract_address: string, msg: object) : Promise { + try { + const execute = new MsgExecuteContract( + wallet.key.accAddress, + contract_address, + { ...msg }, { } + ); + + const executeTx = await wallet.createAndSignTx({ + msgs: [execute] + }); + + const result = await terra.tx.broadcast(executeTx); + return result; + } catch (err) { + console.log(`Error ${err}`); + if (err.response) { + console.log(err.response.data); + } + return null; + } +} + +export async function query_contract(contract_address: string, query: object) : Promise { + const result = await terra.wasm.contractQuery( + contract_address, query + ); + return result; +} \ No newline at end of file