Merge pull request #160 from filecoin-project/feat/gas3
Charge per put and get
This commit is contained in:
commit
24fb5ca624
@ -6,7 +6,9 @@ import (
|
||||
. "github.com/filecoin-project/go-lotus/chain/actors"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDumpEmpyStruct(t *testing.T) {
|
||||
@ -15,121 +17,62 @@ func TestDumpEmpyStruct(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStorageMarketCreateMiner(t *testing.T) {
|
||||
h := NewHarness(t)
|
||||
var sminer address.Address
|
||||
h.Steps = []Step{
|
||||
{
|
||||
M: types.Message{
|
||||
To: StorageMarketAddress,
|
||||
From: h.From,
|
||||
Method: SMAMethods.CreateStorageMiner,
|
||||
GasPrice: types.NewInt(1),
|
||||
GasLimit: types.NewInt(1000),
|
||||
Value: types.NewInt(0),
|
||||
Params: h.DumpObject(&CreateStorageMinerParams{
|
||||
Owner: h.From,
|
||||
Worker: h.Third,
|
||||
SectorSize: types.NewInt(SectorSize),
|
||||
PeerID: "fakepeerid",
|
||||
}),
|
||||
},
|
||||
Ret: func(t *testing.T, ret *types.MessageReceipt) {
|
||||
if ret.ExitCode != 0 {
|
||||
t.Fatal("invokation failed: ", ret.ExitCode)
|
||||
}
|
||||
var ownerAddr, workerAddr address.Address
|
||||
|
||||
var err error
|
||||
sminer, err = address.NewFromBytes(ret.Return)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if sminer.String() != "t0103" {
|
||||
t.Fatalf("hold up got: %s", sminer)
|
||||
}
|
||||
h.Steps[1].M.Params = h.DumpObject(&IsMinerParam{Addr: sminer})
|
||||
h.Steps[2].M.Params = h.DumpObject(&PowerLookupParams{Miner: sminer})
|
||||
},
|
||||
},
|
||||
{
|
||||
M: types.Message{
|
||||
To: StorageMarketAddress,
|
||||
From: h.From,
|
||||
Method: SMAMethods.IsMiner,
|
||||
GasPrice: types.NewInt(1),
|
||||
GasLimit: types.NewInt(1),
|
||||
Value: types.NewInt(0),
|
||||
Nonce: 1,
|
||||
// Params is sent in previous set
|
||||
},
|
||||
Ret: func(t *testing.T, ret *types.MessageReceipt) {
|
||||
if ret.ExitCode != 0 {
|
||||
t.Fatal("invokation failed: ", ret.ExitCode)
|
||||
}
|
||||
var output bool
|
||||
err := cbor.DecodeInto(ret.Return, &output)
|
||||
if err != nil {
|
||||
t.Fatalf("error decoding: %+v", err)
|
||||
}
|
||||
|
||||
if !output {
|
||||
t.Fatalf("%s is miner but IsMiner call returned false", sminer)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
M: types.Message{
|
||||
To: StorageMarketAddress,
|
||||
From: h.From,
|
||||
Method: SMAMethods.PowerLookup,
|
||||
GasPrice: types.NewInt(1),
|
||||
GasLimit: types.NewInt(1),
|
||||
Value: types.NewInt(0),
|
||||
Nonce: 2,
|
||||
// Params is sent in previous set
|
||||
},
|
||||
Ret: func(t *testing.T, ret *types.MessageReceipt) {
|
||||
if ret.ExitCode != 0 {
|
||||
t.Fatal("invokation failed: ", ret.ExitCode)
|
||||
}
|
||||
power := types.BigFromBytes(ret.Return)
|
||||
|
||||
if types.BigCmp(power, types.NewInt(0)) != 0 {
|
||||
t.Fatalf("power should be zero, is: %s", power)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
state := h.Execute()
|
||||
act, err := state.GetActor(sminer)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if act.Code != StorageMinerCodeCid {
|
||||
t.Fatalf("Expected correct code, got %s, instead of %s", act.Code, StorageMinerCodeCid)
|
||||
}
|
||||
hblock, err := h.bs.Get(act.Head)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
opts := []HarnessOpt{
|
||||
HarnessAddr(&ownerAddr, 10000),
|
||||
HarnessAddr(&workerAddr, 10000),
|
||||
}
|
||||
|
||||
smas := &StorageMinerActorState{}
|
||||
err = cbor.DecodeInto(hblock.RawData(), smas)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
h := NewHarness2(t, opts...)
|
||||
|
||||
var minerAddr address.Address
|
||||
{
|
||||
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.CreateStorageMiner,
|
||||
CreateStorageMinerParams{
|
||||
Owner: ownerAddr,
|
||||
Worker: workerAddr,
|
||||
SectorSize: types.NewInt(SectorSize),
|
||||
PeerID: "fakepeerid",
|
||||
})
|
||||
ApplyOK(t, ret)
|
||||
var err error
|
||||
minerAddr, err = address.NewFromBytes(ret.Return)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
iblock, err := h.bs.Get(smas.Info)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
{
|
||||
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.IsMiner,
|
||||
IsMinerParam{Addr: minerAddr})
|
||||
ApplyOK(t, ret)
|
||||
|
||||
var output bool
|
||||
err := cbor.DecodeInto(ret.Return, &output)
|
||||
if err != nil {
|
||||
t.Fatalf("error decoding: %+v", err)
|
||||
}
|
||||
|
||||
if !output {
|
||||
t.Fatalf("%s is miner but IsMiner call returned false", minerAddr)
|
||||
}
|
||||
}
|
||||
|
||||
var minfo MinerInfo
|
||||
if err := cbor.DecodeInto(iblock.RawData(), &minfo); err != nil {
|
||||
t.Fatal(err)
|
||||
{
|
||||
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.PowerLookup,
|
||||
PowerLookupParams{Miner: minerAddr})
|
||||
ApplyOK(t, ret)
|
||||
power := types.BigFromBytes(ret.Return)
|
||||
|
||||
if types.BigCmp(power, types.NewInt(0)) != 0 {
|
||||
t.Fatalf("power should be zero, is: %s", power)
|
||||
}
|
||||
}
|
||||
|
||||
if minfo.Owner != h.From {
|
||||
t.Fatalf("Owner should be %s, but is %s", h.From, minfo.Owner)
|
||||
{
|
||||
ret, _ := h.Invoke(t, ownerAddr, minerAddr, MAMethods.GetOwner, nil)
|
||||
ApplyOK(t, ret)
|
||||
oA, err := address.NewFromBytes(ret.Return)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, ownerAddr, oA, "return from GetOwner should be equal to the owner")
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
||||
)
|
||||
|
||||
const testGasLimit = 100
|
||||
const testGasLimit = 1000
|
||||
|
||||
type HarnessInit struct {
|
||||
NAddrs uint64
|
||||
|
@ -234,7 +234,7 @@ func TestSyncMining(t *testing.T) {
|
||||
|
||||
require.NoError(t, tu.mn.LinkAll())
|
||||
tu.connect(1, 0)
|
||||
time.Sleep(time.Second * 2)
|
||||
time.Sleep(time.Second * 4)
|
||||
|
||||
tu.checkHeight("client", client, H)
|
||||
|
||||
|
@ -26,6 +26,9 @@ var log = logging.Logger("vm")
|
||||
|
||||
const (
|
||||
gasFundTransfer = 10
|
||||
gasGetObj = 10
|
||||
gasPutObj = 20
|
||||
gasCommit = 50
|
||||
)
|
||||
|
||||
type VMContext struct {
|
||||
@ -45,8 +48,6 @@ type VMContext struct {
|
||||
|
||||
// address that started invokation chain
|
||||
origin address.Address
|
||||
|
||||
storage *storage
|
||||
}
|
||||
|
||||
// Message is the message that kicked off the current invocation
|
||||
@ -54,41 +55,47 @@ func (vmc *VMContext) Message() *types.Message {
|
||||
return vmc.msg
|
||||
}
|
||||
|
||||
type storage struct {
|
||||
// would be great to stop depending on this crap everywhere
|
||||
// I am my own worst enemy
|
||||
cst *hamt.CborIpldStore
|
||||
head cid.Cid
|
||||
}
|
||||
// Storage interface
|
||||
|
||||
func (s *storage) Put(i interface{}) (cid.Cid, aerrors.ActorError) {
|
||||
c, err := s.cst.Put(context.TODO(), i)
|
||||
func (vmc *VMContext) Put(i interface{}) (cid.Cid, aerrors.ActorError) {
|
||||
if err := vmc.ChargeGas(gasPutObj); err != nil {
|
||||
return cid.Undef, aerrors.Wrap(err, "out of gas")
|
||||
}
|
||||
c, err := vmc.cst.Put(context.TODO(), i)
|
||||
if err != nil {
|
||||
return cid.Undef, aerrors.Escalate(err, "putting cid")
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (s *storage) Get(c cid.Cid, out interface{}) aerrors.ActorError {
|
||||
return aerrors.Escalate(s.cst.Get(context.TODO(), c, out), "getting cid")
|
||||
func (vmc *VMContext) Get(c cid.Cid, out interface{}) aerrors.ActorError {
|
||||
if err := vmc.ChargeGas(gasGetObj); err != nil {
|
||||
return aerrors.Wrap(err, "out of gas")
|
||||
}
|
||||
return aerrors.Escalate(vmc.cst.Get(context.TODO(), c, out), "getting cid")
|
||||
}
|
||||
|
||||
func (s *storage) GetHead() cid.Cid {
|
||||
return s.head
|
||||
func (vmc *VMContext) GetHead() cid.Cid {
|
||||
return vmc.sroot
|
||||
}
|
||||
|
||||
func (s *storage) Commit(oldh, newh cid.Cid) aerrors.ActorError {
|
||||
if s.head != oldh {
|
||||
func (vmc *VMContext) Commit(oldh, newh cid.Cid) aerrors.ActorError {
|
||||
if err := vmc.ChargeGas(gasCommit); err != nil {
|
||||
return aerrors.Wrap(err, "out of gas")
|
||||
}
|
||||
if vmc.sroot != oldh {
|
||||
return aerrors.New(1, "failed to update, inconsistent base reference")
|
||||
}
|
||||
|
||||
s.head = newh
|
||||
vmc.sroot = newh
|
||||
return nil
|
||||
}
|
||||
|
||||
// End of storage interface
|
||||
|
||||
// Storage provides access to the VM storage layer
|
||||
func (vmc *VMContext) Storage() types.Storage {
|
||||
return vmc.storage
|
||||
return vmc
|
||||
}
|
||||
|
||||
func (vmc *VMContext) Ipld() *hamt.CborIpldStore {
|
||||
@ -204,10 +211,6 @@ func (vm *VM) makeVMContext(ctx context.Context, sroot cid.Cid, msg *types.Messa
|
||||
origin: origin,
|
||||
height: vm.blockHeight,
|
||||
cst: vm.cst,
|
||||
storage: &storage{
|
||||
cst: vm.cst,
|
||||
head: sroot,
|
||||
},
|
||||
|
||||
gasUsed: usedGas,
|
||||
gasAvailable: msg.GasLimit,
|
||||
|
Loading…
Reference in New Issue
Block a user