Merge pull request #1450 from filecoin-project/asr/gas
Re: #1446: Enable gas tracking in validation tests
This commit is contained in:
commit
1aef03bdd7
@ -9,7 +9,6 @@ import (
|
|||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -343,6 +342,6 @@ func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHand
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *calledEvents) CalledMsg(ctx context.Context, hnd CalledHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, msg store.ChainMsg) error {
|
func (e *calledEvents) CalledMsg(ctx context.Context, hnd CalledHandler, rev RevertHandler, confidence int, timeout abi.ChainEpoch, msg types.ChainMsg) error {
|
||||||
return e.Called(e.CheckMsg(ctx, msg, hnd), hnd, rev, confidence, timeout, e.MatchMsg(msg.VMMessage()))
|
return e.Called(e.CheckMsg(ctx, msg, hnd), hnd, rev, confidence, timeout, e.MatchMsg(msg.VMMessage()))
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,10 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e *calledEvents) CheckMsg(ctx context.Context, smsg store.ChainMsg, hnd CalledHandler) CheckFunc {
|
func (e *calledEvents) CheckMsg(ctx context.Context, smsg types.ChainMsg, hnd CalledHandler) CheckFunc {
|
||||||
msg := smsg.VMMessage()
|
msg := smsg.VMMessage()
|
||||||
|
|
||||||
return func(ts *types.TipSet) (done bool, more bool, err error) {
|
return func(ts *types.TipSet) (done bool, more bool, err error) {
|
||||||
|
@ -31,7 +31,7 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value
|
|||||||
return nil, xerrors.Errorf("doExec failed to get from actor: %w", err)
|
return nil, xerrors.Errorf("doExec failed to get from actor: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := vm.ApplyMessage(ctx, &types.Message{
|
ret, err := vm.ApplyImplicitMessage(ctx, &types.Message{
|
||||||
To: to,
|
To: to,
|
||||||
From: from,
|
From: from,
|
||||||
Method: method,
|
Method: method,
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/lib/sigs"
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
@ -109,11 +108,11 @@ func (ms *msgSet) add(m *types.SignedMessage) error {
|
|||||||
|
|
||||||
type Provider interface {
|
type Provider interface {
|
||||||
SubscribeHeadChanges(func(rev, app []*types.TipSet) error) *types.TipSet
|
SubscribeHeadChanges(func(rev, app []*types.TipSet) error) *types.TipSet
|
||||||
PutMessage(m store.ChainMsg) (cid.Cid, error)
|
PutMessage(m types.ChainMsg) (cid.Cid, error)
|
||||||
PubSubPublish(string, []byte) error
|
PubSubPublish(string, []byte) error
|
||||||
StateGetActor(address.Address, *types.TipSet) (*types.Actor, error)
|
StateGetActor(address.Address, *types.TipSet) (*types.Actor, error)
|
||||||
MessagesForBlock(*types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
|
MessagesForBlock(*types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
|
||||||
MessagesForTipset(*types.TipSet) ([]store.ChainMsg, error)
|
MessagesForTipset(*types.TipSet) ([]types.ChainMsg, error)
|
||||||
LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
|
LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +130,7 @@ func (mpp *mpoolProvider) SubscribeHeadChanges(cb func(rev, app []*types.TipSet)
|
|||||||
return mpp.sm.ChainStore().GetHeaviestTipSet()
|
return mpp.sm.ChainStore().GetHeaviestTipSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mpp *mpoolProvider) PutMessage(m store.ChainMsg) (cid.Cid, error) {
|
func (mpp *mpoolProvider) PutMessage(m types.ChainMsg) (cid.Cid, error) {
|
||||||
return mpp.sm.ChainStore().PutMessage(m)
|
return mpp.sm.ChainStore().PutMessage(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +146,7 @@ func (mpp *mpoolProvider) MessagesForBlock(h *types.BlockHeader) ([]*types.Messa
|
|||||||
return mpp.sm.ChainStore().MessagesForBlock(h)
|
return mpp.sm.ChainStore().MessagesForBlock(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mpp *mpoolProvider) MessagesForTipset(ts *types.TipSet) ([]store.ChainMsg, error) {
|
func (mpp *mpoolProvider) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) {
|
||||||
return mpp.sm.ChainStore().MessagesForTipset(ts)
|
return mpp.sm.ChainStore().MessagesForTipset(ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/types/mock"
|
"github.com/filecoin-project/lotus/chain/types/mock"
|
||||||
"github.com/filecoin-project/lotus/chain/wallet"
|
"github.com/filecoin-project/lotus/chain/wallet"
|
||||||
@ -60,7 +59,7 @@ func (tma *testMpoolApi) SubscribeHeadChanges(cb func(rev, app []*types.TipSet)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tma *testMpoolApi) PutMessage(m store.ChainMsg) (cid.Cid, error) {
|
func (tma *testMpoolApi) PutMessage(m types.ChainMsg) (cid.Cid, error) {
|
||||||
return cid.Undef, nil
|
return cid.Undef, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +78,7 @@ func (tma *testMpoolApi) MessagesForBlock(h *types.BlockHeader) ([]*types.Messag
|
|||||||
return nil, tma.bmsgs[h.Cid()], nil
|
return nil, tma.bmsgs[h.Cid()], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tma *testMpoolApi) MessagesForTipset(ts *types.TipSet) ([]store.ChainMsg, error) {
|
func (tma *testMpoolApi) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) {
|
||||||
if len(ts.Blocks()) != 1 {
|
if len(ts.Blocks()) != 1 {
|
||||||
panic("cant deal with multiblock tipsets in this test")
|
panic("cant deal with multiblock tipsets in this test")
|
||||||
}
|
}
|
||||||
@ -89,7 +88,7 @@ func (tma *testMpoolApi) MessagesForTipset(ts *types.TipSet) ([]store.ChainMsg,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var out []store.ChainMsg
|
var out []types.ChainMsg
|
||||||
for _, m := range bm {
|
for _, m := range bm {
|
||||||
out = append(out, m)
|
out = append(out, m)
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ func (st *StateTree) ClearSnapshot() {
|
|||||||
st.snapshots = st.snapshots[:len(st.snapshots)-1]
|
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
|
var out address.Address
|
||||||
err := st.MutateActor(builtin.InitActorAddr, func(initact *types.Actor) error {
|
err := st.MutateActor(builtin.InitActorAddr, func(initact *types.Actor) error {
|
||||||
var ias init_.State
|
var ias init_.State
|
||||||
@ -214,10 +214,6 @@ func (st *StateTree) RegisterNewAddress(addr address.Address, act *types.Actor)
|
|||||||
return address.Undef, err
|
return address.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := st.SetActor(out, act); err != nil {
|
|
||||||
return address.Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate
|
|||||||
msg.Nonce = fromActor.Nonce
|
msg.Nonce = fromActor.Nonce
|
||||||
|
|
||||||
// TODO: maybe just use the invoker directly?
|
// TODO: maybe just use the invoker directly?
|
||||||
ret, err := vmi.ApplyMessage(ctx, msg)
|
ret, err := vmi.ApplyImplicitMessage(ctx, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("apply message failed: %w", err)
|
return nil, xerrors.Errorf("apply message failed: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -140,8 +140,8 @@ func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (c
|
|||||||
|
|
||||||
type BlockMessages struct {
|
type BlockMessages struct {
|
||||||
Miner address.Address
|
Miner address.Address
|
||||||
BlsMessages []store.ChainMsg
|
BlsMessages []types.ChainMsg
|
||||||
SecpkMessages []store.ChainMsg
|
SecpkMessages []types.ChainMsg
|
||||||
TicketCount int64
|
TicketCount int64
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,23 +153,8 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, pstate cid.Cid, bms []B
|
|||||||
return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err)
|
return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
applied := make(map[address.Address]uint64)
|
|
||||||
balances := make(map[address.Address]types.BigInt)
|
|
||||||
|
|
||||||
preloadAddr := func(a address.Address) error {
|
|
||||||
if _, ok := applied[a]; !ok {
|
|
||||||
act, err := vmi.StateTree().GetActor(a)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
applied[a] = act.Nonce
|
|
||||||
balances[a] = act.Balance
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var receipts []cbg.CBORMarshaler
|
var receipts []cbg.CBORMarshaler
|
||||||
|
processedMsgs := map[cid.Cid]bool{}
|
||||||
for _, b := range bms {
|
for _, b := range bms {
|
||||||
vmi.SetBlockMiner(b.Miner)
|
vmi.SetBlockMiner(b.Miner)
|
||||||
|
|
||||||
@ -178,33 +163,24 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, pstate cid.Cid, bms []B
|
|||||||
|
|
||||||
for _, cm := range append(b.BlsMessages, b.SecpkMessages...) {
|
for _, cm := range append(b.BlsMessages, b.SecpkMessages...) {
|
||||||
m := cm.VMMessage()
|
m := cm.VMMessage()
|
||||||
if err := preloadAddr(m.From); err != nil {
|
if _, found := processedMsgs[m.Cid()]; found {
|
||||||
return cid.Undef, cid.Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if applied[m.From] != m.Nonce {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
applied[m.From]++
|
r, err := vmi.ApplyMessage(ctx, cm)
|
||||||
|
|
||||||
if balances[m.From].LessThan(m.RequiredFunds()) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
balances[m.From] = types.BigSub(balances[m.From], m.RequiredFunds())
|
|
||||||
|
|
||||||
r, err := vmi.ApplyMessage(ctx, m)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, cid.Undef, err
|
return cid.Undef, cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
receipts = append(receipts, &r.MessageReceipt)
|
receipts = append(receipts, &r.MessageReceipt)
|
||||||
gasReward = big.Add(gasReward, big.NewInt(r.GasUsed))
|
gasReward = big.Add(gasReward, big.NewInt(r.GasUsed))
|
||||||
|
penalty = big.Add(penalty, r.Penalty)
|
||||||
|
|
||||||
if cb != nil {
|
if cb != nil {
|
||||||
if err := cb(cm.Cid(), m, r); err != nil {
|
if err := cb(cm.Cid(), m, r); err != nil {
|
||||||
return cid.Undef, cid.Undef, err
|
return cid.Undef, cid.Undef, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
processedMsgs[m.Cid()] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@ -233,7 +209,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, pstate cid.Cid, bms []B
|
|||||||
Method: builtin.MethodsReward.AwardBlockReward,
|
Method: builtin.MethodsReward.AwardBlockReward,
|
||||||
Params: params,
|
Params: params,
|
||||||
}
|
}
|
||||||
ret, err := vmi.ApplyMessage(ctx, rwMsg)
|
ret, err := vmi.ApplyImplicitMessage(ctx, rwMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, cid.Undef, xerrors.Errorf("failed to apply reward message for miner %s: %w", b.Miner, err)
|
return cid.Undef, cid.Undef, xerrors.Errorf("failed to apply reward message for miner %s: %w", b.Miner, err)
|
||||||
}
|
}
|
||||||
@ -265,7 +241,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, pstate cid.Cid, bms []B
|
|||||||
Method: builtin.MethodsCron.EpochTick,
|
Method: builtin.MethodsCron.EpochTick,
|
||||||
Params: nil,
|
Params: nil,
|
||||||
}
|
}
|
||||||
ret, err := vmi.ApplyMessage(ctx, cronMsg)
|
ret, err := vmi.ApplyImplicitMessage(ctx, cronMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, cid.Undef, err
|
return cid.Undef, cid.Undef, err
|
||||||
}
|
}
|
||||||
@ -335,8 +311,8 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
|
|||||||
|
|
||||||
bm := BlockMessages{
|
bm := BlockMessages{
|
||||||
Miner: b.Miner,
|
Miner: b.Miner,
|
||||||
BlsMessages: make([]store.ChainMsg, 0, len(bms)),
|
BlsMessages: make([]types.ChainMsg, 0, len(bms)),
|
||||||
SecpkMessages: make([]store.ChainMsg, 0, len(sms)),
|
SecpkMessages: make([]types.ChainMsg, 0, len(sms)),
|
||||||
TicketCount: int64(len(b.EPostProof.Proofs)),
|
TicketCount: int64(len(b.EPostProof.Proofs)),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,7 +591,7 @@ func (sm *StateManager) SearchForMessage(ctx context.Context, mcid cid.Cid) (*ty
|
|||||||
return fts, r, nil
|
return fts, r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet, m store.ChainMsg) (*types.TipSet, *types.MessageReceipt, error) {
|
func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet, m types.ChainMsg) (*types.TipSet, *types.MessageReceipt, error) {
|
||||||
|
|
||||||
cur := from
|
cur := from
|
||||||
for {
|
for {
|
||||||
|
@ -330,6 +330,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i, msg := range msgs {
|
for i, msg := range msgs {
|
||||||
|
// TODO: Use the signed message length for secp messages
|
||||||
ret, err := vmi.ApplyMessage(ctx, msg)
|
ret, err := vmi.ApplyMessage(ctx, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, nil, xerrors.Errorf("applying message %s: %w", msg.Cid(), err)
|
return cid.Undef, nil, xerrors.Errorf("applying message %s: %w", msg.Cid(), err)
|
||||||
|
@ -597,7 +597,7 @@ func (cs *ChainStore) GetGenesis() (*types.BlockHeader, error) {
|
|||||||
return types.DecodeBlock(genb.RawData())
|
return types.DecodeBlock(genb.RawData())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) GetCMessage(c cid.Cid) (ChainMsg, error) {
|
func (cs *ChainStore) GetCMessage(c cid.Cid) (types.ChainMsg, error) {
|
||||||
m, err := cs.GetMessage(c)
|
m, err := cs.GetMessage(c)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return m, nil
|
return m, nil
|
||||||
@ -650,13 +650,7 @@ func (cs *ChainStore) readAMTCids(root cid.Cid) ([]cid.Cid, error) {
|
|||||||
return cids, nil
|
return cids, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChainMsg interface {
|
func (cs *ChainStore) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) {
|
||||||
Cid() cid.Cid
|
|
||||||
VMMessage() *types.Message
|
|
||||||
ToStorageBlock() (block.Block, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cs *ChainStore) MessagesForTipset(ts *types.TipSet) ([]ChainMsg, error) {
|
|
||||||
applied := make(map[address.Address]uint64)
|
applied := make(map[address.Address]uint64)
|
||||||
balances := make(map[address.Address]types.BigInt)
|
balances := make(map[address.Address]types.BigInt)
|
||||||
|
|
||||||
@ -679,14 +673,14 @@ func (cs *ChainStore) MessagesForTipset(ts *types.TipSet) ([]ChainMsg, error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var out []ChainMsg
|
var out []types.ChainMsg
|
||||||
for _, b := range ts.Blocks() {
|
for _, b := range ts.Blocks() {
|
||||||
bms, sms, err := cs.MessagesForBlock(b)
|
bms, sms, err := cs.MessagesForBlock(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to get messages for block: %w", err)
|
return nil, xerrors.Errorf("failed to get messages for block: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsgs := make([]ChainMsg, 0, len(bms)+len(sms))
|
cmsgs := make([]types.ChainMsg, 0, len(bms)+len(sms))
|
||||||
for _, m := range bms {
|
for _, m := range bms {
|
||||||
cmsgs = append(cmsgs, m)
|
cmsgs = append(cmsgs, m)
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,7 @@ func (cs *ChainStore) call(ctx context.Context, msg *types.Message, ts *types.Ti
|
|||||||
msg.Nonce = fromActor.Nonce
|
msg.Nonce = fromActor.Nonce
|
||||||
|
|
||||||
// TODO: maybe just use the invoker directly?
|
// TODO: maybe just use the invoker directly?
|
||||||
|
// TODO: use signed message length for secp messages
|
||||||
ret, err := vmi.ApplyMessage(ctx, msg)
|
ret, err := vmi.ApplyMessage(ctx, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("apply message failed: %w", err)
|
return nil, xerrors.Errorf("apply message failed: %w", err)
|
||||||
|
@ -12,6 +12,13 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ChainMsg interface {
|
||||||
|
Cid() cid.Cid
|
||||||
|
VMMessage() *Message
|
||||||
|
ToStorageBlock() (block.Block, error)
|
||||||
|
ChainLength() int
|
||||||
|
}
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
To address.Address
|
To address.Address
|
||||||
From address.Address
|
From address.Address
|
||||||
@ -60,6 +67,14 @@ func (m *Message) Serialize() ([]byte, error) {
|
|||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Message) ChainLength() int {
|
||||||
|
ser, err := m.Serialize()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return len(ser)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Message) ToStorageBlock() (block.Block, error) {
|
func (m *Message) ToStorageBlock() (block.Block, error) {
|
||||||
data, err := m.Serialize()
|
data, err := m.Serialize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -63,6 +63,14 @@ func (sm *SignedMessage) Serialize() ([]byte, error) {
|
|||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *SignedMessage) ChainLength() int {
|
||||||
|
ser, err := m.Serialize()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return len(ser)
|
||||||
|
}
|
||||||
|
|
||||||
func (sm *SignedMessage) Size() int {
|
func (sm *SignedMessage) Size() int {
|
||||||
serdata, err := sm.Serialize()
|
serdata, err := sm.Serialize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -41,7 +41,8 @@ func (a *Applier) ApplyMessage(eCtx *vtypes.ExecutionContext, state vstate.VMWra
|
|||||||
return vtypes.MessageReceipt{}, err
|
return vtypes.MessageReceipt{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := lotusVM.ApplyMessage(ctx, toLotusMsg(message))
|
lm := toLotusMsg(message)
|
||||||
|
ret, err := lotusVM.ApplyMessage(ctx, lm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return vtypes.MessageReceipt{}, err
|
return vtypes.MessageReceipt{}, err
|
||||||
}
|
}
|
||||||
@ -82,7 +83,7 @@ func (a *Applier) ApplyTipSetMessages(state vstate.VMWrapper, blocks []vtypes.Bl
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, m := range b.SECPMessages {
|
for _, m := range b.SECPMessages {
|
||||||
bm.SecpkMessages = append(bm.SecpkMessages, toLotusMsg(&m.Message))
|
bm.SecpkMessages = append(bm.SecpkMessages, toLotusSignedMsg(m))
|
||||||
}
|
}
|
||||||
|
|
||||||
bms = append(bms, bm)
|
bms = append(bms, bm)
|
||||||
@ -145,3 +146,10 @@ func toLotusMsg(msg *vtypes.Message) *types.Message {
|
|||||||
Params: msg.Params,
|
Params: msg.Params,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toLotusSignedMsg(msg *vtypes.SignedMessage) *types.SignedMessage {
|
||||||
|
return &types.SignedMessage{
|
||||||
|
Message: *toLotusMsg(&msg.Message),
|
||||||
|
Signature: msg.Signature,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -39,7 +39,7 @@ func (f *Factories) NewRandomnessSource() vstate.RandomnessSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *Factories) NewValidationConfig() vstate.ValidationConfig {
|
func (f *Factories) NewValidationConfig() vstate.ValidationConfig {
|
||||||
trackGas := false
|
trackGas := true
|
||||||
checkExit := true
|
checkExit := true
|
||||||
checkRet := true
|
checkRet := true
|
||||||
// ignore gas and return value assertions
|
// ignore gas and return value assertions
|
||||||
|
@ -87,7 +87,8 @@ func (k *KeyManager) newBLSKey() *wallet.Key {
|
|||||||
//sk := ffi.PrivateKeyGenerate(s.blsSeed)
|
//sk := ffi.PrivateKeyGenerate(s.blsSeed)
|
||||||
// s.blsSeed++
|
// s.blsSeed++
|
||||||
sk := [32]byte{}
|
sk := [32]byte{}
|
||||||
sk[0] = uint8(k.blsSeed + 1) // hack to keep gas values determinist
|
sk[0] = uint8(k.blsSeed) // hack to keep gas values determinist
|
||||||
|
k.blsSeed++
|
||||||
key, err := wallet.NewKey(types.KeyInfo{
|
key, err := wallet.NewKey(types.KeyInfo{
|
||||||
Type: wallet.KTBLS,
|
Type: wallet.KTBLS,
|
||||||
PrivateKey: sk[:],
|
PrivateKey: sk[:],
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-datastore"
|
"github.com/ipfs/go-datastore"
|
||||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
@ -18,7 +17,6 @@ import (
|
|||||||
|
|
||||||
vstate "github.com/filecoin-project/chain-validation/state"
|
vstate "github.com/filecoin-project/chain-validation/state"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/gen/genesis"
|
|
||||||
"github.com/filecoin-project/lotus/chain/state"
|
"github.com/filecoin-project/lotus/chain/state"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
@ -116,37 +114,50 @@ func (s *StateWrapper) SetActorState(addr address.Address, balance abi.TokenAmou
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *StateWrapper) CreateActor(code cid.Cid, addr address.Address, balance abi.TokenAmount, actorState runtime.CBORMarshaler) (vstate.Actor, address.Address, error) {
|
func (s *StateWrapper) CreateActor(code cid.Cid, addr address.Address, balance abi.TokenAmount, actorState runtime.CBORMarshaler) (vstate.Actor, address.Address, error) {
|
||||||
if addr == builtin.InitActorAddr || addr == builtin.StoragePowerActorAddr || addr == builtin.StorageMarketActorAddr {
|
idAddr := addr
|
||||||
act, err := s.SetupSingletonActor(addr)
|
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
|
||||||
|
if err != nil {
|
||||||
|
return nil, address.Undef, err
|
||||||
|
}
|
||||||
|
if addr.Protocol() != address.ID {
|
||||||
|
|
||||||
|
actHead, err := tree.Store.Put(context.Background(), actorState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, address.Undef, err
|
return nil, address.Undef, err
|
||||||
}
|
}
|
||||||
return act, addr, nil
|
actr := &actorWrapper{types.Actor{
|
||||||
|
Code: code,
|
||||||
|
Head: actHead,
|
||||||
|
Balance: balance,
|
||||||
|
}}
|
||||||
|
|
||||||
|
idAddr, err = tree.RegisterNewAddress(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, address.Undef, xerrors.Errorf("register new address for actor: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tree.SetActor(addr, &actr.Actor); err != nil {
|
||||||
|
return nil, address.Undef, xerrors.Errorf("setting new actor for actor: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tree, err := state.LoadStateTree(s.cst, s.Root())
|
|
||||||
|
// store newState
|
||||||
|
head, err := tree.Store.Put(context.Background(), actorState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, address.Undef, err
|
return nil, address.Undef, err
|
||||||
}
|
}
|
||||||
actHead, err := tree.Store.Put(context.Background(), actorState)
|
|
||||||
if err != nil {
|
// create and store actor object
|
||||||
return nil, address.Undef, err
|
a := types.Actor{
|
||||||
}
|
|
||||||
actr := &actorWrapper{types.Actor{
|
|
||||||
Code: code,
|
Code: code,
|
||||||
Head: actHead,
|
Head: head,
|
||||||
Balance: balance,
|
Balance: balance,
|
||||||
}}
|
}
|
||||||
|
if err := tree.SetActor(idAddr, &a); err != nil {
|
||||||
idAddr, err := tree.RegisterNewAddress(addr, &actr.Actor)
|
return nil, address.Undef, err
|
||||||
if err != nil {
|
|
||||||
return nil, address.Undef, xerrors.Errorf("register new address for actor: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tree.SetActor(addr, &actr.Actor); err != nil {
|
return &actorWrapper{a}, idAddr, s.flush(tree)
|
||||||
return nil, address.Undef, xerrors.Errorf("setting new actor for actor: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return actr, idAddr, s.flush(tree)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flushes a state tree to storage and sets this state's root to that tree's root CID.
|
// Flushes a state tree to storage and sets this state's root to that tree's root CID.
|
||||||
@ -192,46 +203,3 @@ type contextStore struct {
|
|||||||
func (s *contextStore) Context() context.Context {
|
func (s *contextStore) Context() context.Context {
|
||||||
return s.ctx
|
return s.ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StateWrapper) SetupSingletonActor(addr address.Address) (vstate.Actor, error) {
|
|
||||||
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
switch addr {
|
|
||||||
case builtin.InitActorAddr:
|
|
||||||
// FIXME this is going to be a problem if go-filecoin and lotus setup their init actors with different netnames
|
|
||||||
// ideally lotus should use the init actor constructor
|
|
||||||
initact, err := genesis.SetupInitActor(s.bs, "chain-validation", nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, xerrors.Errorf("setup init actor: %w", err)
|
|
||||||
}
|
|
||||||
if err := tree.SetActor(builtin.InitActorAddr, initact); err != nil {
|
|
||||||
return nil, xerrors.Errorf("set init actor: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &actorWrapper{*initact}, s.flush(tree)
|
|
||||||
case builtin.StorageMarketActorAddr:
|
|
||||||
smact, err := genesis.SetupStorageMarketActor(s.bs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, xerrors.Errorf("setup storage marker actor: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := tree.SetActor(builtin.StorageMarketActorAddr, smact); err != nil {
|
|
||||||
return nil, xerrors.Errorf("set storage marker actor: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &actorWrapper{*smact}, s.flush(tree)
|
|
||||||
case builtin.StoragePowerActorAddr:
|
|
||||||
spact, err := genesis.SetupStoragePowerActor(s.bs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, xerrors.Errorf("setup storage power actor: %w", err)
|
|
||||||
}
|
|
||||||
if err := tree.SetActor(builtin.StoragePowerActorAddr, spact); err != nil {
|
|
||||||
return nil, xerrors.Errorf("set storage power actor: %w", err)
|
|
||||||
}
|
|
||||||
return &actorWrapper{*spact}, s.flush(tree)
|
|
||||||
default:
|
|
||||||
return nil, xerrors.Errorf("%v is not a singleton actor address", addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -2,9 +2,11 @@ package vm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"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"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
|
||||||
@ -27,25 +29,50 @@ func init() {
|
|||||||
var EmptyObjectCid cid.Cid
|
var EmptyObjectCid cid.Cid
|
||||||
|
|
||||||
// Creates account actors from only BLS/SECP256K1 addresses.
|
// Creates account actors from only BLS/SECP256K1 addresses.
|
||||||
func TryCreateAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
func TryCreateAccountActor(ctx context.Context, rt *Runtime, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
||||||
act, err := makeActor(st, addr)
|
addrID, err := rt.state.RegisterNewAddress(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := st.RegisterNewAddress(addr, act); err != nil {
|
|
||||||
return nil, aerrors.Escalate(err, "registering actor address")
|
return nil, aerrors.Escalate(err, "registering actor address")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := rt.chargeGasSafe(PricelistByEpoch(rt.height).OnCreateActor()); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
return act, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
func makeActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
||||||
switch addr.Protocol() {
|
switch addr.Protocol() {
|
||||||
case address.BLS:
|
case address.BLS:
|
||||||
return NewBLSAccountActor(st, addr)
|
return NewBLSAccountActor()
|
||||||
case address.SECP256K1:
|
case address.SECP256K1:
|
||||||
return NewSecp256k1AccountActor(st, addr)
|
return NewSecp256k1AccountActor()
|
||||||
case address.ID:
|
case address.ID:
|
||||||
return nil, aerrors.Newf(1, "no actor with given ID: %s", addr)
|
return nil, aerrors.Newf(1, "no actor with given ID: %s", addr)
|
||||||
case address.Actor:
|
case address.Actor:
|
||||||
@ -55,37 +82,21 @@ func makeActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBLSAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
func NewBLSAccountActor() (*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")
|
|
||||||
}
|
|
||||||
|
|
||||||
nact := &types.Actor{
|
nact := &types.Actor{
|
||||||
Code: builtin.AccountActorCodeID,
|
Code: builtin.AccountActorCodeID,
|
||||||
Balance: types.NewInt(0),
|
Balance: types.NewInt(0),
|
||||||
Head: c,
|
Head: EmptyObjectCid,
|
||||||
}
|
}
|
||||||
|
|
||||||
return nact, nil
|
return nact, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSecp256k1AccountActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
func NewSecp256k1AccountActor() (*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")
|
|
||||||
}
|
|
||||||
|
|
||||||
nact := &types.Actor{
|
nact := &types.Actor{
|
||||||
Code: builtin.AccountActorCodeID,
|
Code: builtin.AccountActorCodeID,
|
||||||
Balance: types.NewInt(0),
|
Balance: types.NewInt(0),
|
||||||
Head: c,
|
Head: EmptyObjectCid,
|
||||||
}
|
}
|
||||||
|
|
||||||
return nact, nil
|
return nact, nil
|
||||||
|
@ -281,7 +281,7 @@ func (rs *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMars
|
|||||||
params = buf.Bytes()
|
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 != nil {
|
||||||
if err.IsFatal() {
|
if err.IsFatal() {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -292,7 +292,7 @@ func (rs *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMars
|
|||||||
return &dumbWrapperType{ret}, 0
|
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")
|
ctx, span := trace.StartSpan(rt.ctx, "vmc.Send")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
if span.IsRecordingEvents() {
|
if span.IsRecordingEvents() {
|
||||||
@ -304,7 +304,7 @@ func (rt *Runtime) internalSend(to address.Address, method abi.MethodNum, value
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
From: rt.Message().Receiver(),
|
From: from,
|
||||||
To: to,
|
To: to,
|
||||||
Method: method,
|
Method: method,
|
||||||
Value: value,
|
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)
|
return nil, aerrors.Fatalf("snapshot failed: %s", err)
|
||||||
}
|
}
|
||||||
defer st.ClearSnapshot()
|
defer st.ClearSnapshot()
|
||||||
rt.ChargeGas(rt.Pricelist().OnMethodInvocation(value, method))
|
|
||||||
|
|
||||||
ret, errSend, subrt := rt.vm.send(ctx, msg, rt, 0)
|
ret, errSend, subrt := rt.vm.send(ctx, msg, rt, 0)
|
||||||
if errSend != nil {
|
if errSend != nil {
|
||||||
|
@ -8,8 +8,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
suites "github.com/filecoin-project/chain-validation/suites"
|
suites "github.com/filecoin-project/chain-validation/suites"
|
||||||
"github.com/filecoin-project/chain-validation/suites/tipset"
|
|
||||||
|
|
||||||
factory "github.com/filecoin-project/lotus/chain/validation"
|
factory "github.com/filecoin-project/lotus/chain/validation"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,7 +34,6 @@ func init() {
|
|||||||
// initialize the test skipper with tests being skipped
|
// initialize the test skipper with tests being skipped
|
||||||
TestSuiteSkipper = TestSkipper{testSkips: []suites.TestCase{
|
TestSuiteSkipper = TestSkipper{testSkips: []suites.TestCase{
|
||||||
/* tests to skip go here */
|
/* tests to skip go here */
|
||||||
tipset.TestMinerRewardsAndPenalties,
|
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
@ -185,7 +184,7 @@ type Rand interface {
|
|||||||
type ApplyRet struct {
|
type ApplyRet struct {
|
||||||
types.MessageReceipt
|
types.MessageReceipt
|
||||||
ActorErr aerrors.ActorError
|
ActorErr aerrors.ActorError
|
||||||
Penalty big.Int
|
Penalty types.BigInt
|
||||||
InternalExecutions []*ExecutionResult
|
InternalExecutions []*ExecutionResult
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,25 +210,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)
|
toActor, err := st.GetActor(msg.To)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if xerrors.Is(err, init_.ErrAddressNotFound) {
|
if xerrors.Is(err, init_.ErrAddressNotFound) {
|
||||||
a, err := TryCreateAccountActor(st, msg.To)
|
a, err := TryCreateAccountActor(ctx, rt, msg.To)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, aerrors.Absorb(err, 1, "could not create account"), rt
|
return nil, aerrors.Absorb(err, 1, "could not create account"), rt
|
||||||
}
|
}
|
||||||
toActor = a
|
toActor = a
|
||||||
gasUsed += PricelistByEpoch(vm.blockHeight).OnCreateActor()
|
|
||||||
} else {
|
} else {
|
||||||
return nil, aerrors.Escalate(err, "getting actor"), rt
|
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 types.BigCmp(msg.Value, types.NewInt(0)) != 0 {
|
||||||
if err := vm.transfer(msg.From, msg.To, msg.Value); err != nil {
|
if err := vm.transfer(msg.From, msg.To, msg.Value); err != nil {
|
||||||
return nil, aerrors.Absorb(err, 1, "failed to transfer funds"), nil
|
return nil, aerrors.Absorb(err, 1, "failed to transfer funds"), nil
|
||||||
@ -263,9 +261,24 @@ func checkMessage(msg *types.Message) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet, error) {
|
func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*ApplyRet, error) {
|
||||||
|
ret, actorErr, _ := vm.send(ctx, msg, nil, 0)
|
||||||
|
return &ApplyRet{
|
||||||
|
MessageReceipt: types.MessageReceipt{
|
||||||
|
ExitCode: exitcode.ExitCode(aerrors.RetCode(actorErr)),
|
||||||
|
Return: ret,
|
||||||
|
GasUsed: 0,
|
||||||
|
},
|
||||||
|
ActorErr: actorErr,
|
||||||
|
InternalExecutions: nil,
|
||||||
|
Penalty: types.NewInt(0),
|
||||||
|
}, actorErr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "vm.ApplyMessage")
|
ctx, span := trace.StartSpan(ctx, "vm.ApplyMessage")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
msg := cmsg.VMMessage()
|
||||||
if span.IsRecordingEvents() {
|
if span.IsRecordingEvents() {
|
||||||
span.AddAttributes(
|
span.AddAttributes(
|
||||||
trace.StringAttribute("to", msg.To.String()),
|
trace.StringAttribute("to", msg.To.String()),
|
||||||
@ -279,42 +292,52 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pl := PricelistByEpoch(vm.blockHeight)
|
pl := PricelistByEpoch(vm.blockHeight)
|
||||||
serMsg, err := msg.Serialize()
|
msgGasCost := pl.OnChainMessage(cmsg.ChainLength())
|
||||||
if err != nil {
|
|
||||||
return nil, xerrors.Errorf("could not serialize message: %w", err)
|
|
||||||
}
|
|
||||||
msgGasCost := pl.OnChainMessage(len(serMsg))
|
|
||||||
// TODO: charge miner??
|
// TODO: charge miner??
|
||||||
if msgGasCost > msg.GasLimit {
|
if msgGasCost > msg.GasLimit {
|
||||||
return &ApplyRet{
|
return &ApplyRet{
|
||||||
MessageReceipt: types.MessageReceipt{
|
MessageReceipt: types.MessageReceipt{
|
||||||
ExitCode: exitcode.SysErrOutOfGas,
|
ExitCode: exitcode.SysErrOutOfGas,
|
||||||
GasUsed: msg.GasLimit,
|
GasUsed: 0,
|
||||||
},
|
},
|
||||||
|
Penalty: types.BigMul(msg.GasPrice, types.NewInt(uint64(msgGasCost))),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
st := vm.cstate
|
st := vm.cstate
|
||||||
|
|
||||||
|
minerPenaltyAmount := types.BigMul(msg.GasPrice, types.NewInt(uint64(msgGasCost)))
|
||||||
fromActor, err := st.GetActor(msg.From)
|
fromActor, err := st.GetActor(msg.From)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if xerrors.Is(err, types.ErrActorNotFound) {
|
if xerrors.Is(err, types.ErrActorNotFound) {
|
||||||
return &ApplyRet{
|
return &ApplyRet{
|
||||||
MessageReceipt: types.MessageReceipt{
|
MessageReceipt: types.MessageReceipt{
|
||||||
ExitCode: exitcode.SysErrActorNotFound,
|
ExitCode: exitcode.SysErrActorNotFound,
|
||||||
GasUsed: msg.GasLimit,
|
GasUsed: 0,
|
||||||
},
|
},
|
||||||
|
Penalty: minerPenaltyAmount,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("failed to look up from actor: %w", err)
|
return nil, xerrors.Errorf("failed to look up from actor: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !fromActor.Code.Equals(builtin.AccountActorCodeID) {
|
||||||
|
return &ApplyRet{
|
||||||
|
MessageReceipt: types.MessageReceipt{
|
||||||
|
ExitCode: exitcode.SysErrForbidden,
|
||||||
|
GasUsed: 0,
|
||||||
|
},
|
||||||
|
Penalty: minerPenaltyAmount,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
if msg.Nonce != fromActor.Nonce {
|
if msg.Nonce != fromActor.Nonce {
|
||||||
return &ApplyRet{
|
return &ApplyRet{
|
||||||
MessageReceipt: types.MessageReceipt{
|
MessageReceipt: types.MessageReceipt{
|
||||||
ExitCode: exitcode.SysErrInvalidCallSeqNum,
|
ExitCode: exitcode.SysErrInvalidCallSeqNum,
|
||||||
GasUsed: 0,
|
GasUsed: 0,
|
||||||
},
|
},
|
||||||
|
Penalty: minerPenaltyAmount,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,8 +347,9 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet,
|
|||||||
return &ApplyRet{
|
return &ApplyRet{
|
||||||
MessageReceipt: types.MessageReceipt{
|
MessageReceipt: types.MessageReceipt{
|
||||||
ExitCode: exitcode.SysErrInsufficientFunds,
|
ExitCode: exitcode.SysErrInsufficientFunds,
|
||||||
GasUsed: msg.GasLimit,
|
GasUsed: 0,
|
||||||
},
|
},
|
||||||
|
Penalty: minerPenaltyAmount,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,21 +391,19 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet,
|
|||||||
var gasUsed int64
|
var gasUsed int64
|
||||||
|
|
||||||
if errcode = aerrors.RetCode(actorErr); errcode != 0 {
|
if errcode = aerrors.RetCode(actorErr); errcode != 0 {
|
||||||
gasUsed = msg.GasLimit
|
|
||||||
// revert all state changes since snapshot
|
// revert all state changes since snapshot
|
||||||
if err := st.Revert(); err != nil {
|
if err := st.Revert(); err != nil {
|
||||||
return nil, xerrors.Errorf("revert state failed: %w", err)
|
return nil, xerrors.Errorf("revert state failed: %w", err)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
gasUsed = rt.gasUsed
|
gasUsed = rt.gasUsed
|
||||||
if gasUsed < 0 {
|
if gasUsed < 0 {
|
||||||
gasUsed = 0
|
gasUsed = 0
|
||||||
}
|
}
|
||||||
// refund unused gas
|
// refund unused gas
|
||||||
refund := types.BigMul(types.NewInt(uint64(msg.GasLimit-gasUsed)), msg.GasPrice)
|
refund := types.BigMul(types.NewInt(uint64(msg.GasLimit-gasUsed)), msg.GasPrice)
|
||||||
if err := vm.transferFromGasHolder(msg.From, gasHolder, refund); err != nil {
|
if err := vm.transferFromGasHolder(msg.From, gasHolder, refund); err != nil {
|
||||||
return nil, xerrors.Errorf("failed to refund gas")
|
return nil, xerrors.Errorf("failed to refund gas")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gasReward := types.BigMul(msg.GasPrice, types.NewInt(uint64(gasUsed)))
|
gasReward := types.BigMul(msg.GasPrice, types.NewInt(uint64(gasUsed)))
|
||||||
@ -401,6 +423,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet,
|
|||||||
},
|
},
|
||||||
ActorErr: actorErr,
|
ActorErr: actorErr,
|
||||||
InternalExecutions: rt.internalExecutions,
|
InternalExecutions: rt.internalExecutions,
|
||||||
|
Penalty: types.NewInt(0),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user