fix some gas charge bugs, and make our new account actor creation follow GFC
This commit is contained in:
parent
08ca60cfa8
commit
09a46e5d80
@ -188,7 +188,7 @@ func (st *StateTree) ClearSnapshot() {
|
||||
st.snapshots = st.snapshots[:len(st.snapshots)-1]
|
||||
}
|
||||
|
||||
func (st *StateTree) RegisterNewAddress(addr address.Address, act *types.Actor) (address.Address, error) {
|
||||
func (st *StateTree) RegisterNewAddress(addr address.Address) (address.Address, error) {
|
||||
var out address.Address
|
||||
err := st.MutateActor(builtin.InitActorAddr, func(initact *types.Actor) error {
|
||||
var ias init_.State
|
||||
@ -214,10 +214,6 @@ func (st *StateTree) RegisterNewAddress(addr address.Address, act *types.Actor)
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
if err := st.SetActor(out, act); err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ func (s *StateWrapper) CreateActor(code cid.Cid, addr address.Address, balance a
|
||||
Balance: balance,
|
||||
}}
|
||||
|
||||
idAddr, err := tree.RegisterNewAddress(addr, &actr.Actor)
|
||||
idAddr, err := tree.RegisterNewAddress(addr)
|
||||
if err != nil {
|
||||
return nil, address.Undef, xerrors.Errorf("register new address for actor: %w", err)
|
||||
}
|
||||
|
@ -2,9 +2,10 @@ package vm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
@ -27,25 +28,46 @@ func init() {
|
||||
var EmptyObjectCid cid.Cid
|
||||
|
||||
// Creates account actors from only BLS/SECP256K1 addresses.
|
||||
func TryCreateAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
||||
act, err := makeActor(st, addr)
|
||||
func TryCreateAccountActor(ctx context.Context, rt *Runtime, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
||||
addrID, err := rt.state.RegisterNewAddress(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := st.RegisterNewAddress(addr, act); err != nil {
|
||||
return nil, aerrors.Escalate(err, "registering actor address")
|
||||
}
|
||||
rt.gasUsed += PricelistByEpoch(rt.height).OnCreateActor()
|
||||
act, aerr := makeActor(rt.state, addr)
|
||||
if aerr != nil {
|
||||
return nil, aerr
|
||||
}
|
||||
|
||||
if err := rt.state.SetActor(addrID, act); err != nil {
|
||||
return nil, aerrors.Escalate(err, "creating new actor failed")
|
||||
}
|
||||
|
||||
p, err := actors.SerializeParams(&addr)
|
||||
if err != nil {
|
||||
return nil, aerrors.Escalate(err, "registering actor address")
|
||||
}
|
||||
// call constructor on account
|
||||
|
||||
_, aerr = rt.internalSend(builtin.SystemActorAddr, addrID, builtin.MethodsAccount.Constructor, big.Zero(), p)
|
||||
|
||||
if aerr != nil {
|
||||
return nil, aerrors.Fatal("failed to invoke account constructor")
|
||||
}
|
||||
|
||||
act, err = rt.state.GetActor(addrID)
|
||||
if err != nil {
|
||||
return nil, aerrors.Escalate(err, "loading newly created actor failed")
|
||||
}
|
||||
return act, nil
|
||||
}
|
||||
|
||||
func makeActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
||||
switch addr.Protocol() {
|
||||
case address.BLS:
|
||||
return NewBLSAccountActor(st, addr)
|
||||
return NewBLSAccountActor()
|
||||
case address.SECP256K1:
|
||||
return NewSecp256k1AccountActor(st, addr)
|
||||
return NewSecp256k1AccountActor()
|
||||
case address.ID:
|
||||
return nil, aerrors.Newf(1, "no actor with given ID: %s", addr)
|
||||
case address.Actor:
|
||||
@ -55,37 +77,21 @@ func makeActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors
|
||||
}
|
||||
}
|
||||
|
||||
func NewBLSAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
||||
var acstate account.State
|
||||
acstate.Address = addr
|
||||
|
||||
c, err := st.Store.Put(context.TODO(), &acstate)
|
||||
if err != nil {
|
||||
return nil, aerrors.Escalate(err, "serializing account actor state")
|
||||
}
|
||||
|
||||
func NewBLSAccountActor() (*types.Actor, aerrors.ActorError) {
|
||||
nact := &types.Actor{
|
||||
Code: builtin.AccountActorCodeID,
|
||||
Balance: types.NewInt(0),
|
||||
Head: c,
|
||||
Head: EmptyObjectCid,
|
||||
}
|
||||
|
||||
return nact, nil
|
||||
}
|
||||
|
||||
func NewSecp256k1AccountActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
||||
var acstate account.State
|
||||
acstate.Address = addr
|
||||
|
||||
c, err := st.Store.Put(context.TODO(), &acstate)
|
||||
if err != nil {
|
||||
return nil, aerrors.Escalate(err, "serializing account actor state")
|
||||
}
|
||||
|
||||
func NewSecp256k1AccountActor() (*types.Actor, aerrors.ActorError) {
|
||||
nact := &types.Actor{
|
||||
Code: builtin.AccountActorCodeID,
|
||||
Balance: types.NewInt(0),
|
||||
Head: c,
|
||||
Head: EmptyObjectCid,
|
||||
}
|
||||
|
||||
return nact, nil
|
||||
|
@ -281,7 +281,7 @@ func (rs *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMars
|
||||
params = buf.Bytes()
|
||||
}
|
||||
|
||||
ret, err := rs.internalSend(to, method, types.BigInt(value), params)
|
||||
ret, err := rs.internalSend(rs.Message().Receiver(), to, method, types.BigInt(value), params)
|
||||
if err != nil {
|
||||
if err.IsFatal() {
|
||||
panic(err)
|
||||
@ -292,7 +292,7 @@ func (rs *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMars
|
||||
return &dumbWrapperType{ret}, 0
|
||||
}
|
||||
|
||||
func (rt *Runtime) internalSend(to address.Address, method abi.MethodNum, value types.BigInt, params []byte) ([]byte, aerrors.ActorError) {
|
||||
func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum, value types.BigInt, params []byte) ([]byte, aerrors.ActorError) {
|
||||
ctx, span := trace.StartSpan(rt.ctx, "vmc.Send")
|
||||
defer span.End()
|
||||
if span.IsRecordingEvents() {
|
||||
@ -304,7 +304,7 @@ func (rt *Runtime) internalSend(to address.Address, method abi.MethodNum, value
|
||||
}
|
||||
|
||||
msg := &types.Message{
|
||||
From: rt.Message().Receiver(),
|
||||
From: from,
|
||||
To: to,
|
||||
Method: method,
|
||||
Value: value,
|
||||
@ -317,7 +317,6 @@ func (rt *Runtime) internalSend(to address.Address, method abi.MethodNum, value
|
||||
return nil, aerrors.Fatalf("snapshot failed: %s", err)
|
||||
}
|
||||
defer st.ClearSnapshot()
|
||||
rt.ChargeGas(rt.Pricelist().OnMethodInvocation(value, method))
|
||||
|
||||
ret, errSend, subrt := rt.vm.send(ctx, msg, rt, 0)
|
||||
if errSend != nil {
|
||||
|
@ -211,25 +211,24 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
|
||||
}()
|
||||
}
|
||||
|
||||
aerr := rt.chargeGasSafe(rt.Pricelist().OnMethodInvocation(msg.Value, msg.Method))
|
||||
if aerr != nil {
|
||||
return nil, aerr, rt
|
||||
}
|
||||
|
||||
toActor, err := st.GetActor(msg.To)
|
||||
if err != nil {
|
||||
if xerrors.Is(err, init_.ErrAddressNotFound) {
|
||||
a, err := TryCreateAccountActor(st, msg.To)
|
||||
a, err := TryCreateAccountActor(ctx, rt, msg.To)
|
||||
if err != nil {
|
||||
return nil, aerrors.Absorb(err, 1, "could not create account"), rt
|
||||
}
|
||||
toActor = a
|
||||
gasUsed += PricelistByEpoch(vm.blockHeight).OnCreateActor()
|
||||
} else {
|
||||
return nil, aerrors.Escalate(err, "getting actor"), rt
|
||||
}
|
||||
}
|
||||
|
||||
aerr := rt.chargeGasSafe(rt.Pricelist().OnMethodInvocation(msg.Value, msg.Method))
|
||||
if aerr != nil {
|
||||
return nil, aerr, rt
|
||||
}
|
||||
|
||||
if types.BigCmp(msg.Value, types.NewInt(0)) != 0 {
|
||||
if err := vm.transfer(msg.From, msg.To, msg.Value); err != nil {
|
||||
return nil, aerrors.Absorb(err, 1, "failed to transfer funds"), nil
|
||||
|
Loading…
Reference in New Issue
Block a user