Fix Ipld serialization in `State*Msg*` RPC API
- Dominant language
- Rust
- Stars
- 697
- Forks
- 200
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 65
Description
**Issue summary**
Lotus uses runtime reflection for IPLD serialization in RPC API json responses, it's ignored in forest for now. More investigation is needed to implement it in forest.
Related lotus code
```go
type MsgLookup struct {
Message cid.Cid // Can be different than requested, in case it was replaced, but only gas values changed
Receipt types.MessageReceipt
ReturnDec interface{}
TipSet types.TipSetKey
Height abi.ChainEpoch
}
var returndec interface{}
if recpt.ExitCode == 0 && len(recpt.Return) > 0 {
cmsg, err := m.Chain.GetCMessage(ctx, msg)
if err != nil {
return nil, xerrors.Errorf("failed to load message after successful receipt search: %w", err)
}
vmsg := cmsg.VMMessage()
switch t, err := stmgr.GetReturnType(ctx, m.StateManager, vmsg.To, vmsg.Method, ts); {
case errors.Is(err, stmgr.ErrMetadataNotFound):
// This is not necessarily an error -- EVM methods (and in the future native actors) may
// return just bytes, and in the not so distant future we'll have native wasm actors
// that are by definition not in the registry.
// So in this case, log a debug message and retun the raw bytes.
log.Debugf("failed to get return type: %s", err)
returndec = recpt.Return
case err != nil:
return nil, xerrors.Errorf("failed to get return type: %w", err)
default:
if err := t.UnmarshalCBOR(bytes.NewReader(recpt.Return)); err != nil {
return nil, err
}
returndec = t
}
}
return &api.MsgLookup{
Message: found,
Receipt: *recpt,
ReturnDec: returndec,
TipSet: ts.Key(),
Height: ts.Height(),
}, nil
func GetReturnType(ctx context.Context, sm *StateManager, to address.Address, method abi.MethodNum, ts *types.TipSet) (cbg.CBORUnmarshaler, error) {
act, err := sm.LoadActor(ctx, to, ts)
if err != nil {
return nil, xerrors.Errorf("(get sset) failed to load actor: %w", err)
}
m, found := sm.tsExec.NewActorRegistry().Methods[act.Code][method]
if !found {
return nil, fmt.Errorf("unknown method %d for actor %s: %w", method, act.Code, ErrMetadataNotFound)
}
return reflect.New(m.Ret.Elem()).Interface().(cbg.CBORUnmarshaler), nil
}
```
example lotus API call:
request:
```json
{
"id": 0,
"jsonrpc": "2.0",
"method": "Filecoin.StateWaitMsg",
"params": [
{
"/": "bafy2bzacear2xvf6lnxvtyooupaosxgh2bosn7bp35bzz6syofzk7b45gp2es"
},
0
]
}
```
response:
```json
{
"jsonrpc": "2.0",
"result": {
"Message": {
"/": "bafy2bzacear2xvf6lnxvtyooupaosxgh2bosn7bp35bzz6syofzk7b45gp2es"
},
"Receipt": {
"ExitCode": 0,
"Return": "gxnmiFUCU1RCVs/3Evl82pH2EU27iJjACWtUdZ6JBkmIZWDdZSQ9ieRv0l4paI4=",
"GasUsed": 82943114,
"EventsRoot": null
},
"ReturnDec": {
"ActorID": 59016,
"RobustAddress": "t2knkeevwp64jps7g2sh3bctn3rcmmaclltnpwtdi",
"EthAddress": [
117,
158,
137,
6,
73,
136,
101,
96,
221,
101,
36,
61,
137,
228,
111,
210,
94,
41,
104,
142
]
},
"TipSet": [
{
"/": "bafy2bzaceanaa2pyrqcn43ybv4ig5urvtumte4ftlkoaqudojyjptvtiadq7w"
}
],
"Height": 1144812
},
"id": 0
}
```
**Other information and links**
https://github.com/ChainSafe/forest/pull/3783
https://github.com/ChainSafe/forest/issues/3769
Contributor guide
Assessment
This issue has not been assessed yet.