Skip to content

Commit

Permalink
Hedera int with TXM fixes & config (#14129)
Browse files Browse the repository at this point in the history
* re-changes on top of develop

* Docs update

* changeset

* merged the error tests & Config fix

* Apply suggestions from code review

Co-authored-by: Jordan Krage <[email protected]>

* added newly found error

* formatting

* formatting

* updated docs

* Updating config to run with multiple RPCs

* bump seth to v1.2.2

* updated configs

---------

Co-authored-by: Jordan Krage <[email protected]>
Co-authored-by: davidcauchi <[email protected]>
  • Loading branch information
3 people authored Sep 20, 2024
1 parent ec585d4 commit 85a8d09
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/many-lamps-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

#added Hedera configs
12 changes: 11 additions & 1 deletion core/chains/evm/client/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,16 @@ var mantle = ClientErrors{
Fatal: regexp.MustCompile(`(: |^)'*invalid sender`),
}

var hederaFatal = regexp.MustCompile(`(: |^)(execution reverted)(:|$) | ^Transaction gas limit '(\d+)' exceeds block gas limit '(\d+)' | ^Transaction gas limit provided '(\d+)' is insufficient of intrinsic gas required '(\d+)' | ^Oversized data:|status INVALID_SIGNATURE`)
var hedera = ClientErrors{
NonceTooLow: regexp.MustCompile(`Nonce too low`),
NonceTooHigh: regexp.MustCompile(`Nonce too high`),
TerminallyUnderpriced: regexp.MustCompile(`(Gas price '(\d+)' is below configured minimum gas price '(\d+)')|(Gas price too low)`),
InsufficientEth: regexp.MustCompile(`Insufficient funds for transfer| failed precheck with status INSUFFICIENT_PAYER_BALANCE`),
ServiceUnavailable: regexp.MustCompile(`Transaction execution returns a null value for transaction`),
Fatal: hederaFatal,
}

var gnosis = ClientErrors{
TransactionAlreadyInMempool: regexp.MustCompile(`(: |^)(alreadyknown)`),
}
Expand All @@ -278,7 +288,7 @@ var internal = ClientErrors{
TerminallyStuck: regexp.MustCompile(TerminallyStuckMsg),
}

var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm, treasure, mantle, aStar, gnosis, internal}
var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm, treasure, mantle, aStar, hedera, gnosis, internal}

// ClientErrorRegexes returns a map of compiled regexes for each error type
func ClientErrorRegexes(errsRegex config.ClientErrors) *ClientErrors {
Expand Down
7 changes: 7 additions & 0 deletions core/chains/evm/client/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func Test_Eth_Errors(t *testing.T) {
{"call failed: OldNonce, Current nonce: 22, nonce of rejected tx: 17", true, "Nethermind"},
{"nonce too low. allowed nonce range: 427 - 447, actual: 426", true, "zkSync"},
{"client error nonce too low", true, "tomlConfig"},
{"[Request ID: 2e952947-ffad-408b-aed9-35f3ed152001] Nonce too low. Provided nonce: 15, current nonce: 15", true, "hedera"},
}

for _, test := range tests {
Expand All @@ -67,6 +68,7 @@ func Test_Eth_Errors(t *testing.T) {
{"nonce too high", true, "Erigon"},
{"nonce too high. allowed nonce range: 427 - 477, actual: 527", true, "zkSync"},
{"client error nonce too high", true, "tomlConfig"},
{"[Request ID: 3ec591b4-9396-49f4-a03f-06c415a7cc6a] Nonce too high. Provided nonce: 16, current nonce: 15", true, "hedera"},
}

for _, test := range tests {
Expand Down Expand Up @@ -170,6 +172,7 @@ func Test_Eth_Errors(t *testing.T) {
{"virtual machine entered unexpected state. please contact developers and provide transaction details that caused this error. Error description: The operator included transaction with an unacceptable gas price", true, "zkSync"},
{"client error terminally underpriced", true, "tomlConfig"},
{"gas price less than block base fee", true, "aStar"},
{"[Request ID: e4d09e44-19a4-4eb7-babe-270db4c2ebc9] Gas price '830000000000' is below configured minimum gas price '950000000000'", true, "hedera"},
}

for _, test := range tests {
Expand Down Expand Up @@ -219,6 +222,8 @@ func Test_Eth_Errors(t *testing.T) {
{"client error insufficient eth", true, "tomlConfig"},
{"transaction would cause overdraft", true, "Geth"},
{"failed to forward tx to sequencer, please try again. Error message: 'insufficient funds for gas * price + value'", true, "Mantle"},
{"[Request ID: 9dd78806-58c8-4e6d-89a8-a60962abe705] Error invoking RPC: transaction [email protected] failed precheck with status INSUFFICIENT_PAYER_BALANCE", true, "hedera"},
{"[Request ID: 6198d2a3-590f-4724-aae5-69fecead0c49] Insufficient funds for transfer", true, "hedera"},
}
for _, test := range tests {
err = evmclient.NewSendErrorS(test.message)
Expand All @@ -235,6 +240,7 @@ func Test_Eth_Errors(t *testing.T) {
{"i/o timeout", true, "Arbitrum"},
{"network is unreachable", true, "Arbitrum"},
{"client error service unavailable", true, "tomlConfig"},
{"[Request ID: 825608a8-fd8a-4b5b-aea7-92999509306d] Error invoking RPC: [Request ID: 825608a8-fd8a-4b5b-aea7-92999509306d] Transaction execution returns a null value for transaction", true, "hedera"},
}
for _, test := range tests {
err = evmclient.NewSendErrorS(test.message)
Expand Down Expand Up @@ -409,6 +415,7 @@ func Test_Eth_Errors_Fatal(t *testing.T) {
{"failed to forward tx to sequencer, please try again. Error message: 'invalid sender'", true, "Mantle"},

{"client error fatal", true, "tomlConfig"},
{"[Request ID: d9711488-4c1e-4af2-bc1f-7969913d7b60] Error invoking RPC: transaction [email protected] failed precheck with status INVALID_SIGNATURE", true, "hedera"},
{"invalid chain id for signer", true, "Treasure"},
}

Expand Down
31 changes: 31 additions & 0 deletions core/chains/evm/config/toml/defaults/Hedera_Mainnet.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ChainID = '295'
ChainType = 'hedera'
# Considering the 3-5 (6 including a buffer) seconds of finality and 2 seconds block production
# We set the depth to 6/2 = 3 blocks, setting to 10 for safety
FinalityDepth = 10
# Hedera has high TPS, so polling less often
LogPollInterval = '10s'
MinIncomingConfirmations = 1

[BalanceMonitor]
Enabled = true

[GasEstimator]
Mode = 'SuggestedPrice'
# Since Hedera dont have mempool and there's no way for a node to front run or a user to bribe a node to submit the transaction earlier than it's consensus timestamp,
# But they have automated congesting pricing throttling which would mean at high sustained level the gasPrice itself could be increased to prevent malicious behaviour.
# Disabling the Bumpthreshold as TXM now implicity handles the bumping after checking on-chain nonce & re-broadcast for Hedera chain type
BumpThreshold = 0
BumpMin = '10 gwei'
BumpPercent = 20

[Transactions]
# To hit throttling you'd need to maintain 15 m gas /sec over a prolonged period of time.
# Because Hedera's block times are every 2 secs it's less less likely to happen as compared to other chains
# Setting this to little higher even though Hedera has High TPS, We have seen 10-12s to get the trasaction mined & 20-25s incase of failures
# Accounting for Node syncs & avoid re-sending txns before fetching the receipt, setting to 2m
ResendAfterThreshold = '2m'


[NodePool]
SyncThreshold = 10
31 changes: 31 additions & 0 deletions core/chains/evm/config/toml/defaults/Hedera_Testnet.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ChainID = '296'
ChainType = 'hedera'
# Considering the 3-5 (6 including a buffer) seconds of finality and 2 seconds block production
# We set the depth to 6/2 = 3 blocks, setting to 10 for safety
FinalityDepth = 10
# Hedera has high TPS, so polling less often
LogPollInterval = '10s'
MinIncomingConfirmations = 1

[BalanceMonitor]
Enabled = true

[GasEstimator]
Mode = 'SuggestedPrice'
# Since Hedera dont have mempool and there's no way for a node to front run or a user to bribe a node to submit the transaction earlier than it's consensus timestamp,
# But they have automated congesting pricing throttling which would mean at high sustained level the gasPrice itself could be increased to prevent malicious behaviour.
# Disabling the Bumpthreshold as TXM now implicity handles the bumping after checking on-chain nonce & re-broadcast for Hedera chain type
BumpThreshold = 0
BumpMin = '10 gwei'
BumpPercent = 20

[Transactions]
# To hit throttling you'd need to maintain 15 m gas /sec over a prolonged period of time.
# Because Hedera's block times are every 2 secs it's less less likely to happen as compared to other chains
# Setting this to little higher even though Hedera has High TPS, We have seen 10-12s to get the trasaction mined & 20-25s incase of failures
# Accounting for Node syncs & avoid re-sending txns before fetching the receipt, setting to 2m
ResendAfterThreshold = '2m'


[NodePool]
SyncThreshold = 10
204 changes: 204 additions & 0 deletions docs/CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4000,6 +4000,210 @@ GasLimitDefault = 400000

</p></details>

<details><summary>Hedera Mainnet (295)</summary><p>

```toml
AutoCreateKey = true
BlockBackfillDepth = 10
BlockBackfillSkip = false
ChainType = 'hedera'
FinalityDepth = 10
FinalityTagEnabled = false
LogBackfillBatchSize = 1000
LogPollInterval = '10s'
LogKeepBlocksDepth = 100000
LogPrunePageSize = 0
BackupLogPollerBlockDelay = 100
MinIncomingConfirmations = 1
MinContractPayment = '0.00001 link'
NonceAutoSync = true
NoNewHeadsThreshold = '3m0s'
LogBroadcasterEnabled = true
RPCDefaultBatchSize = 250
RPCBlockQueryDelay = 1
FinalizedBlockOffset = 0
NoNewFinalizedHeadsThreshold = '0s'

[Transactions]
ForwardersEnabled = false
MaxInFlight = 16
MaxQueued = 250
ReaperInterval = '1h0m0s'
ReaperThreshold = '168h0m0s'
ResendAfterThreshold = '2m0s'

[Transactions.AutoPurge]
Enabled = false

[BalanceMonitor]
Enabled = true

[GasEstimator]
Mode = 'SuggestedPrice'
PriceDefault = '20 gwei'
PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether'
PriceMin = '1 gwei'
LimitDefault = 500000
LimitMax = 500000
LimitMultiplier = '1'
LimitTransfer = 21000
EstimateLimit = false
BumpMin = '10 gwei'
BumpPercent = 20
BumpThreshold = 0
EIP1559DynamicFees = false
FeeCapDefault = '100 gwei'
TipCapDefault = '1 wei'
TipCapMin = '1 wei'

[GasEstimator.BlockHistory]
BatchSize = 25
BlockHistorySize = 8
CheckInclusionBlocks = 12
CheckInclusionPercentile = 90
TransactionPercentile = 60

[GasEstimator.FeeHistory]
CacheTimeout = '10s'

[HeadTracker]
HistoryDepth = 100
MaxBufferSize = 3
SamplingInterval = '1s'
MaxAllowedFinalityDepth = 10000
FinalityTagBypass = true

[NodePool]
PollFailureThreshold = 5
PollInterval = '10s'
SelectionMode = 'HighestHead'
SyncThreshold = 10
LeaseDuration = '0s'
NodeIsSyncingEnabled = false
FinalizedBlockPollInterval = '5s'
EnforceRepeatableRead = false
DeathDeclarationDelay = '10s'

[OCR]
ContractConfirmations = 4
ContractTransmitterTransmitTimeout = '10s'
DatabaseTimeout = '10s'
DeltaCOverride = '168h0m0s'
DeltaCJitterOverride = '1h0m0s'
ObservationGracePeriod = '1s'

[OCR2]
[OCR2.Automation]
GasLimit = 5400000

[Workflow]
GasLimitDefault = 400000
```

</p></details>

<details><summary>Hedera Testnet (296)</summary><p>

```toml
AutoCreateKey = true
BlockBackfillDepth = 10
BlockBackfillSkip = false
ChainType = 'hedera'
FinalityDepth = 10
FinalityTagEnabled = false
LogBackfillBatchSize = 1000
LogPollInterval = '10s'
LogKeepBlocksDepth = 100000
LogPrunePageSize = 0
BackupLogPollerBlockDelay = 100
MinIncomingConfirmations = 1
MinContractPayment = '0.00001 link'
NonceAutoSync = true
NoNewHeadsThreshold = '3m0s'
LogBroadcasterEnabled = true
RPCDefaultBatchSize = 250
RPCBlockQueryDelay = 1
FinalizedBlockOffset = 0
NoNewFinalizedHeadsThreshold = '0s'

[Transactions]
ForwardersEnabled = false
MaxInFlight = 16
MaxQueued = 250
ReaperInterval = '1h0m0s'
ReaperThreshold = '168h0m0s'
ResendAfterThreshold = '2m0s'

[Transactions.AutoPurge]
Enabled = false

[BalanceMonitor]
Enabled = true

[GasEstimator]
Mode = 'SuggestedPrice'
PriceDefault = '20 gwei'
PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether'
PriceMin = '1 gwei'
LimitDefault = 500000
LimitMax = 500000
LimitMultiplier = '1'
LimitTransfer = 21000
EstimateLimit = false
BumpMin = '10 gwei'
BumpPercent = 20
BumpThreshold = 0
EIP1559DynamicFees = false
FeeCapDefault = '100 gwei'
TipCapDefault = '1 wei'
TipCapMin = '1 wei'

[GasEstimator.BlockHistory]
BatchSize = 25
BlockHistorySize = 8
CheckInclusionBlocks = 12
CheckInclusionPercentile = 90
TransactionPercentile = 60

[GasEstimator.FeeHistory]
CacheTimeout = '10s'

[HeadTracker]
HistoryDepth = 100
MaxBufferSize = 3
SamplingInterval = '1s'
MaxAllowedFinalityDepth = 10000
FinalityTagBypass = true

[NodePool]
PollFailureThreshold = 5
PollInterval = '10s'
SelectionMode = 'HighestHead'
SyncThreshold = 10
LeaseDuration = '0s'
NodeIsSyncingEnabled = false
FinalizedBlockPollInterval = '5s'
EnforceRepeatableRead = false
DeathDeclarationDelay = '10s'

[OCR]
ContractConfirmations = 4
ContractTransmitterTransmitTimeout = '10s'
DatabaseTimeout = '10s'
DeltaCOverride = '168h0m0s'
DeltaCJitterOverride = '1h0m0s'
ObservationGracePeriod = '1s'

[OCR2]
[OCR2.Automation]
GasLimit = 5400000

[Workflow]
GasLimitDefault = 400000
```

</p></details>

<details><summary>zkSync Sepolia (300)</summary><p>

```toml
Expand Down

0 comments on commit 85a8d09

Please sign in to comment.