Skip to content

Commit 781a32b

Browse files
authored
Merge pull request #190 from kaleido-io/introduce-lightweight-tracking
introduce a light weight mode for tracking block progression
2 parents f8166fa + 457132d commit 781a32b

14 files changed

Lines changed: 349 additions & 34 deletions

README.md

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,40 +34,58 @@ For a full list of configuration options see [config.md](./config.md)
3434

3535
```yaml
3636
connectors:
37-
- type: ethereum
38-
server:
39-
port: 5102
40-
ethereum:
41-
url: http://localhost:8545
37+
- type: ethereum
38+
server:
39+
port: 5102
40+
ethereum:
41+
url: http://localhost:8545
4242
```
4343
4444
## Blockchain node compatibility
4545
4646
For EVM connector to function properly, you should check the blockchain node supports the following JSON-RPC Methods over HTTP:
47+
4748
### Event tracking
49+
4850
- `eth_blockNumber`
4951
- `eth_newBlockFilter`
5052
- `eth_getFilterLogs`
5153
- `eth_getFilterChanges`
52-
- `eth_getBlockByHash`
5354
- `eth_getLogs`
5455
- `eth_newFilter`
5556
- `eth_uninstallFilter`
5657
- `eth_getTransactionByHash`
5758
- `eth_getTransactionReceipt`
5859

5960
### Query
61+
6062
- `eth_call`
6163
- `eth_getBalance`
62-
- `eth_gasPrice`[^1]
63-
64+
- `eth_gasPrice`
65+
6466
### Transaction submission
67+
6568
- `eth_estimateGas`
66-
- `eth_sendTransaction`
69+
- `eth_sendTransaction` / `eth_sendRawTransaction`
6770
- `eth_getTransactionCount`
68-
- `eth_sendRawTransaction`[^2]
6971

72+
### Optional methods
73+
74+
#### Transaction tracing
75+
76+
> Required when [connector.traceTXForRevertReason](./config.md#connector) is set to `true` (default: `false`)
77+
78+
- `debug_traceTransaction`
79+
80+
#### Block listener
81+
82+
> Required when [connector.blockTrackingMode](./config.md#connector) is set to `inMemoryPartialChain`
83+
84+
- `eth_getBlockByHash`
85+
- `eth_getBlockByNumber`
86+
87+
#### Receipt fetching
7088

71-
[^1]: also used by Transaction submission if the handler is configured to get gas price using "connector".
89+
> Required when [connector.useGetBlockReceipts](./config.md#connector) is set to `true`
7290

73-
[^2]: only required by custom transaction handlers that supports pre-signing.
91+
- `eth_getBlockReceipts`

config.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
|---|-----------|----|-------------|
6868
|blockCacheSize|Maximum of blocks to hold in the block info cache|`int`|`250`
6969
|blockPollingInterval|Interval for polling to check for new blocks|[`time.Duration`](https://pkg.go.dev/time#Duration)|`1s`
70+
|chainTrackingMode|Tracking mode for connector block progression. light: fetches head block numbers only, does not download block details, disables block listener support, and confirmation results include only the confirmation count. full: fetches head block numbers and block details, maintains an in-memory partial chain, enables block listener support, and confirmation results include both confirmation count and block details.|`light` or `full`|`full`
7071
|connectionTimeout|The maximum amount of time that a connection is allowed to remain with no data transmitted|[`time.Duration`](https://pkg.go.dev/time#Duration)|`30s`
7172
|dataFormat|Configure the JSON data format for query output and events|map,flat_array,self_describing|`map`
7273
|expectContinueTimeout|See [ExpectContinueTimeout in the Go docs](https://pkg.go.dev/net/http#Transport)|[`time.Duration`](https://pkg.go.dev/time#Duration)|`1s`

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/hashicorp/golang-lru v1.0.2
88
github.com/hyperledger/firefly-common v1.5.9
99
github.com/hyperledger/firefly-signer v1.1.23-0.20260422080826-42345c6c6b85
10-
github.com/hyperledger/firefly-transaction-manager v1.4.4
10+
github.com/hyperledger/firefly-transaction-manager v1.4.5
1111
github.com/sirupsen/logrus v1.9.3
1212
github.com/spf13/cobra v1.8.0
1313
github.com/stretchr/testify v1.9.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ github.com/hyperledger/firefly-common v1.5.9 h1:Z1+SuKNYJ8hPKQ5CvcsMg6r/E4RyW6wb
104104
github.com/hyperledger/firefly-common v1.5.9/go.mod h1:1Xawm5PUhxT7k+CL/Kr3i1LE3cTTzoQwZMLimvlW8rs=
105105
github.com/hyperledger/firefly-signer v1.1.23-0.20260422080826-42345c6c6b85 h1:gh3YhxUYYwOfBCsEJXFmWO7SFzFrNuNulXftOam2JRI=
106106
github.com/hyperledger/firefly-signer v1.1.23-0.20260422080826-42345c6c6b85/go.mod h1:cb40Xkm/t2+KH+V1q3/zxZPohBNEA0iOA7mcr9wyfzI=
107-
github.com/hyperledger/firefly-transaction-manager v1.4.4 h1:cbG9FkQWriOcc1MMGaMqU7OpOwLloSV+PImOoaN0ckU=
108-
github.com/hyperledger/firefly-transaction-manager v1.4.4/go.mod h1:1kbYt8ofDXqfwC02vwV/HoOjmiv0IuT9UkJ//bbrliE=
107+
github.com/hyperledger/firefly-transaction-manager v1.4.5 h1:zBe8hbzv6lJEWD5Ypk6efO5WXFs4+pqIFLUu7zbdmsg=
108+
github.com/hyperledger/firefly-transaction-manager v1.4.5/go.mod h1:1kbYt8ofDXqfwC02vwV/HoOjmiv0IuT9UkJ//bbrliE=
109109
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
110110
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
111111
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=

internal/ethereum/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ package ethereum
1919
import (
2020
"github.com/hyperledger/firefly-common/pkg/config"
2121
"github.com/hyperledger/firefly-common/pkg/wsclient"
22+
"github.com/hyperledger/firefly-transaction-manager/pkg/ffcapi"
2223
)
2324

2425
const (
2526
ConfigGasEstimationFactor = "gasEstimationFactor"
2627
ConfigDataFormat = "dataFormat"
2728
BlockPollingInterval = "blockPollingInterval"
2829
BlockCacheSize = "blockCacheSize"
30+
ChainTrackingMode = "chainTrackingMode"
2931
EventsCatchupPageSize = "events.catchupPageSize"
3032
EventsCatchupThreshold = "events.catchupThreshold"
3133
EventsCatchupDownscaleRegex = "events.catchupDownscaleRegex"
@@ -70,6 +72,7 @@ func InitConfig(conf config.Section) {
7072
conf.AddKnownKey(WebSocketsEnabled, false)
7173
conf.AddKnownKey(BlockCacheSize, 250)
7274
conf.AddKnownKey(BlockPollingInterval, "1s")
75+
conf.AddKnownKey(ChainTrackingMode, ffcapi.ChainTrackingModeFull)
7376
conf.AddKnownKey(ConfigDataFormat, "map")
7477
conf.AddKnownKey(ConfigGasEstimationFactor, DefaultGasEstimationFactor)
7578
conf.AddKnownKey(EventsBlockTimestamps, true)

internal/ethereum/ethereum.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ import (
4343
)
4444

4545
type ethConnector struct {
46-
backend rpcbackend.Backend
47-
wsBackend rpcbackend.WebSocketRPCClient
46+
backend rpcbackend.Backend
47+
wsBackend rpcbackend.WebSocketRPCClient
48+
chainTrackingMode ffcapi.ChainTrackingMode
49+
4850
serializer *abi.Serializer
4951
gasEstimationFactor *big.Float
5052
catchupPageSize int64
@@ -78,6 +80,15 @@ type Connector interface {
7880
}
7981

8082
func NewEthereumConnector(ctx context.Context, conf config.Section) (cc Connector, err error) {
83+
84+
chainTrackingMode := ffcapi.ChainTrackingMode(conf.GetString(ChainTrackingMode))
85+
if chainTrackingMode == "" {
86+
chainTrackingMode = ffcapi.ChainTrackingModeFull
87+
}
88+
if chainTrackingMode != ffcapi.ChainTrackingModeLight && chainTrackingMode != ffcapi.ChainTrackingModeFull {
89+
return nil, i18n.NewError(ctx, msgs.MsgInvalidChainTrackingMode, chainTrackingMode)
90+
}
91+
8192
c := &ethConnector{
8293
eventStreams: make(map[fftypes.UUID]*eventStream),
8394
catchupPageSize: conf.GetInt64(EventsCatchupPageSize),
@@ -86,6 +97,7 @@ func NewEthereumConnector(ctx context.Context, conf config.Section) (cc Connecto
8697
eventBlockTimestamps: conf.GetBool(EventsBlockTimestamps),
8798
eventFilterPollingInterval: conf.GetDuration(EventsFilterPollingInterval),
8899
traceTXForRevertReason: conf.GetBool(TraceTXForRevertReason),
100+
chainTrackingMode: chainTrackingMode,
89101
retry: retryutil.RetryWrapper{Retry: &retry.Retry{}},
90102
}
91103

@@ -164,6 +176,7 @@ func NewEthereumConnector(ctx context.Context, conf config.Section) (cc Connecto
164176
BlockCacheSize: conf.GetInt(BlockCacheSize),
165177
MaxAsyncBlockFetchConcurrency: conf.GetInt(MaxAsyncBlockFetchConcurrency),
166178
UseGetBlockReceipts: conf.GetBool(UseGetBlockReceipts),
179+
ChainTrackingMode: c.chainTrackingMode,
167180
}, c.backend, c.wsBackend); err != nil {
168181
return nil, err
169182
}
@@ -212,11 +225,12 @@ func (c *ethConnector) ReconcileConfirmationsForTransaction(ctx context.Context,
212225
}
213226
if err == nil && ethrpcRes != nil {
214227
res = &ffcapi.ConfirmationUpdateResult{
215-
Confirmations: ethRPCtoFFCAPIConfirmations(ethrpcRes.Confirmations),
216-
Rebuilt: ethrpcRes.Rebuilt,
217-
NewFork: ethrpcRes.NewFork,
218-
Confirmed: ethrpcRes.Confirmed,
219-
TargetConfirmationCount: ethrpcRes.TargetConfirmationCount,
228+
Confirmations: ethRPCtoFFCAPIConfirmations(ethrpcRes.Confirmations),
229+
Rebuilt: ethrpcRes.Rebuilt,
230+
NewFork: ethrpcRes.NewFork,
231+
Confirmed: ethrpcRes.Confirmed,
232+
CurrentConfirmationCount: ethrpcRes.CurrentConfirmationCount,
233+
TargetConfirmationCount: ethrpcRes.TargetConfirmationCount,
220234
}
221235
if ethrpcReceipt != nil {
222236
res.Receipt = c.enrichTransactionReceipt(ctx, ethrpcReceipt)

internal/ethereum/new_block_listener.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ import (
2323
"github.com/hyperledger/firefly-transaction-manager/pkg/ffcapi"
2424
)
2525

26+
func (c *ethConnector) GetChainTrackingMode(_ context.Context) ffcapi.ChainTrackingMode {
27+
return c.chainTrackingMode
28+
}
29+
2630
func (c *ethConnector) NewBlockListener(_ context.Context, req *ffcapi.NewBlockListenerRequest) (*ffcapi.NewBlockListenerResponse, ffcapi.ErrorReason, error) {
2731
// Add the block consumer
2832
c.blockListener.AddConsumer(req.ListenerContext, &ethblocklistener.BlockUpdateConsumer{

internal/msgs/en_config_descriptions.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ var (
5151
_ = ffc("config.connector.traceTXForRevertReason", "Enable the use of transaction trace functions (e.g. debug_traceTransaction) to obtain transaction revert reasons. This can place a high load on the EVM client.", i18n.BooleanType)
5252
_ = ffc("config.connector.maxAsyncBlockFetchConcurrency", "Maximum concurrency when using asynchronous block downloading (minium 1)", i18n.IntType)
5353
_ = ffc("config.connector.useGetBlockReceipts", "When true, the eth_getBlockReceipts call is available for this connector to use", i18n.BooleanType)
54+
_ = ffc("config.connector.chainTrackingMode", "Tracking mode for connector block progression. light: fetches head block numbers only, does not download block details, disables block listener support, and confirmation results include only the confirmation count. full: fetches head block numbers and block details, maintains an in-memory partial chain, enables block listener support, and confirmation results include both confirmation count and block details.", "`light` or `full`")
5455
)

internal/msgs/en_error_messages.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,6 @@ var (
8686
MsgUnknownJSONFormatOptions = ffe("FF23066", "JSON formatting option unknown %s=%s")
8787
MsgObservedPanic = ffe("FF23067", "Observed panic: %v")
8888
MsgReturnedBlockHashMismatch = ffe("FF23068", "Returned block %d hash %s does not match requested hash %s")
89+
MsgInvalidChainTrackingMode = ffe("FF23069", "Invalid chain tracking mode '%s': must be 'light' or 'full'")
90+
MsgTransactionNotIncludedInChainHead = ffe("FF23070", "Transaction '%s' cannot be reconciled because chain head %d is before receipt block %s")
8991
)

mocks/fftmmocks/manager.go

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)