Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more methods (IsMiner, GetPower) #51

Merged
merged 3 commits into from
Jul 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions chain/actors/actor_miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,24 @@ type StorageMinerConstructorParams struct {

func (sma StorageMinerActor) Exports() []interface{} {
return []interface{}{
sma.StorageMinerActor,
sma.CommitSector,
0: sma.StorageMinerConstructor,
1: sma.CommitSector,
//2: sma.SubmitPost,
//3: sma.SlashStorageFault,
//4: sma.GetCurrentProvingSet,
//5: sma.ArbitrateDeal,
//6: sma.DePledge,
//7: sma.GetOwner,
//8: sma.GetWorkerAddr,
9: sma.GetPower,
//10: sma.GetPeerID,
//11: sma.GetSectorSize,
//12: sma.UpdatePeerID,
//13: sma.ChangeWorker,
}
}

func (sma StorageMinerActor) StorageMinerActor(act *types.Actor, vmctx types.VMContext, params *StorageMinerConstructorParams) (types.InvokeRet, error) {
func (sma StorageMinerActor) StorageMinerConstructor(act *types.Actor, vmctx types.VMContext, params *StorageMinerConstructorParams) (types.InvokeRet, error) {
var self StorageMinerActorState
self.Owner = params.Owner
self.Worker = params.Worker
Expand Down Expand Up @@ -209,6 +221,17 @@ func (sma StorageMinerActor) CommitSector(act *types.Actor, vmctx types.VMContex
return types.InvokeRet{}, nil
}

func (sma StorageMinerActor) GetPower(act *types.Actor, vmctx types.VMContext, params *struct{}) (types.InvokeRet, error) {
var self StorageMinerActorState
state := vmctx.Storage().GetHead()
if err := vmctx.Storage().Get(state, &self); err != nil {
return types.InvokeRet{}, err
}
return types.InvokeRet{
Result: self.Power.Bytes(),
}, nil
}

func SectorIsUnique(cst *hamt.CborIpldStore, sroot cid.Cid, sid types.BigInt) (bool, error) {
nd, err := hamt.LoadNode(context.TODO(), cst, sroot)
if err != nil {
Expand Down
52 changes: 39 additions & 13 deletions chain/actors/actor_storagemarket.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,30 @@ import (

cbor "github.com/ipfs/go-ipld-cbor"
"github.com/libp2p/go-libp2p-core/peer"
"golang.org/x/xerrors"
)

const SectorSize = 1024

func init() {
cbor.RegisterCborType(StorageMarketState{})
cbor.RegisterCborType(CreateStorageMinerParams{})
cbor.RegisterCborType(IsMinerParam{})
cbor.RegisterCborType(PowerLookupParams{})
}

type StorageMarketActor struct{}

func (sma StorageMarketActor) Exports() []interface{} {
return []interface{}{
nil,
sma.CreateStorageMiner,
nil, // TODO: slash consensus fault
sma.UpdateStorage,
//0: sma.StorageMarketConstructor,
1: sma.CreateStorageMiner,
//2: sma.SlashConsensusFault,
3: sma.UpdateStorage,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait. what? Thats real syntax?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is real: https://golang.org/ref/spec#Composite_literals
Composite literals use the same syntax for maps and slices/arrays.

4: sma.GetTotalStorage,
5: sma.PowerLookup,
6: sma.IsMiner,
//7: sma.StorageCollateralForSize,
}
}

Expand Down Expand Up @@ -61,17 +68,17 @@ func (sma StorageMarketActor) CreateStorageMiner(act *types.Actor, vmctx types.V
return types.InvokeRet{}, err
}

naddr, err := address.NewFromBytes(ret)
if err != nil {
return types.InvokeRet{}, err
}

if exit != 0 {
return types.InvokeRet{
ReturnCode: 2,
}, nil
}

naddr, err := address.NewFromBytes(ret)
if err != nil {
return types.InvokeRet{}, err
}

var self StorageMarketState
old := vmctx.Storage().GetHead()
if err := vmctx.Storage().Get(old, &self); err != nil {
Expand Down Expand Up @@ -123,7 +130,7 @@ func (sma StorageMarketActor) UpdateStorage(act *types.Actor, vmctx types.VMCont
return types.InvokeRet{}, nil
}

func (sma StorageMarketActor) GetTotalStorage(act *types.Actor, vmctx types.VMContext, params struct{}) (types.InvokeRet, error) {
func (sma StorageMarketActor) GetTotalStorage(act *types.Actor, vmctx types.VMContext, params *struct{}) (types.InvokeRet, error) {
var self StorageMarketState
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
return types.InvokeRet{}, err
Expand All @@ -141,7 +148,7 @@ type PowerLookupParams struct {
func (sma StorageMarketActor) PowerLookup(act *types.Actor, vmctx types.VMContext, params *PowerLookupParams) (types.InvokeRet, error) {
var self StorageMarketState
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
return types.InvokeRet{}, err
return types.InvokeRet{}, xerrors.Errorf("getting head: %w", err)
}

if _, ok := self.Miners[params.Miner]; !ok {
Expand All @@ -151,9 +158,9 @@ func (sma StorageMarketActor) PowerLookup(act *types.Actor, vmctx types.VMContex
}, nil
}

ret, code, err := vmctx.Send(params.Miner, 9999, types.NewInt(0), nil)
ret, code, err := vmctx.Send(params.Miner, 9, types.NewInt(0), EmptyStructCBOR)
if err != nil {
return types.InvokeRet{}, err
return types.InvokeRet{}, xerrors.Errorf("invoke Miner.GetPower: %w", err)
}

if code != 0 {
Expand All @@ -167,3 +174,22 @@ func (sma StorageMarketActor) PowerLookup(act *types.Actor, vmctx types.VMContex
Result: ret,
}, nil
}

type IsMinerParam struct {
Addr address.Address
}

func (sma StorageMarketActor) IsMiner(act *types.Actor, vmctx types.VMContext, param *IsMinerParam) (types.InvokeRet, error) {
var self StorageMarketState
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
return types.InvokeRet{}, err
}
_, ok := self.Miners[param.Addr]
out, err := SerializeParams(ok)
if err != nil {
return types.InvokeRet{}, err
}
return types.InvokeRet{
Result: out,
}, nil
}
63 changes: 59 additions & 4 deletions chain/actors/actor_storagemarket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@ import (
cbor "github.com/ipfs/go-ipld-cbor"
)

func TestDumpEmpyStruct(t *testing.T) {
res, err := SerializeParams(struct{}{})
t.Logf("res: %x, err: %+v", res, err)
}

func TestStorageMarketCreateMiner(t *testing.T) {
h := NewHarness(t)
var outaddr address.Address
var sminer address.Address
h.Steps = []Step{
{
M: types.Message{
Expand All @@ -34,19 +39,69 @@ func TestStorageMarketCreateMiner(t *testing.T) {
}

var err error
outaddr, err = address.NewFromBytes(ret.Return)
sminer, err = address.NewFromBytes(ret.Return)
if err != nil {
t.Fatal(err)
}

if outaddr.String() != "t0102" {
if sminer.String() != "t0102" {
t.Fatal("hold up")
}
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: 6,
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: 5,
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(outaddr)
act, err := state.GetActor(sminer)
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion chain/actors/harness_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func (h *Harness) DumpObject(obj interface{}) []byte {
}
func (h *Harness) NoError(t *testing.T, err error) {
if err != nil {
t.Fatalf("Error in step %d: %s", h.currStep, err)
t.Fatalf("Error in step %d: %+v", h.currStep, err)
}
}

Expand Down
13 changes: 13 additions & 0 deletions chain/actors/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package actors

import (
cbor "github.com/ipfs/go-ipld-cbor"
)

var (
EmptyStructCBOR = []byte{0xa0}
)

func SerializeParams(i interface{}) ([]byte, error) {
return cbor.DumpObject(i)
}
11 changes: 7 additions & 4 deletions chain/invoker.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
"golang.org/x/xerrors"
)

type invoker struct {
Expand All @@ -34,10 +35,10 @@ func (inv *invoker) Invoke(act *types.Actor, vmctx *VMContext, method uint64, pa

code, ok := inv.builtInCode[act.Code]
if !ok {
return types.InvokeRet{}, fmt.Errorf("no code for actor %s", act.Code)
return types.InvokeRet{}, xerrors.Errorf("no code for actor %s", act.Code)
}
if method >= uint64(len(code)) || code[method] == nil {
return types.InvokeRet{}, fmt.Errorf("no method %d on actor", method)
return types.InvokeRet{}, xerrors.Errorf("no method %d on actor", method)
}
return code[method](act, vmctx, params)

Expand All @@ -63,7 +64,8 @@ func (*invoker) transform(instance Invokee) (nativeCode, error) {
exports := instance.Exports()
for i, m := range exports {
i := i
newErr := func(str string) error {
newErr := func(format string, args ...interface{}) error {
str := fmt.Sprintf(format, args)
return fmt.Errorf("transform(%s) export(%d): %s", itype.Name(), i, str)
}
if m == nil {
Expand All @@ -86,7 +88,8 @@ func (*invoker) transform(instance Invokee) (nativeCode, error) {
}

if t.In(2).Kind() != reflect.Ptr {
return nil, newErr("parameter has to be a pointer to parameter")
return nil, newErr("parameter has to be a pointer to parameter, is: %s",
t.In(2).Kind())
}

if t.NumOut() != 2 {
Expand Down
6 changes: 4 additions & 2 deletions chain/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type VMContext struct {
// address that started invokation chain
origin address.Address

storage types.Storage
storage *storage
}

// Message is the message that kicked off the current invocation
Expand Down Expand Up @@ -215,7 +215,7 @@ func (vm *VM) ApplyMessage(msg *types.Message) (*types.MessageReceipt, error) {
if msg.Method != 0 {
ret, errcode, err = vm.Invoke(toActor, vmctx, msg.Method, msg.Params)
if err != nil {
return nil, err
return nil, xerrors.Errorf("during invoke: %w", err)
}

if errcode != 0 {
Expand All @@ -226,6 +226,8 @@ func (vm *VM) ApplyMessage(msg *types.Message) (*types.MessageReceipt, error) {
panic("invariant violated: " + err.Error())
}
} else {
// Update actor head reference
toActor.Head = vmctx.storage.head
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah. good catch

Copy link
Contributor Author

@Kubuxu Kubuxu Jul 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have the same issue in Send. And also send is won't handle errors well.

// refund unused gas
refund := types.BigMul(types.BigSub(msg.GasLimit, vmctx.GasUsed()), msg.GasPrice)
DepositFunds(fromActor, refund)
Expand Down