feat(config): move Fevm.Events->Events, implement soft deprecation
Closes: https://github.com/filecoin-project/lotus/issues/11679 * Introduce a `moved:"To.New.Config"` tag which prints a stderr warning when you use one of these, but will move any set value to the new location if the new location isn't already set itself. * Look for `X is DEPRECATED` to hold certain fields back from documentation. * Use `toml:"omitempty"` to prevent the default config output from having these deprecated values.
This commit is contained in:
parent
b4e7374cd5
commit
e5ccf1915d
@ -136,7 +136,7 @@ Additionally, Filecoin is not Ethereum no matter how much we try to provide API/
|
|||||||
|
|
||||||
[FIP-0049](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0049.md) introduced _Actor Events_ that can be emitted by user programmed actors. [FIP-0083](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0083.md) introduces new events emitted by the builtin Verified Registry, Miner and Market Actors. These new events for builtin actors are being activated with network version 22 to coincide with _Direct Data Onboarding_ as defined in [FIP-0076](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0076.md) which introduces additional flexibility for data onboarding. Sector, Deal and DataCap lifecycles can be tracked with these events, providing visibility and options for programmatic responses to changes in state.
|
[FIP-0049](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0049.md) introduced _Actor Events_ that can be emitted by user programmed actors. [FIP-0083](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0083.md) introduces new events emitted by the builtin Verified Registry, Miner and Market Actors. These new events for builtin actors are being activated with network version 22 to coincide with _Direct Data Onboarding_ as defined in [FIP-0076](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0076.md) which introduces additional flexibility for data onboarding. Sector, Deal and DataCap lifecycles can be tracked with these events, providing visibility and options for programmatic responses to changes in state.
|
||||||
|
|
||||||
Actor events are available on message receipts, but can now be retrieved from a node using the new `GetActorEvents` and `SubscribeActorEvents` methods. These methods allow for querying and subscribing to actor events, respectively. They depend on the Lotus node both collecting events (with `Fevm.Events.RealTimeFilterAPI` and `Fevm.Events.HistoricFilterAPI`) and being enabled with the new configuration option `Events.EnableActorEventsAPI`. Note that a Lotus node can only respond to requests for historic events that it retains in its event store.
|
Actor events are available on message receipts, but can now be retrieved from a node using the new `GetActorEvents` and `SubscribeActorEvents` methods. These methods allow for querying and subscribing to actor events, respectively. They depend on the Lotus node both collecting events (with `Events.RealTimeFilterAPI` and `Events.HistoricFilterAPI`) and being enabled with the new configuration option `Events.EnableActorEventsAPI`. Note that a Lotus node can only respond to requests for historic events that it retains in its event store.
|
||||||
|
|
||||||
Both `GetActorEvents` and `SubscribeActorEvents` take a filter parameter which can optionally filter events on:
|
Both `GetActorEvents` and `SubscribeActorEvents` take a filter parameter which can optionally filter events on:
|
||||||
|
|
||||||
@ -147,7 +147,14 @@ Both `GetActorEvents` and `SubscribeActorEvents` take a filter parameter which c
|
|||||||
|
|
||||||
`GetActorEvents` provides a one-time query for actor events, while `SubscribeActorEvents` provides a long-lived connection (via websockets) to the Lotus node, allowing for real-time updates on actor events. The subscription can be cancelled by the client at any time.
|
`GetActorEvents` provides a one-time query for actor events, while `SubscribeActorEvents` provides a long-lived connection (via websockets) to the Lotus node, allowing for real-time updates on actor events. The subscription can be cancelled by the client at any time.
|
||||||
|
|
||||||
|
### Events Configuration Changes
|
||||||
|
|
||||||
|
All configuration options previously under `Fevm.Events` are now in the top-level `Events` section along with the new `Events.EnableActorEventsAPI` option mentioned above. If you have non-default options in `[Events]` under `[Fevm]` in your configuration file, please move them to the top-level `[Events]`.
|
||||||
|
|
||||||
|
While `Fevm.Events.*` options are deprecated and replaced by `Events.*`, any existing custom values will be respected if their new form isn't set, but a warning will be printed to standard error upon startup. Support for these deprecated options will be removed in a future Lotus release, so please migrate your configuration promptly.
|
||||||
|
|
||||||
### GetAllClaims and GetAllAlocations
|
### GetAllClaims and GetAllAlocations
|
||||||
|
|
||||||
Additionally the methods `GetAllAllocations` and `GetAllClaims` has been added to the Lotus API. These methods lists all the available allocations and claims available in the actor state.
|
Additionally the methods `GetAllAllocations` and `GetAllClaims` has been added to the Lotus API. These methods lists all the available allocations and claims available in the actor state.
|
||||||
|
|
||||||
### Lotus CLI
|
### Lotus CLI
|
||||||
|
@ -337,46 +337,56 @@
|
|||||||
# env var: LOTUS_FEVM_ETHTXHASHMAPPINGLIFETIMEDAYS
|
# env var: LOTUS_FEVM_ETHTXHASHMAPPINGLIFETIMEDAYS
|
||||||
#EthTxHashMappingLifetimeDays = 0
|
#EthTxHashMappingLifetimeDays = 0
|
||||||
|
|
||||||
[Fevm.Events]
|
|
||||||
|
[Events]
|
||||||
# DisableRealTimeFilterAPI will disable the RealTimeFilterAPI that can create and query filters for actor events as they are emitted.
|
# DisableRealTimeFilterAPI will disable the RealTimeFilterAPI that can create and query filters for actor events as they are emitted.
|
||||||
# The API is enabled when EnableEthRPC or Events.EnableActorEventsAPI is true, but can be disabled selectively with this flag.
|
# The API is enabled when Fevm.EnableEthRPC or EnableActorEventsAPI is true, but can be disabled selectively with this flag.
|
||||||
#
|
#
|
||||||
# type: bool
|
# type: bool
|
||||||
# env var: LOTUS_FEVM_EVENTS_DISABLEREALTIMEFILTERAPI
|
# env var: LOTUS_EVENTS_DISABLEREALTIMEFILTERAPI
|
||||||
#DisableRealTimeFilterAPI = false
|
#DisableRealTimeFilterAPI = false
|
||||||
|
|
||||||
# DisableHistoricFilterAPI will disable the HistoricFilterAPI that can create and query filters for actor events
|
# DisableHistoricFilterAPI will disable the HistoricFilterAPI that can create and query filters for actor events
|
||||||
# that occurred in the past. HistoricFilterAPI maintains a queryable index of events.
|
# that occurred in the past. HistoricFilterAPI maintains a queryable index of events.
|
||||||
# The API is enabled when EnableEthRPC or Events.EnableActorEventsAPI is true, but can be disabled selectively with this flag.
|
# The API is enabled when Fevm.EnableEthRPC or EnableActorEventsAPI is true, but can be disabled selectively with this flag.
|
||||||
#
|
#
|
||||||
# type: bool
|
# type: bool
|
||||||
# env var: LOTUS_FEVM_EVENTS_DISABLEHISTORICFILTERAPI
|
# env var: LOTUS_EVENTS_DISABLEHISTORICFILTERAPI
|
||||||
#DisableHistoricFilterAPI = false
|
#DisableHistoricFilterAPI = false
|
||||||
|
|
||||||
|
# EnableActorEventsAPI enables the Actor events API that enables clients to consume events
|
||||||
|
# emitted by (smart contracts + built-in Actors).
|
||||||
|
# This will also enable the RealTimeFilterAPI and HistoricFilterAPI by default, but they can be
|
||||||
|
# disabled by setting their respective Disable* options.
|
||||||
|
#
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_EVENTS_ENABLEACTOREVENTSAPI
|
||||||
|
#EnableActorEventsAPI = false
|
||||||
|
|
||||||
# FilterTTL specifies the time to live for actor event filters. Filters that haven't been accessed longer than
|
# FilterTTL specifies the time to live for actor event filters. Filters that haven't been accessed longer than
|
||||||
# this time become eligible for automatic deletion.
|
# this time become eligible for automatic deletion.
|
||||||
#
|
#
|
||||||
# type: Duration
|
# type: Duration
|
||||||
# env var: LOTUS_FEVM_EVENTS_FILTERTTL
|
# env var: LOTUS_EVENTS_FILTERTTL
|
||||||
#FilterTTL = "24h0m0s"
|
#FilterTTL = "24h0m0s"
|
||||||
|
|
||||||
# MaxFilters specifies the maximum number of filters that may exist at any one time.
|
# MaxFilters specifies the maximum number of filters that may exist at any one time.
|
||||||
#
|
#
|
||||||
# type: int
|
# type: int
|
||||||
# env var: LOTUS_FEVM_EVENTS_MAXFILTERS
|
# env var: LOTUS_EVENTS_MAXFILTERS
|
||||||
#MaxFilters = 100
|
#MaxFilters = 100
|
||||||
|
|
||||||
# MaxFilterResults specifies the maximum number of results that can be accumulated by an actor event filter.
|
# MaxFilterResults specifies the maximum number of results that can be accumulated by an actor event filter.
|
||||||
#
|
#
|
||||||
# type: int
|
# type: int
|
||||||
# env var: LOTUS_FEVM_EVENTS_MAXFILTERRESULTS
|
# env var: LOTUS_EVENTS_MAXFILTERRESULTS
|
||||||
#MaxFilterResults = 10000
|
#MaxFilterResults = 10000
|
||||||
|
|
||||||
# MaxFilterHeightRange specifies the maximum range of heights that can be used in a filter (to avoid querying
|
# MaxFilterHeightRange specifies the maximum range of heights that can be used in a filter (to avoid querying
|
||||||
# the entire chain)
|
# the entire chain)
|
||||||
#
|
#
|
||||||
# type: uint64
|
# type: uint64
|
||||||
# env var: LOTUS_FEVM_EVENTS_MAXFILTERHEIGHTRANGE
|
# env var: LOTUS_EVENTS_MAXFILTERHEIGHTRANGE
|
||||||
#MaxFilterHeightRange = 2880
|
#MaxFilterHeightRange = 2880
|
||||||
|
|
||||||
# DatabasePath is the full path to a sqlite database that will be used to index actor events to
|
# DatabasePath is the full path to a sqlite database that will be used to index actor events to
|
||||||
@ -385,21 +395,10 @@
|
|||||||
# relative to the CWD (current working directory).
|
# relative to the CWD (current working directory).
|
||||||
#
|
#
|
||||||
# type: string
|
# type: string
|
||||||
# env var: LOTUS_FEVM_EVENTS_DATABASEPATH
|
# env var: LOTUS_EVENTS_DATABASEPATH
|
||||||
#DatabasePath = ""
|
#DatabasePath = ""
|
||||||
|
|
||||||
|
|
||||||
[Events]
|
|
||||||
# EnableActorEventsAPI enables the Actor events API that enables clients to consume events
|
|
||||||
# emitted by (smart contracts + built-in Actors).
|
|
||||||
# This will also enable the RealTimeFilterAPI and HistoricFilterAPI by default, but they can be
|
|
||||||
# disabled by setting their respective Disable* options in Fevm.Events.
|
|
||||||
#
|
|
||||||
# type: bool
|
|
||||||
# env var: LOTUS_EVENTS_ENABLEACTOREVENTSAPI
|
|
||||||
#EnableActorEventsAPI = false
|
|
||||||
|
|
||||||
|
|
||||||
[Index]
|
[Index]
|
||||||
# EXPERIMENTAL FEATURE. USE WITH CAUTION
|
# EXPERIMENTAL FEATURE. USE WITH CAUTION
|
||||||
# EnableMsgIndex enables indexing of messages on chain.
|
# EnableMsgIndex enables indexing of messages on chain.
|
||||||
|
@ -65,7 +65,7 @@ var DefaultNodeOpts = nodeOpts{
|
|||||||
// test defaults
|
// test defaults
|
||||||
|
|
||||||
cfg.Fevm.EnableEthRPC = true
|
cfg.Fevm.EnableEthRPC = true
|
||||||
cfg.Fevm.Events.MaxFilterHeightRange = math.MaxInt64
|
cfg.Events.MaxFilterHeightRange = math.MaxInt64
|
||||||
cfg.Events.EnableActorEventsAPI = true
|
cfg.Events.EnableActorEventsAPI = true
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -266,13 +266,13 @@ func ConfigFullNode(c interface{}) Option {
|
|||||||
|
|
||||||
// Actor event filtering support
|
// Actor event filtering support
|
||||||
Override(new(events.EventHelperAPI), From(new(modules.EventHelperAPI))),
|
Override(new(events.EventHelperAPI), From(new(modules.EventHelperAPI))),
|
||||||
Override(new(*filter.EventFilterManager), modules.EventFilterManager(cfg.Fevm)),
|
Override(new(*filter.EventFilterManager), modules.EventFilterManager(cfg.Events)),
|
||||||
|
|
||||||
// in lite-mode Eth api is provided by gateway
|
// in lite-mode Eth api is provided by gateway
|
||||||
ApplyIf(isFullNode,
|
ApplyIf(isFullNode,
|
||||||
If(cfg.Fevm.EnableEthRPC,
|
If(cfg.Fevm.EnableEthRPC,
|
||||||
Override(new(full.EthModuleAPI), modules.EthModuleAPI(cfg.Fevm)),
|
Override(new(full.EthModuleAPI), modules.EthModuleAPI(cfg.Fevm)),
|
||||||
Override(new(full.EthEventAPI), modules.EthEventHandler(cfg.Fevm)),
|
Override(new(full.EthEventAPI), modules.EthEventHandler(cfg.Events, cfg.Fevm.EnableEthRPC)),
|
||||||
),
|
),
|
||||||
If(!cfg.Fevm.EnableEthRPC,
|
If(!cfg.Fevm.EnableEthRPC,
|
||||||
Override(new(full.EthModuleAPI), &full.EthModuleDummy{}),
|
Override(new(full.EthModuleAPI), &full.EthModuleDummy{}),
|
||||||
@ -282,7 +282,7 @@ func ConfigFullNode(c interface{}) Option {
|
|||||||
|
|
||||||
ApplyIf(isFullNode,
|
ApplyIf(isFullNode,
|
||||||
If(cfg.Events.EnableActorEventsAPI,
|
If(cfg.Events.EnableActorEventsAPI,
|
||||||
Override(new(full.ActorEventAPI), modules.ActorEventHandler(cfg.Events.EnableActorEventsAPI, cfg.Fevm)),
|
Override(new(full.ActorEventAPI), modules.ActorEventHandler(cfg.Events)),
|
||||||
),
|
),
|
||||||
If(!cfg.Events.EnableActorEventsAPI,
|
If(!cfg.Events.EnableActorEventsAPI,
|
||||||
Override(new(full.ActorEventAPI), &full.ActorEventDummy{}),
|
Override(new(full.ActorEventAPI), &full.ActorEventDummy{}),
|
||||||
|
@ -74,6 +74,11 @@ func run() error {
|
|||||||
name := f[0]
|
name := f[0]
|
||||||
typ := f[1]
|
typ := f[1]
|
||||||
|
|
||||||
|
if len(comment) > 0 && strings.HasPrefix(comment[0], fmt.Sprintf("%s is DEPRECATED", name)) {
|
||||||
|
// don't document deprecated fields
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
out[currentType] = append(out[currentType], field{
|
out[currentType] = append(out[currentType], field{
|
||||||
Name: name,
|
Name: name,
|
||||||
Type: typ,
|
Type: typ,
|
||||||
|
@ -110,18 +110,16 @@ func DefaultFullNode() *FullNode {
|
|||||||
Fevm: FevmConfig{
|
Fevm: FevmConfig{
|
||||||
EnableEthRPC: false,
|
EnableEthRPC: false,
|
||||||
EthTxHashMappingLifetimeDays: 0,
|
EthTxHashMappingLifetimeDays: 0,
|
||||||
Events: Events{
|
},
|
||||||
|
Events: EventsConfig{
|
||||||
DisableRealTimeFilterAPI: false,
|
DisableRealTimeFilterAPI: false,
|
||||||
DisableHistoricFilterAPI: false,
|
DisableHistoricFilterAPI: false,
|
||||||
|
EnableActorEventsAPI: false,
|
||||||
FilterTTL: Duration(time.Hour * 24),
|
FilterTTL: Duration(time.Hour * 24),
|
||||||
MaxFilters: 100,
|
MaxFilters: 100,
|
||||||
MaxFilterResults: 10000,
|
MaxFilterResults: 10000,
|
||||||
MaxFilterHeightRange: 2880, // conservative limit of one day
|
MaxFilterHeightRange: 2880, // conservative limit of one day
|
||||||
},
|
},
|
||||||
},
|
|
||||||
Events: EventsConfig{
|
|
||||||
EnableActorEventsAPI: false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,13 +357,13 @@ see https://lotus.filecoin.io/storage-providers/advanced-configurations/market/#
|
|||||||
Comment: ``,
|
Comment: ``,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Events": {
|
"EventsConfig": {
|
||||||
{
|
{
|
||||||
Name: "DisableRealTimeFilterAPI",
|
Name: "DisableRealTimeFilterAPI",
|
||||||
Type: "bool",
|
Type: "bool",
|
||||||
|
|
||||||
Comment: `DisableRealTimeFilterAPI will disable the RealTimeFilterAPI that can create and query filters for actor events as they are emitted.
|
Comment: `DisableRealTimeFilterAPI will disable the RealTimeFilterAPI that can create and query filters for actor events as they are emitted.
|
||||||
The API is enabled when EnableEthRPC or Events.EnableActorEventsAPI is true, but can be disabled selectively with this flag.`,
|
The API is enabled when Fevm.EnableEthRPC or EnableActorEventsAPI is true, but can be disabled selectively with this flag.`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "DisableHistoricFilterAPI",
|
Name: "DisableHistoricFilterAPI",
|
||||||
@ -371,7 +371,16 @@ The API is enabled when EnableEthRPC or Events.EnableActorEventsAPI is true, but
|
|||||||
|
|
||||||
Comment: `DisableHistoricFilterAPI will disable the HistoricFilterAPI that can create and query filters for actor events
|
Comment: `DisableHistoricFilterAPI will disable the HistoricFilterAPI that can create and query filters for actor events
|
||||||
that occurred in the past. HistoricFilterAPI maintains a queryable index of events.
|
that occurred in the past. HistoricFilterAPI maintains a queryable index of events.
|
||||||
The API is enabled when EnableEthRPC or Events.EnableActorEventsAPI is true, but can be disabled selectively with this flag.`,
|
The API is enabled when Fevm.EnableEthRPC or EnableActorEventsAPI is true, but can be disabled selectively with this flag.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "EnableActorEventsAPI",
|
||||||
|
Type: "bool",
|
||||||
|
|
||||||
|
Comment: `EnableActorEventsAPI enables the Actor events API that enables clients to consume events
|
||||||
|
emitted by (smart contracts + built-in Actors).
|
||||||
|
This will also enable the RealTimeFilterAPI and HistoricFilterAPI by default, but they can be
|
||||||
|
disabled by setting their respective Disable* options.`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "FilterTTL",
|
Name: "FilterTTL",
|
||||||
@ -409,17 +418,6 @@ the database must already exist and be writeable. If a relative path is provided
|
|||||||
relative to the CWD (current working directory).`,
|
relative to the CWD (current working directory).`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"EventsConfig": {
|
|
||||||
{
|
|
||||||
Name: "EnableActorEventsAPI",
|
|
||||||
Type: "bool",
|
|
||||||
|
|
||||||
Comment: `EnableActorEventsAPI enables the Actor events API that enables clients to consume events
|
|
||||||
emitted by (smart contracts + built-in Actors).
|
|
||||||
This will also enable the RealTimeFilterAPI and HistoricFilterAPI by default, but they can be
|
|
||||||
disabled by setting their respective Disable* options in Fevm.Events.`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"FaultReporterConfig": {
|
"FaultReporterConfig": {
|
||||||
{
|
{
|
||||||
Name: "EnableConsensusFaultReporter",
|
Name: "EnableConsensusFaultReporter",
|
||||||
@ -474,7 +472,7 @@ Set to 0 to keep all mappings`,
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Events",
|
Name: "Events",
|
||||||
Type: "Events",
|
Type: "DeprecatedEvents",
|
||||||
|
|
||||||
Comment: ``,
|
Comment: ``,
|
||||||
},
|
},
|
||||||
|
@ -18,12 +18,9 @@ import (
|
|||||||
// FromFile loads config from a specified file overriding defaults specified in
|
// FromFile loads config from a specified file overriding defaults specified in
|
||||||
// the def parameter. If file does not exist or is empty defaults are assumed.
|
// the def parameter. If file does not exist or is empty defaults are assumed.
|
||||||
func FromFile(path string, opts ...LoadCfgOpt) (interface{}, error) {
|
func FromFile(path string, opts ...LoadCfgOpt) (interface{}, error) {
|
||||||
var loadOpts cfgLoadOpts
|
loadOpts, err := applyOpts(opts...)
|
||||||
var err error
|
if err != nil {
|
||||||
for _, opt := range opts {
|
return nil, err
|
||||||
if err = opt(&loadOpts); err != nil {
|
|
||||||
return nil, xerrors.Errorf("failed to apply load cfg option: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
var def interface{}
|
var def interface{}
|
||||||
if loadOpts.defaultCfg != nil {
|
if loadOpts.defaultCfg != nil {
|
||||||
@ -56,16 +53,43 @@ func FromFile(path string, opts ...LoadCfgOpt) (interface{}, error) {
|
|||||||
return nil, xerrors.Errorf("config failed validation: %w", err)
|
return nil, xerrors.Errorf("config failed validation: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FromReader(buf, def)
|
return FromReader(buf, def, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromReader loads config from a reader instance.
|
// FromReader loads config from a reader instance.
|
||||||
func FromReader(reader io.Reader, def interface{}) (interface{}, error) {
|
func FromReader(reader io.Reader, def interface{}, opts ...LoadCfgOpt) (interface{}, error) {
|
||||||
cfg := def
|
loadOpts, err := applyOpts(opts...)
|
||||||
_, err := toml.NewDecoder(reader).Decode(cfg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
cfg := def
|
||||||
|
md, err := toml.NewDecoder(reader).Decode(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// find any fields with a tag: `moved:"New.Config.Location"` and move any set values there over to
|
||||||
|
// the new location if they are not already set there.
|
||||||
|
movedFields := findMovedFields(nil, cfg)
|
||||||
|
var warningOut io.Writer = os.Stderr
|
||||||
|
if loadOpts.warningWriter != nil {
|
||||||
|
warningOut = loadOpts.warningWriter
|
||||||
|
}
|
||||||
|
for _, d := range movedFields {
|
||||||
|
if md.IsDefined(d.Field...) {
|
||||||
|
fmt.Fprintf(
|
||||||
|
warningOut,
|
||||||
|
"WARNING: Use of deprecated configuration option '%s' will be removed in a future release, use '%s' instead\n",
|
||||||
|
strings.Join(d.Field, "."),
|
||||||
|
strings.Join(d.NewField, "."))
|
||||||
|
if !md.IsDefined(d.NewField...) {
|
||||||
|
// new value isn't set but old is, we should move what the user set there
|
||||||
|
if err := moveFieldValue(cfg, d.Field, d.NewField); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to move field value: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = envconfig.Process("LOTUS", cfg)
|
err = envconfig.Process("LOTUS", cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -75,14 +99,105 @@ func FromReader(reader io.Reader, def interface{}) (interface{}, error) {
|
|||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// move a value from the location in the valPtr struct specified by oldPath, to the location
|
||||||
|
// specified by newPath; where the path is an array of nested field names.
|
||||||
|
func moveFieldValue(valPtr interface{}, oldPath []string, newPath []string) error {
|
||||||
|
oldValue, err := getFieldValue(valPtr, oldPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
val := reflect.ValueOf(valPtr).Elem()
|
||||||
|
for {
|
||||||
|
field := val.FieldByName(newPath[0])
|
||||||
|
if !field.IsValid() {
|
||||||
|
return fmt.Errorf("unexpected error fetching field value")
|
||||||
|
}
|
||||||
|
if len(newPath) == 1 {
|
||||||
|
if field.Kind() != oldValue.Kind() {
|
||||||
|
return fmt.Errorf("unexpected error, old kind != new kind")
|
||||||
|
}
|
||||||
|
// set field on val to be the new one, and we're done
|
||||||
|
field.Set(oldValue)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if field.Kind() != reflect.Struct {
|
||||||
|
return fmt.Errorf("unexpected error fetching field value, is not a struct")
|
||||||
|
}
|
||||||
|
newPath = newPath[1:]
|
||||||
|
val = field
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recursively iterate into `path` to find the terminal value
|
||||||
|
func getFieldValue(val interface{}, path []string) (reflect.Value, error) {
|
||||||
|
if reflect.ValueOf(val).Kind() == reflect.Ptr {
|
||||||
|
val = reflect.ValueOf(val).Elem().Interface()
|
||||||
|
}
|
||||||
|
field := reflect.ValueOf(val).FieldByName(path[0])
|
||||||
|
if !field.IsValid() {
|
||||||
|
return reflect.Value{}, fmt.Errorf("unexpected error fetching field value")
|
||||||
|
}
|
||||||
|
if len(path) > 1 {
|
||||||
|
if field.Kind() != reflect.Struct {
|
||||||
|
return reflect.Value{}, fmt.Errorf("unexpected error fetching field value, is not a struct")
|
||||||
|
}
|
||||||
|
return getFieldValue(field.Interface(), path[1:])
|
||||||
|
}
|
||||||
|
return field, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type movedField struct {
|
||||||
|
Field []string
|
||||||
|
NewField []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// inspect the fields recursively within a struct and find any with "moved" tags
|
||||||
|
func findMovedFields(path []string, val interface{}) []movedField {
|
||||||
|
dep := make([]movedField, 0)
|
||||||
|
if reflect.ValueOf(val).Kind() == reflect.Ptr {
|
||||||
|
val = reflect.ValueOf(val).Elem().Interface()
|
||||||
|
}
|
||||||
|
t := reflect.TypeOf(val)
|
||||||
|
if t.Kind() != reflect.Struct {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
field := t.Field(i)
|
||||||
|
// could also do a "deprecated" in here
|
||||||
|
if idx := field.Tag.Get("moved"); idx != "" && idx != "-" {
|
||||||
|
dep = append(dep, movedField{
|
||||||
|
Field: append(path, field.Name),
|
||||||
|
NewField: strings.Split(idx, "."),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if field.Type.Kind() == reflect.Struct && reflect.ValueOf(val).FieldByName(field.Name).IsValid() {
|
||||||
|
deps := findMovedFields(append(path, field.Name), reflect.ValueOf(val).FieldByName(field.Name).Interface())
|
||||||
|
dep = append(dep, deps...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dep
|
||||||
|
}
|
||||||
|
|
||||||
type cfgLoadOpts struct {
|
type cfgLoadOpts struct {
|
||||||
defaultCfg func() (interface{}, error)
|
defaultCfg func() (interface{}, error)
|
||||||
canFallbackOnDefault func() error
|
canFallbackOnDefault func() error
|
||||||
validate func(string) error
|
validate func(string) error
|
||||||
|
warningWriter io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoadCfgOpt func(opts *cfgLoadOpts) error
|
type LoadCfgOpt func(opts *cfgLoadOpts) error
|
||||||
|
|
||||||
|
func applyOpts(opts ...LoadCfgOpt) (cfgLoadOpts, error) {
|
||||||
|
var loadOpts cfgLoadOpts
|
||||||
|
var err error
|
||||||
|
for _, opt := range opts {
|
||||||
|
if err = opt(&loadOpts); err != nil {
|
||||||
|
return loadOpts, fmt.Errorf("failed to apply load cfg option: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return loadOpts, nil
|
||||||
|
}
|
||||||
|
|
||||||
func SetDefault(f func() (interface{}, error)) LoadCfgOpt {
|
func SetDefault(f func() (interface{}, error)) LoadCfgOpt {
|
||||||
return func(opts *cfgLoadOpts) error {
|
return func(opts *cfgLoadOpts) error {
|
||||||
opts.defaultCfg = f
|
opts.defaultCfg = f
|
||||||
@ -104,6 +219,13 @@ func SetValidate(f func(string) error) LoadCfgOpt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetWarningWriter(w io.Writer) LoadCfgOpt {
|
||||||
|
return func(opts *cfgLoadOpts) error {
|
||||||
|
opts.warningWriter = w
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func NoDefaultForSplitstoreTransition() error {
|
func NoDefaultForSplitstoreTransition() error {
|
||||||
return xerrors.Errorf("FullNode config not found and fallback to default disallowed while we transition to splitstore discard default. Use `lotus config default` to set this repo up with a default config. Be sure to set `EnableSplitstore` to `false` if you are running a full archive node")
|
return xerrors.Errorf("FullNode config not found and fallback to default disallowed while we transition to splitstore discard default. Use `lotus config default` to set this repo up with a default config. Be sure to set `EnableSplitstore` to `false` if you are running a full archive node")
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fullNodeDefault() (interface{}, error) { return DefaultFullNode(), nil }
|
func fullNodeDefault() (interface{}, error) { return DefaultFullNode(), nil }
|
||||||
@ -138,3 +139,77 @@ func TestFailToFallbackToDefault(t *testing.T) {
|
|||||||
_, err = FromFile(nonExistantFileName, SetDefault(fullNodeDefault), SetCanFallbackOnDefault(NoDefaultForSplitstoreTransition))
|
_, err = FromFile(nonExistantFileName, SetDefault(fullNodeDefault), SetCanFallbackOnDefault(NoDefaultForSplitstoreTransition))
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrintDeprecated(t *testing.T) {
|
||||||
|
type ChildCfg struct {
|
||||||
|
Field string `moved:"Bang"`
|
||||||
|
NewField string
|
||||||
|
}
|
||||||
|
type Old struct {
|
||||||
|
Thing1 int `moved:"New.Thing1"`
|
||||||
|
Thing2 int `moved:"New.Thing2"`
|
||||||
|
}
|
||||||
|
type New struct {
|
||||||
|
Thing1 int
|
||||||
|
Thing2 int
|
||||||
|
}
|
||||||
|
type ParentCfg struct {
|
||||||
|
Child ChildCfg
|
||||||
|
Old Old
|
||||||
|
New New
|
||||||
|
Foo int
|
||||||
|
Baz string `moved:"Child.NewField"`
|
||||||
|
Boom int `moved:"Foo"`
|
||||||
|
Bang string
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("warning output", func(t *testing.T) {
|
||||||
|
cfg := `
|
||||||
|
Baz = "baz"
|
||||||
|
Foo = 100
|
||||||
|
[Child]
|
||||||
|
Field = "bip"
|
||||||
|
NewField = "bop"
|
||||||
|
`
|
||||||
|
|
||||||
|
warningWriter := bytes.NewBuffer(nil)
|
||||||
|
|
||||||
|
v, err := FromReader(bytes.NewReader([]byte(cfg)), &ParentCfg{Boom: 200, Bang: "300"}, SetWarningWriter(warningWriter))
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, &ParentCfg{
|
||||||
|
Child: ChildCfg{
|
||||||
|
Field: "bip",
|
||||||
|
NewField: "bop",
|
||||||
|
},
|
||||||
|
Baz: "baz",
|
||||||
|
Foo: 100,
|
||||||
|
Boom: 200,
|
||||||
|
Bang: "bip",
|
||||||
|
}, v)
|
||||||
|
require.Regexp(t, `\WChild\.Field\W.+use 'Bang' instead`, warningWriter.String())
|
||||||
|
require.Regexp(t, `\WBaz\W.+use 'Child\.NewField' instead`, warningWriter.String())
|
||||||
|
require.NotContains(t, warningWriter.String(), "don't use this at all")
|
||||||
|
require.NotContains(t, warningWriter.String(), "Boom")
|
||||||
|
})
|
||||||
|
|
||||||
|
defaultNew := New{Thing1: 42, Thing2: 800}
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
cfg string
|
||||||
|
expected New
|
||||||
|
}{
|
||||||
|
{"simple", ``, defaultNew},
|
||||||
|
{"set new", "[New]\nThing1 = 101\nThing2 = 102\n", New{Thing1: 101, Thing2: 102}},
|
||||||
|
// should move old to new fields if new isn't set
|
||||||
|
{"set old", "[Old]\nThing1 = 101\nThing2 = 102\n", New{Thing1: 101, Thing2: 102}},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
v, err := FromReader(bytes.NewReader([]byte(tc.cfg)), &ParentCfg{New: defaultNew})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, tc.expected, v.(*ParentCfg).New)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -791,19 +791,48 @@ type FevmConfig struct {
|
|||||||
// Set to 0 to keep all mappings
|
// Set to 0 to keep all mappings
|
||||||
EthTxHashMappingLifetimeDays int
|
EthTxHashMappingLifetimeDays int
|
||||||
|
|
||||||
Events Events
|
Events DeprecatedEvents `toml:"Events,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Events struct {
|
type DeprecatedEvents struct {
|
||||||
|
// DisableRealTimeFilterAPI is DEPRECATED and will be removed in a future release. Use Events.DisableRealTimeFilterAPI instead.
|
||||||
|
DisableRealTimeFilterAPI bool `moved:"Events.DisableRealTimeFilterAPI" toml:"DisableRealTimeFilterAPI,omitempty"`
|
||||||
|
|
||||||
|
// DisableHistoricFilterAPI is DEPRECATED and will be removed in a future release. Use Events.DisableHistoricFilterAPI instead.
|
||||||
|
DisableHistoricFilterAPI bool `moved:"Events.DisableHistoricFilterAPI" toml:"DisableHistoricFilterAPI,omitempty"`
|
||||||
|
|
||||||
|
// FilterTTL is DEPRECATED and will be removed in a future release. Use Events.FilterTTL instead.
|
||||||
|
FilterTTL Duration `moved:"Events.FilterTTL" toml:"FilterTTL,omitzero"`
|
||||||
|
|
||||||
|
// MaxFilters is DEPRECATED and will be removed in a future release. Use Events.MaxFilters instead.
|
||||||
|
MaxFilters int `moved:"Events.MaxFilters" toml:"MaxFilters,omitzero"`
|
||||||
|
|
||||||
|
// MaxFilterResults is DEPRECATED and will be removed in a future release. Use Events.MaxFilterResults instead.
|
||||||
|
MaxFilterResults int `moved:"Events.MaxFilterResults" toml:"MaxFilterResults,omitzero"`
|
||||||
|
|
||||||
|
// MaxFilterHeightRange is DEPRECATED and will be removed in a future release. Use Events.MaxFilterHeightRange instead.
|
||||||
|
MaxFilterHeightRange uint64 `moved:"Events.MaxFilterHeightRange" toml:"MaxFilterHeightRange,omitzero"`
|
||||||
|
|
||||||
|
// DatabasePath is DEPRECATED and will be removed in a future release. Use Events.DatabasePath instead.
|
||||||
|
DatabasePath string `moved:"Events.DatabasePath" toml:"DatabasePath,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventsConfig struct {
|
||||||
// DisableRealTimeFilterAPI will disable the RealTimeFilterAPI that can create and query filters for actor events as they are emitted.
|
// DisableRealTimeFilterAPI will disable the RealTimeFilterAPI that can create and query filters for actor events as they are emitted.
|
||||||
// The API is enabled when EnableEthRPC or Events.EnableActorEventsAPI is true, but can be disabled selectively with this flag.
|
// The API is enabled when Fevm.EnableEthRPC or EnableActorEventsAPI is true, but can be disabled selectively with this flag.
|
||||||
DisableRealTimeFilterAPI bool
|
DisableRealTimeFilterAPI bool
|
||||||
|
|
||||||
// DisableHistoricFilterAPI will disable the HistoricFilterAPI that can create and query filters for actor events
|
// DisableHistoricFilterAPI will disable the HistoricFilterAPI that can create and query filters for actor events
|
||||||
// that occurred in the past. HistoricFilterAPI maintains a queryable index of events.
|
// that occurred in the past. HistoricFilterAPI maintains a queryable index of events.
|
||||||
// The API is enabled when EnableEthRPC or Events.EnableActorEventsAPI is true, but can be disabled selectively with this flag.
|
// The API is enabled when Fevm.EnableEthRPC or EnableActorEventsAPI is true, but can be disabled selectively with this flag.
|
||||||
DisableHistoricFilterAPI bool
|
DisableHistoricFilterAPI bool
|
||||||
|
|
||||||
|
// EnableActorEventsAPI enables the Actor events API that enables clients to consume events
|
||||||
|
// emitted by (smart contracts + built-in Actors).
|
||||||
|
// This will also enable the RealTimeFilterAPI and HistoricFilterAPI by default, but they can be
|
||||||
|
// disabled by setting their respective Disable* options.
|
||||||
|
EnableActorEventsAPI bool
|
||||||
|
|
||||||
// FilterTTL specifies the time to live for actor event filters. Filters that haven't been accessed longer than
|
// FilterTTL specifies the time to live for actor event filters. Filters that haven't been accessed longer than
|
||||||
// this time become eligible for automatic deletion.
|
// this time become eligible for automatic deletion.
|
||||||
FilterTTL Duration
|
FilterTTL Duration
|
||||||
@ -830,14 +859,6 @@ type Events struct {
|
|||||||
// Set upper bound on index size
|
// Set upper bound on index size
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventsConfig struct {
|
|
||||||
// EnableActorEventsAPI enables the Actor events API that enables clients to consume events
|
|
||||||
// emitted by (smart contracts + built-in Actors).
|
|
||||||
// This will also enable the RealTimeFilterAPI and HistoricFilterAPI by default, but they can be
|
|
||||||
// disabled by setting their respective Disable* options in Fevm.Events.
|
|
||||||
EnableActorEventsAPI bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type IndexConfig struct {
|
type IndexConfig struct {
|
||||||
// EXPERIMENTAL FEATURE. USE WITH CAUTION
|
// EXPERIMENTAL FEATURE. USE WITH CAUTION
|
||||||
// EnableMsgIndex enables indexing of messages on chain.
|
// EnableMsgIndex enables indexing of messages on chain.
|
||||||
|
@ -32,17 +32,17 @@ type EventHelperAPI struct {
|
|||||||
|
|
||||||
var _ events.EventHelperAPI = &EventHelperAPI{}
|
var _ events.EventHelperAPI = &EventHelperAPI{}
|
||||||
|
|
||||||
func EthEventHandler(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRepo, fx.Lifecycle, *filter.EventFilterManager, *store.ChainStore, *stmgr.StateManager, EventHelperAPI, *messagepool.MessagePool, full.StateAPI, full.ChainAPI) (*full.EthEventHandler, error) {
|
func EthEventHandler(cfg config.EventsConfig, enableEthRPC bool) func(helpers.MetricsCtx, repo.LockedRepo, fx.Lifecycle, *filter.EventFilterManager, *store.ChainStore, *stmgr.StateManager, EventHelperAPI, *messagepool.MessagePool, full.StateAPI, full.ChainAPI) (*full.EthEventHandler, error) {
|
||||||
return func(mctx helpers.MetricsCtx, r repo.LockedRepo, lc fx.Lifecycle, fm *filter.EventFilterManager, cs *store.ChainStore, sm *stmgr.StateManager, evapi EventHelperAPI, mp *messagepool.MessagePool, stateapi full.StateAPI, chainapi full.ChainAPI) (*full.EthEventHandler, error) {
|
return func(mctx helpers.MetricsCtx, r repo.LockedRepo, lc fx.Lifecycle, fm *filter.EventFilterManager, cs *store.ChainStore, sm *stmgr.StateManager, evapi EventHelperAPI, mp *messagepool.MessagePool, stateapi full.StateAPI, chainapi full.ChainAPI) (*full.EthEventHandler, error) {
|
||||||
ctx := helpers.LifecycleCtx(mctx, lc)
|
ctx := helpers.LifecycleCtx(mctx, lc)
|
||||||
|
|
||||||
ee := &full.EthEventHandler{
|
ee := &full.EthEventHandler{
|
||||||
Chain: cs,
|
Chain: cs,
|
||||||
MaxFilterHeightRange: abi.ChainEpoch(cfg.Events.MaxFilterHeightRange),
|
MaxFilterHeightRange: abi.ChainEpoch(cfg.MaxFilterHeightRange),
|
||||||
SubscribtionCtx: ctx,
|
SubscribtionCtx: ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cfg.EnableEthRPC || cfg.Events.DisableRealTimeFilterAPI {
|
if !enableEthRPC || cfg.DisableRealTimeFilterAPI {
|
||||||
// all event functionality is disabled
|
// all event functionality is disabled
|
||||||
// the historic filter API relies on the real time one
|
// the historic filter API relies on the real time one
|
||||||
return ee, nil
|
return ee, nil
|
||||||
@ -53,21 +53,21 @@ func EthEventHandler(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.Locked
|
|||||||
StateAPI: stateapi,
|
StateAPI: stateapi,
|
||||||
ChainAPI: chainapi,
|
ChainAPI: chainapi,
|
||||||
}
|
}
|
||||||
ee.FilterStore = filter.NewMemFilterStore(cfg.Events.MaxFilters)
|
ee.FilterStore = filter.NewMemFilterStore(cfg.MaxFilters)
|
||||||
|
|
||||||
// Start garbage collection for filters
|
// Start garbage collection for filters
|
||||||
lc.Append(fx.Hook{
|
lc.Append(fx.Hook{
|
||||||
OnStart: func(context.Context) error {
|
OnStart: func(context.Context) error {
|
||||||
go ee.GC(ctx, time.Duration(cfg.Events.FilterTTL))
|
go ee.GC(ctx, time.Duration(cfg.FilterTTL))
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
ee.TipSetFilterManager = &filter.TipSetFilterManager{
|
ee.TipSetFilterManager = &filter.TipSetFilterManager{
|
||||||
MaxFilterResults: cfg.Events.MaxFilterResults,
|
MaxFilterResults: cfg.MaxFilterResults,
|
||||||
}
|
}
|
||||||
ee.MemPoolFilterManager = &filter.MemPoolFilterManager{
|
ee.MemPoolFilterManager = &filter.MemPoolFilterManager{
|
||||||
MaxFilterResults: cfg.Events.MaxFilterResults,
|
MaxFilterResults: cfg.MaxFilterResults,
|
||||||
}
|
}
|
||||||
ee.EventFilterManager = fm
|
ee.EventFilterManager = fm
|
||||||
|
|
||||||
@ -94,22 +94,22 @@ func EthEventHandler(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.Locked
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func EventFilterManager(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRepo, fx.Lifecycle, *store.ChainStore, *stmgr.StateManager, EventHelperAPI, full.ChainAPI) (*filter.EventFilterManager, error) {
|
func EventFilterManager(cfg config.EventsConfig) func(helpers.MetricsCtx, repo.LockedRepo, fx.Lifecycle, *store.ChainStore, *stmgr.StateManager, EventHelperAPI, full.ChainAPI) (*filter.EventFilterManager, error) {
|
||||||
return func(mctx helpers.MetricsCtx, r repo.LockedRepo, lc fx.Lifecycle, cs *store.ChainStore, sm *stmgr.StateManager, evapi EventHelperAPI, chainapi full.ChainAPI) (*filter.EventFilterManager, error) {
|
return func(mctx helpers.MetricsCtx, r repo.LockedRepo, lc fx.Lifecycle, cs *store.ChainStore, sm *stmgr.StateManager, evapi EventHelperAPI, chainapi full.ChainAPI) (*filter.EventFilterManager, error) {
|
||||||
ctx := helpers.LifecycleCtx(mctx, lc)
|
ctx := helpers.LifecycleCtx(mctx, lc)
|
||||||
|
|
||||||
// Enable indexing of actor events
|
// Enable indexing of actor events
|
||||||
var eventIndex *filter.EventIndex
|
var eventIndex *filter.EventIndex
|
||||||
if !cfg.Events.DisableHistoricFilterAPI {
|
if !cfg.DisableHistoricFilterAPI {
|
||||||
var dbPath string
|
var dbPath string
|
||||||
if cfg.Events.DatabasePath == "" {
|
if cfg.DatabasePath == "" {
|
||||||
sqlitePath, err := r.SqlitePath()
|
sqlitePath, err := r.SqlitePath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dbPath = filepath.Join(sqlitePath, "events.db")
|
dbPath = filepath.Join(sqlitePath, "events.db")
|
||||||
} else {
|
} else {
|
||||||
dbPath = cfg.Events.DatabasePath
|
dbPath = cfg.DatabasePath
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@ -144,7 +144,7 @@ func EventFilterManager(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.Loc
|
|||||||
return *actor.Address, true
|
return *actor.Address, true
|
||||||
},
|
},
|
||||||
|
|
||||||
MaxFilterResults: cfg.Events.MaxFilterResults,
|
MaxFilterResults: cfg.MaxFilterResults,
|
||||||
}
|
}
|
||||||
|
|
||||||
lc.Append(fx.Hook{
|
lc.Append(fx.Hook{
|
||||||
@ -162,10 +162,10 @@ func EventFilterManager(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.Loc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ActorEventHandler(enable bool, fevmCfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRepo, fx.Lifecycle, *filter.EventFilterManager, *store.ChainStore, *stmgr.StateManager, EventHelperAPI, *messagepool.MessagePool, full.StateAPI, full.ChainAPI) (*full.ActorEventHandler, error) {
|
func ActorEventHandler(cfg config.EventsConfig) func(helpers.MetricsCtx, repo.LockedRepo, fx.Lifecycle, *filter.EventFilterManager, *store.ChainStore, *stmgr.StateManager, EventHelperAPI, *messagepool.MessagePool, full.StateAPI, full.ChainAPI) (*full.ActorEventHandler, error) {
|
||||||
return func(mctx helpers.MetricsCtx, r repo.LockedRepo, lc fx.Lifecycle, fm *filter.EventFilterManager, cs *store.ChainStore, sm *stmgr.StateManager, evapi EventHelperAPI, mp *messagepool.MessagePool, stateapi full.StateAPI, chainapi full.ChainAPI) (*full.ActorEventHandler, error) {
|
return func(mctx helpers.MetricsCtx, r repo.LockedRepo, lc fx.Lifecycle, fm *filter.EventFilterManager, cs *store.ChainStore, sm *stmgr.StateManager, evapi EventHelperAPI, mp *messagepool.MessagePool, stateapi full.StateAPI, chainapi full.ChainAPI) (*full.ActorEventHandler, error) {
|
||||||
|
|
||||||
if !enable || fevmCfg.Events.DisableRealTimeFilterAPI {
|
if !cfg.EnableActorEventsAPI || cfg.DisableRealTimeFilterAPI {
|
||||||
fm = nil
|
fm = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ func ActorEventHandler(enable bool, fevmCfg config.FevmConfig) func(helpers.Metr
|
|||||||
cs,
|
cs,
|
||||||
fm,
|
fm,
|
||||||
time.Duration(build.BlockDelaySecs)*time.Second,
|
time.Duration(build.BlockDelaySecs)*time.Second,
|
||||||
abi.ChainEpoch(fevmCfg.Events.MaxFilterHeightRange),
|
abi.ChainEpoch(cfg.MaxFilterHeightRange),
|
||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user