Checklist
Lotus component
Lotus Version
daemon:lotus version 1.34.1+mainnet+git.710b4ac66
local: lotus version 1.34.1+mainnet+git.710b4ac66
Repro Steps
/1. Run '...'
2. Do '...'
3. See error '...'
...
Describe the Bug
Cannot withdraw StorageMarketActor escrow with delegated f4 address (WalletSignMessage / MpoolPush fail)
I’m trying to withdraw FIL from the StorageMarketActor escrow using a delegated f4 address as the client/provider.
The balance is locked in f05 for this f4 address (it has deals and escrow), but any attempt to send a WithdrawBalance message from this f4 address fails at signature / Ethereum-transaction reconstruction level.
It looks like Lotus tries to treat a native FVM message (To = f05, Method = WithdrawBalance) as an Ethereum-style transaction when the From is an f4 delegated address, and then fails while reconstructing/parsing it.
So currently I have no way to withdraw market escrow for this f4 address.
Environment
- Lotus version:
lotus version 1.34.1+mainnet+git.710b4ac66
- Network:
mainnet
- FEVM / Eth RPC: enabled
lotus version output:
lotus version 1.34.1+mainnet+git.710b4ac66
lotus wallet market withdraw output:
lotus wallet market withdraw -w f410......q -a f410......q
Submitting WithdrawBalance message for amount 1000 FIL for address f410......q
ERROR: fund manager withdraw error: failed to reconstruct eth transaction: failed to get eth params and recipient: failed to read params byte array: expected cbor type 'byte string' in input
The delegated address
The wallet export for my f4 address looks like this:
{
"Type": "delegated",
"PrivateKey": "+3.......0="
}
The address is :
This address has market escrow balance in f05 (confirmed via StateMarketBalance / StateReadState etc).
How I build the WithdrawBalance message
I am talking to the same Lotus daemon via JSON-RPC.
1. Get StorageMarketActor code CID
Filecoin.StateGetActor("f05", null)
-> Code = { "/": "bafk2bzacebsnn4nk5crrlrvhg5vdpaxsrs4r72etaofxdi7tucr72om22z6a4" }
2. Encode WithdrawBalance params with StateEncodeParams
paramsObj = {
"ProviderOrClientAddress": "f410......q",
"TokenAmount": "1000000000000000000000" // (example amount)
}
Filecoin.StateEncodeParams(
CodeCID, // from step 1
2280458852, // WithdrawBalance method number
paramsObj
)
-> Encoded Params (base64): "glYECvtrGcdqegZZSr0080iAP9HXPH1+QA=="
3. Get nonce for the f4 address
Filecoin.MpoolGetNonce("f410......q")
-> Nonce: 1
4. Build unsigned message (Lotus schema)
{
"Version": 0,
"To": "f05",
"From": "f410......q",
"Nonce": 1,
"Value": "0",
"GasLimit": 2249752,
"GasFeeCap": "100891",
"GasPremium": "99742",
"Method": 2280458852,
"Params": "gl.......=="
}
Failure 1: WalletSignMessage error (ETH tx reconstruction)
When I call:
Filecoin.WalletSignMessage(
"f410......q",
unsignedMsg
)
I consistently get this error:
RPC Filecoin.WalletSignMessage error:
{
"code": 1,
"message": "failed to reconstruct eth transaction: failed to get eth params and recipient: failed to read params byte array: expected cbor type 'byte string' in input"
}
So instead of just treating this as a normal FVM message From f4 -> To f05 -> Method WithdrawBalance, Lotus is trying to reconstruct an Ethereum transaction and parse something as calldata, and fails with expected cbor type 'byte string'.
Failure 2: Signing externally + MpoolPush => invalid compact signature / ETH reconstruction
To bypass WalletSignMessage, I also tried:
-
Use a custom Go tool to CBOR-encode the unsigned message and get:
CBOR_HEX of the message
CID_HEX = digest of the message CID (something like 0171a0e4...).
-
Use lotus wallet sign <f4> <CID_HEX> to sign the digest:
lotus wallet sign f410......q 0171a0e4...
-> 03350ad7dcbac9f6c24fbb...
The returned value is a hex string, which I convert to base64 and put into a SignedMessage:
{
"Message": {
"Version": 0,
"To": "f05",
"From": "f410......q",
"Nonce": 1,
"Value": "0",
"GasLimit": 2249752,
"GasFeeCap": "100891",
"GasPremium": "99742",
"Method": 2280458852,
"Params": "glYECvtrGcdqegZZSr0080iAP9HXPH1+QA=="
},
"Signature": {
"Type": 3,
"Data": "AzUK19y6yfbCT7ugBdlHHtUYvnSlyMVocJe2kLpk095Dc16jIUlfR0YhXMbUqi1TuQW/asESBVDxmdKgVaT5yb4B"
}
}
-
Then I push it via:
Filecoin.MpoolPush(signedMsg)
This fails with:
RPC Filecoin.MpoolPush error:
{
"code": 1,
"message": "signature verification failed: failed to validate signature:
invalid signature for message bafy2bzacecsjtiddmoyb3oenccpddbhyqbnnlgnbvou3ojtejcwopnbildqjy (type 1):
secp256k1/secec: invalid compact signature"
}
If I change Signature.Type to 3 (delegated / ECDSA / ETH-style), I get back to the previous kind of error:
"signature verification failed: failed to validate signature: failed to reconstruct Ethereum transaction:
failed to parse input params and recipient: failed to read params byte array: expected cbor type 'byte string' in input"
So:
Type = 1 → invalid compact signature (even though it was produced by lotus wallet sign against the CID digest).
Type = 3 → Lotus tries to treat it as an ETH tx, fails to decode params as CBOR byte string.
What I expected
OR:
Right now, it feels like a bug / incomplete integration between delegated f4 accounts and the market actor:
- The system allows the f4 to accumulate escrow in
f05,
- But there is no working path to withdraw that escrow using that same f4 address —
both WalletSignMessage and MpoolPush fail in ways that look like FEVM reconstruction issues.
What I tried / extra notes
- JWT token has
["read", "write", "sign"] permissions.
- The same flow (StateEncodeParams → WalletSignMessage → MpoolPush) works fine when
From is a secp256k1 f1 address. The problem appears only with From = f4 delegated.
- I also checked the OpenRPC docs and noticed there is
MarketWithdraw RPC with Perms: sign, but using the low-level message flow hits the same error path.
Questions for maintainers
-
Is it supposed to be possible to call StorageMarketActor.WithdrawBalance from a delegated f4 address using a native FVM message?
-
If yes, is the behavior above a known bug / regression in the delegated account handling (trying to reconstruct ETH tx for a native actor call)?
-
If no, what is the recommended / supported way to:
- withdraw market escrow that is already locked for an f4 delegated client?
- or avoid ending up with escrow that is not withdrawable?
Any guidance or workaround would be greatly appreciated.
Logging Information
lotus wallet market withdraw -w f410......q -a f410......q
Submitting WithdrawBalance message for amount 1000 FIL for address f410......q
ERROR: fund manager withdraw error: failed to reconstruct eth transaction: failed to get eth params and recipient: failed to read params byte array: expected cbor type 'byte string' in input
Checklist
Latest release, the most recent RC(release canadiate) for the upcoming release or the dev branch(master), or have an issue updating to any of these.Lotus component
Lotus Version
Repro Steps
/1. Run '...'
2. Do '...'
3. See error '...'
...
Describe the Bug
Cannot withdraw StorageMarketActor escrow with delegated f4 address (WalletSignMessage / MpoolPush fail)
I’m trying to withdraw FIL from the StorageMarketActor escrow using a delegated f4 address as the client/provider.
The balance is locked in
f05for this f4 address (it has deals and escrow), but any attempt to send aWithdrawBalancemessage from this f4 address fails at signature / Ethereum-transaction reconstruction level.It looks like Lotus tries to treat a native FVM message (
To = f05,Method = WithdrawBalance) as an Ethereum-style transaction when theFromis an f4 delegated address, and then fails while reconstructing/parsing it.So currently I have no way to withdraw market escrow for this f4 address.
Environment
lotus version 1.34.1+mainnet+git.710b4ac66mainnetlotus versionoutput:lotus wallet market withdrawoutput:The delegated address
The wallet export for my f4 address looks like this:
{ "Type": "delegated", "PrivateKey": "+3.......0=" }The address is :
This address has market escrow balance in
f05(confirmed viaStateMarketBalance/StateReadStateetc).How I build the WithdrawBalance message
I am talking to the same Lotus daemon via JSON-RPC.
1. Get StorageMarketActor code CID
2. Encode
WithdrawBalanceparams withStateEncodeParams3. Get nonce for the f4 address
4. Build unsigned message (Lotus schema)
{ "Version": 0, "To": "f05", "From": "f410......q", "Nonce": 1, "Value": "0", "GasLimit": 2249752, "GasFeeCap": "100891", "GasPremium": "99742", "Method": 2280458852, "Params": "gl.......==" }Failure 1:
WalletSignMessageerror (ETH tx reconstruction)When I call:
I consistently get this error:
So instead of just treating this as a normal FVM message
From f4 -> To f05 -> Method WithdrawBalance, Lotus is trying to reconstruct an Ethereum transaction and parse something as calldata, and fails withexpected cbor type 'byte string'.Failure 2: Signing externally +
MpoolPush=> invalid compact signature / ETH reconstructionTo bypass
WalletSignMessage, I also tried:Use a custom Go tool to CBOR-encode the unsigned message and get:
CBOR_HEXof the messageCID_HEX= digest of the message CID (something like0171a0e4...).Use
lotus wallet sign <f4> <CID_HEX>to sign the digest:lotus wallet sign f410......q 0171a0e4... -> 03350ad7dcbac9f6c24fbb...The returned value is a hex string, which I convert to base64 and put into a
SignedMessage:{ "Message": { "Version": 0, "To": "f05", "From": "f410......q", "Nonce": 1, "Value": "0", "GasLimit": 2249752, "GasFeeCap": "100891", "GasPremium": "99742", "Method": 2280458852, "Params": "glYECvtrGcdqegZZSr0080iAP9HXPH1+QA==" }, "Signature": { "Type": 3, "Data": "AzUK19y6yfbCT7ugBdlHHtUYvnSlyMVocJe2kLpk095Dc16jIUlfR0YhXMbUqi1TuQW/asESBVDxmdKgVaT5yb4B" } }Then I push it via:
Filecoin.MpoolPush(signedMsg)This fails with:
If I change
Signature.Typeto3(delegated / ECDSA / ETH-style), I get back to the previous kind of error:So:
Type = 1→ invalid compact signature (even though it was produced bylotus wallet signagainst the CID digest).Type = 3→ Lotus tries to treat it as an ETH tx, fails to decode params as CBOR byte string.What I expected
A delegated f4 address should be able to:
Type = 1,f05/WithdrawBalanceviaMpoolPush,OR:
If this is not supported by design, there should be a clear error / documentation that:
Right now, it feels like a bug / incomplete integration between delegated f4 accounts and the market actor:
f05,both
WalletSignMessageandMpoolPushfail in ways that look like FEVM reconstruction issues.What I tried / extra notes
["read", "write", "sign"]permissions.Fromis a secp256k1 f1 address. The problem appears only withFrom = f4 delegated.MarketWithdrawRPC withPerms: sign, but using the low-level message flow hits the same error path.Questions for maintainers
Is it supposed to be possible to call
StorageMarketActor.WithdrawBalancefrom a delegated f4 address using a native FVM message?If yes, is the behavior above a known bug / regression in the delegated account handling (trying to reconstruct ETH tx for a native actor call)?
If no, what is the recommended / supported way to:
Any guidance or workaround would be greatly appreciated.
Logging Information