fix some gas charge bugs, and make our new account actor creation follow GFC

This commit is contained in:
Aayush Rajasekaran 2020-03-24 22:25:20 -04:00
parent 08ca60cfa8
commit 09a46e5d80
5 changed files with 46 additions and 46 deletions

View File

@ -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
}

View File

@ -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)
}

View File

@ -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

View File

@ -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 {

View File

@ -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