From 88794b1deb7fbf45df837f27a04ddbb30fcd18f7 Mon Sep 17 00:00:00 2001 From: SamMayWork Date: Thu, 7 Mar 2024 16:27:48 +0000 Subject: [PATCH 1/7] fix: allow for bytes to be truncated down Signed-off-by: SamMayWork --- go.mod | 2 ++ go.sum | 10 ++-------- internal/ethereum/blocklistener.go | 11 +++++++++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 254d804..0e52393 100644 --- a/go.mod +++ b/go.mod @@ -99,3 +99,5 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace github.com/hyperledger/firefly-signer => github.com/SamMayWork/firefly-signer v0.0.0-20240307121035-e654fb9ef55b diff --git a/go.sum b/go.sum index d20bcbe..28e214f 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,8 @@ github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8 github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/SamMayWork/firefly-signer v0.0.0-20240307121035-e654fb9ef55b h1:XMWx/jEupPkbF1cKEvi682R23xteeNf6EZRrc0O23tk= +github.com/SamMayWork/firefly-signer v0.0.0-20240307121035-e654fb9ef55b/go.mod h1:pK6kivzBFSue3zpJSQpH67VasnLLbwBJOBUNv0zHbRA= github.com/aidarkhanov/nanoid v1.0.8 h1:yxyJkgsEDFXP7+97vc6JevMcjyb03Zw+/9fqhlVXBXA= github.com/aidarkhanov/nanoid v1.0.8/go.mod h1:vadfZHT+m4uDhttg0yY4wW3GKtl2T6i4d2Age+45pYk= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -100,16 +102,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/hyperledger/firefly-common v1.4.6-0.20240131185020-80d20a173401 h1:bcIg8zUalHyjxPmhIggwg/VK/IVDvpH2XJwCkfAYrSU= -github.com/hyperledger/firefly-common v1.4.6-0.20240131185020-80d20a173401/go.mod h1:jkErZdQmC9fsAJZQO427tURdwB9iiW+NMUZSqS3eBIE= github.com/hyperledger/firefly-common v1.4.6 h1:qqXoSaRml3WjUnWcWxrrXs5AIOWa+UcMXLCF8yEa4Pk= github.com/hyperledger/firefly-common v1.4.6/go.mod h1:jkErZdQmC9fsAJZQO427tURdwB9iiW+NMUZSqS3eBIE= -github.com/hyperledger/firefly-signer v1.1.12 h1:wv1cq4HV60G2MQdmIEkYkywoxUSkaH0ss95Nn3ohdEk= -github.com/hyperledger/firefly-signer v1.1.12/go.mod h1:4MW7bcTqPsS7SKwANJZRL030cJRsHcpB/a+06wUROvc= -github.com/hyperledger/firefly-signer v1.1.13 h1:eiHjc6HPRG8AzXUCUgm51qqX1I9BokiuiiqJ89XwK4M= -github.com/hyperledger/firefly-signer v1.1.13/go.mod h1:pK6kivzBFSue3zpJSQpH67VasnLLbwBJOBUNv0zHbRA= -github.com/hyperledger/firefly-transaction-manager v1.3.7 h1:rHQw0UopJMl4s6RigW6As+VkjGYuV+oTp+jLOATOptw= -github.com/hyperledger/firefly-transaction-manager v1.3.7/go.mod h1:kwhCuzcFwhmj2+LYsE5dEzI7NqA+l0SYexsCMj06xXg= github.com/hyperledger/firefly-transaction-manager v1.3.8 h1:F/bg4P4jueny/rkPkSqXCcxpQpE9KJr6Z8w19/TOaK4= github.com/hyperledger/firefly-transaction-manager v1.3.8/go.mod h1:N3BoHh8+dWG710oQKuNiXmJNEOBBeLTsQ8GpZ41vhog= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= diff --git a/internal/ethereum/blocklistener.go b/internal/ethereum/blocklistener.go index af07a62..7a63557 100644 --- a/internal/ethereum/blocklistener.go +++ b/internal/ethereum/blocklistener.go @@ -137,6 +137,17 @@ func (bl *blockListener) listenLoop() { continue } + for i := 0; i < len(blockHashes); i++ { + truncatedHash, err := blockHashes[i].Truncate(32) + if err != nil { + log.L(bl.ctx).Errorf("Failed to truncate block hash") + failCount++ + continue + } + + blockHashes[i] = truncatedHash + } + update := &ffcapi.BlockHashEvent{GapPotential: gapPotential} var notifyPos *list.Element for _, h := range blockHashes { From 7fbecb341c35b393a0ef7b6215caea64277f54c7 Mon Sep 17 00:00:00 2001 From: SamMayWork Date: Mon, 25 Mar 2024 11:36:26 +0000 Subject: [PATCH 2/7] feat: allow for support for non-standard block hash lengths Signed-off-by: SamMayWork --- internal/ethereum/blocklistener.go | 73 +++++++++------ internal/ethereum/blocklistener_test.go | 119 ++++++++++++++++++++++++ internal/ethereum/config.go | 36 ++++--- internal/msgs/en_config_descriptions.go | 28 +++--- 4 files changed, 199 insertions(+), 57 deletions(-) diff --git a/internal/ethereum/blocklistener.go b/internal/ethereum/blocklistener.go index 7a63557..8c23189 100644 --- a/internal/ethereum/blocklistener.go +++ b/internal/ethereum/blocklistener.go @@ -39,16 +39,18 @@ type blockUpdateConsumer struct { // 1) To establish and keep track of what the head block height of the blockchain is, so event streams know how far from the head they are // 2) To feed new block information to any registered consumers type blockListener struct { - ctx context.Context - c *ethConnector - listenLoopDone chan struct{} - initialBlockHeightObtained chan struct{} - highestBlock int64 - mux sync.Mutex - consumers map[fftypes.UUID]*blockUpdateConsumer - blockPollingInterval time.Duration - unstableHeadLength int - canonicalChain *list.List + ctx context.Context + c *ethConnector + listenLoopDone chan struct{} + initialBlockHeightObtained chan struct{} + highestBlock int64 + mux sync.Mutex + consumers map[fftypes.UUID]*blockUpdateConsumer + blockPollingInterval time.Duration + unstableHeadLength int + canonicalChain *list.List + allowNonStandardBlockHashLength bool + nonStandardBlockHashSizeResolutionMethod string } type minimalBlockInfo struct { @@ -59,14 +61,16 @@ type minimalBlockInfo struct { func newBlockListener(ctx context.Context, c *ethConnector, conf config.Section) *blockListener { bl := &blockListener{ - ctx: log.WithLogField(ctx, "role", "blocklistener"), - c: c, - initialBlockHeightObtained: make(chan struct{}), - highestBlock: -1, - consumers: make(map[fftypes.UUID]*blockUpdateConsumer), - blockPollingInterval: conf.GetDuration(BlockPollingInterval), - canonicalChain: list.New(), - unstableHeadLength: int(c.checkpointBlockGap), + ctx: log.WithLogField(ctx, "role", "blocklistener"), + c: c, + initialBlockHeightObtained: make(chan struct{}), + highestBlock: -1, + consumers: make(map[fftypes.UUID]*blockUpdateConsumer), + blockPollingInterval: conf.GetDuration(BlockPollingInterval), + canonicalChain: list.New(), + unstableHeadLength: int(c.checkpointBlockGap), + allowNonStandardBlockHashLength: conf.GetBool(AllowNonStandardBlockHashSize), + nonStandardBlockHashSizeResolutionMethod: conf.GetString(NonStandardBlockHashSizeResolutionMethod), } return bl } @@ -137,20 +141,31 @@ func (bl *blockListener) listenLoop() { continue } - for i := 0; i < len(blockHashes); i++ { - truncatedHash, err := blockHashes[i].Truncate(32) - if err != nil { - log.L(bl.ctx).Errorf("Failed to truncate block hash") - failCount++ - continue - } - - blockHashes[i] = truncatedHash - } - update := &ffcapi.BlockHashEvent{GapPotential: gapPotential} var notifyPos *list.Element for _, h := range blockHashes { + if len(h) != 32 { + if !bl.allowNonStandardBlockHashLength { + log.L(bl.ctx).Errorf("Tried to index a non-standard size block hash length: %s", h.String()) + failCount++ + continue + } + + if bl.nonStandardBlockHashSizeResolutionMethod == "" { + log.L(bl.ctx).Warnf("No non-standard hash length resolution method was provided, defaulting to truncation") + bl.nonStandardBlockHashSizeResolutionMethod = "truncate" + } + + if bl.nonStandardBlockHashSizeResolutionMethod == "truncate" { + h, err = h.Truncate(32) + if err != nil { + log.L(bl.ctx).Errorf("Input hash was shorter than the standard block hash length: %s", h.String()) + failCount++ + continue + } + } + } + // Do a lookup of the block (which will then go into our cache). bi, err := bl.c.getBlockInfoByHash(bl.ctx, h.String()) switch { diff --git a/internal/ethereum/blocklistener_test.go b/internal/ethereum/blocklistener_test.go index 08663ac..f4f598e 100644 --- a/internal/ethereum/blocklistener_test.go +++ b/internal/ethereum/blocklistener_test.go @@ -861,6 +861,125 @@ func TestBlockListenerBlockHashFailed(t *testing.T) { } +func TestBlockListenerProcessNonStandardHashRejected(t *testing.T) { + + _, c, mRPC, done := newTestConnector(t) + bl := c.blockListener + bl.blockPollingInterval = 1 * time.Microsecond + bl.allowNonStandardBlockHashLength = false + + block1003Hash := ethtypes.MustNewHexBytes0xPrefix("0xef177df3b87beed681b1557e8ba7c3ecbd7e4db83d87b66c1e86aa484937ab93f1fae0eb6d4b24ca30aee13f29c83cc9") + + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_blockNumber").Return(nil).Run(func(args mock.Arguments) { + hbh := args[1].(*ethtypes.HexInteger) + *hbh = *ethtypes.NewHexInteger64(1000) + }).Once() + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_newBlockFilter").Return(nil).Run(func(args mock.Arguments) { + hbh := args[1].(*string) + *hbh = "filter_id1" + }) + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getFilterChanges", "filter_id1").Return(nil).Run(func(args mock.Arguments) { + hbh := args[1].(*[]ethtypes.HexBytes0xPrefix) + *hbh = []ethtypes.HexBytes0xPrefix{ + block1003Hash, + } + }).Once() + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getFilterChanges", mock.Anything).Return(nil).Run(func(args mock.Arguments) { + go done() // Close after we've processed the log + }) + + bl.checkStartedLocked() + + c.WaitClosed() + + mRPC.AssertExpectations(t) + +} + +func TestBlockListenerProcessNonStandardHashAccepted(t *testing.T) { + + _, c, mRPC, done := newTestConnector(t) + bl := c.blockListener + bl.blockPollingInterval = 1 * time.Microsecond + bl.allowNonStandardBlockHashLength = true + bl.nonStandardBlockHashSizeResolutionMethod = "truncate" + + block1003Hash := ethtypes.MustNewHexBytes0xPrefix("0xef177df3b87beed681b1557e8ba7c3ecbd7e4db83d87b66c1e86aa484937ab93f1fae0eb6d4b24ca30aee13f29c83cc9") + block1004Hash := ethtypes.MustNewHexBytes0xPrefix("0xef177df3b87beed681") + truncatedBlock1003Hash := ethtypes.MustNewHexBytes0xPrefix("0xef177df3b87beed681b1557e8ba7c3ecbd7e4db83d87b66c1e86aa484937ab93") + + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_blockNumber").Return(nil).Run(func(args mock.Arguments) { + hbh := args[1].(*ethtypes.HexInteger) + *hbh = *ethtypes.NewHexInteger64(1000) + }).Once() + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_newBlockFilter").Return(nil).Run(func(args mock.Arguments) { + hbh := args[1].(*string) + *hbh = "filter_id1" + }) + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getFilterChanges", "filter_id1").Return(nil).Run(func(args mock.Arguments) { + hbh := args[1].(*[]ethtypes.HexBytes0xPrefix) + *hbh = []ethtypes.HexBytes0xPrefix{ + block1003Hash, + block1004Hash, + } + }).Once() + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getFilterChanges", mock.Anything).Return(nil).Run(func(args mock.Arguments) { + go done() // Close after we've processed the log + }) + + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getBlockByHash", mock.MatchedBy(func(bh string) bool { + return bh == truncatedBlock1003Hash.String() + }), false).Return(&rpcbackend.RPCError{Message: "pop"}) + + bl.checkStartedLocked() + + c.WaitClosed() + + mRPC.AssertExpectations(t) + +} + +func TestBlockListenerProcessNonStandardHashNoResolutionMethodSpecified(t *testing.T) { + + _, c, mRPC, done := newTestConnector(t) + bl := c.blockListener + bl.blockPollingInterval = 1 * time.Microsecond + bl.allowNonStandardBlockHashLength = true + bl.nonStandardBlockHashSizeResolutionMethod = "" + + block1003Hash := ethtypes.MustNewHexBytes0xPrefix("0xef177df3b87beed681b1557e8ba7c3ecbd7e4db83d87b66c1e86aa484937ab93f1fae0eb6d4b24ca30aee13f29c83cc9") + truncatedBlock1003Hash := ethtypes.MustNewHexBytes0xPrefix("0xef177df3b87beed681b1557e8ba7c3ecbd7e4db83d87b66c1e86aa484937ab93") + + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_blockNumber").Return(nil).Run(func(args mock.Arguments) { + hbh := args[1].(*ethtypes.HexInteger) + *hbh = *ethtypes.NewHexInteger64(1000) + }).Once() + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_newBlockFilter").Return(nil).Run(func(args mock.Arguments) { + hbh := args[1].(*string) + *hbh = "filter_id1" + }) + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getFilterChanges", "filter_id1").Return(nil).Run(func(args mock.Arguments) { + hbh := args[1].(*[]ethtypes.HexBytes0xPrefix) + *hbh = []ethtypes.HexBytes0xPrefix{ + block1003Hash, + } + }).Once() + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getFilterChanges", mock.Anything).Return(nil).Run(func(args mock.Arguments) { + go done() // Close after we've processed the log + }) + + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getBlockByHash", mock.MatchedBy(func(bh string) bool { + return bh == truncatedBlock1003Hash.String() + }), false).Return(&rpcbackend.RPCError{Message: "pop"}) + + bl.checkStartedLocked() + + c.WaitClosed() + + mRPC.AssertExpectations(t) + +} + func TestBlockListenerReestablishBlockFilter(t *testing.T) { _, c, mRPC, done := newTestConnector(t) diff --git a/internal/ethereum/config.go b/internal/ethereum/config.go index 4a8f837..8921d57 100644 --- a/internal/ethereum/config.go +++ b/internal/ethereum/config.go @@ -22,21 +22,23 @@ import ( ) const ( - ConfigGasEstimationFactor = "gasEstimationFactor" - ConfigDataFormat = "dataFormat" - BlockPollingInterval = "blockPollingInterval" - BlockCacheSize = "blockCacheSize" - EventsCatchupPageSize = "events.catchupPageSize" - EventsCatchupThreshold = "events.catchupThreshold" - EventsCatchupDownscaleRegex = "events.catchupDownscaleRegex" - EventsCheckpointBlockGap = "events.checkpointBlockGap" - EventsBlockTimestamps = "events.blockTimestamps" - EventsFilterPollingInterval = "events.filterPollingInterval" - RetryInitDelay = "retry.initialDelay" - RetryMaxDelay = "retry.maxDelay" - RetryFactor = "retry.factor" - MaxConcurrentRequests = "maxConcurrentRequests" - TxCacheSize = "txCacheSize" + ConfigGasEstimationFactor = "gasEstimationFactor" + ConfigDataFormat = "dataFormat" + BlockPollingInterval = "blockPollingInterval" + BlockCacheSize = "blockCacheSize" + EventsCatchupPageSize = "events.catchupPageSize" + EventsCatchupThreshold = "events.catchupThreshold" + EventsCatchupDownscaleRegex = "events.catchupDownscaleRegex" + EventsCheckpointBlockGap = "events.checkpointBlockGap" + EventsBlockTimestamps = "events.blockTimestamps" + EventsFilterPollingInterval = "events.filterPollingInterval" + RetryInitDelay = "retry.initialDelay" + RetryMaxDelay = "retry.maxDelay" + RetryFactor = "retry.factor" + MaxConcurrentRequests = "maxConcurrentRequests" + TxCacheSize = "txCacheSize" + AllowNonStandardBlockHashSize = "allowNonStandardBlockHashSize" + NonStandardBlockHashSizeResolutionMethod = "nonStandardBlockHashSizeResolutionMethod" ) const ( @@ -51,6 +53,8 @@ const ( DefaultRetryInitDelay = "100ms" DefaultRetryMaxDelay = "30s" DefaultRetryDelayFactor = 2.0 + + DefaultAllowNonStandardBlockHashSize = false ) func InitConfig(conf config.Section) { @@ -70,4 +74,6 @@ func InitConfig(conf config.Section) { conf.AddKnownKey(RetryMaxDelay, DefaultRetryMaxDelay) conf.AddKnownKey(MaxConcurrentRequests, 50) conf.AddKnownKey(TxCacheSize, 250) + conf.AddKnownKey(AllowNonStandardBlockHashSize, DefaultAllowNonStandardBlockHashSize) + conf.AddKnownKey(NonStandardBlockHashSizeResolutionMethod, "truncate") } diff --git a/internal/msgs/en_config_descriptions.go b/internal/msgs/en_config_descriptions.go index aea61b4..8c0eceb 100644 --- a/internal/msgs/en_config_descriptions.go +++ b/internal/msgs/en_config_descriptions.go @@ -27,17 +27,19 @@ var ffc = func(key, translation string, fieldType string) i18n.ConfigMessageKey //revive:disable var ( - ConfigEthereumURL = ffc("config.connector.url", "URL of JSON/RPC endpoint for the Ethereum node/gateway", "string") - ConfigEthereumDataFormat = ffc("config.connector.dataFormat", "Configure the JSON data format for query output and events", "map,flat_array,self_describing") - ConfigEthereumGasEstimationFactor = ffc("config.connector.gasEstimationFactor", "The factor to apply to the gas estimation to determine the gas limit", "float") - ConfigBlockCacheSize = ffc("config.connector.blockCacheSize", "Maximum of blocks to hold in the block info cache", i18n.IntType) - ConfigBlockPollingInterval = ffc("config.connector.blockPollingInterval", "Interval for polling to check for new blocks", i18n.TimeDurationType) - ConfigEventsBlockTimestamps = ffc("config.connector.events.blockTimestamps", "Whether to include the block timestamps in the event information", i18n.BooleanType) - ConfigEventsCatchupPageSize = ffc("config.connector.events.catchupPageSize", "Number of blocks to query per poll when catching up to the head of the blockchain", i18n.IntType) - ConfigEventsCatchupThreshold = ffc("config.connector.events.catchupThreshold", "How many blocks behind the chain head an event stream or listener must be on startup, to enter catchup mode", i18n.IntType) - ConfigEventsCatchupDownscaleRegex = ffc("config.connector.events.catchupDownscaleRegex", "An error pattern to check for from JSON/RPC providers if they limit response sizes to eth_getLogs(). If an error is returned from eth_getLogs() and that error matches the configured pattern, the number of logs requested (catchupPageSize) will be reduced automatically.", "string") - ConfigEventsCheckpointBlockGap = ffc("config.connector.events.checkpointBlockGap", "The number of blocks at the head of the chain that should be considered unstable (could be dropped from the canonical chain after a re-org). Unless events with a full set of confirmations are detected, the restart checkpoint will this many blocks behind the chain head.", i18n.IntType) - ConfigEventsFilterPollingInterval = ffc("config.connector.events.filterPollingInterval", "The interval between polling calls to a filter, when checking for newly arrived events", i18n.TimeDurationType) - ConfigTxCacheSize = ffc("config.connector.txCacheSize", "Maximum of transactions to hold in the transaction info cache", i18n.IntType) - ConfigMaxConcurrentRequests = ffc("config.connector.maxConcurrentRequests", "Maximum of concurrent requests to be submitted to the blockchain", i18n.IntType) + ConfigEthereumURL = ffc("config.connector.url", "URL of JSON/RPC endpoint for the Ethereum node/gateway", "string") + ConfigEthereumDataFormat = ffc("config.connector.dataFormat", "Configure the JSON data format for query output and events", "map,flat_array,self_describing") + ConfigEthereumGasEstimationFactor = ffc("config.connector.gasEstimationFactor", "The factor to apply to the gas estimation to determine the gas limit", "float") + ConfigBlockCacheSize = ffc("config.connector.blockCacheSize", "Maximum of blocks to hold in the block info cache", i18n.IntType) + ConfigBlockPollingInterval = ffc("config.connector.blockPollingInterval", "Interval for polling to check for new blocks", i18n.TimeDurationType) + ConfigEventsBlockTimestamps = ffc("config.connector.events.blockTimestamps", "Whether to include the block timestamps in the event information", i18n.BooleanType) + ConfigEventsCatchupPageSize = ffc("config.connector.events.catchupPageSize", "Number of blocks to query per poll when catching up to the head of the blockchain", i18n.IntType) + ConfigEventsCatchupThreshold = ffc("config.connector.events.catchupThreshold", "How many blocks behind the chain head an event stream or listener must be on startup, to enter catchup mode", i18n.IntType) + ConfigEventsCatchupDownscaleRegex = ffc("config.connector.events.catchupDownscaleRegex", "An error pattern to check for from JSON/RPC providers if they limit response sizes to eth_getLogs(). If an error is returned from eth_getLogs() and that error matches the configured pattern, the number of logs requested (catchupPageSize) will be reduced automatically.", "string") + ConfigEventsCheckpointBlockGap = ffc("config.connector.events.checkpointBlockGap", "The number of blocks at the head of the chain that should be considered unstable (could be dropped from the canonical chain after a re-org). Unless events with a full set of confirmations are detected, the restart checkpoint will this many blocks behind the chain head.", i18n.IntType) + ConfigEventsFilterPollingInterval = ffc("config.connector.events.filterPollingInterval", "The interval between polling calls to a filter, when checking for newly arrived events", i18n.TimeDurationType) + ConfigTxCacheSize = ffc("config.connector.txCacheSize", "Maximum of transactions to hold in the transaction info cache", i18n.IntType) + ConfigMaxConcurrentRequests = ffc("config.connector.maxConcurrentRequests", "Maximum of concurrent requests to be submitted to the blockchain", i18n.IntType) + ConfigAllowNonStandardBlockHashSize = ffc("config.connector.allowNonStandardBlockHashSize", "Whether to permit block hases of a non-standard (i.e. not 32 bytes) length", i18n.BooleanType) + ConfigNonStandardBlockHashSizeResolutionMethod = ffc("config.connector.nonStandardBlockHashSizeResolutionMethod", "How to resolve block hashes that are non-standard (i.e. not 32 bytes) in length. Currently only 'truncate' is supported.", i18n.StringType) ) From 388881d280ccfa82e737fa4ab036ba0cedee5521 Mon Sep 17 00:00:00 2001 From: SamMayWork Date: Mon, 25 Mar 2024 11:41:18 +0000 Subject: [PATCH 3/7] fix: revert to normal launch json Signed-off-by: SamMayWork --- .vscode/launch.json | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index e42f7ee..6a9cea9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,22 +1,22 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Run evmconnect", - "type": "go", - "request": "launch", - "mode": "auto", - "program": "${workspaceFolder}/evmconnect/main.go", - "args": [ - "-f", - "/Users/samuelmay/.firefly/stacks/hedera-anglo-demo/runtime/config/evmconnect_0.yaml" - ], - "env": { - "FIREFLY_PERSISTENCE_LEVELDB_PATH": "/tmp/.leveldb3" - } + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Run evmconnect", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/evmconnect/main.go", + "args": [ + "-f", + "${workspaceFolder}/evmconnect_config.yml" + ], + "env": { + "FIREFLY_PERSISTENCE_LEVELDB_PATH": "${workspaceFolder}/.leveldb" } - ] + } + ] } \ No newline at end of file From 7717d191256dd77ae1555eb38d4c4d27a760e4ee Mon Sep 17 00:00:00 2001 From: SamMayWork Date: Fri, 10 May 2024 16:07:53 +0100 Subject: [PATCH 4/7] fix: change to more obvious spelling Signed-off-by: SamMayWork --- config.md | 1 + internal/ethereum/blocklistener.go | 60 ++++++++++--------------- internal/ethereum/blocklistener_test.go | 52 ++------------------- internal/ethereum/config.go | 38 +++++++--------- internal/msgs/en_config_descriptions.go | 29 ++++++------ 5 files changed, 59 insertions(+), 121 deletions(-) diff --git a/config.md b/config.md index 357d756..f7c0de6 100644 --- a/config.md +++ b/config.md @@ -68,6 +68,7 @@ |expectContinueTimeout|See [ExpectContinueTimeout in the Go docs](https://pkg.go.dev/net/http#Transport)|[`time.Duration`](https://pkg.go.dev/time#Duration)|`1s` |gasEstimationFactor|The factor to apply to the gas estimation to determine the gas limit|float|`1.5` |headers|Adds custom headers to HTTP requests|`map[string]string`|`` +|hederaCompatibilityMode|Compatibility mode for Hedera, allowing non-standard block header hashes to be processed|`boolean`|`false` |idleTimeout|The max duration to hold a HTTP keepalive connection between calls|[`time.Duration`](https://pkg.go.dev/time#Duration)|`475ms` |maxConcurrentRequests|Maximum of concurrent requests to be submitted to the blockchain|`int`|`50` |maxConnsPerHost|The max number of connections, per unique hostname. Zero means no limit|`int`|`0` diff --git a/internal/ethereum/blocklistener.go b/internal/ethereum/blocklistener.go index 8c23189..0c9f101 100644 --- a/internal/ethereum/blocklistener.go +++ b/internal/ethereum/blocklistener.go @@ -39,18 +39,17 @@ type blockUpdateConsumer struct { // 1) To establish and keep track of what the head block height of the blockchain is, so event streams know how far from the head they are // 2) To feed new block information to any registered consumers type blockListener struct { - ctx context.Context - c *ethConnector - listenLoopDone chan struct{} - initialBlockHeightObtained chan struct{} - highestBlock int64 - mux sync.Mutex - consumers map[fftypes.UUID]*blockUpdateConsumer - blockPollingInterval time.Duration - unstableHeadLength int - canonicalChain *list.List - allowNonStandardBlockHashLength bool - nonStandardBlockHashSizeResolutionMethod string + ctx context.Context + c *ethConnector + listenLoopDone chan struct{} + initialBlockHeightObtained chan struct{} + highestBlock int64 + mux sync.Mutex + consumers map[fftypes.UUID]*blockUpdateConsumer + blockPollingInterval time.Duration + unstableHeadLength int + canonicalChain *list.List + hederaCompatibilityMode bool } type minimalBlockInfo struct { @@ -61,16 +60,15 @@ type minimalBlockInfo struct { func newBlockListener(ctx context.Context, c *ethConnector, conf config.Section) *blockListener { bl := &blockListener{ - ctx: log.WithLogField(ctx, "role", "blocklistener"), - c: c, - initialBlockHeightObtained: make(chan struct{}), - highestBlock: -1, - consumers: make(map[fftypes.UUID]*blockUpdateConsumer), - blockPollingInterval: conf.GetDuration(BlockPollingInterval), - canonicalChain: list.New(), - unstableHeadLength: int(c.checkpointBlockGap), - allowNonStandardBlockHashLength: conf.GetBool(AllowNonStandardBlockHashSize), - nonStandardBlockHashSizeResolutionMethod: conf.GetString(NonStandardBlockHashSizeResolutionMethod), + ctx: log.WithLogField(ctx, "role", "blocklistener"), + c: c, + initialBlockHeightObtained: make(chan struct{}), + highestBlock: -1, + consumers: make(map[fftypes.UUID]*blockUpdateConsumer), + blockPollingInterval: conf.GetDuration(BlockPollingInterval), + canonicalChain: list.New(), + unstableHeadLength: int(c.checkpointBlockGap), + hederaCompatibilityMode: conf.GetBool(HederaCompatibilityMode), } return bl } @@ -145,25 +143,13 @@ func (bl *blockListener) listenLoop() { var notifyPos *list.Element for _, h := range blockHashes { if len(h) != 32 { - if !bl.allowNonStandardBlockHashLength { - log.L(bl.ctx).Errorf("Tried to index a non-standard size block hash length: %s", h.String()) + if !bl.hederaCompatibilityMode { + log.L(bl.ctx).Errorf("Attempted to index block header with non-standard length: %d", len(h)) failCount++ continue } - if bl.nonStandardBlockHashSizeResolutionMethod == "" { - log.L(bl.ctx).Warnf("No non-standard hash length resolution method was provided, defaulting to truncation") - bl.nonStandardBlockHashSizeResolutionMethod = "truncate" - } - - if bl.nonStandardBlockHashSizeResolutionMethod == "truncate" { - h, err = h.Truncate(32) - if err != nil { - log.L(bl.ctx).Errorf("Input hash was shorter than the standard block hash length: %s", h.String()) - failCount++ - continue - } - } + h = h[0:32] } // Do a lookup of the block (which will then go into our cache). diff --git a/internal/ethereum/blocklistener_test.go b/internal/ethereum/blocklistener_test.go index f4f598e..8f1be9f 100644 --- a/internal/ethereum/blocklistener_test.go +++ b/internal/ethereum/blocklistener_test.go @@ -861,12 +861,12 @@ func TestBlockListenerBlockHashFailed(t *testing.T) { } -func TestBlockListenerProcessNonStandardHashRejected(t *testing.T) { +func TestBlockListenerProcessNonStandardHashRejectedWhenNotInHederaCompatibilityMode(t *testing.T) { _, c, mRPC, done := newTestConnector(t) bl := c.blockListener bl.blockPollingInterval = 1 * time.Microsecond - bl.allowNonStandardBlockHashLength = false + bl.hederaCompatibilityMode = false block1003Hash := ethtypes.MustNewHexBytes0xPrefix("0xef177df3b87beed681b1557e8ba7c3ecbd7e4db83d87b66c1e86aa484937ab93f1fae0eb6d4b24ca30aee13f29c83cc9") @@ -896,56 +896,12 @@ func TestBlockListenerProcessNonStandardHashRejected(t *testing.T) { } -func TestBlockListenerProcessNonStandardHashAccepted(t *testing.T) { +func TestBlockListenerProcessNonStandardHashAcceptedWhenInHederaCompatbilityMode(t *testing.T) { _, c, mRPC, done := newTestConnector(t) bl := c.blockListener bl.blockPollingInterval = 1 * time.Microsecond - bl.allowNonStandardBlockHashLength = true - bl.nonStandardBlockHashSizeResolutionMethod = "truncate" - - block1003Hash := ethtypes.MustNewHexBytes0xPrefix("0xef177df3b87beed681b1557e8ba7c3ecbd7e4db83d87b66c1e86aa484937ab93f1fae0eb6d4b24ca30aee13f29c83cc9") - block1004Hash := ethtypes.MustNewHexBytes0xPrefix("0xef177df3b87beed681") - truncatedBlock1003Hash := ethtypes.MustNewHexBytes0xPrefix("0xef177df3b87beed681b1557e8ba7c3ecbd7e4db83d87b66c1e86aa484937ab93") - - mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_blockNumber").Return(nil).Run(func(args mock.Arguments) { - hbh := args[1].(*ethtypes.HexInteger) - *hbh = *ethtypes.NewHexInteger64(1000) - }).Once() - mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_newBlockFilter").Return(nil).Run(func(args mock.Arguments) { - hbh := args[1].(*string) - *hbh = "filter_id1" - }) - mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getFilterChanges", "filter_id1").Return(nil).Run(func(args mock.Arguments) { - hbh := args[1].(*[]ethtypes.HexBytes0xPrefix) - *hbh = []ethtypes.HexBytes0xPrefix{ - block1003Hash, - block1004Hash, - } - }).Once() - mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getFilterChanges", mock.Anything).Return(nil).Run(func(args mock.Arguments) { - go done() // Close after we've processed the log - }) - - mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getBlockByHash", mock.MatchedBy(func(bh string) bool { - return bh == truncatedBlock1003Hash.String() - }), false).Return(&rpcbackend.RPCError{Message: "pop"}) - - bl.checkStartedLocked() - - c.WaitClosed() - - mRPC.AssertExpectations(t) - -} - -func TestBlockListenerProcessNonStandardHashNoResolutionMethodSpecified(t *testing.T) { - - _, c, mRPC, done := newTestConnector(t) - bl := c.blockListener - bl.blockPollingInterval = 1 * time.Microsecond - bl.allowNonStandardBlockHashLength = true - bl.nonStandardBlockHashSizeResolutionMethod = "" + bl.hederaCompatibilityMode = true block1003Hash := ethtypes.MustNewHexBytes0xPrefix("0xef177df3b87beed681b1557e8ba7c3ecbd7e4db83d87b66c1e86aa484937ab93f1fae0eb6d4b24ca30aee13f29c83cc9") truncatedBlock1003Hash := ethtypes.MustNewHexBytes0xPrefix("0xef177df3b87beed681b1557e8ba7c3ecbd7e4db83d87b66c1e86aa484937ab93") diff --git a/internal/ethereum/config.go b/internal/ethereum/config.go index 8921d57..3716176 100644 --- a/internal/ethereum/config.go +++ b/internal/ethereum/config.go @@ -22,23 +22,22 @@ import ( ) const ( - ConfigGasEstimationFactor = "gasEstimationFactor" - ConfigDataFormat = "dataFormat" - BlockPollingInterval = "blockPollingInterval" - BlockCacheSize = "blockCacheSize" - EventsCatchupPageSize = "events.catchupPageSize" - EventsCatchupThreshold = "events.catchupThreshold" - EventsCatchupDownscaleRegex = "events.catchupDownscaleRegex" - EventsCheckpointBlockGap = "events.checkpointBlockGap" - EventsBlockTimestamps = "events.blockTimestamps" - EventsFilterPollingInterval = "events.filterPollingInterval" - RetryInitDelay = "retry.initialDelay" - RetryMaxDelay = "retry.maxDelay" - RetryFactor = "retry.factor" - MaxConcurrentRequests = "maxConcurrentRequests" - TxCacheSize = "txCacheSize" - AllowNonStandardBlockHashSize = "allowNonStandardBlockHashSize" - NonStandardBlockHashSizeResolutionMethod = "nonStandardBlockHashSizeResolutionMethod" + ConfigGasEstimationFactor = "gasEstimationFactor" + ConfigDataFormat = "dataFormat" + BlockPollingInterval = "blockPollingInterval" + BlockCacheSize = "blockCacheSize" + EventsCatchupPageSize = "events.catchupPageSize" + EventsCatchupThreshold = "events.catchupThreshold" + EventsCatchupDownscaleRegex = "events.catchupDownscaleRegex" + EventsCheckpointBlockGap = "events.checkpointBlockGap" + EventsBlockTimestamps = "events.blockTimestamps" + EventsFilterPollingInterval = "events.filterPollingInterval" + RetryInitDelay = "retry.initialDelay" + RetryMaxDelay = "retry.maxDelay" + RetryFactor = "retry.factor" + MaxConcurrentRequests = "maxConcurrentRequests" + TxCacheSize = "txCacheSize" + HederaCompatibilityMode = "hederaCompatibilityMode" ) const ( @@ -53,8 +52,6 @@ const ( DefaultRetryInitDelay = "100ms" DefaultRetryMaxDelay = "30s" DefaultRetryDelayFactor = 2.0 - - DefaultAllowNonStandardBlockHashSize = false ) func InitConfig(conf config.Section) { @@ -74,6 +71,5 @@ func InitConfig(conf config.Section) { conf.AddKnownKey(RetryMaxDelay, DefaultRetryMaxDelay) conf.AddKnownKey(MaxConcurrentRequests, 50) conf.AddKnownKey(TxCacheSize, 250) - conf.AddKnownKey(AllowNonStandardBlockHashSize, DefaultAllowNonStandardBlockHashSize) - conf.AddKnownKey(NonStandardBlockHashSizeResolutionMethod, "truncate") + conf.AddKnownKey(HederaCompatibilityMode, false) } diff --git a/internal/msgs/en_config_descriptions.go b/internal/msgs/en_config_descriptions.go index 8c0eceb..af00301 100644 --- a/internal/msgs/en_config_descriptions.go +++ b/internal/msgs/en_config_descriptions.go @@ -27,19 +27,18 @@ var ffc = func(key, translation string, fieldType string) i18n.ConfigMessageKey //revive:disable var ( - ConfigEthereumURL = ffc("config.connector.url", "URL of JSON/RPC endpoint for the Ethereum node/gateway", "string") - ConfigEthereumDataFormat = ffc("config.connector.dataFormat", "Configure the JSON data format for query output and events", "map,flat_array,self_describing") - ConfigEthereumGasEstimationFactor = ffc("config.connector.gasEstimationFactor", "The factor to apply to the gas estimation to determine the gas limit", "float") - ConfigBlockCacheSize = ffc("config.connector.blockCacheSize", "Maximum of blocks to hold in the block info cache", i18n.IntType) - ConfigBlockPollingInterval = ffc("config.connector.blockPollingInterval", "Interval for polling to check for new blocks", i18n.TimeDurationType) - ConfigEventsBlockTimestamps = ffc("config.connector.events.blockTimestamps", "Whether to include the block timestamps in the event information", i18n.BooleanType) - ConfigEventsCatchupPageSize = ffc("config.connector.events.catchupPageSize", "Number of blocks to query per poll when catching up to the head of the blockchain", i18n.IntType) - ConfigEventsCatchupThreshold = ffc("config.connector.events.catchupThreshold", "How many blocks behind the chain head an event stream or listener must be on startup, to enter catchup mode", i18n.IntType) - ConfigEventsCatchupDownscaleRegex = ffc("config.connector.events.catchupDownscaleRegex", "An error pattern to check for from JSON/RPC providers if they limit response sizes to eth_getLogs(). If an error is returned from eth_getLogs() and that error matches the configured pattern, the number of logs requested (catchupPageSize) will be reduced automatically.", "string") - ConfigEventsCheckpointBlockGap = ffc("config.connector.events.checkpointBlockGap", "The number of blocks at the head of the chain that should be considered unstable (could be dropped from the canonical chain after a re-org). Unless events with a full set of confirmations are detected, the restart checkpoint will this many blocks behind the chain head.", i18n.IntType) - ConfigEventsFilterPollingInterval = ffc("config.connector.events.filterPollingInterval", "The interval between polling calls to a filter, when checking for newly arrived events", i18n.TimeDurationType) - ConfigTxCacheSize = ffc("config.connector.txCacheSize", "Maximum of transactions to hold in the transaction info cache", i18n.IntType) - ConfigMaxConcurrentRequests = ffc("config.connector.maxConcurrentRequests", "Maximum of concurrent requests to be submitted to the blockchain", i18n.IntType) - ConfigAllowNonStandardBlockHashSize = ffc("config.connector.allowNonStandardBlockHashSize", "Whether to permit block hases of a non-standard (i.e. not 32 bytes) length", i18n.BooleanType) - ConfigNonStandardBlockHashSizeResolutionMethod = ffc("config.connector.nonStandardBlockHashSizeResolutionMethod", "How to resolve block hashes that are non-standard (i.e. not 32 bytes) in length. Currently only 'truncate' is supported.", i18n.StringType) + ConfigEthereumURL = ffc("config.connector.url", "URL of JSON/RPC endpoint for the Ethereum node/gateway", "string") + ConfigEthereumDataFormat = ffc("config.connector.dataFormat", "Configure the JSON data format for query output and events", "map,flat_array,self_describing") + ConfigEthereumGasEstimationFactor = ffc("config.connector.gasEstimationFactor", "The factor to apply to the gas estimation to determine the gas limit", "float") + ConfigBlockCacheSize = ffc("config.connector.blockCacheSize", "Maximum of blocks to hold in the block info cache", i18n.IntType) + ConfigBlockPollingInterval = ffc("config.connector.blockPollingInterval", "Interval for polling to check for new blocks", i18n.TimeDurationType) + ConfigEventsBlockTimestamps = ffc("config.connector.events.blockTimestamps", "Whether to include the block timestamps in the event information", i18n.BooleanType) + ConfigEventsCatchupPageSize = ffc("config.connector.events.catchupPageSize", "Number of blocks to query per poll when catching up to the head of the blockchain", i18n.IntType) + ConfigEventsCatchupThreshold = ffc("config.connector.events.catchupThreshold", "How many blocks behind the chain head an event stream or listener must be on startup, to enter catchup mode", i18n.IntType) + ConfigEventsCatchupDownscaleRegex = ffc("config.connector.events.catchupDownscaleRegex", "An error pattern to check for from JSON/RPC providers if they limit response sizes to eth_getLogs(). If an error is returned from eth_getLogs() and that error matches the configured pattern, the number of logs requested (catchupPageSize) will be reduced automatically.", "string") + ConfigEventsCheckpointBlockGap = ffc("config.connector.events.checkpointBlockGap", "The number of blocks at the head of the chain that should be considered unstable (could be dropped from the canonical chain after a re-org). Unless events with a full set of confirmations are detected, the restart checkpoint will this many blocks behind the chain head.", i18n.IntType) + ConfigEventsFilterPollingInterval = ffc("config.connector.events.filterPollingInterval", "The interval between polling calls to a filter, when checking for newly arrived events", i18n.TimeDurationType) + ConfigTxCacheSize = ffc("config.connector.txCacheSize", "Maximum of transactions to hold in the transaction info cache", i18n.IntType) + ConfigMaxConcurrentRequests = ffc("config.connector.maxConcurrentRequests", "Maximum of concurrent requests to be submitted to the blockchain", i18n.IntType) + ConfigHederaCompatibilityMode = ffc("config.connector.hederaCompatibilityMode", "Compatibility mode for Hedera, allowing non-standard block header hashes to be processed", i18n.BooleanType) ) From aa8644a5931d218c16c2aa69c4014a8dd9d814e9 Mon Sep 17 00:00:00 2001 From: SamMayWork Date: Fri, 10 May 2024 16:21:00 +0100 Subject: [PATCH 5/7] fix: missed one Signed-off-by: SamMayWork --- internal/ethereum/config.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/ethereum/config.go b/internal/ethereum/config.go index 51b4468..30fdd9e 100644 --- a/internal/ethereum/config.go +++ b/internal/ethereum/config.go @@ -72,9 +72,6 @@ func InitConfig(conf config.Section) { conf.AddKnownKey(RetryMaxDelay, DefaultRetryMaxDelay) conf.AddKnownKey(MaxConcurrentRequests, 50) conf.AddKnownKey(TxCacheSize, 250) -<<<<<<< HEAD conf.AddKnownKey(HederaCompatibilityMode, false) -======= conf.AddKnownKey(TraceTXForRevertReason, false) ->>>>>>> 67fdd4913465665a4e21d47636a5674323bdfcf3 } From 7d84b1d4afcfb152a05f6dbbad2c2c0e3c15696b Mon Sep 17 00:00:00 2001 From: SamMayWork Date: Fri, 10 May 2024 16:22:24 +0100 Subject: [PATCH 6/7] fix: drop signer changes Signed-off-by: SamMayWork --- go.mod | 2 -- go.sum | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index c6ef458..39615dc 100644 --- a/go.mod +++ b/go.mod @@ -99,5 +99,3 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) - -replace github.com/hyperledger/firefly-signer => github.com/SamMayWork/firefly-signer v0.0.0-20240307121035-e654fb9ef55b diff --git a/go.sum b/go.sum index 207414a..390a3b5 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,6 @@ github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8 github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/SamMayWork/firefly-signer v0.0.0-20240307121035-e654fb9ef55b h1:XMWx/jEupPkbF1cKEvi682R23xteeNf6EZRrc0O23tk= -github.com/SamMayWork/firefly-signer v0.0.0-20240307121035-e654fb9ef55b/go.mod h1:pK6kivzBFSue3zpJSQpH67VasnLLbwBJOBUNv0zHbRA= github.com/aidarkhanov/nanoid v1.0.8 h1:yxyJkgsEDFXP7+97vc6JevMcjyb03Zw+/9fqhlVXBXA= github.com/aidarkhanov/nanoid v1.0.8/go.mod h1:vadfZHT+m4uDhttg0yY4wW3GKtl2T6i4d2Age+45pYk= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -104,6 +102,8 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hyperledger/firefly-common v1.4.6 h1:qqXoSaRml3WjUnWcWxrrXs5AIOWa+UcMXLCF8yEa4Pk= github.com/hyperledger/firefly-common v1.4.6/go.mod h1:jkErZdQmC9fsAJZQO427tURdwB9iiW+NMUZSqS3eBIE= +github.com/hyperledger/firefly-signer v1.1.13 h1:eiHjc6HPRG8AzXUCUgm51qqX1I9BokiuiiqJ89XwK4M= +github.com/hyperledger/firefly-signer v1.1.13/go.mod h1:pK6kivzBFSue3zpJSQpH67VasnLLbwBJOBUNv0zHbRA= github.com/hyperledger/firefly-transaction-manager v1.3.11 h1:sUYGUSZbuuxzHjQgvSsJtKLSgaQqRjMEy/bgM6dUJwM= github.com/hyperledger/firefly-transaction-manager v1.3.11/go.mod h1:N3BoHh8+dWG710oQKuNiXmJNEOBBeLTsQ8GpZ41vhog= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= From bf4fe5c63448a937dd0fdfe4703968327ef8ee52 Mon Sep 17 00:00:00 2001 From: SamMayWork Date: Mon, 20 May 2024 15:05:58 +0100 Subject: [PATCH 7/7] fix: safety Signed-off-by: SamMayWork --- internal/ethereum/blocklistener.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/ethereum/blocklistener.go b/internal/ethereum/blocklistener.go index 0c9f101..c80885c 100644 --- a/internal/ethereum/blocklistener.go +++ b/internal/ethereum/blocklistener.go @@ -149,6 +149,12 @@ func (bl *blockListener) listenLoop() { continue } + if len(h) < 32 { + log.L(bl.ctx).Errorf("Cannot index block header hash of length: %d", len(h)) + failCount++ + continue + } + h = h[0:32] }