Messagepool: check sender is valid for sending
This commit is contained in:
parent
830c3e49d9
commit
160bcd64a6
@ -764,6 +764,11 @@ workflows:
|
||||
suite: itest-dup_mpool_messages
|
||||
target: "./itests/dup_mpool_messages_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-eth_account_abstraction
|
||||
suite: itest-eth_account_abstraction
|
||||
target: "./itests/eth_account_abstraction_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-fevm
|
||||
suite: itest-fevm
|
||||
|
@ -274,6 +274,24 @@ func IsPaymentChannelActor(c cid.Cid) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func IsEmbryoActor(c cid.Cid) bool {
|
||||
name, _, ok := actors.GetActorMetaByCode(c)
|
||||
if ok {
|
||||
return name == "embryo"
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsEthAccountActor(c cid.Cid) bool {
|
||||
name, _, ok := actors.GetActorMetaByCode(c)
|
||||
if ok {
|
||||
return name == "ethaccount"
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func makeAddress(addr string) address.Address {
|
||||
ret, err := address.NewFromString(addr)
|
||||
if err != nil {
|
||||
|
@ -153,6 +153,24 @@ func IsPaymentChannelActor(c cid.Cid) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func IsEmbryoActor(c cid.Cid) bool {
|
||||
name, _, ok := actors.GetActorMetaByCode(c)
|
||||
if ok {
|
||||
return name == "embryo"
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsEthAccountActor(c cid.Cid) bool {
|
||||
name, _, ok := actors.GetActorMetaByCode(c)
|
||||
if ok {
|
||||
return name == "ethaccount"
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func makeAddress(addr string) address.Address {
|
||||
ret, err := address.NewFromString(addr)
|
||||
if err != nil {
|
||||
|
@ -1,12 +0,0 @@
|
||||
package builtin
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
)
|
||||
|
||||
func IsEmbryo(c cid.Cid) bool {
|
||||
name, _, ok := actors.GetActorMetaByCode(c)
|
||||
return ok && name == "embryo"
|
||||
}
|
@ -436,15 +436,15 @@ func (filec *FilecoinEC) VerifyWinningPoStProof(ctx context.Context, nv network.
|
||||
return nil
|
||||
}
|
||||
|
||||
func isValidForSending(act *types.Actor) bool {
|
||||
if builtin.IsAccountActor(act.Code) {
|
||||
func IsValidForSending(act *types.Actor) bool {
|
||||
if builtin.IsAccountActor(act.Code) || builtin.IsEthAccountActor(act.Code) {
|
||||
return true
|
||||
}
|
||||
|
||||
// HACK: Allow Eth embryos to send messages
|
||||
if !builtin.IsEmbryo(act.Code) || act.Address == nil || act.Address.Protocol() != address.Delegated {
|
||||
if !builtin.IsEmbryoActor(act.Code) || act.Address == nil || act.Address.Protocol() != address.Delegated {
|
||||
return false
|
||||
}
|
||||
|
||||
id, _, err := varint.FromUvarint(act.Address.Payload())
|
||||
return err == nil && id == builtintypes.EthereumAddressManagerActorID
|
||||
}
|
||||
@ -521,7 +521,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
|
||||
return xerrors.Errorf("failed to get actor: %w", err)
|
||||
}
|
||||
|
||||
if !isValidForSending(act) {
|
||||
if !IsValidForSending(act) {
|
||||
return xerrors.New("Sender must be an account actor")
|
||||
}
|
||||
nonces[sender] = act.Nonce
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
||||
"github.com/filecoin-project/lotus/chain/eth"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
@ -873,18 +874,28 @@ func (mp *MessagePool) addTs(ctx context.Context, m *types.SignedMessage, curTs
|
||||
mp.lk.Lock()
|
||||
defer mp.lk.Unlock()
|
||||
|
||||
senderAct, err := mp.api.GetActorAfter(m.Message.From, curTs)
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("failed to get sender actor: %w", err)
|
||||
}
|
||||
|
||||
// TODO: I'm not thrilled about depending on filcns here, but I prefer this to duplicating logic
|
||||
if !filcns.IsValidForSending(senderAct) {
|
||||
return false, xerrors.Errorf("sender actor %s is not a valid top-level sender", m.Message.From)
|
||||
}
|
||||
|
||||
publish, err := mp.verifyMsgBeforeAdd(ctx, m, curTs, local)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, xerrors.Errorf("verify msg failed: %w", err)
|
||||
}
|
||||
|
||||
if err := mp.checkBalance(ctx, m, curTs); err != nil {
|
||||
return false, err
|
||||
return false, xerrors.Errorf("failed to check balance: %w", err)
|
||||
}
|
||||
|
||||
err = mp.addLocked(ctx, m, !local, untrusted)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, xerrors.Errorf("failed to add locked: %w", err)
|
||||
}
|
||||
|
||||
if local {
|
||||
|
@ -285,7 +285,7 @@ func DecodeParams(b []byte, out interface{}) error {
|
||||
|
||||
func DumpActorState(i *ActorRegistry, act *types.Actor, b []byte) (interface{}, error) {
|
||||
// Account & Embryo code special case
|
||||
if builtin.IsAccountActor(act.Code) || builtin.IsEmbryo(act.Code) {
|
||||
if builtin.IsAccountActor(act.Code) || builtin.IsEmbryoActor(act.Code) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -2,22 +2,18 @@ package itests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/itests/kit"
|
||||
)
|
||||
@ -54,7 +50,7 @@ func TestEthAccountAbstraction(t *testing.T) {
|
||||
embryoActor, err := client.StateGetActor(ctx, embryoAddress, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.True(t, builtin.IsEmbryo(embryoActor.Code))
|
||||
require.True(t, builtin.IsEmbryoActor(embryoActor.Code))
|
||||
|
||||
// send a message from the embryo address
|
||||
msgFromEmbryo := &types.Message{
|
||||
@ -70,9 +66,8 @@ func TestEthAccountAbstraction(t *testing.T) {
|
||||
Signature: crypto.Signature{Type: crypto.SigTypeDelegated},
|
||||
}
|
||||
|
||||
// TODO: Hack delegated verification to always be true
|
||||
// TODO: Unhack delegated verification to always be true
|
||||
|
||||
fmt.Println(smFromEmbryo.Message.From)
|
||||
_, err = client.MpoolPush(ctx, smFromEmbryo)
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -80,12 +75,41 @@ func TestEthAccountAbstraction(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode)
|
||||
|
||||
// confirm ugly embryo duckling has turned into a beautiful EOA swan
|
||||
// confirm ugly Embryo duckling has turned into a beautiful EthAccount swan
|
||||
|
||||
eoaActor, err := client.StateGetActor(ctx, embryoAddress, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.False(t, builtin.IsEmbryo(eoaActor.Code))
|
||||
// TODO: Uncomment when method exists
|
||||
//require.True(t, builtin.IsEOAActor(embryoActor.Code))
|
||||
require.False(t, builtin.IsEmbryoActor(eoaActor.Code))
|
||||
require.True(t, builtin.IsEthAccountActor(eoaActor.Code))
|
||||
|
||||
// Send another message, it should succeed without any code CID changes
|
||||
|
||||
msgFromEmbryo = &types.Message{
|
||||
From: embryoAddress,
|
||||
To: embryoAddress,
|
||||
}
|
||||
|
||||
msgFromEmbryo, err = client.GasEstimateMessageGas(ctx, msgFromEmbryo, nil, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
smFromEmbryo = &types.SignedMessage{
|
||||
Message: *msgFromEmbryo,
|
||||
Signature: crypto.Signature{Type: crypto.SigTypeDelegated},
|
||||
}
|
||||
|
||||
_, err = client.MpoolPush(ctx, smFromEmbryo)
|
||||
require.NoError(t, err)
|
||||
|
||||
mLookup, err = client.StateWaitMsg(ctx, smFromEmbryo.Cid(), 3, api.LookbackNoLimit, true)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode)
|
||||
|
||||
// confirm no changes in code CID
|
||||
|
||||
eoaActor, err = client.StateGetActor(ctx, embryoAddress, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.False(t, builtin.IsEmbryoActor(eoaActor.Code))
|
||||
require.True(t, builtin.IsEthAccountActor(eoaActor.Code))
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ func (s delegatedSigner) Sign(pk []byte, msg []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
func (delegatedSigner) Verify(sig []byte, a address.Address, msg []byte) error {
|
||||
// TODO: Drop this!
|
||||
return nil
|
||||
hasher := sha3.NewLegacyKeccak256()
|
||||
hasher.Write(msg)
|
||||
|
Loading…
Reference in New Issue
Block a user