Merge pull request #51 from filecoin-project/feat/more-methods
Add more methods (IsMiner, GetPower)
This commit is contained in:
commit
6e24543e57
@ -89,12 +89,24 @@ type StorageMinerConstructorParams struct {
|
|||||||
|
|
||||||
func (sma StorageMinerActor) Exports() []interface{} {
|
func (sma StorageMinerActor) Exports() []interface{} {
|
||||||
return []interface{}{
|
return []interface{}{
|
||||||
sma.StorageMinerActor,
|
0: sma.StorageMinerConstructor,
|
||||||
sma.CommitSector,
|
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
|
var self StorageMinerActorState
|
||||||
self.Owner = params.Owner
|
self.Owner = params.Owner
|
||||||
self.Worker = params.Worker
|
self.Worker = params.Worker
|
||||||
@ -209,6 +221,17 @@ func (sma StorageMinerActor) CommitSector(act *types.Actor, vmctx types.VMContex
|
|||||||
return types.InvokeRet{}, nil
|
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) {
|
func SectorIsUnique(cst *hamt.CborIpldStore, sroot cid.Cid, sid types.BigInt) (bool, error) {
|
||||||
nd, err := hamt.LoadNode(context.TODO(), cst, sroot)
|
nd, err := hamt.LoadNode(context.TODO(), cst, sroot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const SectorSize = 1024
|
const SectorSize = 1024
|
||||||
@ -13,16 +14,22 @@ const SectorSize = 1024
|
|||||||
func init() {
|
func init() {
|
||||||
cbor.RegisterCborType(StorageMarketState{})
|
cbor.RegisterCborType(StorageMarketState{})
|
||||||
cbor.RegisterCborType(CreateStorageMinerParams{})
|
cbor.RegisterCborType(CreateStorageMinerParams{})
|
||||||
|
cbor.RegisterCborType(IsMinerParam{})
|
||||||
|
cbor.RegisterCborType(PowerLookupParams{})
|
||||||
}
|
}
|
||||||
|
|
||||||
type StorageMarketActor struct{}
|
type StorageMarketActor struct{}
|
||||||
|
|
||||||
func (sma StorageMarketActor) Exports() []interface{} {
|
func (sma StorageMarketActor) Exports() []interface{} {
|
||||||
return []interface{}{
|
return []interface{}{
|
||||||
nil,
|
//0: sma.StorageMarketConstructor,
|
||||||
sma.CreateStorageMiner,
|
1: sma.CreateStorageMiner,
|
||||||
nil, // TODO: slash consensus fault
|
//2: sma.SlashConsensusFault,
|
||||||
sma.UpdateStorage,
|
3: sma.UpdateStorage,
|
||||||
|
4: sma.GetTotalStorage,
|
||||||
|
5: sma.PowerLookup,
|
||||||
|
6: sma.IsMiner,
|
||||||
|
//7: sma.StorageCollateralForSize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,17 +68,17 @@ func (sma StorageMarketActor) CreateStorageMiner(act *types.Actor, vmctx types.V
|
|||||||
return types.InvokeRet{}, err
|
return types.InvokeRet{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
naddr, err := address.NewFromBytes(ret)
|
|
||||||
if err != nil {
|
|
||||||
return types.InvokeRet{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if exit != 0 {
|
if exit != 0 {
|
||||||
return types.InvokeRet{
|
return types.InvokeRet{
|
||||||
ReturnCode: 2,
|
ReturnCode: 2,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
naddr, err := address.NewFromBytes(ret)
|
||||||
|
if err != nil {
|
||||||
|
return types.InvokeRet{}, err
|
||||||
|
}
|
||||||
|
|
||||||
var self StorageMarketState
|
var self StorageMarketState
|
||||||
old := vmctx.Storage().GetHead()
|
old := vmctx.Storage().GetHead()
|
||||||
if err := vmctx.Storage().Get(old, &self); err != nil {
|
if err := vmctx.Storage().Get(old, &self); err != nil {
|
||||||
@ -123,7 +130,7 @@ func (sma StorageMarketActor) UpdateStorage(act *types.Actor, vmctx types.VMCont
|
|||||||
return types.InvokeRet{}, nil
|
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
|
var self StorageMarketState
|
||||||
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
|
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
|
||||||
return types.InvokeRet{}, err
|
return types.InvokeRet{}, err
|
||||||
@ -141,7 +148,7 @@ type PowerLookupParams struct {
|
|||||||
func (sma StorageMarketActor) PowerLookup(act *types.Actor, vmctx types.VMContext, params *PowerLookupParams) (types.InvokeRet, error) {
|
func (sma StorageMarketActor) PowerLookup(act *types.Actor, vmctx types.VMContext, params *PowerLookupParams) (types.InvokeRet, error) {
|
||||||
var self StorageMarketState
|
var self StorageMarketState
|
||||||
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
|
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 {
|
if _, ok := self.Miners[params.Miner]; !ok {
|
||||||
@ -151,9 +158,9 @@ func (sma StorageMarketActor) PowerLookup(act *types.Actor, vmctx types.VMContex
|
|||||||
}, nil
|
}, 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 {
|
if err != nil {
|
||||||
return types.InvokeRet{}, err
|
return types.InvokeRet{}, xerrors.Errorf("invoke Miner.GetPower: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
@ -167,3 +174,22 @@ func (sma StorageMarketActor) PowerLookup(act *types.Actor, vmctx types.VMContex
|
|||||||
Result: ret,
|
Result: ret,
|
||||||
}, nil
|
}, 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
|
||||||
|
}
|
||||||
|
@ -9,9 +9,14 @@ import (
|
|||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
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) {
|
func TestStorageMarketCreateMiner(t *testing.T) {
|
||||||
h := NewHarness(t)
|
h := NewHarness(t)
|
||||||
var outaddr address.Address
|
var sminer address.Address
|
||||||
h.Steps = []Step{
|
h.Steps = []Step{
|
||||||
{
|
{
|
||||||
M: types.Message{
|
M: types.Message{
|
||||||
@ -34,19 +39,69 @@ func TestStorageMarketCreateMiner(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
outaddr, err = address.NewFromBytes(ret.Return)
|
sminer, err = address.NewFromBytes(ret.Return)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if outaddr.String() != "t0102" {
|
if sminer.String() != "t0102" {
|
||||||
t.Fatal("hold up")
|
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()
|
state := h.Execute()
|
||||||
act, err := state.GetActor(outaddr)
|
act, err := state.GetActor(sminer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ func (h *Harness) DumpObject(obj interface{}) []byte {
|
|||||||
}
|
}
|
||||||
func (h *Harness) NoError(t *testing.T, err error) {
|
func (h *Harness) NoError(t *testing.T, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error in step %d: %s", h.currStep, err)
|
t.Fatalf("Error in step %d: %+v", h.currStep, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
chain/actors/params.go
Normal file
13
chain/actors/params.go
Normal file
@ -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)
|
||||||
|
}
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type invoker struct {
|
type invoker struct {
|
||||||
@ -34,10 +35,10 @@ func (inv *invoker) Invoke(act *types.Actor, vmctx *VMContext, method uint64, pa
|
|||||||
|
|
||||||
code, ok := inv.builtInCode[act.Code]
|
code, ok := inv.builtInCode[act.Code]
|
||||||
if !ok {
|
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 {
|
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)
|
return code[method](act, vmctx, params)
|
||||||
|
|
||||||
@ -63,7 +64,8 @@ func (*invoker) transform(instance Invokee) (nativeCode, error) {
|
|||||||
exports := instance.Exports()
|
exports := instance.Exports()
|
||||||
for i, m := range exports {
|
for i, m := range exports {
|
||||||
i := i
|
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)
|
return fmt.Errorf("transform(%s) export(%d): %s", itype.Name(), i, str)
|
||||||
}
|
}
|
||||||
if m == nil {
|
if m == nil {
|
||||||
@ -86,7 +88,8 @@ func (*invoker) transform(instance Invokee) (nativeCode, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if t.In(2).Kind() != reflect.Ptr {
|
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 {
|
if t.NumOut() != 2 {
|
||||||
|
@ -30,7 +30,7 @@ type VMContext struct {
|
|||||||
// address that started invokation chain
|
// address that started invokation chain
|
||||||
origin address.Address
|
origin address.Address
|
||||||
|
|
||||||
storage types.Storage
|
storage *storage
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message is the message that kicked off the current invocation
|
// Message is the message that kicked off the current invocation
|
||||||
@ -215,7 +215,7 @@ func (vm *VM) ApplyMessage(msg *types.Message) (*types.MessageReceipt, error) {
|
|||||||
if msg.Method != 0 {
|
if msg.Method != 0 {
|
||||||
ret, errcode, err = vm.Invoke(toActor, vmctx, msg.Method, msg.Params)
|
ret, errcode, err = vm.Invoke(toActor, vmctx, msg.Method, msg.Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, xerrors.Errorf("during invoke: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if errcode != 0 {
|
if errcode != 0 {
|
||||||
@ -226,6 +226,8 @@ func (vm *VM) ApplyMessage(msg *types.Message) (*types.MessageReceipt, error) {
|
|||||||
panic("invariant violated: " + err.Error())
|
panic("invariant violated: " + err.Error())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Update actor head reference
|
||||||
|
toActor.Head = vmctx.storage.head
|
||||||
// refund unused gas
|
// refund unused gas
|
||||||
refund := types.BigMul(types.BigSub(msg.GasLimit, vmctx.GasUsed()), msg.GasPrice)
|
refund := types.BigMul(types.BigSub(msg.GasLimit, vmctx.GasUsed()), msg.GasPrice)
|
||||||
DepositFunds(fromActor, refund)
|
DepositFunds(fromActor, refund)
|
||||||
|
Loading…
Reference in New Issue
Block a user