diff --git a/Makefile b/Makefile index 34be3b05..3fc58a49 100644 --- a/Makefile +++ b/Makefile @@ -17,4 +17,4 @@ lint: golangci-lint run -E gofmt -E gosec -E goconst -E gocritic --timeout 5m test: - go test -race ./... \ No newline at end of file + go test -race -timeout 25m ./... diff --git a/actors/cache/actors_cache.go b/actors/cache/actors_cache.go index e74df5f4..33823a38 100644 --- a/actors/cache/actors_cache.go +++ b/actors/cache/actors_cache.go @@ -212,6 +212,10 @@ func (a *ActorsCache) storeRobustAddress(add address.Address, info types.Address return nil } +func (a *ActorsCache) StoreAddressInfoAddress(addInfo types.AddressInfo) { + a.offChainCache.StoreAddressInfo(addInfo) +} + func (a *ActorsCache) isBadAddress(add address.Address) bool { _, bad := a.badAddress.Get(add.String()) return bad diff --git a/actors/cache/impl/zcache.go b/actors/cache/impl/zcache.go index 2706a223..69e34d20 100644 --- a/actors/cache/impl/zcache.go +++ b/actors/cache/impl/zcache.go @@ -3,6 +3,8 @@ package impl import ( "context" "fmt" + "github.com/zondax/fil-parser/actors/constants" + "strings" "github.com/filecoin-project/go-address" filTypes "github.com/filecoin-project/lotus/chain/types" @@ -19,7 +21,7 @@ const ( ZCacheLocalOnly = "in-memory" ZCacheCombined = "combined" NoTtl = -1 - DummyTtl = -1 + NotExpiringTtl = -1 PrefixSplitter = "/" ) @@ -131,14 +133,20 @@ func (m *ZCache) GetRobustAddress(address address.Address) (string, error) { return "", err } + ctx := context.Background() + if isRobustAddress { - // Already a robust address + // If already a robust address, we attempt to get a f4 address. + // This is particularly useful in the case of EVM actors, where a robust f2 address + // may need to be converted as a f4 address. + if f4Address := m.tryToGetF4Address(address); f4Address != "" { + return f4Address, nil + } + return address.String(), nil } - // This is a short address, get the robust one var robustAdd string - ctx := context.Background() if err = m.shortRobustMap.Get(ctx, address.String(), &robustAdd); err != nil { return "", common.ErrKeyNotFound } @@ -185,7 +193,7 @@ func (m *ZCache) storeRobustShort(robust string, short string) { // Possible ZCache types can be Local or Combined. Both types set the TTL at instantiation time // The ttl here is pointless ctx := context.Background() - _ = m.robustShortMap.Set(ctx, robust, short, DummyTtl) + _ = m.robustShortMap.Set(ctx, robust, short, NotExpiringTtl) } func (m *ZCache) storeShortRobust(short string, robust string) { @@ -197,13 +205,22 @@ func (m *ZCache) storeShortRobust(short string, robust string) { // Possible ZCache types can be Local or Combined. Both types set the TTL at instantiation time // The ttl here is pointless ctx := context.Background() - _ = m.shortRobustMap.Set(ctx, short, robust, DummyTtl) + _ = m.shortRobustMap.Set(ctx, short, robust, NotExpiringTtl) } func (m *ZCache) StoreAddressInfo(info types.AddressInfo) { m.storeRobustShort(info.Robust, info.Short) - m.storeShortRobust(info.Short, info.Robust) m.storeActorCode(info.Short, info.ActorCid) + + isEvm := strings.EqualFold(info.ActorType, constants.ActorTypeEVM) + isEvmAndAddressIsF4 := isEvm && strings.HasPrefix(info.Robust, constants.AddressTypePrefixF4) + + // Only store the mapping for addresses that are not related to EVM actors, + // or are associated with EVM actors but use an f4 prefix. We skip storing + // addresses when they are f2 for EVM actors because only f4 addresses are of interest. + if !isEvm || isEvmAndAddressIsF4 { + m.storeShortRobust(info.Short, info.Robust) + } } func (m *ZCache) storeActorCode(shortAddress string, cid string) { @@ -215,5 +232,33 @@ func (m *ZCache) storeActorCode(shortAddress string, cid string) { // Possible ZCache types can be Local or Combined. Both types set the TTL at instantiation time // The ttl here is pointless ctx := context.Background() - _ = m.shortCidMap.Set(ctx, shortAddress, cid, DummyTtl) + _ = m.shortCidMap.Set(ctx, shortAddress, cid, NotExpiringTtl) +} + +func (m *ZCache) tryToGetF4Address(address address.Address) string { + ctx := context.Background() + + // Return the address if it's already a f4 address + if strings.HasPrefix(address.String(), constants.AddressTypePrefixF4) { + return address.String() + } + + // If the robust address is not f4, it should be f2 + // Try to get the corresponding f0 for the f2 address + f0Address, err := m.GetShortAddress(address) + if err != nil { + m.logger.Sugar().Errorf("error getting short address for %s: %s", address.String(), err) + return "" + } + + // Try to get the f4 address associated with the f0 address + // If no f4 is found, it implies the address might not be an EVM actor type + var f4Address string + err = m.shortRobustMap.Get(ctx, f0Address, &f4Address) + if err == nil && f4Address != "" { + return f4Address + } + + m.logger.Sugar().Infof("no f4 address associated with f0 address: %s. The address might not be an EVM actor type.", f0Address) + return "" } diff --git a/actors/common.go b/actors/common.go index 4c063a81..57b573f9 100644 --- a/actors/common.go +++ b/actors/common.go @@ -4,7 +4,10 @@ import ( "bytes" "encoding/hex" "github.com/filecoin-project/go-address" + "github.com/zondax/fil-parser/actors/cache" + "github.com/zondax/fil-parser/actors/cache/impl/common" "github.com/zondax/fil-parser/parser" + "go.uber.org/zap" ) func (p *ActorParser) parseSend(msg *parser.LotusMessage) map[string]interface{} { @@ -40,3 +43,16 @@ func (p *ActorParser) unknownMetadata(msgParams, msgReturn []byte) (map[string]i func (p *ActorParser) emptyParamsAndReturn() (map[string]interface{}, error) { return make(map[string]interface{}), nil } + +func EnsureRobustAddress(address address.Address, actorCache *cache.ActorsCache, logger *zap.Logger) string { + if isRobust, _ := common.IsRobustAddress(address); isRobust { + return address.String() + } + + robustAddress, err := actorCache.GetRobustAddress(address) + if err != nil { + logger.Sugar().Warnf("Error converting address to robust format: %v", err) + return address.String() // Fallback + } + return robustAddress +} diff --git a/actors/constants/constants.go b/actors/constants/constants.go new file mode 100644 index 00000000..9636a36b --- /dev/null +++ b/actors/constants/constants.go @@ -0,0 +1,8 @@ +package constants + +const ( + ActorTypeEVM = "evm" + AddressTypePrefixF4 = "f4" + + ActorTypeMiner = "miner" +) diff --git a/actors/eam.go b/actors/eam.go index fb1b69c0..e5636684 100644 --- a/actors/eam.go +++ b/actors/eam.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "fmt" "github.com/filecoin-project/go-state-types/abi" + "github.com/zondax/fil-parser/actors/constants" "github.com/zondax/fil-parser/parser" "strconv" @@ -102,9 +103,10 @@ func (p *ActorParser) parseCreate(rawParams, rawReturn []byte, msgCid cid.Cid) ( Short: parser.FilPrefix + strconv.FormatUint(r.ActorID, 10), Robust: r.RobustAddress.String(), EthAddress: parser.EthPrefix + hex.EncodeToString(r.EthAddress[:]), - ActorType: "evm", + ActorType: constants.ActorTypeEVM, CreationTxCid: msgCid.String(), } + p.helper.GetActorsCache().StoreAddressInfoAddress(*createdEvmActor) return metadata, createdEvmActor, nil } @@ -135,9 +137,10 @@ func (p *ActorParser) parseCreate2(rawParams, rawReturn []byte, msgCid cid.Cid) Short: parser.FilPrefix + strconv.FormatUint(r.ActorID, 10), Robust: r.RobustAddress.String(), EthAddress: parser.EthPrefix + hex.EncodeToString(r.EthAddress[:]), - ActorType: "evm", + ActorType: constants.ActorTypeEVM, CreationTxCid: msgCid.String(), } + p.helper.GetActorsCache().StoreAddressInfoAddress(*createdEvmActor) return metadata, createdEvmActor, nil } @@ -171,8 +174,9 @@ func (p *ActorParser) parseCreateExternal(rawParams, rawReturn []byte, msgCid ci Short: parser.FilPrefix + strconv.FormatUint(r.ActorID, 10), Robust: r.RobustAddress.String(), EthAddress: parser.EthPrefix + hex.EncodeToString(r.EthAddress[:]), - ActorType: "evm", + ActorType: constants.ActorTypeEVM, CreationTxCid: msgCid.String(), } + p.helper.GetActorsCache().StoreAddressInfoAddress(*createdEvmActor) return metadata, createdEvmActor, nil } diff --git a/actors/init.go b/actors/init.go index 7ee8752b..da717312 100644 --- a/actors/init.go +++ b/actors/init.go @@ -77,6 +77,7 @@ func (p *ActorParser) parseExec(msg *parser.LotusMessage, rawReturn []byte) (map CreationTxCid: msg.Cid.String(), } metadata[parser.ReturnKey] = createdActor + p.helper.GetActorsCache().StoreAddressInfoAddress(*createdActor) return metadata, createdActor, nil } @@ -114,6 +115,7 @@ func (p *ActorParser) parseExec4(msg *parser.LotusMessage, rawReturn []byte) (ma CreationTxCid: msg.Cid.String(), } metadata[parser.ReturnKey] = createdActor + p.helper.GetActorsCache().StoreAddressInfoAddress(*createdActor) return metadata, createdActor, nil } diff --git a/actors/power.go b/actors/power.go index 06828cd1..7b8c189b 100644 --- a/actors/power.go +++ b/actors/power.go @@ -2,6 +2,7 @@ package actors import ( "bytes" + "github.com/zondax/fil-parser/actors/constants" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/builtin/v11/power" @@ -105,10 +106,11 @@ func (p *ActorParser) parseCreateMiner(msg *parser.LotusMessage, rawReturn []byt createdActor := &types.AddressInfo{ Short: r.IDAddress.String(), Robust: r.RobustAddress.String(), - ActorType: "miner", + ActorType: constants.ActorTypeMiner, CreationTxCid: msg.Cid.String(), } metadata[parser.ReturnKey] = createdActor + p.helper.GetActorsCache().StoreAddressInfoAddress(*createdActor) return metadata, createdActor, nil } diff --git a/parser/v1/parser.go b/parser/v1/parser.go index c0766211..fe665256 100644 --- a/parser/v1/parser.go +++ b/parser/v1/parser.go @@ -242,6 +242,9 @@ func (p *Parser) parseTrace(trace typesV1.ExecutionTraceV1, mainMsgCid cid.Cid, messageUuid := tools.BuildMessageId(tipsetCid, blockCid, mainMsgCid.String(), trace.Msg.Cid().String(), parentId) + txFromRobust := actors.EnsureRobustAddress(trace.Msg.From, p.helper.GetActorsCache(), p.logger) + txToRobust := actors.EnsureRobustAddress(trace.Msg.To, p.helper.GetActorsCache(), p.logger) + tx := &types.Transaction{ TxBasicBlockData: types.TxBasicBlockData{ BasicBlockData: types.BasicBlockData{ @@ -254,8 +257,8 @@ func (p *Parser) parseTrace(trace typesV1.ExecutionTraceV1, mainMsgCid cid.Cid, Id: messageUuid, TxTimestamp: parser.GetTimestamp(tipset.MinTimestamp()), TxCid: mainMsgCid.String(), - TxFrom: trace.Msg.From.String(), - TxTo: trace.Msg.To.String(), + TxFrom: txFromRobust, + TxTo: txToRobust, Amount: trace.Msg.Value.Int, Status: parser.GetExitCodeStatus(trace.MsgRct.ExitCode), TxType: txType, diff --git a/parser/v2/parser.go b/parser/v2/parser.go index 309d6ab1..0ec2b4c0 100644 --- a/parser/v2/parser.go +++ b/parser/v2/parser.go @@ -217,6 +217,8 @@ func (p *Parser) parseTrace(trace typesV2.ExecutionTraceV2, mainMsgCid cid.Cid, tipsetCid := tipset.GetCidString() messageUuid := tools.BuildMessageId(tipsetCid, blockCid, mainMsgCid.String(), msgCid, parentId) + txFromRobust := actors.EnsureRobustAddress(trace.Msg.From, p.helper.GetActorsCache(), p.logger) + txToRobust := actors.EnsureRobustAddress(trace.Msg.To, p.helper.GetActorsCache(), p.logger) tx := &types.Transaction{ TxBasicBlockData: types.TxBasicBlockData{ @@ -230,8 +232,8 @@ func (p *Parser) parseTrace(trace typesV2.ExecutionTraceV2, mainMsgCid cid.Cid, Id: messageUuid, TxTimestamp: parser.GetTimestamp(tipset.MinTimestamp()), TxCid: mainMsgCid.String(), - TxFrom: trace.Msg.From.String(), - TxTo: trace.Msg.To.String(), + TxFrom: txFromRobust, + TxTo: txToRobust, Amount: trace.Msg.Value.Int, Status: parser.GetExitCodeStatus(trace.MsgRct.ExitCode), TxType: txType,