diff --git a/.codecov.yml b/.codecov.yml index 7f4fc86b..6c87592e 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -47,5 +47,6 @@ ignore: - "types/*.pb.go" - "test/*" - "test/**/*" + - "diagrams/**/*" - "scripts/" - "contrib" diff --git a/.golangci.yml b/.golangci.yml index 25153f73..9bf57c63 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -2,6 +2,7 @@ run: tests: false skip-dirs: - test + - diagrams govet: # Enable analyzers by name (in addition to default). diff --git a/CHANGELOG.md b/CHANGELOG.md index d9e5821c..7af91986 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements +[#275](https://github.com/umee-network/peggo/pull/275) Add diagrams of main loops. [#297](https://github.com/umee-network/peggo/pull/297) Update dependabot reviewers. ### Bug Fixes diff --git a/diagrams/README.md b/diagrams/README.md new file mode 100644 index 00000000..c25caf93 --- /dev/null +++ b/diagrams/README.md @@ -0,0 +1,66 @@ +# Peggo diagrams + +- All the peggo main loops are going to have an specific diagram associated +with it +- All the diagrams were made using [mermaid](https://mermaid-js.github.io/mermaid/#/) +- Can be edited in [mermaid.live](https://mermaid.live/) + +## Loops + +### EthOracleMainLoop + +- The `EthOracleMainLoop` responsible for making sure that Ethereum events are +retrieved from the Ethereum blockchain and ferried over to Cosmos where they +will be used to issue tokens or process batches + +![diagram](./mermaid-diagram-eth_oracle_main_loop-2022_04_26.png) + +- Code for this diagram is in `diagrams/loop_EthOracleMainLoop.mermaid` + +### BatchRequesterLoop + +- This loop really means that peggo checks with umee if there is any batch of tokens + that needs to be batched to ethereum (It doesn't actually sends that batch) it just + request to cosmos that this batch is built to be bridged in another loop + +- This loop is where peggo looks at the BatchFees and uses the query endpoint `BatchFees` + to iterate over the send to Eth tx pool for each token type, the relayer can then + observe the price for the ERC20 tokens being relayed on a dex and compute the gas + cost of executing the batch (via `eth_call()`) as well as the gas cost of + liquidating the earnings on a dex if desired. Once a relayer determines that a + batch is good and profitable it can send a `MsgRequestBatch` and the batch will + be created for the relayer to relay. + +- `MsgRequestBatch` is a message anyone can send that requests a batch of transactions + to send across the bridge be created for whatever block height this message is + included in. This acts as a coordination point, the handler for this message + looks at the `AddToOutgoingPool` tx's in the store and generates a batch, also + available in the store tied to this message. The validators then grab this batch, + sign it, submit the signatures with a MsgConfirmBatch before a relayer + can finally submit the batch + +![diagram](./mermaid-diagram-batch_requester_loop-2022_04_25.png) + +- Code for this diagram is in `diagrams/loop_BatchRequesterLoop.mermaid` + +### EthSignerMainLoop + +- The `EthSignerMainLoop` responsible for making sure that transaciton batches +and validator set are signed and confirmed and sent to the cosmos so that +afterwards they can be relayed and sent to the ethereum smartcontract + +![diagram](./mermaid-diagram-eth_signer_main_loop-2022_05_24.png) + +- Code for this diagram is in `diagrams/loop_EthSignerMainLoop.mermaid` + +### RelayerMainLoop + +- The `RelayerMainLoop` responsible for getting the latest valset available +and updating it on the ethereum smartcontract if needed. Also gets all the pending +transaction batches and it's signatures from cosmos and send it to the ethereum if +that batch of token is profitable, wasn't sent yet by another node (checking the +nonce) and it is not currently in the eth node node mempool. + +![diagram](./mermaid-diagram-relayer_main_loop-2022_05_24.png) + +- Code for this diagram is in `diagrams/loop_RelayerMainLoop.mermaid` diff --git a/diagrams/loop_BatchRequesterLoop.mermaid b/diagrams/loop_BatchRequesterLoop.mermaid new file mode 100644 index 00000000..c5f1d22c --- /dev/null +++ b/diagrams/loop_BatchRequesterLoop.mermaid @@ -0,0 +1,17 @@ +sequenceDiagram + title: BatchRequesterLoop + + Peggo->>+Cosmos: BatchFees queries the batch fees + Cosmos-->>-Peggo: return the batches from unbatched pool + Peggo->>+Oracle: GetPrice of all unbatched tokens + Oracle-->>-Peggo: return all token prices and symbols of unbatched tokens + Peggo->>+Ethereum: Get tokens decimals of unbatched tokens + Ethereum-->>-Peggo: return decimals of each unbatched tokens + Peggo->>+Cosmos: Get token denom from erc20 address + Cosmos-->>-Peggo: returns denoms of each token + Peggo->>+Peggo: Calculate batch profitability + Peggo-->>-Peggo: Batch is profitable + Peggo->>+Cosmos: SendRequestBatch for each token denom + Cosmos->>+Cosmos: Generates a batch tx to send across the bridge + Cosmos-->>-Cosmos: Validators grab batch and sign an MsgConfirmBatch + Cosmos->>-Peggo: Continue in RelayerMainLoop diff --git a/diagrams/loop_EthOracleMainLoop.mermaid b/diagrams/loop_EthOracleMainLoop.mermaid new file mode 100644 index 00000000..a0d0045b --- /dev/null +++ b/diagrams/loop_EthOracleMainLoop.mermaid @@ -0,0 +1,37 @@ +sequenceDiagram + title: EthOracleMainLoop + + Peggo->>+Cosmos: queries Gravity Bridge Params + Cosmos-->>-Peggo: returns current params + + Peggo-->>Peggo: Smart Contract is confirmed + + Peggo->>+Peggo: Init GetLastCheckedBlock + + Peggo->>+Cosmos: LastEventNonceByAddr gets last nonce from this addr + Cosmos-->>-Peggo: returns last nonce from this addr + + Peggo->>+Ethereum: GetLastBlock + Ethereum-->>-Peggo: returns last block + + Peggo->>+Ethereum: get sendToCosmosEvent, sendToCosmosEvent, TransactionBatchExecuted,
ERC20Deployed, ValsetUpdatedEvent events from last block + Ethereum-->>-Peggo: returns all events + + Peggo->>-Peggo: End GetLastCheckedBlock + + Peggo->>+Peggo: Init CheckForEvents + Peggo->>+Ethereum: Get Last block + Ethereum-->>-Peggo: returns last block + + Peggo->>+Ethereum: get all events ERC20Deployed, SendToCosmos,
TransactionBatchExecuted, ValsetUpdatedEvent + Ethereum-->>-Peggo: returns all the events + + Peggo->>+Cosmos: get LastEventNonceByAddr + Cosmos-->>-Peggo: returns the last nonce for that addr + + Peggo-->>Peggo: filter all the events from the nonce + + Peggo->>+Cosmos: broadcast all the eth events + Cosmos-->>-Peggo: waits for tx to be included in block + + Peggo-->>-Peggo: End CheckForEvents diff --git a/diagrams/loop_EthSignerMainLoop.mermaid b/diagrams/loop_EthSignerMainLoop.mermaid new file mode 100644 index 00000000..7028c3be --- /dev/null +++ b/diagrams/loop_EthSignerMainLoop.mermaid @@ -0,0 +1,24 @@ +sequenceDiagram + title: EthSignerMainLoop + + Peggo->>+Ethereum: queries Gravity Bridge ID + Ethereum-->>-Peggo: returns current gravityID + + Peggo->>+Cosmos: LastPendingValsetRequestByAddr + Peggo->>+Cosmos: AccFromAddress + Cosmos-->>-Peggo: returns the address + Cosmos-->>-Peggo: returns the validator set snapshots it has not yet signed + + Peggo->>+Peggo: Init Loop for each unsigned Valset + Peggo->>+Cosmos: SendValsetConfirm sends an confirmation for a validator
"MsgValsetConfirm" that sends signatures over to the validator + Cosmos-->>-Peggo: If 66%+ sent the MsgValsetConfirm then we can
submit the new validator set to ethereum + Peggo->>-Peggo: Ends Loop + + Peggo->>+Cosmos: get the LastPendingBatchRequestByAddr + Cosmos-->>-Peggo: returns last pending transaction batch unsigned + + Peggo->>+Peggo: Init Loop for each unsigned transaction batch + Peggo->>+Cosmos: SendBatchConfirm send an MsgConfirmBatch
with txs and eth signature + Cosmos-->>-Peggo: Cosmos validators order the txs of
highest to lowest fee in txqueue + Peggo->>-Peggo: Ends Loop + diff --git a/diagrams/loop_RelayerMainLoop.mermaid b/diagrams/loop_RelayerMainLoop.mermaid new file mode 100644 index 00000000..a6aec056 --- /dev/null +++ b/diagrams/loop_RelayerMainLoop.mermaid @@ -0,0 +1,76 @@ +sequenceDiagram + title: RelayerMainLoop + + Peggo->>+Peggo: FindLatestValset + Peggo->>+Ethereum: GetLastBlockNumber + Ethereum-->>-Peggo: returns the block number + + Peggo->>+Ethereum: GetValsetNonce gets the last valset nonce + Ethereum-->>-Peggo: returns the last nonce on eth + + Peggo->>+Cosmos: ValsetRequest gets the last valset nonce + Cosmos-->>-Peggo: returns the last nonce on cosmos + + Peggo->>+Ethereum: FilterValsetUpdatedEvent gets the last ValsetUpdatedEvent + Ethereum-->>-Peggo: returns the last ValsetUpdatedEvent + + Peggo->>Peggo: Builds all the ValsetUpdatedEvent and
reverse the order + Peggo->>Peggo: CheckIfValsetsDiffer Checks the last valset
from eth if the change is meaningfull + + Peggo-->>-Peggo: returns the latests possible valset + + Peggo->>+Peggo: RelayValsets + + Peggo->>+Cosmos: LastValsetRequests gets the last valset request + Cosmos-->>-Peggo: returns the last valset request on cosmos + + Peggo->>+Cosmos: findLatestValidValset gets the last valid valset + Cosmos-->>-Peggo: returns the lastest valid valset and signatures + + Peggo->>+Ethereum: GetValsetNonce gets the last valset nonce + Ethereum-->>-Peggo: returns the last nonce + + Peggo->>Peggo: Check if nonce wasn't already submitted + + Peggo-->>-Peggo: submit the updated Valset as
an Ethereum transaction if is needed + + Peggo->>+Peggo: getBatchesAndSignatures + + Peggo->>+Cosmos: OutgoingTxBatches gets the outgoing transactions + Cosmos-->>-Peggo: returns the OutgoingTxBatches of the gravity module + + Peggo->>+Cosmos: BatchConfirms foreach batch + Cosmos-->>-Peggo: returns all the signatures for the given batch + + Peggo->>+Ethereum: EncodeTransactionBatch checks with the gravity
contract if the signatures are good to be sent + Ethereum-->>-Peggo: returns error if any + + Peggo->>Peggo: Builds the batches of transactions
as possibleBatches + + Peggo-->>-Peggo: returns possible batches
to be relayed + + Peggo->>+Peggo: RelayBatches + + Peggo->>+Ethereum: GetLastBlockNumber + Ethereum-->>-Peggo: returns the last block number + + Peggo->>+Ethereum: GetTxBatchNonce + Ethereum-->>-Peggo: returns the latest transaction batch nonce + + Peggo->>Peggo: Checks for the last submitted
nonce on eth with the batch nonce + + Peggo->>+Ethereum: EncodeTransactionBatch encodes the
batch with signature (v, r, s) + Ethereum-->>-Peggo: returns encoded batch as bytes + + Peggo->>+Ethereum: EstimateGas calculates the gas usage of the tx to be sent + Ethereum-->>-Peggo: returns the estimated gas cost + + Peggo->>Peggo: Checks if the batch is
profitable using the oracles and
checking the price of each asset + + Peggo->>+Ethereum: IsPendingTxInput check if the tx is pending in the mempool + Ethereum-->>-Peggo: returns whether or not the tx is already there + + Peggo->>+Ethereum: SendTx sends the transaction to
ethereum with the encoded batch + Ethereum-->>-Peggo: returns the transaction hash + + Peggo-->>-Peggo: relayes all the possible
batches to ethereum diff --git a/diagrams/mermaid-diagram-batch_requester_loop-2022_04_25.png b/diagrams/mermaid-diagram-batch_requester_loop-2022_04_25.png new file mode 100644 index 00000000..c62e6a83 Binary files /dev/null and b/diagrams/mermaid-diagram-batch_requester_loop-2022_04_25.png differ diff --git a/diagrams/mermaid-diagram-batch_requester_loop-2022_04_25.svg b/diagrams/mermaid-diagram-batch_requester_loop-2022_04_25.svg new file mode 100644 index 00000000..b363b7d9 --- /dev/null +++ b/diagrams/mermaid-diagram-batch_requester_loop-2022_04_25.svg @@ -0,0 +1 @@ +PeggoCosmosOracleEthereumBatchFees queries the batch feesreturn the batches from unbatched poolGetPrice of all unbatched tokensreturn all token prices and symbols of unbatched tokensGet tokens decimals of unbatched tokensreturn decimals of each unbatched tokensGet token denom from erc20 addressreturns denoms of each tokenCalculate batch profitabilityBatch is profitableSendRequestBatch for each token denomGenerates a batch tx to send across the bridgeValidators grab batch and sign an MsgConfirmBatchContinue in RelayerMainLoopPeggoCosmosOracleEthereum \ No newline at end of file diff --git a/diagrams/mermaid-diagram-eth_oracle_main_loop-2022_04_26.png b/diagrams/mermaid-diagram-eth_oracle_main_loop-2022_04_26.png new file mode 100644 index 00000000..a127e19e Binary files /dev/null and b/diagrams/mermaid-diagram-eth_oracle_main_loop-2022_04_26.png differ diff --git a/diagrams/mermaid-diagram-eth_oracle_main_loop-2022_04_26.svg b/diagrams/mermaid-diagram-eth_oracle_main_loop-2022_04_26.svg new file mode 100644 index 00000000..9914891c --- /dev/null +++ b/diagrams/mermaid-diagram-eth_oracle_main_loop-2022_04_26.svg @@ -0,0 +1 @@ +EthOracleMainLoopPeggoCosmosEthereumqueries Gravity Bridge Paramsreturns current paramsSmart Contract is confirmedInit GetLastCheckedBlockLastEventNonceByAddr gets last nonce from this addrreturns last nonce from this addrGetLastBlockreturns last blockget sendToCosmosEvent, sendToCosmosEvent, TransactionBatchExecuted, ERC20Deployed, ValsetUpdatedEvent events from last blockreturns all eventsEnd GetLastCheckedBlockInit CheckForEventsGet Last blockreturns last blockget all events ERC20Deployed, SendToCosmos, TransactionBatchExecuted, ValsetUpdatedEventreturns all the eventsget LastEventNonceByAddrreturns the last nonce for that addrfilter all the events from the noncebroadcast all the eth eventswaits for tx to be included in blockEnd CheckForEventsPeggoCosmosEthereumEthOracleMainLoop \ No newline at end of file diff --git a/diagrams/mermaid-diagram-eth_signer_main_loop-2022_05_24.png b/diagrams/mermaid-diagram-eth_signer_main_loop-2022_05_24.png new file mode 100644 index 00000000..f12cdda3 Binary files /dev/null and b/diagrams/mermaid-diagram-eth_signer_main_loop-2022_05_24.png differ diff --git a/diagrams/mermaid-diagram-eth_signer_main_loop-2022_05_24.svg b/diagrams/mermaid-diagram-eth_signer_main_loop-2022_05_24.svg new file mode 100644 index 00000000..d2db9ed2 --- /dev/null +++ b/diagrams/mermaid-diagram-eth_signer_main_loop-2022_05_24.svg @@ -0,0 +1 @@ +PeggoEthereumCosmosqueries Gravity Bridge IDreturns current gravityIDLastPendingValsetRequestByAddrAccFromAddressreturns the addressreturns the validator set snapshots it has not yet signedInit Loop for each unsigned ValsetSendValsetConfirm sends an confirmation for a validator "MsgValsetConfirm" that sends signatures over to the validatorIf 66%+ sent the MsgValsetConfirm then we can submit the new validator set to ethereumEnds Loopget the LastPendingBatchRequestByAddrreturns last pending transaction batch unsignedInit Loop for each unsigned transaction batchSendBatchConfirm send an MsgConfirmBatch with txs and eth signatureCosmos validators order the txs of highest to lowest fee in txqueueEnds LoopPeggoEthereumCosmosEthSignerMainLoop \ No newline at end of file diff --git a/diagrams/mermaid-diagram-relayer_main_loop-2022_05_24.png b/diagrams/mermaid-diagram-relayer_main_loop-2022_05_24.png new file mode 100644 index 00000000..e35af491 Binary files /dev/null and b/diagrams/mermaid-diagram-relayer_main_loop-2022_05_24.png differ diff --git a/diagrams/mermaid-diagram-relayer_main_loop-2022_05_24.svg b/diagrams/mermaid-diagram-relayer_main_loop-2022_05_24.svg new file mode 100644 index 00000000..77583b0c --- /dev/null +++ b/diagrams/mermaid-diagram-relayer_main_loop-2022_05_24.svg @@ -0,0 +1 @@ +PeggoEthereumCosmosFindLatestValsetGetLastBlockNumberreturns the block numberGetValsetNonce gets the last valset noncereturns the last nonce on ethValsetRequest gets the last valset noncereturns the last nonce on cosmosFilterValsetUpdatedEvent gets the last ValsetUpdatedEventreturns the last ValsetUpdatedEventBuilds all the ValsetUpdatedEvent and reverse the orderCheckIfValsetsDiffer Checks the last valset from eth if the change is meaningfullreturns the latests possible valsetRelayValsetsLastValsetRequests gets the last valset requestreturns the last valset request on cosmosfindLatestValidValset gets the last valid valsetreturns the lastest valid valset and signaturesGetValsetNonce gets the last valset noncereturns the last nonceCheck if nonce wasn't already submittedsubmit the updated Valset as an Ethereum transaction if is neededgetBatchesAndSignaturesOutgoingTxBatches gets the outgoing transactionsreturns the OutgoingTxBatches of the gravity moduleBatchConfirms foreach batchreturns all the signatures for the given batchEncodeTransactionBatch checks with the gravity contract if the signatures are good to be sentreturns error if anyBuilds the batches of transactions as possibleBatchesreturns possible batches to be relayedRelayBatchesGetLastBlockNumberreturns the last block numberGetTxBatchNoncereturns the latest transaction batch nonceChecks for the last submitted nonce on eth with the batch nonceEncodeTransactionBatch encodes the batch with signature (v, r, s)returns encoded batch as bytesEstimateGas calculates the gas usage of the tx to be sentreturns the estimated gas costChecks if the batch is profitable using the oracles and checking the price of each assetIsPendingTxInput check if the tx is pending in the mempoolreturns whether or not the tx is already thereSendTx sends the transaction to ethereum with the encoded batchreturns the transaction hashrelayes all the possible batches to ethereumPeggoEthereumCosmosRelayerMainLoop \ No newline at end of file diff --git a/orchestrator/main_loops.go b/orchestrator/main_loops.go index e9eb6680..6be13405 100644 --- a/orchestrator/main_loops.go +++ b/orchestrator/main_loops.go @@ -58,15 +58,36 @@ func (p *gravityOrchestrator) Start(ctx context.Context) error { var pg loops.ParanoidGroup pg.Go(func() error { + // scan all the events emitted by ethereum gravity contract + // from the last block (we get the last block from cosmos) + // broadcast all the eth events to cosmos as "claims" return p.EthOracleMainLoop(ctx) }) + pg.Go(func() error { + // looks at the BatchFees on Cosmos and uses the query endpoint BatchFees + // to iterate over each token to see if it is profitable, if it is + // it will send an request batch for that denom return p.BatchRequesterLoop(ctx) }) + pg.Go(func() error { + // Gets the last pending valset to send an MsgValsetConfirm that sends + // signatures over to the cosmos validator if 66%+ a new validator set + // can be send to ethereum smartcontract. Also get the last pending + // batch request that signs that batch with an MsgConfirmBatch embedded + // with the txs and also the eth signature, then the cosmos validators + // are able to put the transactions in the queue ordered by tx fee return p.EthSignerMainLoop(ctx) }) + pg.Go(func() error { + // Gets the latest valset available and updating it on the ethereum + // smartcontract if needed. Also gets all the pending transaction + // batches and it's signatures from cosmos and send it to the + // ethereum if that batch of token is profitable, wasn't sent yet + // by another node (checking the nonce) and it is not currently + // in the eth node node mempool. return p.RelayerMainLoop(ctx) }) @@ -298,6 +319,7 @@ func (p *gravityOrchestrator) EthSignerMainLoop(ctx context.Context) (err error) }) } +// BatchRequesterLoop sends a batch request to Cosmos (Umee). func (p *gravityOrchestrator) BatchRequesterLoop(ctx context.Context) (err error) { logger := p.logger.With().Str("loop", "BatchRequesterLoop").Logger()