From 85a8d09845d6bd30f62b1de4bf8c62f3a77a6c8e Mon Sep 17 00:00:00 2001 From: Simson Date: Fri, 20 Sep 2024 23:31:52 +0530 Subject: [PATCH] Hedera int with TXM fixes & config (#14129) * 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 * 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 Co-authored-by: davidcauchi --- .changeset/many-lamps-rush.md | 5 + core/chains/evm/client/errors.go | 12 +- core/chains/evm/client/errors_test.go | 7 + .../config/toml/defaults/Hedera_Mainnet.toml | 31 +++ .../config/toml/defaults/Hedera_Testnet.toml | 31 +++ docs/CONFIG.md | 204 ++++++++++++++++++ 6 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 .changeset/many-lamps-rush.md create mode 100644 core/chains/evm/config/toml/defaults/Hedera_Mainnet.toml create mode 100644 core/chains/evm/config/toml/defaults/Hedera_Testnet.toml diff --git a/.changeset/many-lamps-rush.md b/.changeset/many-lamps-rush.md new file mode 100644 index 00000000000..93d779aec95 --- /dev/null +++ b/.changeset/many-lamps-rush.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added Hedera configs diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index 6882cca524f..ba13e1bfea8 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -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)`), } @@ -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 { diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index e6478060917..84e518db666 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -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 { @@ -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 { @@ -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 { @@ -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 0.0.3041916@1717691931.680570179 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) @@ -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) @@ -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 0.0.4425573@1718213476.914320044 failed precheck with status INVALID_SIGNATURE", true, "hedera"}, {"invalid chain id for signer", true, "Treasure"}, } diff --git a/core/chains/evm/config/toml/defaults/Hedera_Mainnet.toml b/core/chains/evm/config/toml/defaults/Hedera_Mainnet.toml new file mode 100644 index 00000000000..4d5e48816fa --- /dev/null +++ b/core/chains/evm/config/toml/defaults/Hedera_Mainnet.toml @@ -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 \ No newline at end of file diff --git a/core/chains/evm/config/toml/defaults/Hedera_Testnet.toml b/core/chains/evm/config/toml/defaults/Hedera_Testnet.toml new file mode 100644 index 00000000000..6086a43af2c --- /dev/null +++ b/core/chains/evm/config/toml/defaults/Hedera_Testnet.toml @@ -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 \ No newline at end of file diff --git a/docs/CONFIG.md b/docs/CONFIG.md index c9262577f10..c3eeaac2827 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -4000,6 +4000,210 @@ GasLimitDefault = 400000

+
Hedera Mainnet (295)

+ +```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 +``` + +

+ +
Hedera Testnet (296)

+ +```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 +``` + +

+
zkSync Sepolia (300)

```toml