Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/InjectiveLabs/peggo into …
Browse files Browse the repository at this point in the history
…release-prod
  • Loading branch information
mankenavenkatesh committed Nov 16, 2021
2 parents d6447e2 + 9c1694e commit 5207f52
Show file tree
Hide file tree
Showing 13 changed files with 390 additions and 64 deletions.
7 changes: 6 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ PEGGO_COSMOS_USE_LEDGER=false

PEGGO_ETH_CHAIN_ID=1337
PEGGO_ETH_RPC="http://localhost:8545"
PEGGO_ETH_ALCHEMY_WS=""
PEGGO_ETH_CONTRACT_ADDRESS=

PEGGO_COINGECKO_API="https://api.coingecko.com/api/v3"
Expand All @@ -29,13 +30,17 @@ PEGGO_ETH_PASSPHRASE=
PEGGO_ETH_PK=
PEGGO_ETH_USE_LEDGER=false
PEGGO_ETH_GAS_PRICE_ADJUSTMENT=1.3
PEGGO_ETH_MAX_GAS_PRICE="500gwei"

PEGGO_RELAY_VALSETS=true
PEGGO_RELAY_VALSET_OFFSET_DUR="5m"
PEGGO_RELAY_BATCHES=true
PEGGO_RELAY_BATCH_OFFSET_DUR="5m"
PEGGO_MIN_BATCH_FEE_USD=23.2
PEGGO_RELAY_PENDING_TX_WAIT_DURATION="20m"

PEGGO_STATSD_PREFIX="peggo."
PEGGO_STATSD_ADDR="localhost:8125"
PEGGO_STATSD_STUCK_DUR="5m"
PEGGO_STATSD_MOCKING=false
PEGGO_STATSD_DISABLED=true
PEGGO_STATSD_DISABLED=true
116 changes: 78 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# Injective's Peggo [![Peggy.sol MythX](https://badgen.net/https/api.mythx.io/v1/projects/82ca9468-f86d-4550-a0ae-bc120eeb055f/badge/data?cache=300&icon=https://raw.githubusercontent.com/ConsenSys/mythx-github-badge/main/logo_white.svg)](https://docs.mythx.io/dashboard/github-badges)

Peggo is a Go implementation of the Peggy Orchestrator for the Injective Chain.
Peggo is a Go implementation of the Peggy Orchestrator for the Injective Chain.

`orchestrator` package provides all required components, while `orchestrator/cmd` has exectables that run.
Important Commands:

List of executables:
* `peggo orchestrator` starts the orchestrator main loop.
* `peggo tx register-eth-key` is a special command to submit an Ethereum key that will be used to sign messages on behalf of your Validator

* `peggo_orchestrator` is the main Validator companion binary for Peggy.
* `register_eth_key` is a special purpose binary for bootstrapping Peggy chains.

## Installation

Expand All @@ -17,7 +16,9 @@ Get yourself `Go 1.15+` at https://golang.org/dl/ first, then:
$ go get github.com/InjectiveLabs/peggo/orchestrator/cmd/...
```

## peggo_orchestrator
## peggo

Peggo is a companion executable for orchestrating a Peggy validator.

### Configuration

Expand All @@ -26,56 +27,95 @@ Use CLI args, flags or create `.env` with environment variables
### Usage

```
$ peggo_orchestrator -h
$ peggo --help
Usage: peggo_orchestrator [OPTIONS] COMMAND [arg...]
Usage: peggo [OPTIONS] COMMAND [arg...]
The Validator companion binary for Peggy.
Peggo is a companion executable for orchestrating a Peggy validator.
Options:
--env Application environment (env $APP_ENV) (default "local")
-l, --log-level Available levels: error, warn, info, debug. (env $APP_LOG_LEVEL) (default "info")
--svc-wait-timeout Standard wait timeout for all service dependencies (e.g. injectived). (env $SERVICE_WAIT_TIMEOUT) (default "1m")
--cosmos-privkey The Cosmos private key of the validator. (env $PEGGY_COSMOS_PRIVKEY)
--cosmos-grpc Cosmos GRPC querying endpoint (env $PEGGY_COSMOS_GRPC) (default "tcp://localhost:9900")
--tendermint-rpc Tednermint RPC endpoint (env $PEGGY_TENDERMINT_RPC) (default "http://localhost:26657")
--fees The Cosmos Denom in which to pay Cosmos chain fees (env $PEGGY_FEE_DENOM) (default "inj")
--chain-id Specify Chain ID of the injectived service. (env $INJECTIVED_CHAIN_ID) (default "888")
--eth-node-http Specify HTTP endpoint for an Ethereum node. (env $PEGGY_ETH_RPC) (default "http://localhost:1317")
--eth-privkey The Ethereum private key of the validator(Ex: 5D862464FE95...) (env $PEGGY_ETH_PRIVATE_KEY)
--contract-address The Ethereum contract address of Peggy (env $PEGGY_CONTRACT_ADDRESS)
--statsd-prefix Specify StatsD compatible metrics prefix. (env $STATSD_PREFIX) (default "relayer_api")
--statsd-addr UDP address of a StatsD compatible metrics aggregator. (env $STATSD_ADDR) (default "localhost:8125")
--statsd-stuck-func Sets a duration to consider a function to be stuck (e.g. in deadlock). (env $STATSD_STUCK_DUR) (default "5m")
--statsd-mocking If enabled replaces statsd client with a mock one that simply logs values. (env $STATSD_MOCKING) (default "false")
--statsd-disabled Force disabling statsd reporting completely. (env $STATSD_DISABLED) (default "false")
-e, --env The environment name this app runs in. Used for metrics and error reporting. (env $PEGGO_ENV) (default "local")
-l, --log-level Available levels: error, warn, info, debug. (env $PEGGO_LOG_LEVEL) (default "info")
--svc-wait-timeout Standard wait timeout for external services (e.g. Cosmos daemon GRPC connection) (env $PEGGO_SERVICE_WAIT_TIMEOUT) (default "1m")
Commands:
version Print the version information and exit.
orchestrator Starts the orchestrator main loop.
q, query Query commands that can get state info from Peggy.
tx Transactions for Peggy governance and maintenance.
version Print the version information and exit.
Run 'peggo_orchestrator COMMAND --help' for more information on a command.
Run 'peggo COMMAND --help' for more information on a command.
```

## register_eth_key
## Commands

### Configuration
### peggo orchestrator

Use CLI args, flags or create `.env` with environment variables
```
$ peggo orchestrator -h
### Usage
Usage: peggo orchestrator [OPTIONS]
Starts the orchestrator main loop.
Options:
--cosmos-chain-id Specify Chain ID of the Cosmos network. (env $PEGGO_COSMOS_CHAIN_ID) (default "888")
--cosmos-grpc Cosmos GRPC querying endpoint (env $PEGGO_COSMOS_GRPC) (default "tcp://localhost:9900")
--tendermint-rpc Tendermint RPC endpoint (env $PEGGO_TENDERMINT_RPC) (default "http://localhost:26657")
--cosmos-gas-prices Specify Cosmos chain transaction fees as DecCoins gas prices (env $PEGGO_COSMOS_GAS_PRICES)
--cosmos-keyring Specify Cosmos keyring backend (os|file|kwallet|pass|test) (env $PEGGO_COSMOS_KEYRING) (default "file")
--cosmos-keyring-dir Specify Cosmos keyring dir, if using file keyring. (env $PEGGO_COSMOS_KEYRING_DIR)
--cosmos-keyring-app Specify Cosmos keyring app name. (env $PEGGO_COSMOS_KEYRING_APP) (default "peggo")
--cosmos-from Specify the Cosmos validator key name or address. If specified, must exist in keyring, ledger or match the privkey. (env $PEGGO_COSMOS_FROM)
--cosmos-from-passphrase Specify keyring passphrase, otherwise Stdin will be used. (env $PEGGO_COSMOS_FROM_PASSPHRASE) (default "peggo")
--cosmos-pk Provide a raw Cosmos account private key of the validator in hex. USE FOR TESTING ONLY! (env $PEGGO_COSMOS_PK)
--cosmos-use-ledger Use the Cosmos app on hardware ledger to sign transactions. (env $PEGGO_COSMOS_USE_LEDGER)
--eth-chain-id Specify Chain ID of the Ethereum network. (env $PEGGO_ETH_CHAIN_ID) (default 42)
--eth-node-http Specify HTTP endpoint for an Ethereum node. (env $PEGGO_ETH_RPC) (default "http://localhost:1317")
--eth-node-alchemy-ws Specify websocket url for an Alchemy ethereum node. (env $PEGGO_ETH_ALCHEMY_WS)
--eth_gas_price_adjustment gas price adjustment for Ethereum transactions (env $PEGGO_ETH_GAS_PRICE_ADJUSTMENT) (default 1.3)
--eth-keystore-dir Specify Ethereum keystore dir (Geth-format) prefix. (env $PEGGO_ETH_KEYSTORE_DIR)
--eth-from Specify the from address. If specified, must exist in keystore, ledger or match the privkey. (env $PEGGO_ETH_FROM)
--eth-passphrase Passphrase to unlock the private key from armor, if empty then stdin is used. (env $PEGGO_ETH_PASSPHRASE)
--eth-pk Provide a raw Ethereum private key of the validator in hex. USE FOR TESTING ONLY! (env $PEGGO_ETH_PK)
--eth-use-ledger Use the Ethereum app on hardware ledger to sign transactions. (env $PEGGO_ETH_USE_LEDGER)
--relay_valsets If enabled, relayer will relay valsets to ethereum (env $PEGGO_RELAY_VALSETS)
--relay_valset_offset_dur If set, relayer will broadcast valsetUpdate only after relayValsetOffsetDur has passed from time of valsetUpdate creation (env $PEGGO_RELAY_VALSET_OFFSET_DUR) (default "5m")
--relay_batches If enabled, relayer will relay batches to ethereum (env $PEGGO_RELAY_BATCHES)
--relay_batch_offset_dur If set, relayer will broadcast batches only after relayBatchOffsetDur has passed from time of batch creation (env $PEGGO_RELAY_BATCH_OFFSET_DUR) (default "5m")
--relay_pending_tx_wait_duration If set, relayer will broadcast pending batches/valsetupdate only after pendingTxWaitDuration has passed (env $PEGGO_RELAY_PENDING_TX_WAIT_DURATION) (default "20m")
--min_batch_fee_usd If set, batch request will create batches only if fee threshold exceeds (env $PEGGO_MIN_BATCH_FEE_USD) (default 23.3)
--coingecko_api Specify HTTP endpoint for coingecko api. (env $PEGGO_COINGECKO_API) (default "https://api.coingecko.com/api/v3")
```

### peggo tx register-eth-key

```
$ register_eth_key -h
peggo tx register-eth-key --help
Usage: register_eth_key [OPTIONS]
Usage: peggo tx register-eth-key [OPTIONS]
Special purpose binary for bootstrapping Peggy chains.
Submits an Ethereum key that will be used to sign messages on behalf of your Validator
Options:
--cosmos-privkey The Cosmos private key of the validator. Must be saved when you generate your key (env $PEGGY_COSMOS_PRIVKEY)
--cosmos-grpc Cosmos GRPC querying endpoint (env $PEGGY_COSMOS_GRPC) (default "tcp://localhost:9900")
--fees The Cosmos Denom in which to pay Cosmos chain fees (env $PEGGY_FEE_DENOM) (default "inj")
--chain-id Specify Chain ID of the injectived service. (env $INJECTIVED_CHAIN_ID) (default "888")
--cosmos-chain-id Specify Chain ID of the Cosmos network. (env $PEGGO_COSMOS_CHAIN_ID) (default "888")
--cosmos-grpc Cosmos GRPC querying endpoint (env $PEGGO_COSMOS_GRPC) (default "tcp://localhost:9900")
--tendermint-rpc Tendermint RPC endpoint (env $PEGGO_TENDERMINT_RPC) (default "http://localhost:26657")
--cosmos-gas-prices Specify Cosmos chain transaction fees as DecCoins gas prices (env $PEGGO_COSMOS_GAS_PRICES)
--cosmos-keyring Specify Cosmos keyring backend (os|file|kwallet|pass|test) (env $PEGGO_COSMOS_KEYRING) (default "file")
--cosmos-keyring-dir Specify Cosmos keyring dir, if using file keyring. (env $PEGGO_COSMOS_KEYRING_DIR)
--cosmos-keyring-app Specify Cosmos keyring app name. (env $PEGGO_COSMOS_KEYRING_APP) (default "peggo")
--cosmos-from Specify the Cosmos validator key name or address. If specified, must exist in keyring, ledger or match the privkey. (env $PEGGO_COSMOS_FROM)
--cosmos-from-passphrase Specify keyring passphrase, otherwise Stdin will be used. (env $PEGGO_COSMOS_FROM_PASSPHRASE) (default "peggo")
--cosmos-pk Provide a raw Cosmos account private key of the validator in hex. USE FOR TESTING ONLY! (env $PEGGO_COSMOS_PK)
--cosmos-use-ledger Use the Cosmos app on hardware ledger to sign transactions. (env $PEGGO_COSMOS_USE_LEDGER)
--eth-keystore-dir Specify Ethereum keystore dir (Geth-format) prefix. (env $PEGGO_ETH_KEYSTORE_DIR)
--eth-from Specify the from address. If specified, must exist in keystore, ledger or match the privkey. (env $PEGGO_ETH_FROM)
--eth-passphrase Passphrase to unlock the private key from armor, if empty then stdin is used. (env $PEGGO_ETH_PASSPHRASE)
--eth-pk Provide a raw Ethereum private key of the validator in hex. USE FOR TESTING ONLY! (env $PEGGO_ETH_PK)
--eth-use-ledger Use the Ethereum app on hardware ledger to sign transactions. (env $PEGGO_ETH_USE_LEDGER)
-y, --yes Always auto-confirm actions, such as transaction sending. (env $PEGGO_ALWAYS_AUTO_CONFIRM)
```

## License
Expand Down
40 changes: 40 additions & 0 deletions cmd/peggo/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ func initEthereumOptions(
cmd *cli.Cmd,
ethChainID **int,
ethNodeRPC **string,
ethNodeAlchemyWS **string,
ethGasPriceAdjustment **float64,
ethMaxGasPrice **string,
) {
*ethChainID = cmd.Int(cli.IntOpt{
Name: "eth-chain-id",
Expand All @@ -157,12 +159,26 @@ func initEthereumOptions(
Value: "http://localhost:1317",
})

*ethNodeAlchemyWS = cmd.String(cli.StringOpt{
Name: "eth-node-alchemy-ws",
Desc: "Specify websocket url for an Alchemy ethereum node.",
EnvVar: "PEGGO_ETH_ALCHEMY_WS",
Value: "",
})

*ethGasPriceAdjustment = cmd.Float64(cli.Float64Opt{
Name: "eth_gas_price_adjustment",
Desc: "gas price adjustment for Ethereum transactions",
EnvVar: "PEGGO_ETH_GAS_PRICE_ADJUSTMENT",
Value: float64(1.3),
})

*ethMaxGasPrice = cmd.String(cli.StringOpt{
Name: "eth-max-gas-price",
Desc: "Specify Max gas price for Ethereum Transactions in GWei",
EnvVar: "PEGGO_ETH_MAX_GAS_PRICE",
Value: "500gwei",
})
}

func initEthereumKeyOptions(
Expand Down Expand Up @@ -254,7 +270,10 @@ func initStatsdOptions(
func initRelayerOptions(
cmd *cli.Cmd,
relayValsets **bool,
relayValsetOffsetDur **string,
relayBatches **bool,
relayBatchOffsetDur **string,
pendingTxWaitDuration **string,
) {
*relayValsets = cmd.Bool(cli.BoolOpt{
Name: "relay_valsets",
Expand All @@ -263,12 +282,33 @@ func initRelayerOptions(
Value: false,
})

*relayValsetOffsetDur = cmd.String(cli.StringOpt{
Name: "relay_valset_offset_dur",
Desc: "If set, relayer will broadcast valsetUpdate only after relayValsetOffsetDur has passed from time of valsetUpdate creation",
EnvVar: "PEGGO_RELAY_VALSET_OFFSET_DUR",
Value: "5m",
})

*relayBatches = cmd.Bool(cli.BoolOpt{
Name: "relay_batches",
Desc: "If enabled, relayer will relay batches to ethereum",
EnvVar: "PEGGO_RELAY_BATCHES",
Value: false,
})

*relayBatchOffsetDur = cmd.String(cli.StringOpt{
Name: "relay_batch_offset_dur",
Desc: "If set, relayer will broadcast batches only after relayBatchOffsetDur has passed from time of batch creation",
EnvVar: "PEGGO_RELAY_BATCH_OFFSET_DUR",
Value: "5m",
})

*pendingTxWaitDuration = cmd.String(cli.StringOpt{
Name: "relay_pending_tx_wait_duration",
Desc: "If set, relayer will broadcast pending batches/valsetupdate only after pendingTxWaitDuration has passed",
EnvVar: "PEGGO_RELAY_PENDING_TX_WAIT_DURATION",
Value: "20m",
})
}

// initBatchRequesterOptions sets options for batch requester.
Expand Down
30 changes: 25 additions & 5 deletions cmd/peggo/orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ func orchestratorCmd(cmd *cli.Cmd) {
// Ethereum params
ethChainID *int
ethNodeRPC *string
ethNodeAlchemyWS *string
ethGasPriceAdjustment *float64
ethMaxGasPrice *string

// Ethereum Key Management
ethKeystoreDir *string
Expand All @@ -63,8 +65,11 @@ func orchestratorCmd(cmd *cli.Cmd) {
ethUseLedger *bool

// Relayer config
relayValsets *bool
relayBatches *bool
relayValsets *bool
relayValsetOffsetDur *string
relayBatches *bool
relayBatchOffsetDur *string
pendingTxWaitDuration *string

// Batch requester config
minBatchFeeUSD *float64
Expand Down Expand Up @@ -95,7 +100,9 @@ func orchestratorCmd(cmd *cli.Cmd) {
cmd,
&ethChainID,
&ethNodeRPC,
&ethNodeAlchemyWS,
&ethGasPriceAdjustment,
&ethMaxGasPrice,
)

initEthereumKeyOptions(
Expand All @@ -110,7 +117,10 @@ func orchestratorCmd(cmd *cli.Cmd) {
initRelayerOptions(
cmd,
&relayValsets,
&relayValsetOffsetDur,
&relayBatches,
&relayBatchOffsetDur,
&pendingTxWaitDuration,
)

initBatchRequesterOptions(
Expand Down Expand Up @@ -220,13 +230,23 @@ func orchestratorCmd(cmd *cli.Cmd) {
ethProvider := provider.NewEVMProvider(evmRPC)
log.Infoln("Connected to Ethereum RPC at", *ethNodeRPC)

ethCommitter, err := committer.NewEthCommitter(ethKeyFromAddress, *ethGasPriceAdjustment, signerFn, ethProvider)
ethCommitter, err := committer.NewEthCommitter(ethKeyFromAddress, *ethGasPriceAdjustment, *ethMaxGasPrice, signerFn, ethProvider)
orShutdown(err)

peggyContract, err := peggy.NewPeggyContract(ethCommitter, peggyAddress)
pendingTxInputList := peggy.PendingTxInputList{}

pendingTxWaitDuration, err := time.ParseDuration(*pendingTxWaitDuration)
orShutdown(err)

peggyContract, err := peggy.NewPeggyContract(ethCommitter, peggyAddress, pendingTxInputList, pendingTxWaitDuration)
orShutdown(err)

relayer := relayer.NewPeggyRelayer(cosmosQueryClient, peggyContract, *relayValsets, *relayBatches)
// If Alchemy Websocket URL is set, then Subscribe to Pending Transaction of Peggy Contract.
if *ethNodeAlchemyWS != "" {
go peggyContract.SubscribeToPendingTxs(*ethNodeAlchemyWS)
}

relayer := relayer.NewPeggyRelayer(cosmosQueryClient, tmclient.NewRPCClient(*tendermintRPC), peggyContract, *relayValsets, *relayValsetOffsetDur, *relayBatches, *relayBatchOffsetDur)

coingeckoConfig := coingecko.Config{
BaseURL: *coingeckoApi,
Expand Down
28 changes: 28 additions & 0 deletions orchestrator/ethereum/committer/committer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package committer
import (
"context"
"math/big"
"strings"
"time"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -65,6 +66,33 @@ func OptionGasPriceFromString(str string) EVMCommitterOption {
}
}

func ParseMaxGasPrice(maxGasPriceStr string) int64 {
maxGasPriceStr = strings.TrimSpace(maxGasPriceStr)
maxGasPriceStr = strings.ToLower(maxGasPriceStr)

// If the denom is gwei, convert to wei
unit := "gwei"
isGwei := false
if strings.HasSuffix(maxGasPriceStr, unit) {
maxGasPriceStr = strings.TrimSuffix(maxGasPriceStr, unit)
isGwei = true
}

// if denom is not present, consider it as wei
maxGasPriceStr = strings.TrimSpace(maxGasPriceStr)
maxGasPrice, err := decimal.NewFromString(maxGasPriceStr)
if err != nil {
err = errors.Wrap(err, "unable to parse max gas price. max_gas_price should be in gwei")
panic(err)
}

if isGwei {
maxGasPrice = maxGasPrice.Shift(9) // Gwei to wei
}

return maxGasPrice.IntPart()
}

func OptionGasPriceFromDecimal(gasPrice decimal.Decimal) EVMCommitterOption {
return func(o *options) error {
o.GasPrice = gasPrice
Expand Down
Loading

0 comments on commit 5207f52

Please sign in to comment.