diff --git a/actors/actor_parser.go b/actors/actor_parser.go index a0fa5ef1..a3213b1e 100644 --- a/actors/actor_parser.go +++ b/actors/actor_parser.go @@ -12,7 +12,9 @@ import ( filTypes "github.com/filecoin-project/lotus/chain/types" "github.com/ipfs/go-cid" "github.com/zondax/fil-parser/parser" + "github.com/zondax/fil-parser/parser/helper" "github.com/zondax/fil-parser/types" + "github.com/zondax/golem/pkg/logger" ) type ActorParserInterface interface { @@ -28,6 +30,10 @@ type Actor interface { Methods(ctx context.Context, network string, height int64) (map[abi.MethodNum]nonLegacyBuiltin.MethodMeta, error) } +// MethodNameFn is a function type that resolves method names for actor methods based on their method number, +// actor type, network parameters, and other contextual information. Allows actors to use GetMethodName without an import cycle. +type MethodNameFn func(ctx context.Context, methodNum abi.MethodNum, actorName string, height int64, network string, helper *helper.Helper, logger *logger.Logger) (string, error) + func ParseSend(msg *parser.LotusMessage) map[string]interface{} { metadata := make(map[string]interface{}) metadata[parser.ParamsKey] = msg.Params diff --git a/actors/cache/actors_cache.go b/actors/cache/actors_cache.go index 5cd0ef46..760b7a1a 100644 --- a/actors/cache/actors_cache.go +++ b/actors/cache/actors_cache.go @@ -53,8 +53,10 @@ var SystemActorsId = map[string]bool{ // Check data/genesis/{network}_genesis_balances.json var GenesisActorsId = map[string]bool{ // multisig - "f080": true, - "f090": true, + "f080": true, + // keyless account actor + "f090": true, + "f0115": true, "f0116": true, "f0117": true, @@ -123,9 +125,10 @@ func (a *ActorsCache) ClearBadAddressCache() { } func (a *ActorsCache) GetActorCode(add address.Address, key filTypes.TipSetKey, onChainOnly bool) (string, error) { + addStr := add.String() // Check if this address is flagged as bad if a.isBadAddress(add) { - return "", fmt.Errorf("address %s is flagged as bad", add.String()) + return "", fmt.Errorf("address %s is flagged as bad", addStr) } if !onChainOnly { @@ -133,15 +136,15 @@ func (a *ActorsCache) GetActorCode(add address.Address, key filTypes.TipSetKey, if err == nil { return actorCode, nil } + a.logger.Debugf("[ActorsCache] - Unable to retrieve actor code from offchain cache for address %s. Trying on-chain cache", addStr) } - a.logger.Debugf("[ActorsCache] - Unable to retrieve actor code from offchain cache for address %s. Trying on-chain cache", add.String()) // Try on-chain cache actorCode, err := a.onChainCache.GetActorCode(add, key, onChainOnly) if err != nil { a.logger.Debugf("[ActorsCache] - Unable to retrieve actor code from node: %s", err.Error()) if strings.Contains(err.Error(), "actor not found") { - a.badAddress.Set(add.String(), true) + a.badAddress.Set(addStr, true) } return "", err @@ -161,18 +164,19 @@ func (a *ActorsCache) GetActorCode(add address.Address, key filTypes.TipSetKey, } func (a *ActorsCache) GetRobustAddress(add address.Address) (string, error) { + addStr := add.String() // check if the address is a system actor ( no robust address) - if _, ok := SystemActorsId[add.String()]; ok { - return add.String(), nil + if _, ok := SystemActorsId[addStr]; ok { + return addStr, nil } // check if the address is a genesis actor ( no robust address) - if _, ok := GenesisActorsId[add.String()]; ok { - return add.String(), nil + if _, ok := GenesisActorsId[addStr]; ok { + return addStr, nil } // check if the address is a calibration genesis actor ( no robust address) if tools.ParseRawNetworkName(a.networkName) == tools.CalibrationNetwork { - if _, ok := CalibrationActorsId[add.String()]; ok { - return add.String(), nil + if _, ok := CalibrationActorsId[addStr]; ok { + return addStr, nil } } @@ -184,10 +188,10 @@ func (a *ActorsCache) GetRobustAddress(add address.Address) (string, error) { // Check if this is a flagged address if a.isBadAddress(add) { - return "", fmt.Errorf("address %s is flagged as bad", add.String()) + return "", fmt.Errorf("address %s is flagged as bad", addStr) } - a.logger.Debugf("[ActorsCache] - Unable to retrieve robust address from offchain cache for address %s. Trying on-chain cache", add.String()) + a.logger.Debugf("[ActorsCache] - Unable to retrieve robust address from offchain cache for address %s. Trying on-chain cache", addStr) // Try on-chain cache robust, err = a.onChainCache.GetRobustAddress(add) @@ -210,6 +214,7 @@ func (a *ActorsCache) GetRobustAddress(add address.Address) (string, error) { } func (a *ActorsCache) GetShortAddress(add address.Address) (string, error) { + addStr := add.String() // Try kv store cache short, err := a.offChainCache.GetShortAddress(add) if err == nil { @@ -218,10 +223,10 @@ func (a *ActorsCache) GetShortAddress(add address.Address) (string, error) { // Check if this is a flagged address if a.isBadAddress(add) { - return "", fmt.Errorf("address %s is flagged as bad", add.String()) + return "", fmt.Errorf("address %s is flagged as bad", addStr) } - a.logger.Debugf("[ActorsCache] - Unable to retrieve short address from offchain cache for address %s. Trying on-chain cache", add.String()) + a.logger.Debugf("[ActorsCache] - Unable to retrieve short address from offchain cache for address %s. Trying on-chain cache", addStr) // Try on-chain cache short, err = a.onChainCache.GetShortAddress(add) diff --git a/actors/v2/actors.go b/actors/v2/actors.go index 4e909e79..b3de4284 100644 --- a/actors/v2/actors.go +++ b/actors/v2/actors.go @@ -72,7 +72,7 @@ func (p *ActorParser) LatestSupportedVersion(actor string) (uint64, error) { func (p *ActorParser) GetActor(actor string) (Actor, error) { if strings.Contains(actor, manifest.MultisigKey) { - return multisig.New(p.helper, p.logger, p.metrics), nil + return multisig.New(p.helper, p.logger, p.metrics, GetMethodName), nil } return internal.GetActor(actor, p.logger, p.helper, p.metrics) diff --git a/actors/v2/init/init.go b/actors/v2/init/init.go index e52c395e..52fc6b39 100644 --- a/actors/v2/init/init.go +++ b/actors/v2/init/init.go @@ -119,7 +119,7 @@ func (i *Init) Exec(network string, height int64, msg *parser.LotusMessage, raw createdActorCid, createdActorName, err := i.getActorDetailsFromAddress(height, version.FilNetworkVersion(), addressInfo) if err == nil { addressInfo.ActorCid = createdActorCid.String() - addressInfo.ActorType = parseExecActor(createdActorName) + addressInfo.ActorType = tools.ParseActorName(createdActorName) // Store the address info in the actors cache // if an actor is created and it's Constructor is called in the next execution, // we will not be able to get the actor type without this. @@ -147,7 +147,7 @@ func (i *Init) Exec4(network string, height int64, msg *parser.LotusMessage, raw createdActorCid, createdActorName, err := i.getActorDetailsFromAddress(height, version.FilNetworkVersion(), addressInfo) if err == nil { addressInfo.ActorCid = createdActorCid.String() - addressInfo.ActorType = parseExecActor(createdActorName) + addressInfo.ActorType = tools.ParseActorName(createdActorName) } } diff --git a/actors/v2/init/utils.go b/actors/v2/init/utils.go index 2c7cb698..aa45a3fd 100644 --- a/actors/v2/init/utils.go +++ b/actors/v2/init/utils.go @@ -3,7 +3,6 @@ package init import ( "encoding/base64" "fmt" - "strings" "github.com/filecoin-project/go-address" builtinInitv10 "github.com/filecoin-project/go-state-types/builtin/v10/init" @@ -163,11 +162,3 @@ func setReturnParams(msg *parser.LotusMessage, actorCID string, params typegen.C return &types.AddressInfo{} } - -func parseExecActor(actor string) string { - s := strings.Split(actor, "/") - if len(s) < 1 { - return actor - } - return s[len(s)-1] -} diff --git a/actors/v2/multisig/multisig.go b/actors/v2/multisig/multisig.go index fd1770be..2257d6c3 100644 --- a/actors/v2/multisig/multisig.go +++ b/actors/v2/multisig/multisig.go @@ -3,6 +3,7 @@ package multisig import ( "bytes" "encoding/hex" + "encoding/json" "fmt" "github.com/filecoin-project/go-address" @@ -66,8 +67,9 @@ func (m *Msig) Propose(network string, msg *parser.LotusMessage, height int64, p params := innerParams // get ParamsKey for innerParams if possible if innerParams != nil && innerParams[parser.ParamsKey] != nil { - if inner, ok := innerParams[parser.ParamsKey].(map[string]any); ok { - params = inner + params, err = m.paramsToMap(innerParams[parser.ParamsKey]) + if err != nil { + return nil, err } } @@ -93,6 +95,27 @@ func (m *Msig) Propose(network string, msg *parser.LotusMessage, height int64, p return metadata, nil } +func (*Msig) paramsToMap(params any) (map[string]any, error) { + dataAsMap := make(map[string]any) + + tmp, err := json.Marshal(params) + if err != nil { + return nil, err + } + + err = json.Unmarshal(tmp, &dataAsMap) + if err != nil { + var dataAsAny any + err = json.Unmarshal(tmp, &dataAsAny) + if err != nil { + return nil, err + } + dataAsMap[parser.ValueKey] = dataAsAny + } + + return dataAsMap, nil +} + func (*Msig) RemoveSigner(network string, msg *parser.LotusMessage, height int64, key filTypes.TipSetKey, rawParams []byte) (map[string]interface{}, error) { version := tools.VersionFromHeight(network, height) params, ok := removeSignerParams2[version.String()] diff --git a/actors/v2/multisig/parse.go b/actors/v2/multisig/parse.go index ce4abef0..ab0547f7 100644 --- a/actors/v2/multisig/parse.go +++ b/actors/v2/multisig/parse.go @@ -41,16 +41,19 @@ type Msig struct { miner *miner.Miner verifreg *verifiedRegistry.VerifiedRegistry evm *evm.Evm + + methodNameFn actors.MethodNameFn } -func New(helper *helper.Helper, logger *logger.Logger, metrics *metrics.ActorsMetricsClient) *Msig { +func New(helper *helper.Helper, logger *logger.Logger, metrics *metrics.ActorsMetricsClient, methodNameFn actors.MethodNameFn) *Msig { return &Msig{ - helper: helper, - logger: logger, - metrics: metrics, - miner: miner.New(logger), - verifreg: verifiedRegistry.New(logger), - evm: evm.New(logger, metrics), + helper: helper, + logger: logger, + metrics: metrics, + miner: miner.New(logger), + verifreg: verifiedRegistry.New(logger), + evm: evm.New(logger, metrics), + methodNameFn: methodNameFn, } } diff --git a/actors/v2/multisig/propose.go b/actors/v2/multisig/propose.go index 0e160a05..d616abe3 100644 --- a/actors/v2/multisig/propose.go +++ b/actors/v2/multisig/propose.go @@ -2,12 +2,11 @@ package multisig import ( "context" - "fmt" - - "github.com/filecoin-project/go-state-types/manifest" + "strings" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/exitcode" + "github.com/filecoin-project/go-state-types/manifest" "github.com/zondax/fil-parser/actors/v2/internal" "github.com/filecoin-project/go-state-types/abi" @@ -48,9 +47,7 @@ func (m *Msig) innerProposeParams( // innerProposeMethod determines the actor and method name for a multisig proposal by: // 1. Getting the actor name from the target address -// 2. Getting the appropriate actor implementation -// 3. Checking for common methods -// 4. Looking up the method name in the actor's method list +// 2. Using the methodNameFn to get the methodName from the methodNum for the actor. func (m *Msig) innerProposeMethod( msg *parser.LotusMessage, network string, height int64, key filTypes.TipSetKey, ) (actors.Actor, string, error) { @@ -59,31 +56,18 @@ func (m *Msig) innerProposeMethod( return nil, "", err } var actor actors.Actor - actor = m - if actorName != manifest.MultisigKey { + if strings.Contains(actorName, manifest.MultisigKey) { + actor = m + } else { actor, err = internal.GetActor(actorName, m.logger, m.helper, m.metrics) if err != nil { return nil, "", err } } - method, err := m.helper.CheckCommonMethods(msg, height, key) + methodName, err := m.methodNameFn(context.Background(), msg.Method, actorName, height, network, m.helper, m.logger) if err != nil { return nil, "", err } - if method != "" { - return actor, method, nil - } - - actorMethods, err := actor.Methods(context.Background(), network, height) - if err != nil { - return nil, "", err - } - - proposeMethod, ok := actorMethods[msg.Method] - if !ok { - return nil, "", fmt.Errorf("unrecognized propose method: %s for actor %s", method, actorName) - } - - return actor, proposeMethod.Name, nil + return actor, methodName, nil } diff --git a/actors/v2/tools.go b/actors/v2/tools.go index f698e48f..7e52e20c 100644 --- a/actors/v2/tools.go +++ b/actors/v2/tools.go @@ -19,6 +19,16 @@ import ( ) func GetMethodName(ctx context.Context, methodNum abi.MethodNum, actorName string, height int64, network string, helper *helper.Helper, logger *logger.Logger) (string, error) { + // Shortcut 1 - Method "0" corresponds to "MethodSend" + if methodNum == 0 { + return parser.MethodSend, nil + } + + // Shortcut 2 - Method "1" corresponds to "MethodConstructor" + if methodNum == 1 { + return parser.MethodConstructor, nil + } + actorMethods, err := ActorMethods(ctx, actorName, height, network, helper, logger) if err != nil { return "", err diff --git a/data/genesis/mainnet_genesis_multisig_info.json b/data/genesis/mainnet_genesis_multisig_info.json index c093b105..53cdb64d 100644 --- a/data/genesis/mainnet_genesis_multisig_info.json +++ b/data/genesis/mainnet_genesis_multisig_info.json @@ -1,83 +1,92 @@ [ { - "id": "fb888252-136e-51c6-857d-8c50150c300e", - "multisig_address": "f0117", - "height": 0, - "tx_cid": "", - "action_type": "Constructor", - "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", - "signer": "" + "id": "481d7634-133a-53d9-a016-2f41964eac06", + "multisig_address": "f090", + "height": 0, + "tx_cid": "", + "action_type": "Constructor", + "value": "{\"NumApprovalsThreshold\":1,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\"],\"StartEpoch\":0,\"UnlockDuration\":0}", + "signer": "" }, { - "id": "ea5a612d-c31a-5a0e-be5e-f461bdf36c26", - "multisig_address": "f0121", - "height": 0, - "tx_cid": "", - "action_type": "Constructor", - "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", - "signer": "" + "id": "fb888252-136e-51c6-857d-8c50150c300e", + "multisig_address": "f0117", + "height": 0, + "tx_cid": "", + "action_type": "Constructor", + "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", + "signer": "" }, { - "id": "399e39c0-0bf6-5728-947d-48079acd5fac", - "multisig_address": "f0118", - "height": 0, - "tx_cid": "", - "action_type": "Constructor", - "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", - "signer": "" + "id": "ea5a612d-c31a-5a0e-be5e-f461bdf36c26", + "multisig_address": "f0121", + "height": 0, + "tx_cid": "", + "action_type": "Constructor", + "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", + "signer": "" }, { - "id": "98ae0f34-727b-52da-afec-ee335e86af80", - "multisig_address": "f0120", - "height": 0, - "tx_cid": "", - "action_type": "Constructor", - "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", - "signer": "" + "id": "399e39c0-0bf6-5728-947d-48079acd5fac", + "multisig_address": "f0118", + "height": 0, + "tx_cid": "", + "action_type": "Constructor", + "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", + "signer": "" }, { - "id": "add41b4f-5786-5d38-b030-6fcc012883ff", - "multisig_address": "f0122", - "height": 0, - "tx_cid": "", - "action_type": "Constructor", - "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":0}", - "signer": "" + "id": "98ae0f34-727b-52da-afec-ee335e86af80", + "multisig_address": "f0120", + "height": 0, + "tx_cid": "", + "action_type": "Constructor", + "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", + "signer": "" }, { - "id": "1a50f298-5377-5601-ac65-9050e1320393", - "multisig_address": "f0116", - "height": 0, - "tx_cid": "", - "action_type": "Constructor", - "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", - "signer": "" + "id": "add41b4f-5786-5d38-b030-6fcc012883ff", + "multisig_address": "f0122", + "height": 0, + "tx_cid": "", + "action_type": "Constructor", + "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":0}", + "signer": "" }, { - "id": "01ce6cda-468e-5a66-b8fb-e0e13a00022f", - "multisig_address": "f080", - "height": 0, - "tx_cid": "", - "action_type": "Constructor", - "value": "{\"NumApprovalsThreshold\":1,\"Signers\":[\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\"],\"StartEpoch\":0,\"UnlockDuration\":0}", - "signer": "" + "id": "1a50f298-5377-5601-ac65-9050e1320393", + "multisig_address": "f0116", + "height": 0, + "tx_cid": "", + "action_type": "Constructor", + "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", + "signer": "" }, { - "id": "03e1a31b-cc54-5fe9-b966-f3be9b3e3791", - "multisig_address": "f0115", - "height": 0, - "tx_cid": "", - "action_type": "Constructor", - "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", - "signer": "" + "id": "01ce6cda-468e-5a66-b8fb-e0e13a00022f", + "multisig_address": "f080", + "height": 0, + "tx_cid": "", + "action_type": "Constructor", + "value": "{\"NumApprovalsThreshold\":1,\"Signers\":[\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\"],\"StartEpoch\":0,\"UnlockDuration\":0}", + "signer": "" }, { - "id": "1248576d-9317-58aa-b7c7-857d57f085f3", - "multisig_address": "f0119", - "height": 0, - "tx_cid": "", - "action_type": "Constructor", - "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", - "signer": "" + "id": "03e1a31b-cc54-5fe9-b966-f3be9b3e3791", + "multisig_address": "f0115", + "height": 0, + "tx_cid": "", + "action_type": "Constructor", + "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", + "signer": "" + }, + { + "id": "1248576d-9317-58aa-b7c7-857d57f085f3", + "multisig_address": "f0119", + "height": 0, + "tx_cid": "", + "action_type": "Constructor", + "value": "{\"NumApprovalsThreshold\":3,\"Signers\":[\"f1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy\",\"f1meqrx2ijvgrdquybafmlwgszpmc34b3kg3nohvy\",\"f1ovvm6oilbdsvbw27jhil3pcywrjuwiv5uzagq6i\",\"f1cadxk4yywa7hfaiz3rs23t3wmyn7cjcdy5rtm4q\",\"f3udf6vhs3xj7broosspzwjpbldee77qnrtzytpqrz2h6lfnx7sp3xwe3nn6lpg5eylpp3f7nmrqclt4zmd42a\",\"f3thj7rtskyyvqw2i4v6xg6x32rgaf5pqpkgzcdreuapfl4revnez62geu4ens2aarapuppsmok5af3rzmtgua\",\"f1t3atfumgpjhismj7pp3x63gpevxrsz4y2hgc4ci\"],\"StartEpoch\":0,\"UnlockDuration\":6307200}", + "signer": "" } -] \ No newline at end of file + ] \ No newline at end of file diff --git a/factory.go b/factory.go index 1586c037..3a84d8d9 100644 --- a/factory.go +++ b/factory.go @@ -407,15 +407,7 @@ func getAddressInfo(addrStr string, tipsetKey types2.TipSetKey, helper *helper2. Short: shortAdd, Robust: robustAdd, ActorCid: actorCode, - ActorType: parseActor(actorName), + ActorType: tools.ParseActorName(actorName), IsSystemActor: helper.IsSystemActor(filAdd) || helper.IsGenesisActor(filAdd), }, nil } - -func parseActor(actor string) string { - s := strings.Split(actor, "/") - if len(s) < 1 { - return actor - } - return s[len(s)-1] -} diff --git a/go.mod b/go.mod index ee42d0dd..742bd3dd 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 github.com/filecoin-project/go-address v1.2.0 github.com/filecoin-project/go-bitfield v0.2.4 - github.com/filecoin-project/go-f3 v0.8.3 + github.com/filecoin-project/go-f3 v0.8.4 github.com/filecoin-project/go-state-types v0.16.0 github.com/filecoin-project/lotus v1.32.2 github.com/filecoin-project/specs-actors v0.9.15 @@ -21,7 +21,7 @@ require ( github.com/spf13/cobra v1.9.1 github.com/stretchr/testify v1.10.0 github.com/whyrusleeping/cbor-gen v0.3.1 - github.com/zondax/golem v0.21.1 + github.com/zondax/golem v0.22.0 github.com/zondax/rosetta-filecoin-lib v1.3202.1 ) @@ -158,7 +158,7 @@ require ( github.com/spf13/afero v1.14.0 // indirect github.com/spf13/cast v1.7.1 // indirect github.com/spf13/pflag v1.0.6 // indirect - github.com/spf13/viper v1.20.0 // indirect + github.com/spf13/viper v1.20.1 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tklauser/numcpus v0.10.0 // indirect @@ -169,15 +169,15 @@ require ( go.opentelemetry.io/otel/trace v1.35.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect - golang.org/x/crypto v0.36.0 // indirect + golang.org/x/crypto v0.37.0 // indirect golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac golang.org/x/mod v0.24.0 - golang.org/x/net v0.38.0 // indirect - golang.org/x/sync v0.13.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sync v0.14.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da - google.golang.org/protobuf v1.36.5 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index 957878bf..1698e9b3 100644 --- a/go.sum +++ b/go.sum @@ -124,8 +124,8 @@ github.com/filecoin-project/go-commp-utils/v2 v2.1.0/go.mod h1:NbxJYlhxtWaNhlVCj github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-crypto v0.1.0 h1:Pob2MphoipMbe/ksxZOMcQvmBHAd3sI/WEqcbpIsGI0= github.com/filecoin-project/go-crypto v0.1.0/go.mod h1:K9UFXvvoyAVvB+0Le7oGlKiT9mgA5FHOJdYQXEE8IhI= -github.com/filecoin-project/go-f3 v0.8.3 h1:0ToWoqJDsunr+Jf945Upvk6rdXn8It5B5LcyiY1Ry1k= -github.com/filecoin-project/go-f3 v0.8.3/go.mod h1:KWksfw7CabMuL4ple/J52gK4soYBpTsL6i5WAgtJDqw= +github.com/filecoin-project/go-f3 v0.8.4 h1:qbdsiMYPWkM2zR/8oFDl4VvHm2YTF7xnr5m/smYKanA= +github.com/filecoin-project/go-f3 v0.8.4/go.mod h1:k23EMAx090NIWKlAYuO4TfjmfQTlIovaQ0nns960s9M= github.com/filecoin-project/go-fil-commcid v0.2.0 h1:B+5UX8XGgdg/XsdUpST4pEBviKkFOw+Fvl2bLhSKGpI= github.com/filecoin-project/go-fil-commcid v0.2.0/go.mod h1:8yigf3JDIil+/WpqR5zoKyP0jBPCOGtEqq/K1CcMy9Q= github.com/filecoin-project/go-fil-commp-hashhash v0.2.0 h1:HYIUugzjq78YvV3vC6rL95+SfC/aSTVSnZSZiDV5pCk= @@ -734,8 +734,8 @@ github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.20.0 h1:zrxIyR3RQIOsarIrgL8+sAvALXul9jeEPa06Y0Ph6vY= -github.com/spf13/viper v1.20.0/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= +github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= +github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -811,8 +811,8 @@ github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zondax/golem v0.21.1 h1:w4vbokuO9qdjRtpy7dpiJwn60Bt6QG9s3ah6LrrHtFc= -github.com/zondax/golem v0.21.1/go.mod h1:vJQwxaOn5swyz8BtGjJUxMqlXlkiq4tjUGp5xRvePwk= +github.com/zondax/golem v0.22.0 h1:0oviYDtvrys5TH4VnS+iKuhJ3rq+1qY1PfM5wNnezDY= +github.com/zondax/golem v0.22.0/go.mod h1:kAYSy2vLTRv38+48WcGnNAUGPzJbDC5lrRSLFV4SlQ8= github.com/zondax/rosetta-filecoin-lib v1.3202.1 h1:pzaCoerToVaxaeUNJlP/MI+VxlrxX1+obDrUWGSUAbA= github.com/zondax/rosetta-filecoin-lib v1.3202.1/go.mod h1:o/pFk+DvYKB9J0GqpmQuGrh9LYWm2ImUNHEqtxFo+8s= gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRySiX3drau9C6Q5CAbNIApmLdat5jPMqChvDA= @@ -870,8 +870,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac h1:l5+whBCLH3iH2ZNHYLbAe58bo7yrN4mVcnkHDYz5vvs= golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac/go.mod h1:hH+7mtFmImwwcMvScyxUhjuVHR3HGaDPMn9rMSUUbxo= @@ -907,8 +907,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -918,8 +918,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -946,8 +946,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -960,8 +960,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1011,8 +1011,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/parser/config.go b/parser/config.go index 01639520..63a41e3d 100644 --- a/parser/config.go +++ b/parser/config.go @@ -8,4 +8,6 @@ type Config struct { NodeMaxWaitBeforeRetrySeconds int64 // linear, exponential default: linear NodeRetryStrategy string + // Height at which to start translating txcids to txhashes + TxCidTranslationStart int64 } diff --git a/parser/constants.go b/parser/constants.go index 79d14855..0e770861 100644 --- a/parser/constants.go +++ b/parser/constants.go @@ -13,6 +13,7 @@ const ( FilPrefix = "f0" // metadata keys + ValueKey = "Value" ParamsKey = "Params" ReturnKey = "Return" ParamsRawKey = "ParamsRaw" diff --git a/parser/helper/helpers.go b/parser/helper/helpers.go index bd3817bb..43cc1ace 100644 --- a/parser/helper/helpers.go +++ b/parser/helper/helpers.go @@ -49,7 +49,18 @@ import ( "github.com/zondax/fil-parser/types" ) -// Deprecated: Use v2/tools.ActorMethods instead +const ( + // keylessAccountActor f090 was a multisig actor until V23 where it was converted to an account actor + // https://github.com/filecoin-project/lotus/releases/tag/v1.28.1 + // https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0085.md + keylessAccountActor = "f090" + // multisig actorcode for nv22 + msigCidStr = "bafk2bzacedef4sqdsfebspu7dqnk7naj27ac4lyho4zmvjrei5qnf2wn6v64u" + // account actorcode for nv23 + accountCidStr = "bafk2bzacedbgei6jkx36fwdgvoohce4aghvpohqdhoco7p4thszgssms7olv2" +) + +// Deprecated: Use v2/tools.GetMethodName instead var allMethods = map[string]map[abi.MethodNum]builtin.MethodMeta{ manifest.InitKey: filInit.Methods, manifest.CronKey: cron.Methods, @@ -72,6 +83,49 @@ var allMethods = map[string]map[abi.MethodNum]builtin.MethodMeta{ manifest.EthAccountKey: evm.Methods, } +var ( + msigCid = cid.MustParse(msigCidStr) + accountCid = cid.MustParse(accountCidStr) + + // specialLegacyActors is a list of actors not included in the lotus manifest but appear on the network. + // StateGetActor(f067253) returns "bafkqadlgnfwc6mrpmfrwg33vnz2a" which is not included in the Lotus Manifest along with the following actor cids. + // https://github.com/filecoin-project/statediff/blob/3e676285574e7bdb4ae0b9e28e6f23cfc86dd089/transform.go#L164 + specialLegacyActors = map[string]string{ + // v1 + "bafkqaddgnfwc6mjpon4xg5dfnu": manifest.SystemKey, + "bafkqactgnfwc6mjpnfxgs5a": manifest.InitKey, + "bafkqaddgnfwc6mjpojsxoylsmq": manifest.RewardKey, + "bafkqactgnfwc6mjpmnzg63q": manifest.CronKey, + "bafkqaetgnfwc6mjpon2g64tbm5sxa33xmvza": manifest.PowerKey, + "bafkqae3gnfwc6mjpon2g64tbm5sw2ylsnnsxi": manifest.MarketKey, + "bafkqaftgnfwc6mjpozsxe2lgnfswi4tfm5uxg5dspe": manifest.VerifregKey, + "bafkqadlgnfwc6mjpmfrwg33vnz2a": manifest.AccountKey, + "bafkqadtgnfwc6mjpnv2wy5djonuwo": manifest.MultisigKey, + "bafkqafdgnfwc6mjpobqxs3lfnz2gg2dbnzxgk3a": manifest.PaychKey, + "bafkqaetgnfwc6mjpon2g64tbm5sw22lomvza": manifest.MinerKey, + + // v2 + "bafkqaddgnfwc6mrpon4xg5dfnu": manifest.SystemKey, + "bafkqactgnfwc6mrpnfxgs5a": manifest.InitKey, + "bafkqaddgnfwc6mrpojsxoylsmq": manifest.RewardKey, + "bafkqactgnfwc6mrpmnzg63q": manifest.CronKey, + "bafkqaetgnfwc6mrpon2g64tbm5sxa33xmvza": manifest.PowerKey, + "bafkqae3gnfwc6mrpon2g64tbm5sw2ylsnnsxi": manifest.MarketKey, + "bafkqaftgnfwc6mrpozsxe2lgnfswi4tfm5uxg5dspe": manifest.VerifregKey, + "bafkqadlgnfwc6mrpmfrwg33vnz2a": manifest.AccountKey, + "bafkqadtgnfwc6mrpnv2wy5djonuwo": manifest.MultisigKey, + "bafkqafdgnfwc6mrpobqxs3lfnz2gg2dbnzxgk3a": manifest.PaychKey, + "bafkqaetgnfwc6mrpon2g64tbm5sw22lomvza": manifest.MinerKey, + } + + // https://github.com/filecoin-project/lotus/blob/58c1ed844b2424a66008728e4c135fa2f6097b60/build/builtin_actors.go#L59 + calibrationBuggyActors = map[string]string{ + "bafk2bzacecnh2ouohmonvebq7uughh4h3ppmg4cjsk74dzxlbbtlcij4xbzxq": manifest.MinerKey, + "bafk2bzaced7emkbbnrewv5uvrokxpf5tlm4jslu2jsv77ofw2yqdglg657uie": manifest.MinerKey, + "bafk2bzacednskl3bykz5qpo54z2j2p4q44t5of4ktd6vs6ymmg2zebsbxazkm": manifest.VerifregKey, + } +) + type Helper struct { lib *rosettaFilecoinLib.RosettaConstructionFilecoin node api.FullNode @@ -118,16 +172,12 @@ func (h *Helper) GetActorAddressInfo(add address.Address, key filTypes.TipSetKey return addInfo } - version := tools.VersionFromHeight(h.network, int64(height)) - addInfo.ActorCid, err = h.actorCache.GetActorCode(add, key, false) + actorCid, actorName, err := h.GetActorNameFromAddress(add, int64(height), key) if err != nil { - h.logger.Errorf("could not get actor code from address. Err: %s", err) + h.logger.Errorf("could not get actor cid and name from address. Err: %s", err) } else { - c, err := cid.Parse(addInfo.ActorCid) - if err != nil { - h.logger.Errorf("Could not parse params. Cannot cid.parse actor code: %v", err) - } - addInfo.ActorType, _ = h.lib.BuiltinActors.GetActorNameFromCidByVersion(c, version.FilNetworkVersion()) + addInfo.ActorCid = actorCid.String() + addInfo.ActorType = actorName } addInfo.Short, err = h.actorCache.GetShortAddress(add) @@ -149,6 +199,12 @@ func (h *Helper) GetActorNameFromAddress(add address.Address, height int64, key if add == address.Undef { return cid.Undef, "", errors.New("address is undefined") } + // The f090 address was a multisig actor until V23 where it was converted to an account actor + // https://github.com/filecoin-project/lotus/releases/tag/v1.28.1 + // https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0085.md + if ok, cid, actorName := h.isKeylessAccountActor(add, height); ok { + return cid, actorName, nil + } onChainOnly := false for { @@ -177,12 +233,36 @@ func (h *Helper) GetActorNameFromAddress(add address.Address, height int64, key } } +// The f090 address was a multisig actor until V23 where it was converted to an account actor +// https://github.com/filecoin-project/lotus/releases/tag/v1.28.1 +// https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0085.md +func (h *Helper) isKeylessAccountActor(add address.Address, height int64) (bool, cid.Cid, string) { + if h.network != tools.MainnetNetwork || add.String() != keylessAccountActor { + return false, cid.Undef, "" + } + version := tools.VersionFromHeight(h.network, int64(height)) + if version.NodeVersion() < tools.V23.NodeVersion() { + return true, msigCid, manifest.MultisigKey + } + return true, accountCid, manifest.AccountKey +} + +// GetActorNameFromCid returns the actor name for the given cid and height from rosetta and fallsback to specialLegacyActors. func (h *Helper) GetActorNameFromCid(cid cid.Cid, height int64) (string, error) { version := tools.VersionFromHeight(h.network, height) actorName, err := h.lib.BuiltinActors.GetActorNameFromCidByVersion(cid, version.FilNetworkVersion()) if err != nil { + // fallback to specialLegacyActors + if name, ok := specialLegacyActors[cid.String()]; ok && h.network == tools.MainnetNetwork { + return name, nil + } + // fallback to calibrationBuggyActors + if name, ok := calibrationBuggyActors[cid.String()]; ok && h.network == tools.CalibrationNetwork { + return name, nil + } return "", err } + return actorName, nil } @@ -220,6 +300,7 @@ func (h *Helper) GetMethodName(msg *parser.LotusMessage, height int64, key filTy return method.Name, nil } +// Deprecated: Use v2/tools.GetMethodName instead // CheckCommonMethods returns the method name for the given message if Send Or Constructor, otherwise returns an empty string func (h *Helper) CheckCommonMethods(msg *parser.LotusMessage, height int64, key filTypes.TipSetKey) (string, error) { if msg == nil { @@ -303,7 +384,7 @@ func (h *Helper) isAnyAddressOfType(_ context.Context, addresses []address.Addre if err != nil { return false, err } - if strings.EqualFold(actorName, actorType) { + if strings.Contains(actorName, actorType) { return true, nil } } diff --git a/parser/v1/parser.go b/parser/v1/parser.go index ecb96025..d92d409c 100644 --- a/parser/v1/parser.go +++ b/parser/v1/parser.go @@ -200,13 +200,15 @@ func (p *Parser) ParseTransactions(ctx context.Context, txsData types.TxsData) ( } // TxCid <-> TxHash - txHash, err := parser.TranslateTxCidToTxHash(p.helper.GetFilecoinNodeClient(), trace.MsgCid, p.actorsCacheMetrics) - if err == nil && txHash != "" { - p.txCidEquivalents = append(p.txCidEquivalents, types.TxCidTranslation{TxCid: trace.MsgCid.String(), TxHash: txHash}) - } - if err != nil { - p.logger.Warnf("Error when trying to translate tx cid to tx hash: %v", err) - _ = p.metrics.UpdateTranslateTxCidToTxHashMetric() + if int64(txsData.Tipset.Height()) >= p.config.TxCidTranslationStart { + txHash, err := parser.TranslateTxCidToTxHash(p.helper.GetFilecoinNodeClient(), trace.MsgCid, p.actorsCacheMetrics) + if err == nil && txHash != "" { + p.txCidEquivalents = append(p.txCidEquivalents, types.TxCidTranslation{TxCid: trace.MsgCid.String(), TxHash: txHash}) + } + if err != nil { + p.logger.Warnf("Error when trying to translate tx cid to tx hash: %v", err) + _ = p.metrics.UpdateTranslateTxCidToTxHashMetric() + } } } @@ -515,17 +517,11 @@ func (p *Parser) getTxType(ctx context.Context, to, from address.Address, method p.logger.Errorf("Error when trying to get actor name in tx cid'%s': %v", mainMsgCid.String(), err) } - txType, err = p.helper.CheckCommonMethods(msg, int64(tipset.Height()), tipset.Key()) + txType, err = actorsV2.GetMethodName(ctx, msg.Method, actorName, int64(tipset.Height()), p.network, p.helper, p.logger) if err != nil { - return "", "", fmt.Errorf("error when trying to check common methods in tx cid'%s': %v", mainMsgCid.String(), err) + p.logger.Errorf("Error when trying to get method name in tx cid'%s' using v2: %v", mainMsgCid.String(), err) + txType = parser.UnknownStr } - if txType == "" && actorName != "" { - txType, err = actorsV2.GetMethodName(ctx, msg.Method, actorName, int64(tipset.Height()), p.network, p.helper, p.logger) - if err != nil { - p.logger.Errorf("Error when trying to get method name in tx cid'%s' using v2: %v", mainMsgCid.String(), err) - txType = parser.UnknownStr - } - } return actorName, txType, err } diff --git a/parser/v2/parser.go b/parser/v2/parser.go index 632cc266..77794699 100644 --- a/parser/v2/parser.go +++ b/parser/v2/parser.go @@ -163,13 +163,15 @@ func (p *Parser) ParseTransactions(ctx context.Context, txsData types.TxsData) ( } // TxCid <-> TxHash - txHash, err := parser.TranslateTxCidToTxHash(p.helper.GetFilecoinNodeClient(), trace.MsgCid, p.actorsCacheMetrics) - if err == nil && txHash != "" { - p.txCidEquivalents = append(p.txCidEquivalents, types.TxCidTranslation{TxCid: trace.MsgCid.String(), TxHash: txHash}) - } - if err != nil { - _ = p.metrics.UpdateTranslateTxCidToTxHashMetric() - p.logger.Warnf("Error when trying to translate tx cid to tx hash: %v", err) + if int64(txsData.Tipset.Height()) >= p.config.TxCidTranslationStart { + txHash, err := parser.TranslateTxCidToTxHash(p.helper.GetFilecoinNodeClient(), trace.MsgCid, p.actorsCacheMetrics) + if err == nil && txHash != "" { + p.txCidEquivalents = append(p.txCidEquivalents, types.TxCidTranslation{TxCid: trace.MsgCid.String(), TxHash: txHash}) + } + if err != nil { + _ = p.metrics.UpdateTranslateTxCidToTxHashMetric() + p.logger.Warnf("Error when trying to translate tx cid to tx hash: %v", err) + } } } @@ -571,16 +573,10 @@ func (p *Parser) getActorAndMethodName(ctx context.Context, trace typesV2.Execut } } - txType, err = p.helper.CheckCommonMethods(msg, int64(tipset.Height()), tipset.Key()) + txType, err = actorsV2.GetMethodName(ctx, trace.Msg.Method, actorName, int64(tipset.Height()), p.network, p.helper, p.logger) if err != nil { - return "", "", fmt.Errorf("error when trying to check common methods in tx cid'%s': %v", mainMsgCid.String(), err) + txType = parser.UnknownStr } - if actorName != "" && txType == "" { - txType, err = actorsV2.GetMethodName(ctx, trace.Msg.Method, actorName, int64(tipset.Height()), p.network, p.helper, p.logger) - if err != nil { - txType = parser.UnknownStr - } - } return actorName, txType, err } diff --git a/parser_test.go b/parser_test.go index 76e41693..bcdd69a3 100644 --- a/parser_test.go +++ b/parser_test.go @@ -1555,12 +1555,12 @@ func TestParser_MultisigEventsFromTxs(t *testing.T) { }{ { name: "multisig events height 14107", - version: v1.NodeVersionsSupported[0], + version: v2.NodeVersionsSupported[0], url: calibNextNodeUrl, height: "14107", results: expectedResults{ proposals: []types.MultisigProposal{ - {Height: 14107, MultisigAddress: "f080", ProposalID: 0, Signer: "f0103", ActionType: "Propose", TxTypeToExecute: "AddVerifier", Value: "{\"Address\":\"f1zo7ub42i3s5cutljzjuqwnltt4xxm4y4f7l5s2i\",\"Allowance\":\"100000000000000\"}"}, + {Height: 14107, MultisigAddress: "f080", ProposalID: 0, Signer: "f0103", ActionType: "Propose", TxTypeToExecute: "AddVerifier", Value: `{"Address":"f1zo7ub42i3s5cutljzjuqwnltt4xxm4y4f7l5s2i","Allowance":"100000000000000"}`}, }, multisigInfo: []types.MultisigInfo{}, }, @@ -1572,7 +1572,7 @@ func TestParser_MultisigEventsFromTxs(t *testing.T) { height: "1467665", results: expectedResults{ proposals: []types.MultisigProposal{ - {Height: 1467665, MultisigAddress: "f080", ProposalID: 11, Signer: "f018896", ActionType: "Approve", TxTypeToExecute: "", Value: "{\"ID\":11,\"ProposalHash\":\"/jgVZzOjfHFnrI5K514wyJ+WSVNtLQhthbCrDsX+Dmg=\"}"}, + {Height: 1467665, MultisigAddress: "f080", ProposalID: 11, Signer: "f018896", ActionType: "Approve", TxTypeToExecute: "", Value: `{"ID":11,"ProposalHash":"/jgVZzOjfHFnrI5K514wyJ+WSVNtLQhthbCrDsX+Dmg="}`}, }, multisigInfo: []types.MultisigInfo{}, }, @@ -1593,19 +1593,20 @@ func TestParser_MultisigEventsFromTxs(t *testing.T) { }, { name: "multisig events height 78689", - version: v1.NodeVersionsSupported[0], + version: v2.NodeVersionsSupported[0], url: calibNextNodeUrl, height: "78689", results: expectedResults{ proposals: []types.MultisigProposal{ - {Height: 78689, MultisigAddress: "f02412", ProposalID: 0, Signer: "f02252", ActionType: "Propose", TxTypeToExecute: "WithdrawBalance", Value: "{\"AmountRequested\":\"3300000000000000000\"}"}, + {Height: 78689, MultisigAddress: "f02412", ProposalID: 0, Signer: "f02252", ActionType: "Propose", TxTypeToExecute: "UniversalReceiverHook", Value: `{"Value":"gUkALcv0hA7KAAA="}`}, }, multisigInfo: []types.MultisigInfo{}, }, }, + { name: "multisig events height 47645", - version: v1.NodeVersionsSupported[0], + version: v2.NodeVersionsSupported[0], url: calibNextNodeUrl, height: "47645", results: expectedResults{ @@ -1615,21 +1616,23 @@ func TestParser_MultisigEventsFromTxs(t *testing.T) { multisigInfo: []types.MultisigInfo{}, }, }, + { name: "multisig events height 39035", - version: v1.NodeVersionsSupported[0], + version: v2.NodeVersionsSupported[0], url: calibNextNodeUrl, height: "39035", results: expectedResults{ proposals: []types.MultisigProposal{ - {Height: 39035, MultisigAddress: "f23pa4gt4jgkl55drdyzb7dscjzdfh725u45xzwsy", ProposalID: 1, Signer: "f01717", ActionType: "Propose", TxTypeToExecute: "Unknown", Value: "{\"MethodNum\":\"2\",\"Params\":{\"Method\":\"\",\"Params\":null,\"To\":\"f01174\",\"Value\":\"0\"},\"Return\":{\"Applied\":false,\"Code\":0,\"Ret\":null,\"TxnID\":1}}"}, + {Height: 39035, MultisigAddress: "f23pa4gt4jgkl55drdyzb7dscjzdfh725u45xzwsy", ProposalID: 1, Signer: "f01717", ActionType: "Propose", TxTypeToExecute: "ChangeOwnerAddress", Value: `{"Value":"f01816"}`}, }, multisigInfo: []types.MultisigInfo{}, }, }, + { name: "multisig events height 47635", - version: v1.NodeVersionsSupported[0], + version: v2.NodeVersionsSupported[0], url: calibNextNodeUrl, height: "47635", results: expectedResults{ @@ -1641,7 +1644,7 @@ func TestParser_MultisigEventsFromTxs(t *testing.T) { }, { name: "multisig events height 38940", - version: v1.NodeVersionsSupported[0], + version: v2.NodeVersionsSupported[0], url: calibNextNodeUrl, height: "38940", results: expectedResults{ @@ -1776,9 +1779,9 @@ func TestParser_MultisigEventsFromTxs(t *testing.T) { var p *FilecoinParser var err error if tt.url == nodeUrl { - p, err = NewFilecoinParser(getLib(tt.url), mainnetCacheDataSource, gLogger) + p, err = NewFilecoinParserWithActorV2(getLib(tt.url), mainnetCacheDataSource, gLogger) } else { - p, err = NewFilecoinParser(getLib(tt.url), calibNextNodeCacheDataSource, gLogger) + p, err = NewFilecoinParserWithActorV2(getLib(tt.url), calibNextNodeCacheDataSource, gLogger) } require.NoError(t, err) @@ -1813,7 +1816,8 @@ func TestParser_MultisigEventsFromTxs(t *testing.T) { assert.Equal(t, expected.Signer, events.Proposals[i].Signer, fmt.Sprintf("Mismatch in Signer at proposal index %d: expected %s, got %s", i, expected.Signer, events.Proposals[i].Signer)) assert.Equal(t, expected.ActionType, events.Proposals[i].ActionType, fmt.Sprintf("Mismatch in ActionType at proposal index %d: expected %s, got %s", i, expected.ActionType, events.Proposals[i].ActionType)) assert.Equal(t, expected.TxTypeToExecute, events.Proposals[i].TxTypeToExecute, fmt.Sprintf("Mismatch in TxTypeToExecute at proposal index %d: expected %s, got %s", i, expected.TxTypeToExecute, events.Proposals[i].TxTypeToExecute)) - assert.Equal(t, expected.Value, events.Proposals[i].Value, fmt.Sprintf("Mismatch in Value at proposal index %d: expected %s, got %s", i, expected.Value, events.Proposals[i].Value)) + compareJSONKeys(t, expected.Value, events.Proposals[i].Value) + // assert.EqualValuesf(t, expected.Value, events.Proposals[i].Value, fmt.Sprintf("Mismatch in Value at proposal index %d: expected %s, got %s", i, expected.Value, events.Proposals[i].Value)) } require.Len(t, events.MultisigInfo, len(tt.results.multisigInfo), fmt.Sprintf("Expected %d multisig info entries, but got %d", len(tt.results.multisigInfo), len(events.MultisigInfo))) @@ -1822,12 +1826,31 @@ func TestParser_MultisigEventsFromTxs(t *testing.T) { assert.Equal(t, expected.TxCid, events.MultisigInfo[i].TxCid, fmt.Sprintf("Mismatch in TxCid at multisig info index %d: expected %s, got %s", i, expected.TxCid, events.MultisigInfo[i].TxCid)) assert.Equal(t, expected.Signer, events.MultisigInfo[i].Signer, fmt.Sprintf("Mismatch in Signer at multisig info index %d: expected %s, got %s", i, expected.Signer, events.MultisigInfo[i].Signer)) assert.Equal(t, expected.ActionType, events.MultisigInfo[i].ActionType, fmt.Sprintf("Mismatch in ActionType at multisig info index %d: expected %s, got %s", i, expected.ActionType, events.MultisigInfo[i].ActionType)) - assert.Equal(t, expected.Value, events.MultisigInfo[i].Value, fmt.Sprintf("Mismatch in Value at multisig info index %d: expected %s, got %s", i, expected.Value, events.MultisigInfo[i].Value)) + compareJSONKeys(t, expected.Value, events.MultisigInfo[i].Value) + // assert.EqualValuesf(t, expected.Value, events.MultisigInfo[i].Value, fmt.Sprintf("Mismatch in Value at multisig info index %d: expected %s, got %s", i, expected.Value, events.MultisigInfo[i].Value)) } }) } } +func compareJSONKeys(t *testing.T, expected, actual string) { + expectedMap := make(map[string]any) + actualMap := make(map[string]any) + + err := json.Unmarshal([]byte(expected), &expectedMap) + require.NoError(t, err) + err = json.Unmarshal([]byte(actual), &actualMap) + require.NoError(t, err) + + for k, expectedValue := range expectedMap { + actualValue, ok := actualMap[k] + if !ok { + assert.Failf(t, "Key %s not found in actual map", k) + } + assert.EqualValuesf(t, expectedValue, actualValue, fmt.Sprintf("Mismatch in Value at key %s: expected %v, got %v", k, expectedValue, actualValue)) + } +} + func TestParseGenesis(t *testing.T) { tests := []struct { name string @@ -2083,33 +2106,14 @@ func TestParser_ActorVersionComparison(t *testing.T) { continue } - // The 'Propose' v1Params structure is being modified to maintain compatibility with the v2 format. - // In v1, the "Params" structure is flatter, while in v2, it has an additional nested level with another "Params" key. - // The code normalizes v1 to match v2's structure for comparison purposes. - if tx.TxType == parser.MethodPropose || tx.TxType == parser.MethodProposeExported { - v1Params := metadataV1[parser.ParamsKey] - v1ParamsMap, ok := v1Params.(map[string]interface{}) - if !ok { - t.Fatalf("Error casting v1 params to map[string]interface{}") - } - if v1ParamsMap[parser.ParamsKey] != nil { - v1ParamsMap[parser.ParamsKey] = v1ParamsMap[parser.ParamsKey].(map[string]interface{})[parser.ParamsKey] - } else { - v1ParamsMap[parser.ParamsKey] = map[string]interface{}{ - parser.ParamsKey: nil, - } - } - metadataV1[parser.ParamsKey] = v1ParamsMap - } - if metadataV1[parser.ParamsKey] != nil { - require.Equalf(t, metadataV1[parser.ParamsKey], metadataV2[parser.ParamsKey], fmt.Sprintf("tx_type: %s \n V1: %s \n V2: %s", tx.TxType, tx.TxMetadata, parsedResultActorV2.Txs[i].TxMetadata)) + require.EqualValuesf(t, metadataV1[parser.ParamsKey], metadataV2[parser.ParamsKey], fmt.Sprintf("tx_type: %s \n V1: %s \n V2: %s", tx.TxType, tx.TxMetadata, parsedResultActorV2.Txs[i].TxMetadata)) } if metadataV1[parser.ReturnKey] != nil { // ClaimAllocations return struct changed to support slices. // ActivateDeals metadata was fixed to parse correctly in v2. if tx.TxType != parser.MethodClaimAllocations && tx.TxType != parser.MethodActivateDeals { - require.Equalf(t, metadataV1[parser.ReturnKey], metadataV2[parser.ReturnKey], fmt.Sprintf("tx_type: %s \n V1: %s \n V2: %s", tx.TxType, tx.TxMetadata, parsedResultActorV2.Txs[i].TxMetadata)) + require.EqualValuesf(t, metadataV1[parser.ReturnKey], metadataV2[parser.ReturnKey], fmt.Sprintf("tx_type: %s \n V1: %s \n V2: %s", tx.TxType, tx.TxMetadata, parsedResultActorV2.Txs[i].TxMetadata)) } } diff --git a/tools/miner/info.go b/tools/miner/info.go index d595fafc..78db8674 100644 --- a/tools/miner/info.go +++ b/tools/miner/info.go @@ -24,6 +24,7 @@ func (eg *eventGenerator) createMinerInfo(tx *types.Transaction, tipsetCid, acto TxCid: tx.TxCid, ActionType: tx.TxType, Value: tx.TxMetadata, + TxTimestamp: tx.TxTimestamp, } return minerInfo, nil @@ -51,5 +52,6 @@ func (eg *eventGenerator) parseAwardBlockReward(tx *types.Transaction, tipsetCid TxCid: tx.TxCid, ActionType: tx.TxType, Value: tx.TxMetadata, + TxTimestamp: tx.TxTimestamp, }, nil } diff --git a/tools/miner/sector.go b/tools/miner/sector.go index 5f6891eb..b18364f8 100644 --- a/tools/miner/sector.go +++ b/tools/miner/sector.go @@ -132,15 +132,7 @@ func (eg *eventGenerator) parsePreCommitStage(_ context.Context, tx *types.Trans if err != nil { return fmt.Errorf("error marshaling event: %w", err) } - sectorEvents = append(sectorEvents, &types.MinerSectorEvent{ - ID: tools.BuildId(tipsetCid, tx.TxCid, tx.TxFrom, tx.TxTo, fmt.Sprint(tx.Height), tx.TxType), - TxCid: tx.TxCid, - Height: tx.Height, - ActionType: tx.TxType, - MinerAddress: tx.TxTo, - SectorNumber: sectorNumber, - Data: string(jsonData), - }) + sectorEvents = append(sectorEvents, createSectorEvent(tipsetCid, tx, sectorNumber, jsonData)) return nil } @@ -180,15 +172,7 @@ func (eg *eventGenerator) parseProveCommitStage(ctx context.Context, tx *types.T if err != nil { return nil, fmt.Errorf("error marshaling event: %w", err) } - sectorEvents = append(sectorEvents, &types.MinerSectorEvent{ - ID: tools.BuildId(tipsetCid, tx.TxCid, tx.TxFrom, tx.TxTo, fmt.Sprint(tx.Height), tx.TxType), - MinerAddress: tx.TxTo, - SectorNumber: sectorNumber, - Height: tx.Height, - TxCid: tx.TxCid, - ActionType: tx.TxType, - Data: string(jsonData), - }) + sectorEvents = append(sectorEvents, createSectorEvent(tipsetCid, tx, sectorNumber, jsonData)) return sectorEvents, nil case parser.MethodProveCommitAggregate: @@ -235,15 +219,7 @@ func (eg *eventGenerator) parseSectorTerminationFaultAndRecoveries(_ context.Con return nil, fmt.Errorf("error marshaling event: %w", err) } for _, sectorNumber := range sectorNumbers { - sectorEvents = append(sectorEvents, &types.MinerSectorEvent{ - ID: tools.BuildId(tipsetCid, tx.TxCid, tx.TxFrom, tx.TxTo, fmt.Sprint(tx.Height), tx.TxType), - MinerAddress: tx.TxTo, - SectorNumber: uint64(sectorNumber), - Height: tx.Height, - TxCid: tx.TxCid, - ActionType: tx.TxType, - Data: string(jsonData), - }) + sectorEvents = append(sectorEvents, createSectorEvent(tipsetCid, tx, sectorNumber, jsonData)) } } return sectorEvents, nil @@ -278,15 +254,7 @@ func (eg *eventGenerator) parseSectorExpiryExtensions(_ context.Context, tx *typ return nil, fmt.Errorf("error marshaling event: %w", err) } for _, sectorNumber := range sectorNumbers { - sectorEvents = append(sectorEvents, &types.MinerSectorEvent{ - ID: tools.BuildId(tipsetCid, tx.TxCid, tx.TxFrom, tx.TxTo, fmt.Sprint(tx.Height), tx.TxType), - MinerAddress: tx.TxTo, - SectorNumber: uint64(sectorNumber), - Height: tx.Height, - TxCid: tx.TxCid, - ActionType: tx.TxType, - Data: string(jsonData), - }) + sectorEvents = append(sectorEvents, createSectorEvent(tipsetCid, tx, sectorNumber, jsonData)) } } return sectorEvents, nil @@ -307,15 +275,7 @@ func (eg *eventGenerator) parseProveCommitSectorsNI(_ context.Context, tx *types if err != nil { return nil, fmt.Errorf("error marshaling event: %w", err) } - sectorEvents = append(sectorEvents, &types.MinerSectorEvent{ - ID: tools.BuildId(tipsetCid, tx.TxCid, tx.TxFrom, tx.TxTo, fmt.Sprint(tx.Height), tx.TxType), - MinerAddress: tx.TxTo, - SectorNumber: sectorNumber, - Height: tx.Height, - TxCid: tx.TxCid, - ActionType: tx.TxType, - Data: string(jsonData), - }) + sectorEvents = append(sectorEvents, createSectorEvent(tipsetCid, tx, sectorNumber, jsonData)) } return sectorEvents, nil } @@ -335,15 +295,7 @@ func (eg *eventGenerator) parseProveCommitSectors3(_ context.Context, tx *types. if err != nil { return nil, fmt.Errorf("error marshaling event: %w", err) } - sectorEvents = append(sectorEvents, &types.MinerSectorEvent{ - ID: tools.BuildId(tipsetCid, tx.TxCid, tx.TxFrom, tx.TxTo, fmt.Sprint(tx.Height), tx.TxType), - MinerAddress: tx.TxTo, - SectorNumber: sectorNumber, - Height: tx.Height, - TxCid: tx.TxCid, - ActionType: tx.TxType, - Data: string(jsonData), - }) + sectorEvents = append(sectorEvents, createSectorEvent(tipsetCid, tx, sectorNumber, jsonData)) } return sectorEvents, nil } @@ -361,16 +313,8 @@ func (eg *eventGenerator) parseConfirmSectorProofsValid(_ context.Context, tx *t return nil, fmt.Errorf("error marshaling event: %w", err) } for _, sector := range sectors { - sectorEvents = append(sectorEvents, &types.MinerSectorEvent{ - ID: tools.BuildId(tipsetCid, tx.TxCid, tx.TxFrom, tx.TxTo, fmt.Sprint(tx.Height), tx.TxType), - MinerAddress: tx.TxTo, - // #nosec G115 - SectorNumber: uint64(sector), - Height: tx.Height, - TxCid: tx.TxCid, - ActionType: tx.TxType, - Data: string(jsonData), - }) + //nolint:gosec + sectorEvents = append(sectorEvents, createSectorEvent(tipsetCid, tx, uint64(sector), jsonData)) } return sectorEvents, nil } @@ -393,15 +337,7 @@ func (eg *eventGenerator) parseProveCommitAggregate(_ context.Context, tx *types return nil, fmt.Errorf("error marshaling event: %w", err) } for _, sectorNumber := range sectorNumbers { - sectorEvents = append(sectorEvents, &types.MinerSectorEvent{ - ID: tools.BuildId(tipsetCid, tx.TxCid, tx.TxFrom, tx.TxTo, fmt.Sprint(tx.Height), tx.TxType), - MinerAddress: tx.TxTo, - SectorNumber: uint64(sectorNumber), - Height: tx.Height, - TxCid: tx.TxCid, - ActionType: tx.TxType, - Data: string(jsonData), - }) + sectorEvents = append(sectorEvents, createSectorEvent(tipsetCid, tx, sectorNumber, jsonData)) } return sectorEvents, nil } @@ -440,3 +376,16 @@ func jsonEncodedBitfieldToSectorNumbers(bitField []int) ([]uint64, error) { } return sectorNumbers, nil } + +func createSectorEvent(tipsetCid string, tx *types.Transaction, sectorNumber uint64, jsonData []byte) *types.MinerSectorEvent { + return &types.MinerSectorEvent{ + ID: tools.BuildId(tipsetCid, tx.TxCid, tx.TxFrom, tx.TxTo, fmt.Sprint(tx.Height), tx.TxType), + MinerAddress: tx.TxTo, + SectorNumber: sectorNumber, + Height: tx.Height, + TxCid: tx.TxCid, + ActionType: tx.TxType, + Data: string(jsonData), + TxTimestamp: tx.TxTimestamp, + } +} diff --git a/tools/multisig/multisig.go b/tools/multisig/multisig.go index 74c33205..1adb9c33 100644 --- a/tools/multisig/multisig.go +++ b/tools/multisig/multisig.go @@ -17,7 +17,6 @@ import ( "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" filTypes "github.com/filecoin-project/lotus/chain/types" cbor "github.com/ipfs/go-ipld-cbor" - actorsV1 "github.com/zondax/fil-parser/actors/v1" "github.com/zondax/fil-parser/parser" "github.com/zondax/fil-parser/parser/helper" "github.com/zondax/fil-parser/tools" @@ -111,7 +110,7 @@ func (eg *eventGenerator) GenerateMultisigEvents(ctx context.Context, transactio continue } - multisigInfo, err := eg.createMultisigInfo(ctx, tx, tipsetCid) + multisigInfo, err := eg.createMultisigInfo(ctx, tx, tipsetCid, metadata[parser.ParamsKey]) if err != nil { continue } @@ -146,13 +145,18 @@ func (eg *eventGenerator) processProposalParams(ctx context.Context, metadata ma proposal.ActionType = cancelApproveTranslateMap[txType] proposal.TxTypeToExecute = "" - metadata[metadataParams] = eg.parseParamsString(ctx, metadata) + metadata[metadataParams] = eg.parseParams(ctx, metadata) if params, ok := metadata[metadataParams].(map[string]interface{}); ok { if metadataID, ok := params[metadataIDField].(float64); ok { proposal.ProposalID = int64(metadataID) } - eg.processNestedParams(ctx, params, proposal) + jsonParams, err := json.Marshal(params) + if err != nil { + eg.logger.Errorf("Error marshaling nested params: %v", err) + return + } + proposal.Value = string(jsonParams) } } else { proposal.ActionType = proposeTranslateMap[txType] @@ -202,15 +206,8 @@ func (eg *eventGenerator) processNestedParams(ctx context.Context, params map[st } -func (eg *eventGenerator) createMultisigInfo(ctx context.Context, tx *types.Transaction, tipsetCid string) (*types.MultisigInfo, error) { - value, err := actorsV1.ParseMultisigMetadata(tx.TxType, tx.TxMetadata) - if err != nil { - _ = eg.metrics.UpdateParseMultisigMetadataMetric(tx.TxType) - eg.logger.Errorf("Multisig error parsing metadata: %s", err.Error()) - value = tx.TxMetadata // if there is an error then we need to store the raw metadata - } - - b, err := json.Marshal(value) +func (eg *eventGenerator) createMultisigInfo(ctx context.Context, tx *types.Transaction, tipsetCid string, parsedMetadata any) (*types.MultisigInfo, error) { + b, err := json.Marshal(parsedMetadata) if err != nil { _ = eg.metrics.UpdateMarshalMultisigMetadataMetric(tx.TxType) eg.logger.Errorf("Multisig error marshaling value: %s", err.Error()) @@ -228,14 +225,20 @@ func (eg *eventGenerator) createMultisigInfo(ctx context.Context, tx *types.Tran }, nil } -func (eg *eventGenerator) parseParamsString(ctx context.Context, metadata map[string]interface{}) map[string]interface{} { +func (eg *eventGenerator) parseParams(ctx context.Context, metadata map[string]interface{}) map[string]interface{} { var params map[string]interface{} - if paramsStr, ok := metadata[metadataParams].(string); ok { - if err := json.Unmarshal([]byte(paramsStr), ¶ms); err != nil { + switch data := metadata[metadataParams].(type) { + case string: + if err := json.Unmarshal([]byte(data), ¶ms); err != nil { eg.logger.Errorf("Error deserializing params string: %v", err) return nil } + case map[string]any: + params = data + default: + eg.logger.Errorf("Unknown params type: %T", data) } + return params } diff --git a/tools/tools.go b/tools/tools.go index cb6cfa81..23f472ce 100644 --- a/tools/tools.go +++ b/tools/tools.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "strings" "github.com/zondax/golem/pkg/logger" @@ -155,3 +156,11 @@ func ParseTxMetadata(txMetadata string) (map[string]interface{}, error) { } return metadata, nil } + +func ParseActorName(actor string) string { + s := strings.Split(actor, "/") + if len(s) < 1 { + return actor + } + return s[len(s)-1] +} diff --git a/types/miner.go b/types/miner.go index 78c1a89d..ea7b6b09 100644 --- a/types/miner.go +++ b/types/miner.go @@ -1,24 +1,28 @@ package types +import "time" + type MinerEvents struct { MinerInfo []*MinerInfo MinerSectors []*MinerSectorEvent } type MinerInfo struct { - ID string `json:"id"` - ActorAddress string `json:"address"` - Height uint64 `json:"height"` - TxCid string `json:"tx_cid"` - ActionType string `json:"action_type"` - Value string `json:"value"` + ID string `json:"id"` + ActorAddress string `json:"address"` + Height uint64 `json:"height"` + TxCid string `json:"tx_cid"` + ActionType string `json:"action_type"` + Value string `json:"value"` + TxTimestamp time.Time `json:"tx_timestamp"` } type MinerSectorEvent struct { - ID string `json:"id"` - MinerAddress string `json:"miner_address"` - SectorNumber uint64 `json:"sector_number"` - Height uint64 `json:"height"` - TxCid string `json:"tx_cid"` - ActionType string `json:"action_type"` - Data string `json:"data"` + ID string `json:"id"` + MinerAddress string `json:"miner_address"` + SectorNumber uint64 `json:"sector_number"` + Height uint64 `json:"height"` + TxCid string `json:"tx_cid"` + ActionType string `json:"action_type"` + Data string `json:"data"` + TxTimestamp time.Time `json:"tx_timestamp"` }