Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(docs): submitter docs #2837

Merged
merged 15 commits into from
Jul 28, 2024
125 changes: 116 additions & 9 deletions docs/bridge/docs/Services/Submitter.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,138 @@ This section is still in progress, please see [here](https://pkg.go.dev/github.c

The Ethergo Submitter module is designed to submit transactions to an EVM-based blockchain. It handles gas bumping and confirmation checking to ensure that transactions are eventually confirmed. This module is essential because the EVM does not specify transaction submission or consensus, and rate limits can affect transaction submission.

![submitter flow](img/submitter/submitter_flow.svg)
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved

## Key Features

- **Transaction Submission**: The main function of the module is the `SubmitTransaction` method, which returns a nonce and ensures that the transaction will eventually be confirmed.
The module is the `SubmitTransaction` method, which returns a nonce and ensures that the transaction will eventually be confirmed. The nonce may then be used in the `GetSubmissionStatus` method to check the state: `Pending`, `Stored`, `Submitted`, `FailedSubmit`, `ReplacedOrConfirmed`, `Replaced`, `Confirmed`.
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add corresponding database interactions.

The description of the SubmitTransaction method is clear, but it would be beneficial to include details about the corresponding database interactions.


- **Gas Bumping**: Automatically adjusts the gas price to ensure timely transaction confirmation.
- **Confirmation Checking**: Continuously checks the status of submitted transactions to confirm their inclusion in the blockchain.
- **Reaper Functionality**: Flushes old entries in the database that have reached a terminal state.

### Reaper

The submitter also has "reaper" functionality, which flushes old entries in the database that have reached a terminal state (`Replaced`, `ReplacedOrConfirmed`, `Confirmed`). By default, entries are flushed after a week, but this functionality is configurable by the `MaxRecordAge` config value.
The Submitter also has "reaper" functionality, which flushes old entries in the database that have reached a terminal state (`Replaced`, `ReplacedOrConfirmed`, `Confirmed`). By default, entries are flushed after a week, but this functionality is configurable by the `MaxRecordAge` config value.

### Submitter Config

This section is still in progress, please see [here](https://pkg.go.dev/github.com/synapsecns/sanguine/ethergo@v0.9.0/submitter/config) for details.
Config contains configuration for the Submitter. It can be loaded from a YAML file.
Chain-specific configuration items can be provided via the `Chains` map, which overrides the global config
for each chain. If a chain-specific item is not provided, the global config is used.

#### Example config

```yaml
submitter_config:
chains:
1:
supports_eip_1559: true
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
gas_estimate: 1000000
43114:
gas_estimate: 30000000
max_gas_price: 100000000000
supports_eip_1559: true
10:
gas_estimate: 400000
max_gas_price: 90000000000
gas_bump_percentage: 20
reaper_interval: 604800000000000 # int64(7 * 24 * time.Hour)
max_record_age: 86400000000000 # int64(1 * 24 * time.Hour)
```

Please see [here](https://pkg.go.dev/github.com/synapsecns/sanguine/ethergo@v0.9.0/submitter/config) for details on the configuration.
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved

### Overview

`SubmitTransaction` abstracts many of the complexities of on-chain transaction submission such as nonce management and gas bumping. In addition, sent transactions are stored in the database for easy indexing of older transactions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add missing comma.

A comma is missing after "submission".

- `SubmitTransaction` abstracts many of the complexities of on-chain transaction submission such as nonce management and gas bumping.
+ `SubmitTransaction` abstracts many of the complexities of on-chain transaction submission, such as nonce management and gas bumping.
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
`SubmitTransaction` abstracts many of the complexities of on-chain transaction submission such as nonce management and gas bumping. In addition, sent transactions are stored in the database for easy indexing of older transactions.
`SubmitTransaction` abstracts many of the complexities of on-chain transaction submission, such as nonce management and gas bumping. In addition, sent transactions are stored in the database for easy indexing of older transactions.
Tools
LanguageTool

[uncategorized] ~75-~75: Possible missing comma found.
Context: ...he complexities of on-chain transaction submission such as nonce management and gas bumpin...

(AI_HYDRA_LEO_MISSING_COMMA)


#### Example of SubmitTransaction

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe have a Using submitter as a library section? This is just very different than the average user configuring submitter/understanding how it works

Below is an example of how to submit a transaction using Submitter. Note that the actual transaction submission logic takes place in the callback. We use an abigen binding here to send the transaction (`ReceiveMessage`), but any way to send a transaction also works, like our [Ethergo/EVM client](https://pkg.go.dev/github.com/synapsecns/sanguine/ethergo@v0.9.0/client) or geth's `ethclient`.

```go
nonce, err := c.txSubmitter.SubmitTransaction(
ctx,
big.NewInt(int64(msg.DestChainID)),
func(transactor *bind.TransactOpts) (tx *types.Transaction, err error) {
tx, err = contract.ReceiveMessage(
transactor,
msg.Message,
msg.Attestation,
)
if err != nil {
return nil, fmt.Errorf("could not submit transaction: %w", err)
}

return tx, nil
},
)
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace hard tabs with spaces.

The example is clear and demonstrates the correct usage of the SubmitTransaction method. However, there are hard tabs that need to be replaced with spaces.

-	tx, err = contract.ReceiveMessage(
-            transactor,
-            msg.Message,
-            msg.Attestation,
-            )
-	if err != nil {
-		return nil, fmt.Errorf("could not submit transaction: %w", err)
-	}
+    tx, err = contract.ReceiveMessage(
+        transactor,
+        msg.Message,
+        msg.Attestation,
+    )
+    if err != nil {
+        return nil, fmt.Errorf("could not submit transaction: %w", err)
+    }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Overview
`SubmitTransaction` abstracts many of the complexities of on-chain transaction submission such as nonce management and gas bumping. In addition, sent transactions are stored in the database for easy indexing of older transactions.
#### Example of SubmitTransaction
Below is an example of how to submit a transaction using Submitter. Note that the actual transaction submission logic takes place in the callback. We use an abigen binding here to send the transaction (`ReceiveMessage`), but any way to send a transaction also works, like our [Ethergo/EVM client](https://pkg.go.dev/github.com/synapsecns/sanguine/ethergo@v0.9.0/client) or geth's `ethclient`.
```go
nonce, err := c.txSubmitter.SubmitTransaction(
ctx,
big.NewInt(int64(msg.DestChainID)),
func(transactor *bind.TransactOpts) (tx *types.Transaction, err error) {
tx, err = contract.ReceiveMessage(
transactor,
msg.Message,
msg.Attestation,
)
if err != nil {
return nil, fmt.Errorf("could not submit transaction: %w", err)
}
return tx, nil
},
)
```
### Overview
`SubmitTransaction` abstracts many of the complexities of on-chain transaction submission such as nonce management and gas bumping. In addition, sent transactions are stored in the database for easy indexing of older transactions.
#### Example of SubmitTransaction
Below is an example of how to submit a transaction using Submitter. Note that the actual transaction submission logic takes place in the callback. We use an abigen binding here to send the transaction (`ReceiveMessage`), but any way to send a transaction also works, like our [Ethergo/EVM client](https://pkg.go.dev/github.com/synapsecns/sanguine/ethergo@v0.9.0/client) or geth's `ethclient`.
```go
nonce, err := c.txSubmitter.SubmitTransaction(
ctx,
big.NewInt(int64(msg.DestChainID)),
func(transactor *bind.TransactOpts) (tx *types.Transaction, err error) {
tx, err = contract.ReceiveMessage(
transactor,
msg.Message,
msg.Attestation,
)
if err != nil {
return nil, fmt.Errorf("could not submit transaction: %w", err)
}
return tx, nil
},
)
```
Tools
Markdownlint

66-66: Column: 1
Hard tabs

(MD010, no-hard-tabs)


71-71: Column: 1
Hard tabs

(MD010, no-hard-tabs)


72-72: Column: 1
Hard tabs

(MD010, no-hard-tabs)


73-73: Column: 1
Hard tabs

(MD010, no-hard-tabs)


75-75: Column: 1
Hard tabs

(MD010, no-hard-tabs)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace hard tabs with spaces.

The example is clear and demonstrates the correct usage of the SubmitTransaction method. However, there are hard tabs that need to be replaced with spaces.

-	tx, err = contract.ReceiveMessage(
-            transactor,
-            msg.Message,
-            msg.Attestation,
-            )
-	if err != nil {
-		return nil, fmt.Errorf("could not submit transaction: %w", err)
-	}
+    tx, err = contract.ReceiveMessage(
+        transactor,
+        msg.Message,
+        msg.Attestation,
+    )
+    if err != nil {
+        return nil, fmt.Errorf("could not submit transaction: %w", err)
+    }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```go
nonce, err := c.txSubmitter.SubmitTransaction(
ctx,
big.NewInt(int64(msg.DestChainID)),
func(transactor *bind.TransactOpts) (tx *types.Transaction, err error) {
tx, err = contract.ReceiveMessage(
transactor,
msg.Message,
msg.Attestation,
)
if err != nil {
return nil, fmt.Errorf("could not submit transaction: %w", err)
}
return tx, nil
},
)
```
```go
nonce, err := c.txSubmitter.SubmitTransaction(
ctx,
big.NewInt(int64(msg.DestChainID)),
func(transactor *bind.TransactOpts) (tx *types.Transaction, err error) {
tx, err = contract.ReceiveMessage(
transactor,
msg.Message,
msg.Attestation,
)
if err != nil {
return nil, fmt.Errorf("could not submit transaction: %w", err)
}
return tx, nil
},
)
```
Tools
Markdownlint

116-116: Column: 1
Hard tabs

(MD010, no-hard-tabs)


121-121: Column: 1
Hard tabs

(MD010, no-hard-tabs)


122-122: Column: 1
Hard tabs

(MD010, no-hard-tabs)


123-123: Column: 1
Hard tabs

(MD010, no-hard-tabs)


125-125: Column: 1
Hard tabs

(MD010, no-hard-tabs)


### Nonce Management, Database, Internals

#### Nonce Management and Multichain
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same goes for this, try to seperate using submitter as a library from as an end user


Submitter was designed with multiple chains in mind by keeping track of a thread-safe `map[chainid]nonce`. When we build the transaction opts, we lock on the chainid until we finish firing off the transaction.
We also keep a `map[txHash]txStatus` with the same thread-safe mechanism.
This allows us to concurrently fire off transactions on different chains while ensuring our nonces are correct.

The [Queue](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/chain_queue.go) has a selector loop running at all times that calls the `processQueue` method, concurrently processing and storing confirmed txs, or using the [chain queue](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/chain_queue.go) to fire off and store pending txs on chain.

#### Customizing DB Behavior

The Chain Queue db interface, [Service](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/db/service.go), allows a user to customize their Transaction DB behavior. The concrete implementation is in [store.go](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/db/txdb/store.go).

#### Transaction DB

The schema for a transaction to be stored in the Transaction DB is:

```go
// ETHTX contains a raw evm transaction that is unsigned.
type ETHTX struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement:true"`
// UUID is a unique ID for this transaction that will persist across retries.
UUID string `gorm:"column:uuid;index"`
// CreatedAt is the time the transaction was created
CreatedAt time.Time
// TXHash is the hash of the transaction
TXHash string `gorm:"column:tx_hash;uniqueIndex;size:256"`
// From is the sender of the transaction
From string `gorm:"column:from;index"`
// ChainID is the chain id the transaction hash will be sent on
ChainID uint64 `gorm:"column:chain_id;index"`
// Nonce is the nonce of the raw evm tx
Nonce uint64 `gorm:"column:nonce;index"`
// RawTx is the raw serialized transaction
RawTx []byte `gorm:"column:raw_tx"`
// Status is the status of the transaction
Status db.Status `gorm:"column:status;index"`
}
```

Using [GORM.db](https://pkg.go.dev/gorm.io/gorm), you can use whatever database you'd like, MySQL, Sqlite, etc.

#### MySQL Example

```go
gdb, err := gorm.Open(mysql.Open(dbURL), &gorm.Config{
Logger: common_base.GetGormLogger(logger),
FullSaveAssociations: true,
NamingStrategy: NamingStrategy,
NowFunc: time.Now,
})
```

### Observability

Submitter exposes metrics for Prometheus. The metrics are:

- `num_pending_txs`: The number of pending transactions.
- `current_nonce`: The current nonce.
- `oldest_pending_tx`: The age of the oldest pending transaction.
- `confirmed_queue`: The number of confirmed transactions.
- `gas_balance`: The current gas balance.

- `num_pending_txs`: The number of pending transactions.
- `current_nonce`: The current nonce.
- `oldest_pending_tx`: The age of the oldest pending transaction.
- `confirmed_queue`: The number of confirmed transactions.
- `gas_balance`: The current gas balance.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

The details about nonce management, database behavior, and observability metrics are clear and valuable.

Fix grammatical issues and hard tabs.

There are some grammatical issues and hard tabs in the code blocks.

- The [Queue](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/chain_queue.go) has a selector loop running at all times that calls the `processQueue` method, concurrently processing and storing confirmed txs, or using the [chain queue](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/chain_queue.go) to fire off and store pending txs on chain.
+ The [Queue](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/chain_queue.go) has a selector loop running at all times which calls the `processQueue` method, concurrently processing and storing confirmed txs, or using the [chain queue](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/chain_queue.go) to fire off and store pending txs on chain.

- - `num_pending_txs`: The number of pending transactions.
- - `current_nonce`: The current nonce.
- - `oldest_pending_tx`: The age of the oldest pending transaction.
- - `confirmed_queue`: The number of confirmed transactions.
- - `gas_balance`: The current gas balance.
+ - `num_pending_txs`: The number of pending transactions
+ - `current_nonce`: The current nonce
+ - `oldest_pending_tx`: The age of the oldest pending transaction
+ - `confirmed_queue`: The number of confirmed transactions
+ - `gas_balance`: The current gas balance

-	 tx, err = contract.ReceiveMessage(
-            transactor,
-            msg.Message,
-            msg.Attestation,
-            )
-	if err != nil {
-		return nil, fmt.Errorf("could not submit transaction: %w", err)
-	}
+    tx, err = contract.ReceiveMessage(
+        transactor,
+        msg.Message,
+        msg.Attestation,
+    )
+    if err != nil {
+        return nil, fmt.Errorf("could not submit transaction: %w", err)
+    }

-	gdb, err := gorm.Open(mysql.Open(dbURL), &gorm.Config{
-	Logger:               common_base.GetGormLogger(logger),
-	FullSaveAssociations: true,
-	NamingStrategy:       NamingStrategy,
-	NowFunc:              time.Now,
+gdb, err := gorm.Open(mysql.Open(dbURL), &gorm.Config{
+    Logger:               common_base.GetGormLogger(logger),
+    FullSaveAssociations: true,
+    NamingStrategy:       NamingStrategy,
+    NowFunc:              time.Now,
})
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Nonce Management, Database, Internals
#### Nonce Management and Multichain
Submitter was designed with multiple chains in mind by keeping track of a thread-safe `map[chainid]nonce`. When we build the transaction opts, we lock on the chainid until we finish firing off the transaction.
We also keep a `map[txHash]txStatus` with the same thread-safe mechanism.
This allows us to concurrently fire off transactions on different chains while ensuring our nonces are correct.
The [Queue](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/chain_queue.go) has a selector loop running at all times that calls the `processQueue` method, concurrently processing and storing confirmed txs, or using the [chain queue](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/chain_queue.go) to fire off and store pending txs on chain.
#### Customizing DB Behavior
The Chain Queue db interface, [Service](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/db/service.go), allows a user to customize their Transaction DB behavior. The concrete implementation is in [store.go](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/db/txdb/store.go).
#### Transaction DB
The schema for a transaction to be stored in the Transaction DB is:
```go
// ETHTX contains a raw evm transaction that is unsigned.
type ETHTX struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement:true"`
// UUID is a unique ID for this transaction that will persist across retries.
UUID string `gorm:"column:uuid;index"`
// CreatedAt is the time the transaction was created
CreatedAt time.Time
// TXHash is the hash of the transaction
TXHash string `gorm:"column:tx_hash;uniqueIndex;size:256"`
// From is the sender of the transaction
From string `gorm:"column:from;index"`
// ChainID is the chain id the transaction hash will be sent on
ChainID uint64 `gorm:"column:chain_id;index"`
// Nonce is the nonce of the raw evm tx
Nonce uint64 `gorm:"column:nonce;index"`
// RawTx is the raw serialized transaction
RawTx []byte `gorm:"column:raw_tx"`
// Status is the status of the transaction
Status db.Status `gorm:"column:status;index"`
}
```
Using [GORM.db](https://pkg.go.dev/gorm.io/gorm), you can use whatever database you'd like, MySQL, Sqlite, etc.
#### MySQL Example
```go
gdb, err := gorm.Open(mysql.Open(dbURL), &gorm.Config{
Logger: common_base.GetGormLogger(logger),
FullSaveAssociations: true,
NamingStrategy: NamingStrategy,
NowFunc: time.Now,
})
```
### Observability
Submitter exposes metrics for Prometheus. The metrics are:
- `num_pending_txs`: The number of pending transactions.
- `current_nonce`: The current nonce.
- `oldest_pending_tx`: The age of the oldest pending transaction.
- `confirmed_queue`: The number of confirmed transactions.
- `gas_balance`: The current gas balance.
- `num_pending_txs`: The number of pending transactions.
- `current_nonce`: The current nonce.
- `oldest_pending_tx`: The age of the oldest pending transaction.
- `confirmed_queue`: The number of confirmed transactions.
- `gas_balance`: The current gas balance.
### Nonce Management, Database, Internals
#### Nonce Management and Multichain
Submitter was designed with multiple chains in mind by keeping track of a thread-safe `map[chainid]nonce`. When we build the transaction opts, we lock on the chainid until we finish firing off the transaction.
We also keep a `map[txHash]txStatus` with the same thread-safe mechanism.
This allows us to concurrently fire off transactions on different chains while ensuring our nonces are correct.
The [Queue](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/chain_queue.go) has a selector loop running at all times which calls the `processQueue` method, concurrently processing and storing confirmed txs, or using the [chain queue](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/chain_queue.go) to fire off and store pending txs on chain.
#### Customizing DB Behavior
The Chain Queue db interface, [Service](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/db/service.go), allows a user to customize their Transaction DB behavior. The concrete implementation is in [store.go](https://github.com/synapsecns/sanguine/blob/ethergo/v0.9.0/ethergo/submitter/db/txdb/store.go).
#### Transaction DB
The schema for a transaction to be stored in the Transaction DB is:
```go
// ETHTX contains a raw evm transaction that is unsigned.
type ETHTX struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement:true"`
// UUID is a unique ID for this transaction that will persist across retries.
UUID string `gorm:"column:uuid;index"`
// CreatedAt is the time the transaction was created
CreatedAt time.Time
// TXHash is the hash of the transaction
TXHash string `gorm:"column:tx_hash;uniqueIndex;size:256"`
// From is the sender of the transaction
From string `gorm:"column:from;index"`
// ChainID is the chain id the transaction hash will be sent on
ChainID uint64 `gorm:"column:chain_id;index"`
// Nonce is the nonce of the raw evm tx
Nonce uint64 `gorm:"column:nonce;index"`
// RawTx is the raw serialized transaction
RawTx []byte `gorm:"column:raw_tx"`
// Status is the status of the transaction
Status db.Status `gorm:"column:status;index"`
}
```
Using [GORM.db](https://pkg.go.dev/gorm.io/gorm), you can use whatever database you'd like, MySQL, Sqlite, etc.
#### MySQL Example
```go
gdb, err := gorm.Open(mysql.Open(dbURL), &gorm.Config{
Logger: common_base.GetGormLogger(logger),
FullSaveAssociations: true,
NamingStrategy: NamingStrategy,
NowFunc: time.Now,
})
```
### Observability
Submitter exposes metrics for Prometheus. The metrics are:
- `num_pending_txs`: The number of pending transactions
- `current_nonce`: The current nonce
- `oldest_pending_tx`: The age of the oldest pending transaction
- `confirmed_queue`: The number of confirmed transactions
- `gas_balance`: The current gas balance
Tools
LanguageTool

[grammar] ~88-~88: Possible subject-verb agreement error detected.
Context: ...selector loop running at all times that calls the processQueue method, concurrently...

(PLURAL_THAT_AGREEMENT)


[uncategorized] ~138-~138: Loose punctuation mark.
Context: ...s. The metrics are: - num_pending_txs: The number of pending transactions. - `...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~139-~139: Loose punctuation mark.
Context: ... pending transactions. - current_nonce: The current nonce. - `oldest_pending_tx...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~140-~140: Loose punctuation mark.
Context: ...The current nonce. - oldest_pending_tx: The age of the oldest pending transacti...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~141-~141: Loose punctuation mark.
Context: ...pending transaction. - confirmed_queue: The number of confirmed transactions. -...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~142-~142: Loose punctuation mark.
Context: ... confirmed transactions. - gas_balance: The current gas balance. The metrics c...

(UNLIKELY_OPENING_PUNCTUATION)

Markdownlint

127-127: Column: 1
Hard tabs

(MD010, no-hard-tabs)


128-128: Column: 1
Hard tabs

(MD010, no-hard-tabs)


129-129: Column: 1
Hard tabs

(MD010, no-hard-tabs)


130-130: Column: 1
Hard tabs

(MD010, no-hard-tabs)

Comment on lines +202 to +206
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix the loose punctuation mark.

The documentation correctly lists the observability metrics, but there is a loose punctuation mark.

- `num_pending_txs`: The number of pending transactions
- `current_nonce`: The current nonce
- `oldest_pending_tx`: The age of the oldest pending transaction
- `confirmed_queue`: The number of confirmed transactions
- `gas_balance`: The current gas balance
+ - `num_pending_txs`: The number of pending transactions.
+ - `current_nonce`: The current nonce.
+ - `oldest_pending_tx`: The age of the oldest pending transaction.
+ - `confirmed_queue`: The number of confirmed transactions.
+ - `gas_balance`: The current gas balance.

Committable suggestion was skipped due to low confidence.

Tools
LanguageTool

[uncategorized] ~202-~202: Loose punctuation mark.
Context: ...s. The metrics are: - num_pending_txs: The number of pending transactions. - `...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~203-~203: Loose punctuation mark.
Context: ... pending transactions. - current_nonce: The current nonce. - `oldest_pending_tx...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~204-~204: Loose punctuation mark.
Context: ...The current nonce. - oldest_pending_tx: The age of the oldest pending transacti...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~205-~205: Loose punctuation mark.
Context: ...pending transaction. - confirmed_queue: The number of confirmed transactions. -...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~206-~206: Loose punctuation mark.
Context: ... confirmed transactions. - gas_balance: The current gas balance. The metrics c...

(UNLIKELY_OPENING_PUNCTUATION)


The metrics can be used in a dashboard [here](https://raw.githubusercontent.com/synapsecns/sanguine/master/ethergo/dashboard.json). It looks like this:

Expand Down
Loading
Loading