Merge pull request #188 from filecoin-project/feat/vm-perf

Switch more VM types to codegen tuple serialization
This commit is contained in:
Whyrusleeping 2019-09-12 03:29:29 +10:00 committed by GitHub
commit c47a0b66d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 3330 additions and 305 deletions

View File

@ -5,9 +5,11 @@ import (
"context"
"encoding/binary"
"fmt"
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/types"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/ipfs/go-cid"
@ -26,8 +28,6 @@ const (
)
func init() {
cbor.RegisterCborType(ExecParams{})
cbor.RegisterCborType(struct{}{})
n, err := cbor.WrapObject(map[string]string{}, mh.SHA2_256, -1)
if err != nil {
@ -64,17 +64,16 @@ type ExecParams struct {
Params []byte
}
func CreateExecParams(act cid.Cid, obj interface{}) ([]byte, aerrors.ActorError) {
func CreateExecParams(act cid.Cid, obj cbg.CBORMarshaler) ([]byte, aerrors.ActorError) {
encparams, err := SerializeParams(obj)
if err != nil {
return nil, aerrors.Wrap(err, "creating ExecParams")
}
var ep ExecParams
ep.Code = act
ep.Params = encparams
return SerializeParams(ep)
return SerializeParams(&ExecParams{
Code: act,
Params: encparams,
})
}
func (ia InitActor) Exec(act *types.Actor, vmctx types.VMContext, p *ExecParams) ([]byte, aerrors.ActorError) {
@ -117,10 +116,6 @@ func (ia InitActor) Exec(act *types.Actor, vmctx types.VMContext, p *ExecParams)
Head: EmptyCBOR,
Nonce: 0,
}
_, err = vmctx.Storage().Put(struct{}{})
if err != nil {
return nil, err
}
// The call to the actors constructor will set up the initial state
// from the given parameters, setting `actor.Head` to a new value when successful.
@ -153,7 +148,7 @@ func (ia InitActor) Exec(act *types.Actor, vmctx types.VMContext, p *ExecParams)
return nil, err
}
c, err := vmctx.Storage().Put(self)
c, err := vmctx.Storage().Put(&self)
if err != nil {
return nil, err
}
@ -207,13 +202,13 @@ func (ias *InitActorState) AddActor(cst *hamt.CborIpldStore, addr address.Addres
func (ias *InitActorState) Lookup(cst *hamt.CborIpldStore, addr address.Address) (address.Address, error) {
amap, err := hamt.LoadNode(context.TODO(), cst, ias.AddressMap)
if err != nil {
return address.Undef, err
return address.Undef, xerrors.Errorf("ias lookup failed loading hamt node: %w", err)
}
var val interface{}
err = amap.Find(context.TODO(), string(addr.Bytes()), &val)
if err != nil {
return address.Undef, err
return address.Undef, xerrors.Errorf("ias lookup failed to do find: %w", err)
}
ival, ok := val.(uint64)

View File

@ -2,6 +2,7 @@ package actors
import (
"context"
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/types"
@ -14,18 +15,6 @@ import (
"golang.org/x/xerrors"
)
func init() {
cbor.RegisterCborType(StorageMinerActorState{})
cbor.RegisterCborType(StorageMinerConstructorParams{})
cbor.RegisterCborType(CommitSectorParams{})
cbor.RegisterCborType(MinerInfo{})
cbor.RegisterCborType(SubmitPoStParams{})
cbor.RegisterCborType(PieceInclVoucherData{})
cbor.RegisterCborType(InclusionProof{})
cbor.RegisterCborType(PaymentVerifyParams{})
cbor.RegisterCborType(UpdatePeerIDParams{})
}
var ProvingPeriodDuration = uint64(2 * 60) // an hour, for now
const POST_SECTORS_COUNT = 8192
@ -190,7 +179,7 @@ func (sma StorageMinerActor) StorageMinerConstructor(act *types.Actor, vmctx typ
self.Info = minfocid
storage := vmctx.Storage()
c, err := storage.Put(self)
c, err := storage.Put(&self)
if err != nil {
return nil, err
}

View File

@ -2,29 +2,18 @@ package actors
import (
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/types"
)
func init() {
cbor.RegisterCborType(MultiSigActorState{})
cbor.RegisterCborType(MultiSigConstructorParams{})
cbor.RegisterCborType(MultiSigProposeParams{})
cbor.RegisterCborType(MultiSigTxID{})
cbor.RegisterCborType(MultiSigSwapSignerParams{})
cbor.RegisterCborType(MultiSigChangeReqParams{})
cbor.RegisterCborType(MTransaction{})
cbor.RegisterCborType(MultiSigRemoveSignerParam{})
cbor.RegisterCborType(MultiSigAddSignerParam{})
}
cbg "github.com/whyrusleeping/cbor-gen"
)
type MultiSigActor struct{}
type MultiSigActorState struct {
Signers []address.Address
Required uint32
Required uint64
NextTxID uint64
//TODO: make this map/sharray/whatever
@ -59,7 +48,7 @@ type MTransaction struct {
Approved []address.Address
Complete bool
Canceled bool
RetCode uint8
RetCode uint64
}
func (tx MTransaction) Active() ActorError {
@ -102,7 +91,7 @@ func (msa MultiSigActor) Exports() []interface{} {
type MultiSigConstructorParams struct {
Signers []address.Address
Required uint32
Required uint64
}
func (MultiSigActor) MultiSigConstructor(act *types.Actor, vmctx types.VMContext,
@ -194,7 +183,7 @@ func (msa MultiSigActor) Propose(act *types.Actor, vmctx types.VMContext,
if aerrors.IsFatal(err) {
return nil, err
}
tx.RetCode = aerrors.RetCode(err)
tx.RetCode = uint64(aerrors.RetCode(err))
tx.Complete = true
}
@ -203,7 +192,9 @@ func (msa MultiSigActor) Propose(act *types.Actor, vmctx types.VMContext,
return nil, aerrors.Wrap(err, "saving state")
}
return SerializeParams(tx.TxID)
// REVIEW: On one hand, I like being very explicit about how we're doing the serialization
// on the other, maybe we shouldnt do direct calls to underlying serialization libs?
return cbg.CborEncodeMajorType(cbg.MajUnsignedInt, tx.TxID), nil
}
type MultiSigTxID struct {
@ -229,12 +220,12 @@ func (msa MultiSigActor) Approve(act *types.Actor, vmctx types.VMContext,
}
}
tx.Approved = append(tx.Approved, vmctx.Message().From)
if uint32(len(tx.Approved)) >= self.Required {
if uint64(len(tx.Approved)) >= self.Required {
_, err := vmctx.Send(tx.To, tx.Method, tx.Value, tx.Params)
if aerrors.IsFatal(err) {
return nil, err
}
tx.RetCode = aerrors.RetCode(err)
tx.RetCode = uint64(aerrors.RetCode(err))
tx.Complete = true
}
@ -319,7 +310,7 @@ func (msa MultiSigActor) RemoveSigner(act *types.Actor, vmctx types.VMContext,
newSigners = append(newSigners, s)
}
}
if params.Decrease || uint32(len(self.Signers)-1) < self.Required {
if params.Decrease || uint64(len(self.Signers)-1) < self.Required {
self.Required = self.Required - 1
}
@ -366,7 +357,7 @@ func (msa MultiSigActor) SwapSigner(act *types.Actor, vmctx types.VMContext,
}
type MultiSigChangeReqParams struct {
Req uint32
Req uint64
}
func (msa MultiSigActor) ChangeRequirement(act *types.Actor, vmctx types.VMContext,

View File

@ -5,6 +5,7 @@ import (
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/stretchr/testify/assert"
cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/address"
@ -23,7 +24,7 @@ func TestMultiSigCreate(t *testing.T) {
h := NewHarness(t, opts...)
ret, _ := h.CreateActor(t, creatorAddr, actors.MultisigActorCodeCid,
actors.MultiSigConstructorParams{
&actors.MultiSigConstructorParams{
Signers: []address.Address{creatorAddr, sig1Addr, sig2Addr},
Required: 2,
})
@ -49,8 +50,8 @@ func TestMultiSigOps(t *testing.T) {
HarnessAddr(&sig2Addr, 100000),
HarnessAddr(&outsideAddr, 100000),
HarnessActor(&multSigAddr, &creatorAddr, actors.MultisigActorCodeCid,
func() interface{} {
return actors.MultiSigConstructorParams{
func() cbg.CBORMarshaler {
return &actors.MultiSigConstructorParams{
Signers: []address.Address{creatorAddr, sig1Addr, sig2Addr},
Required: 2,
}
@ -71,8 +72,7 @@ func TestMultiSigOps(t *testing.T) {
// Transfer funds outside of multsig
const sendVal = 1000
ret, _ := h.Invoke(t, creatorAddr, multSigAddr, actors.MultiSigMethods.Propose,
actors.MultiSigProposeParams{
&actors.MultiSigProposeParams{
To: outsideAddr,
Value: types.NewInt(sendVal),
})
@ -82,12 +82,12 @@ func TestMultiSigOps(t *testing.T) {
assert.NoError(t, err, "decoding txid")
ret, _ = h.Invoke(t, outsideAddr, multSigAddr, actors.MultiSigMethods.Approve,
txIDParam)
&txIDParam)
assert.Equal(t, uint8(1), ret.ExitCode, "outsideAddr should not approve")
h.AssertBalanceChange(t, multSigAddr, 0)
ret2, _ := h.Invoke(t, sig1Addr, multSigAddr, actors.MultiSigMethods.Approve,
txIDParam)
&txIDParam)
ApplyOK(t, ret2)
h.AssertBalanceChange(t, outsideAddr, sendVal)

View File

@ -5,7 +5,6 @@ import (
"fmt"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/filecoin-project/go-lotus/build"
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
@ -13,14 +12,6 @@ import (
"github.com/filecoin-project/go-lotus/chain/types"
)
func init() {
cbor.RegisterCborType(PaymentChannelActorState{})
cbor.RegisterCborType(PCAConstructorParams{})
cbor.RegisterCborType(LaneState{})
cbor.RegisterCborType(PCAUpdateChannelStateParams{})
cbor.RegisterCborType(PaymentInfo{})
}
type PaymentChannelActor struct{}
type PaymentInfo struct {
@ -84,7 +75,7 @@ func (pca PaymentChannelActor) Constructor(act *types.Actor, vmctx types.VMConte
self.LaneStates = make(map[string]*LaneState)
storage := vmctx.Storage()
c, err := storage.Put(self)
c, err := storage.Put(&self)
if err != nil {
return nil, err
}
@ -129,14 +120,14 @@ func (pca PaymentChannelActor) UpdateChannelState(act *types.Actor, vmctx types.
return nil, aerrors.New(2, "cannot use this voucher yet!")
}
if sv.SecretPreimage != nil {
if len(sv.SecretPreimage) > 0 {
if !bytes.Equal(hash(params.Secret), sv.SecretPreimage) {
return nil, aerrors.New(3, "incorrect secret!")
}
}
if sv.Extra != nil {
encoded, err := SerializeParams(PaymentVerifyParams{sv.Extra.Data, params.Proof})
encoded, err := SerializeParams(&PaymentVerifyParams{sv.Extra.Data, params.Proof})
if err != nil {
return nil, err
}
@ -203,7 +194,7 @@ func (pca PaymentChannelActor) UpdateChannelState(act *types.Actor, vmctx types.
}
}
ncid, err := storage.Put(self)
ncid, err := storage.Put(&self)
if err != nil {
return nil, err
}
@ -235,7 +226,7 @@ func (pca PaymentChannelActor) Close(act *types.Actor, vmctx types.VMContext, pa
self.ClosingAt = self.MinCloseHeight
}
ncid, err := storage.Put(self)
ncid, err := storage.Put(&self)
if err != nil {
return nil, err
}
@ -272,7 +263,7 @@ func (pca PaymentChannelActor) Collect(act *types.Actor, vmctx types.VMContext,
self.ToSend = types.NewInt(0)
ncid, err := storage.Put(self)
ncid, err := storage.Put(&self)
if err != nil {
return nil, err
}

View File

@ -19,7 +19,7 @@ func TestPaychCreate(t *testing.T) {
h := NewHarness(t, opts...)
ret, _ := h.CreateActor(t, creatorAddr, actors.PaymentChannelActorCodeCid,
actors.PCAConstructorParams{
&actors.PCAConstructorParams{
To: targetAddr,
})
ApplyOK(t, ret)
@ -48,7 +48,7 @@ func TestPaychUpdate(t *testing.T) {
h := NewHarness(t, opts...)
ret, _ := h.CreateActor(t, creatorAddr, actors.PaymentChannelActorCodeCid,
actors.PCAConstructorParams{
&actors.PCAConstructorParams{
To: targetAddr,
})
ApplyOK(t, ret)
@ -66,12 +66,12 @@ func TestPaychUpdate(t *testing.T) {
}
signVoucher(t, h.w, creatorAddr, sv)
ret, _ = h.Invoke(t, targetAddr, pch, actors.PCAMethods.UpdateChannelState, actors.PCAUpdateChannelStateParams{
ret, _ = h.Invoke(t, targetAddr, pch, actors.PCAMethods.UpdateChannelState, &actors.PCAUpdateChannelStateParams{
Sv: *sv,
})
ApplyOK(t, ret)
ret, _ = h.Invoke(t, targetAddr, pch, actors.PCAMethods.GetToSend, struct{}{})
ret, _ = h.Invoke(t, targetAddr, pch, actors.PCAMethods.GetToSend, nil)
ApplyOK(t, ret)
bi := types.BigFromBytes(ret.Return)
@ -79,13 +79,13 @@ func TestPaychUpdate(t *testing.T) {
t.Fatal("toSend amount was wrong: ", bi.String())
}
ret, _ = h.Invoke(t, targetAddr, pch, actors.PCAMethods.Close, struct{}{})
ret, _ = h.Invoke(t, targetAddr, pch, actors.PCAMethods.Close, nil)
ApplyOK(t, ret)
// now we have to 'wait' for the chain to advance.
h.vm.SetBlockHeight(1000)
ret, _ = h.Invoke(t, targetAddr, pch, actors.PCAMethods.Collect, struct{}{})
ret, _ = h.Invoke(t, targetAddr, pch, actors.PCAMethods.Collect, nil)
ApplyOK(t, ret)
h.AssertBalanceChange(t, targetAddr, 100)

View File

@ -1,23 +1,19 @@
package actors
import (
"context"
"github.com/filecoin-project/go-lotus/build"
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/types"
cbor "github.com/ipfs/go-ipld-cbor"
cid "github.com/ipfs/go-cid"
hamt "github.com/ipfs/go-hamt-ipld"
"github.com/libp2p/go-libp2p-core/peer"
cbg "github.com/whyrusleeping/cbor-gen"
)
func init() {
cbor.RegisterCborType(StorageMarketState{})
cbor.RegisterCborType(CreateStorageMinerParams{})
cbor.RegisterCborType(IsMinerParam{})
cbor.RegisterCborType(PowerLookupParams{})
cbor.RegisterCborType(UpdateStorageParams{})
}
type StorageMarketActor struct{}
type smaMethods struct {
@ -46,7 +42,7 @@ func (sma StorageMarketActor) Exports() []interface{} {
}
type StorageMarketState struct {
Miners map[address.Address]struct{}
Miners cid.Cid
TotalStorage types.BigInt
}
@ -88,9 +84,13 @@ func (sma StorageMarketActor) CreateStorageMiner(act *types.Actor, vmctx types.V
return nil, err
}
self.Miners[naddr] = struct{}{}
ncid, err := MinerSetAdd(context.TODO(), vmctx, self.Miners, naddr)
if err != nil {
return nil, err
}
self.Miners = ncid
nroot, err := vmctx.Storage().Put(self)
nroot, err := vmctx.Storage().Put(&self)
if err != nil {
return nil, err
}
@ -120,14 +120,18 @@ func (sma StorageMarketActor) UpdateStorage(act *types.Actor, vmctx types.VMCont
return nil, err
}
_, ok := self.Miners[vmctx.Message().From]
if !ok {
has, err := MinerSetHas(context.TODO(), vmctx, self.Miners, vmctx.Message().From)
if err != nil {
return nil, err
}
if !has {
return nil, aerrors.New(1, "update storage must only be called by a miner actor")
}
self.TotalStorage = types.BigAdd(self.TotalStorage, params.Delta)
nroot, err := vmctx.Storage().Put(self)
nroot, err := vmctx.Storage().Put(&self)
if err != nil {
return nil, err
}
@ -158,11 +162,16 @@ func (sma StorageMarketActor) PowerLookup(act *types.Actor, vmctx types.VMContex
return nil, aerrors.Wrap(err, "getting head")
}
if _, ok := self.Miners[params.Miner]; !ok {
has, err := MinerSetHas(context.TODO(), vmctx, self.Miners, params.Miner)
if err != nil {
return nil, err
}
if !has {
return nil, aerrors.New(1, "miner not registered with storage market")
}
ret, err := vmctx.Send(params.Miner, MAMethods.GetPower, types.NewInt(0), EmptyStructCBOR)
ret, err := vmctx.Send(params.Miner, MAMethods.GetPower, types.NewInt(0), nil)
if err != nil {
return nil, aerrors.Wrap(err, "invoke Miner.GetPower")
}
@ -179,10 +188,50 @@ func (sma StorageMarketActor) IsMiner(act *types.Actor, vmctx types.VMContext, p
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
return nil, err
}
_, ok := self.Miners[param.Addr]
out, err := SerializeParams(ok)
has, err := MinerSetHas(context.TODO(), vmctx, self.Miners, param.Addr)
if err != nil {
return nil, err
}
return out, nil
return cbg.EncodeBool(has), nil
}
func MinerSetHas(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (bool, aerrors.ActorError) {
nd, err := hamt.LoadNode(ctx, vmctx.Ipld(), rcid)
if err != nil {
return false, aerrors.Escalate(err, "failed to load miner set")
}
err = nd.Find(ctx, string(maddr.Bytes()), nil)
switch err {
case hamt.ErrNotFound:
return false, nil
case nil:
return true, nil
default:
return false, aerrors.Escalate(err, "failed to do set lookup")
}
}
func MinerSetAdd(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (cid.Cid, aerrors.ActorError) {
nd, err := hamt.LoadNode(ctx, vmctx.Ipld(), rcid)
if err != nil {
return cid.Undef, aerrors.Escalate(err, "failed to load miner set")
}
if err := nd.Set(ctx, string(maddr.Bytes()), uint64(1)); err != nil {
return cid.Undef, aerrors.Escalate(err, "adding miner address to set failed")
}
if err := nd.Flush(ctx); err != nil {
return cid.Undef, aerrors.Escalate(err, "failed to flush miner set")
}
c, err := vmctx.Ipld().Put(ctx, nd)
if err != nil {
return cid.Undef, aerrors.Escalate(err, "failed to persist miner set to storage")
}
return c, nil
}

View File

@ -1,9 +1,10 @@
package actors_test
import (
"github.com/filecoin-project/go-lotus/build"
"testing"
"github.com/filecoin-project/go-lotus/build"
. "github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/types"
@ -12,11 +13,6 @@ import (
"github.com/stretchr/testify/assert"
)
func TestDumpEmpyStruct(t *testing.T) {
res, err := SerializeParams(struct{}{})
t.Logf("res: %x, err: %+v", res, err)
}
func TestStorageMarketCreateMiner(t *testing.T) {
var ownerAddr, workerAddr address.Address
@ -30,7 +26,7 @@ func TestStorageMarketCreateMiner(t *testing.T) {
var minerAddr address.Address
{
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.CreateStorageMiner,
CreateStorageMinerParams{
&CreateStorageMinerParams{
Owner: ownerAddr,
Worker: workerAddr,
SectorSize: types.NewInt(build.SectorSize),
@ -44,7 +40,7 @@ func TestStorageMarketCreateMiner(t *testing.T) {
{
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.IsMiner,
IsMinerParam{Addr: minerAddr})
&IsMinerParam{Addr: minerAddr})
ApplyOK(t, ret)
var output bool
@ -60,7 +56,7 @@ func TestStorageMarketCreateMiner(t *testing.T) {
{
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.PowerLookup,
PowerLookupParams{Miner: minerAddr})
&PowerLookupParams{Miner: minerAddr})
ApplyOK(t, ret)
power := types.BigFromBytes(ret.Return)

View File

@ -4,15 +4,9 @@ import (
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
mh "github.com/multiformats/go-multihash"
)
func init() {
cbor.RegisterCborType(InitActorState{})
cbor.RegisterCborType(AccountActorState{})
}
var AccountActorCodeCid cid.Cid
var StorageMarketActorCodeCid cid.Cid
var StorageMinerCodeCid cid.Cid

View File

@ -3,9 +3,10 @@ package actors_test
import (
"context"
"encoding/binary"
"github.com/filecoin-project/go-lotus/build"
"testing"
"github.com/filecoin-project/go-lotus/build"
. "github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/gen"
@ -14,7 +15,6 @@ import (
"github.com/filecoin-project/go-lotus/chain/vm"
dstore "github.com/ipfs/go-datastore"
bstore "github.com/ipfs/go-ipfs-blockstore"
cbor "github.com/ipfs/go-ipld-cbor"
)
func blsaddr(n uint64) address.Address {
@ -62,7 +62,8 @@ func TestVMInvokeMethod(t *testing.T) {
vm, addrs := setupVMTestEnv(t)
from := addrs[0]
cenc, err := cbor.DumpObject(StorageMinerConstructorParams{})
var err error
cenc, err := SerializeParams(&StorageMinerConstructorParams{})
if err != nil {
t.Fatal(err)
}
@ -71,7 +72,7 @@ func TestVMInvokeMethod(t *testing.T) {
Code: StorageMinerCodeCid,
Params: cenc,
}
enc, err := cbor.DumpObject(execparams)
enc, err := SerializeParams(execparams)
if err != nil {
t.Fatal(err)
}
@ -115,7 +116,8 @@ func TestStorageMarketActorCreateMiner(t *testing.T) {
SectorSize: types.NewInt(build.SectorSize),
PeerID: "fakepeerid",
}
enc, err := cbor.DumpObject(params)
var err error
enc, err := SerializeParams(params)
if err != nil {
t.Fatal(err)
}

2557
chain/actors/cbor_gen.go Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
package actors_test
import (
"bytes"
"context"
"testing"
@ -9,7 +10,7 @@ import (
hamt "github.com/ipfs/go-hamt-ipld"
blockstore "github.com/ipfs/go-ipfs-blockstore"
bstore "github.com/ipfs/go-ipfs-blockstore"
cbor "github.com/ipfs/go-ipld-cbor"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-lotus/chain/actors"
@ -91,7 +92,7 @@ func HarnessMiner(addr *address.Address) HarnessOpt {
}
}
func HarnessActor(actor *address.Address, creator *address.Address, code cid.Cid, params func() interface{}) HarnessOpt {
func HarnessActor(actor *address.Address, creator *address.Address, code cid.Cid, params func() cbg.CBORMarshaler) HarnessOpt {
return func(t testing.TB, h *Harness) error {
if h.Stage != HarnessPostInit {
return nil
@ -205,7 +206,7 @@ func (h *Harness) Apply(t testing.TB, msg types.Message) (*vm.ApplyRet, *state.S
}
func (h *Harness) CreateActor(t testing.TB, from address.Address,
code cid.Cid, params interface{}) (*vm.ApplyRet, *state.StateTree) {
code cid.Cid, params cbg.CBORMarshaler) (*vm.ApplyRet, *state.StateTree) {
t.Helper()
return h.Apply(t, types.Message{
@ -237,7 +238,7 @@ func (h *Harness) SendFunds(t testing.TB, from address.Address, to address.Addre
}
func (h *Harness) Invoke(t testing.TB, from address.Address, to address.Address,
method uint64, params interface{}) (*vm.ApplyRet, *state.StateTree) {
method uint64, params cbg.CBORMarshaler) (*vm.ApplyRet, *state.StateTree) {
t.Helper()
return h.Apply(t, types.Message{
To: to,
@ -297,11 +298,14 @@ func (h *Harness) AssertBalanceChange(t testing.TB, addr address.Address, amt in
}
}
func DumpObject(t testing.TB, obj interface{}) []byte {
func DumpObject(t testing.TB, obj cbg.CBORMarshaler) []byte {
if obj == nil {
return nil
}
t.Helper()
enc, err := cbor.DumpObject(obj)
if err != nil {
b := new(bytes.Buffer)
if err := obj.MarshalCBOR(b); err != nil {
t.Fatalf("dumping params: %+v", err)
}
return enc
return b.Bytes()
}

View File

@ -1,19 +1,21 @@
package actors
import (
"bytes"
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
cbor "github.com/ipfs/go-ipld-cbor"
cbg "github.com/whyrusleeping/cbor-gen"
)
var (
EmptyStructCBOR = []byte{0xa0}
)
func SerializeParams(i interface{}) ([]byte, aerrors.ActorError) {
dump, err := cbor.DumpObject(i)
if err != nil {
func SerializeParams(i cbg.CBORMarshaler) ([]byte, aerrors.ActorError) {
buf := new(bytes.Buffer)
if err := i.MarshalCBOR(buf); err != nil {
// TODO: shouldnt this be a fatal error?
return nil, aerrors.Absorb(err, 1, "failed to encode parameter")
}
return dump, nil
return buf.Bytes(), nil
}

View File

@ -67,6 +67,7 @@ func (m mybs) Get(c cid.Cid) (block.Block, error) {
b, err := m.Blockstore.Get(c)
if err != nil {
// change to error for stacktraces, don't commit with that pls
// TODO: debug why we get so many not founds in tests
log.Warnf("Get failed: %s %s", c, err)
return nil, err
}

View File

@ -18,6 +18,7 @@ import (
hamt "github.com/ipfs/go-hamt-ipld"
bstore "github.com/ipfs/go-ipfs-blockstore"
peer "github.com/libp2p/go-libp2p-peer"
cbg "github.com/whyrusleeping/cbor-gen"
sharray "github.com/whyrusleeping/sharray"
)
@ -66,12 +67,12 @@ func MakeInitialStateTree(bs bstore.Blockstore, actmap map[address.Address]types
cst := hamt.CSTFromBstore(bs)
state, err := state.NewStateTree(cst)
if err != nil {
return nil, err
return nil, xerrors.Errorf("making new state tree: %w", err)
}
emptyobject, err := cst.Put(context.TODO(), map[string]string{})
if err != nil {
return nil, err
return nil, xerrors.Errorf("failed putting empty object: %w", err)
}
var addrs []address.Address
@ -81,20 +82,20 @@ func MakeInitialStateTree(bs bstore.Blockstore, actmap map[address.Address]types
initact, err := SetupInitActor(bs, addrs)
if err != nil {
return nil, err
return nil, xerrors.Errorf("setup init actor: %w", err)
}
if err := state.SetActor(actors.InitActorAddress, initact); err != nil {
return nil, err
return nil, xerrors.Errorf("set init actor: %w", err)
}
smact, err := SetupStorageMarketActor(bs)
if err != nil {
return nil, err
return nil, xerrors.Errorf("setup storage market actor: %w", err)
}
if err := state.SetActor(actors.StorageMarketAddress, smact); err != nil {
return nil, err
return nil, xerrors.Errorf("set storage market actor: %w", err)
}
err = state.SetActor(actors.NetworkAddress, &types.Actor{
@ -103,7 +104,7 @@ func MakeInitialStateTree(bs bstore.Blockstore, actmap map[address.Address]types
Head: emptyobject,
})
if err != nil {
return nil, err
return nil, xerrors.Errorf("set network account actor: %w", err)
}
for a, v := range actmap {
@ -113,7 +114,7 @@ func MakeInitialStateTree(bs bstore.Blockstore, actmap map[address.Address]types
Head: emptyobject,
})
if err != nil {
return nil, err
return nil, xerrors.Errorf("setting account from actmap: %w", err)
}
}
@ -121,12 +122,19 @@ func MakeInitialStateTree(bs bstore.Blockstore, actmap map[address.Address]types
}
func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) {
cst := hamt.CSTFromBstore(bs)
nd := hamt.NewNode(cst)
emptyhamt, err := cst.Put(context.TODO(), nd)
if err != nil {
return nil, err
}
sms := &actors.StorageMarketState{
Miners: make(map[address.Address]struct{}),
Miners: emptyhamt,
TotalStorage: types.NewInt(0),
}
stcid, err := hamt.CSTFromBstore(bs).Put(context.TODO(), sms)
stcid, err := cst.Put(context.TODO(), sms)
if err != nil {
return nil, err
}
@ -152,7 +160,7 @@ type GenMinerCfg struct {
PeerIDs []peer.ID
}
func mustEnc(i interface{}) []byte {
func mustEnc(i cbg.CBORMarshaler) []byte {
enc, err := actors.SerializeParams(i)
if err != nil {
panic(err)
@ -171,7 +179,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
worker := gmcfg.Workers[i]
pid := gmcfg.PeerIDs[i]
params := mustEnc(actors.CreateStorageMinerParams{
params := mustEnc(&actors.CreateStorageMinerParams{
Owner: owner,
Worker: worker,
SectorSize: types.NewInt(build.SectorSize),
@ -190,7 +198,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
gmcfg.MinerAddrs = append(gmcfg.MinerAddrs, maddr)
params = mustEnc(actors.UpdateStorageParams{Delta: types.NewInt(5000)})
params = mustEnc(&actors.UpdateStorageParams{Delta: types.NewInt(5000)})
_, err = doExec(ctx, vm, actors.StorageMarketAddress, maddr, actors.SMAMethods.UpdateStorage, params)
if err != nil {
@ -217,7 +225,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
}
mstate.Power = types.NewInt(5000)
nstate, err := cst.Put(ctx, mstate)
nstate, err := cst.Put(ctx, &mstate)
if err != nil {
return cid.Undef, err
}
@ -249,7 +257,7 @@ func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method uin
Nonce: act.Nonce,
})
if err != nil {
return nil, err
return nil, xerrors.Errorf("doExec apply message failed: %w", err)
}
if ret.ExitCode != 0 {

View File

@ -8,6 +8,7 @@ import (
hamt "github.com/ipfs/go-hamt-ipld"
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/address"
@ -50,7 +51,7 @@ func (st *StateTree) SetActor(addr address.Address, act *types.Actor) error {
if addr.Protocol() != address.ID {
iaddr, err := st.lookupID(addr)
if err != nil {
return err
return xerrors.Errorf("ID lookup failed: %w", err)
}
addr = iaddr
}
@ -68,12 +69,12 @@ func (st *StateTree) SetActor(addr address.Address, act *types.Actor) error {
func (st *StateTree) lookupID(addr address.Address) (address.Address, error) {
act, err := st.GetActor(actors.InitActorAddress)
if err != nil {
return address.Undef, err
return address.Undef, xerrors.Errorf("getting init actor: %w", err)
}
var ias actors.InitActorState
if err := st.Store.Get(context.TODO(), act.Head, &ias); err != nil {
return address.Undef, err
return address.Undef, xerrors.Errorf("loading init actor state: %w", err)
}
return ias.Lookup(st.Store, addr)
@ -87,10 +88,10 @@ func (st *StateTree) GetActor(addr address.Address) (*types.Actor, error) {
if addr.Protocol() != address.ID {
iaddr, err := st.lookupID(addr)
if err != nil {
if err == hamt.ErrNotFound {
return nil, types.ErrActorNotFound
if xerrors.Is(err, hamt.ErrNotFound) {
return nil, xerrors.Errorf("resolution lookup failed (%s): %w", addr, types.ErrActorNotFound)
}
return nil, err
return nil, xerrors.Errorf("address resolution: %w", err)
}
addr = iaddr
}

View File

@ -26,12 +26,6 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate
if msg.Value == types.EmptyInt {
msg.Value = types.NewInt(0)
}
if msg.Params == nil {
msg.Params, err = actors.SerializeParams(struct{}{})
if err != nil {
return nil, err
}
}
fromActor, err := vmi.StateTree().GetActor(msg.From)
if err != nil {

View File

@ -124,13 +124,13 @@ func (sm *StateManager) GetActor(addr address.Address) (*types.Actor, error) {
ts := sm.cs.GetHeaviestTipSet()
stcid, err := sm.TipSetState(ts.Cids())
if err != nil {
return nil, err
return nil, xerrors.Errorf("tipset state: %w", err)
}
cst := hamt.CSTFromBstore(sm.cs.Blockstore())
state, err := state.LoadStateTree(cst, stcid)
if err != nil {
return nil, err
return nil, xerrors.Errorf("load state tree: %w", err)
}
return state.GetActor(addr)
@ -139,7 +139,7 @@ func (sm *StateManager) GetActor(addr address.Address) (*types.Actor, error) {
func (sm *StateManager) GetBalance(addr address.Address) (types.BigInt, error) {
act, err := sm.GetActor(addr)
if err != nil {
return types.BigInt{}, err
return types.BigInt{}, xerrors.Errorf("get actor: %w", err)
}
return act.Balance, nil

View File

@ -14,6 +14,10 @@ import (
var _ = xerrors.Errorf
func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{140}); err != nil {
return err
}
@ -93,7 +97,8 @@ func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
return nil
}
func (t *BlockHeader) UnmarshalCBOR(br io.Reader) error {
func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br)
if err != nil {
@ -109,9 +114,13 @@ func (t *BlockHeader) UnmarshalCBOR(br io.Reader) error {
// t.t.Miner (address.Address)
{
if err := t.Miner.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.Tickets ([]*types.Ticket)
maj, extra, err = cbg.CborReadHeader(br)
@ -181,9 +190,13 @@ func (t *BlockHeader) UnmarshalCBOR(br io.Reader) error {
// t.t.ParentWeight (types.BigInt)
{
if err := t.ParentWeight.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.Height (uint64)
maj, extra, err = cbg.CborReadHeader(br)
@ -214,9 +227,13 @@ func (t *BlockHeader) UnmarshalCBOR(br io.Reader) error {
}
// t.t.BLSAggregate (types.Signature)
{
if err := t.BLSAggregate.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.MessageReceipts (cid.Cid)
{
@ -238,13 +255,21 @@ func (t *BlockHeader) UnmarshalCBOR(br io.Reader) error {
t.Timestamp = extra
// t.t.BlockSig (types.Signature)
{
if err := t.BlockSig.UnmarshalCBOR(br); err != nil {
return err
}
}
return nil
}
func (t *Ticket) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{131}); err != nil {
return err
}
@ -275,7 +300,8 @@ func (t *Ticket) MarshalCBOR(w io.Writer) error {
return nil
}
func (t *Ticket) UnmarshalCBOR(br io.Reader) error {
func (t *Ticket) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br)
if err != nil {
@ -344,6 +370,10 @@ func (t *Ticket) UnmarshalCBOR(br io.Reader) error {
}
func (t *Message) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{136}); err != nil {
return err
}
@ -393,7 +423,8 @@ func (t *Message) MarshalCBOR(w io.Writer) error {
return nil
}
func (t *Message) UnmarshalCBOR(br io.Reader) error {
func (t *Message) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br)
if err != nil {
@ -409,14 +440,22 @@ func (t *Message) UnmarshalCBOR(br io.Reader) error {
// t.t.To (address.Address)
{
if err := t.To.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.From (address.Address)
{
if err := t.From.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.Nonce (uint64)
maj, extra, err = cbg.CborReadHeader(br)
@ -429,19 +468,31 @@ func (t *Message) UnmarshalCBOR(br io.Reader) error {
t.Nonce = extra
// t.t.Value (types.BigInt)
{
if err := t.Value.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.GasPrice (types.BigInt)
{
if err := t.GasPrice.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.GasLimit (types.BigInt)
{
if err := t.GasLimit.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.Method (uint64)
maj, extra, err = cbg.CborReadHeader(br)
@ -473,6 +524,10 @@ func (t *Message) UnmarshalCBOR(br io.Reader) error {
}
func (t *SignedMessage) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{130}); err != nil {
return err
}
@ -489,7 +544,8 @@ func (t *SignedMessage) MarshalCBOR(w io.Writer) error {
return nil
}
func (t *SignedMessage) UnmarshalCBOR(br io.Reader) error {
func (t *SignedMessage) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br)
if err != nil {
@ -505,18 +561,30 @@ func (t *SignedMessage) UnmarshalCBOR(br io.Reader) error {
// t.t.Message (types.Message)
{
if err := t.Message.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.Signature (types.Signature)
{
if err := t.Signature.UnmarshalCBOR(br); err != nil {
return err
}
}
return nil
}
func (t *MsgMeta) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{130}); err != nil {
return err
}
@ -533,7 +601,8 @@ func (t *MsgMeta) MarshalCBOR(w io.Writer) error {
return nil
}
func (t *MsgMeta) UnmarshalCBOR(br io.Reader) error {
func (t *MsgMeta) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br)
if err != nil {
@ -567,3 +636,360 @@ func (t *MsgMeta) UnmarshalCBOR(br io.Reader) error {
}
return nil
}
func (t *SignedVoucher) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{137}); err != nil {
return err
}
// t.t.TimeLock (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.TimeLock)); err != nil {
return err
}
// t.t.SecretPreimage ([]uint8)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.SecretPreimage)))); err != nil {
return err
}
if _, err := w.Write(t.SecretPreimage); err != nil {
return err
}
// t.t.Extra (types.ModVerifyParams)
if err := t.Extra.MarshalCBOR(w); err != nil {
return err
}
// t.t.Lane (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.Lane)); err != nil {
return err
}
// t.t.Nonce (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.Nonce)); err != nil {
return err
}
// t.t.Amount (types.BigInt)
if err := t.Amount.MarshalCBOR(w); err != nil {
return err
}
// t.t.MinCloseHeight (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.MinCloseHeight)); err != nil {
return err
}
// t.t.Merges ([]types.Merge)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Merges)))); err != nil {
return err
}
for _, v := range t.Merges {
if err := v.MarshalCBOR(w); err != nil {
return err
}
}
// t.t.Signature (types.Signature)
if err := t.Signature.MarshalCBOR(w); err != nil {
return err
}
return nil
}
func (t *SignedVoucher) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajArray {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 9 {
return fmt.Errorf("cbor input had wrong number of fields")
}
// t.t.TimeLock (uint64)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.TimeLock = extra
// t.t.SecretPreimage ([]uint8)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("array too large")
}
if maj != cbg.MajByteString {
return fmt.Errorf("expected byte array")
}
t.SecretPreimage = make([]byte, extra)
if _, err := io.ReadFull(br, t.SecretPreimage); err != nil {
return err
}
// t.t.Extra (types.ModVerifyParams)
{
pb, err := br.PeekByte()
if err != nil {
return err
}
if pb == cbg.CborNull[0] {
var nbuf [1]byte
if _, err := br.Read(nbuf[:]); err != nil {
return err
}
} else {
t.Extra = new(ModVerifyParams)
if err := t.Extra.UnmarshalCBOR(br); err != nil {
return err
}
}
}
// t.t.Lane (uint64)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.Lane = extra
// t.t.Nonce (uint64)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.Nonce = extra
// t.t.Amount (types.BigInt)
{
if err := t.Amount.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.MinCloseHeight (uint64)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.MinCloseHeight = extra
// t.t.Merges ([]types.Merge)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("array too large")
}
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Merges = make([]Merge, extra)
}
for i := 0; i < int(extra); i++ {
var v Merge
if err := v.UnmarshalCBOR(br); err != nil {
return err
}
t.Merges[i] = v
}
// t.t.Signature (types.Signature)
{
pb, err := br.PeekByte()
if err != nil {
return err
}
if pb == cbg.CborNull[0] {
var nbuf [1]byte
if _, err := br.Read(nbuf[:]); err != nil {
return err
}
} else {
t.Signature = new(Signature)
if err := t.Signature.UnmarshalCBOR(br); err != nil {
return err
}
}
}
return nil
}
func (t *ModVerifyParams) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{131}); err != nil {
return err
}
// t.t.Actor (address.Address)
if err := t.Actor.MarshalCBOR(w); err != nil {
return err
}
// t.t.Method (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.Method)); err != nil {
return err
}
// t.t.Data ([]uint8)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Data)))); err != nil {
return err
}
if _, err := w.Write(t.Data); err != nil {
return err
}
return nil
}
func (t *ModVerifyParams) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajArray {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 3 {
return fmt.Errorf("cbor input had wrong number of fields")
}
// t.t.Actor (address.Address)
{
if err := t.Actor.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.Method (uint64)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.Method = extra
// t.t.Data ([]uint8)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("array too large")
}
if maj != cbg.MajByteString {
return fmt.Errorf("expected byte array")
}
t.Data = make([]byte, extra)
if _, err := io.ReadFull(br, t.Data); err != nil {
return err
}
return nil
}
func (t *Merge) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{130}); err != nil {
return err
}
// t.t.Lane (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.Lane)); err != nil {
return err
}
// t.t.Nonce (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.Nonce)); err != nil {
return err
}
return nil
}
func (t *Merge) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajArray {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 2 {
return fmt.Errorf("cbor input had wrong number of fields")
}
// t.t.Lane (uint64)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.Lane = extra
// t.t.Nonce (uint64)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.Nonce = extra
return nil
}

View File

@ -6,8 +6,6 @@ import (
"fmt"
"io"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/polydawn/refmt/obj/atlas"
cbg "github.com/whyrusleeping/cbor-gen"
)
@ -25,21 +23,6 @@ const (
IKTBLS
)
func init() {
cbor.RegisterCborType(atlas.BuildEntry(Signature{}).Transform().
TransformMarshal(atlas.MakeMarshalTransformFunc(
func(s Signature) ([]byte, error) {
buf := make([]byte, 4)
n := binary.PutUvarint(buf, uint64(s.TypeCode()))
return append(buf[:n], s.Data...), nil
})).
TransformUnmarshal(atlas.MakeUnmarshalTransformFunc(
func(x []byte) (Signature, error) {
return SignatureFromBytes(x)
})).
Complete())
}
type Signature struct {
Type string
Data []byte
@ -80,6 +63,11 @@ func (s *Signature) TypeCode() int {
}
func (s *Signature) MarshalCBOR(w io.Writer) error {
if s == nil {
_, err := w.Write(cbg.CborNull)
return err
}
header := cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(s.Data)+1))
if _, err := w.Write(header); err != nil {

View File

@ -6,11 +6,12 @@ import (
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-hamt-ipld"
cbg "github.com/whyrusleeping/cbor-gen"
)
type Storage interface {
Put(interface{}) (cid.Cid, aerrors.ActorError)
Get(cid.Cid, interface{}) aerrors.ActorError
Put(cbg.CBORMarshaler) (cid.Cid, aerrors.ActorError)
Get(cid.Cid, cbg.CBORUnmarshaler) aerrors.ActorError
GetHead() cid.Cid
@ -42,7 +43,7 @@ type storageWrapper struct {
}
func (sw *storageWrapper) Put(i interface{}) (cid.Cid, error) {
c, err := sw.s.Put(i)
c, err := sw.s.Put(i.(cbg.CBORMarshaler))
if err != nil {
return cid.Undef, err
}
@ -51,7 +52,7 @@ func (sw *storageWrapper) Put(i interface{}) (cid.Cid, error) {
}
func (sw *storageWrapper) Get(c cid.Cid, out interface{}) error {
if err := sw.s.Get(c, out); err != nil {
if err := sw.s.Get(c, out.(cbg.CBORUnmarshaler)); err != nil {
return err
}

View File

@ -8,12 +8,6 @@ import (
cbor "github.com/ipfs/go-ipld-cbor"
)
func init() {
cbor.RegisterCborType(Merge{})
cbor.RegisterCborType(SignedVoucher{})
cbor.RegisterCborType(ModVerifyParams{})
}
type SignedVoucher struct {
TimeLock uint64
SecretPreimage []byte
@ -31,16 +25,22 @@ type SignedVoucher struct {
func (sv *SignedVoucher) SigningBytes() ([]byte, error) {
osv := *sv
osv.Signature = nil
return cbor.DumpObject(osv)
buf := new(bytes.Buffer)
if err := osv.MarshalCBOR(buf); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (sv *SignedVoucher) EncodedString() (string, error) {
data, err := cbor.DumpObject(sv)
if err != nil {
buf := new(bytes.Buffer)
if err := sv.MarshalCBOR(buf); err != nil {
return "", err
}
return base64.RawURLEncoding.EncodeToString(data), nil
return base64.RawURLEncoding.EncodeToString(buf.Bytes()), nil
}
func (sv *SignedVoucher) Equals(other *SignedVoucher) bool {

View File

@ -1,11 +1,13 @@
package vm
import (
"bytes"
"fmt"
"reflect"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
actors "github.com/filecoin-project/go-lotus/chain/actors"
@ -121,8 +123,7 @@ func (*invoker) transform(instance Invokee) (nativeCode, error) {
inBytes := in[2].Interface().([]byte)
if len(inBytes) > 0 {
err := cbor.DecodeInto(inBytes, param.Interface())
if err != nil {
if err := DecodeParams(inBytes, param.Interface()); err != nil {
aerr := aerrors.Absorb(err, 1, "failed to decode parameters")
return []reflect.Value{
reflect.ValueOf([]byte{}),
@ -142,6 +143,15 @@ func (*invoker) transform(instance Invokee) (nativeCode, error) {
return code, nil
}
func DecodeParams(b []byte, out interface{}) error {
um, ok := out.(cbg.CBORUnmarshaler)
if !ok {
return fmt.Errorf("type %T does not implement UnmarshalCBOR", out)
}
return um.UnmarshalCBOR(bytes.NewReader(b))
}
func DumpActorState(code cid.Cid, b []byte) (interface{}, error) {
i := newInvoker() // TODO: register builtins in init block

View File

@ -1,11 +1,15 @@
package vm
import (
"fmt"
"io"
"testing"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/stretchr/testify/assert"
cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
"github.com/filecoin-project/go-lotus/chain/types"
)
@ -15,6 +19,25 @@ type basicParams struct {
B byte
}
func (b *basicParams) MarshalCBOR(w io.Writer) error {
_, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(b.B)))
return err
}
func (b *basicParams) UnmarshalCBOR(r io.Reader) error {
maj, val, err := cbg.CborReadHeader(r)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("bad cbor type")
}
b.B = byte(val)
return nil
}
func init() {
cbor.RegisterCborType(basicParams{})
}
@ -39,6 +62,7 @@ func (basicContract) InvokeSomething0(act *types.Actor, vmctx types.VMContext,
params *basicParams) ([]byte, aerrors.ActorError) {
return nil, aerrors.New(params.B, "params.B")
}
func (basicContract) BadParam(act *types.Actor, vmctx types.VMContext,
params *basicParams) ([]byte, aerrors.ActorError) {
return nil, aerrors.New(255, "bad params")
@ -55,7 +79,7 @@ func TestInvokerBasic(t *testing.T) {
assert.NoError(t, err)
{
bParam, err := cbor.DumpObject(basicParams{B: 1})
bParam, err := actors.SerializeParams(&basicParams{B: 1})
assert.NoError(t, err)
_, aerr := code[0](nil, &VMContext{}, bParam)
@ -67,7 +91,7 @@ func TestInvokerBasic(t *testing.T) {
}
{
bParam, err := cbor.DumpObject(basicParams{B: 2})
bParam, err := actors.SerializeParams(&basicParams{B: 2})
assert.NoError(t, err)
_, aerr := code[10](nil, &VMContext{}, bParam)
@ -77,7 +101,7 @@ func TestInvokerBasic(t *testing.T) {
}
}
_, aerr := code[1](nil, &VMContext{}, []byte{0})
_, aerr := code[1](nil, &VMContext{}, []byte{99})
if aerrors.IsFatal(aerr) {
t.Fatal("err should not be fatal")
}

View File

@ -2,9 +2,9 @@ package vm
import (
"context"
"fmt"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/state"
"github.com/filecoin-project/go-lotus/chain/types"
@ -27,42 +27,41 @@ func init() {
var EmptyObjectCid cid.Cid
func TryCreateAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
func TryCreateAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
act, err := makeActor(st, addr)
if err != nil {
return nil, err
}
_, err = st.RegisterNewAddress(addr, act)
if err != nil {
return nil, err
if _, err := st.RegisterNewAddress(addr, act); err != nil {
return nil, aerrors.Escalate(err, "registering actor address")
}
return act, nil
}
func makeActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
func makeActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
switch addr.Protocol() {
case address.BLS:
return NewBLSAccountActor(st, addr)
case address.SECP256K1:
return NewSecp256k1AccountActor(st, addr)
case address.ID:
return nil, fmt.Errorf("no actor with given ID")
return nil, aerrors.New(1, "no actor with given ID")
case address.Actor:
return nil, fmt.Errorf("no such actor: %s", addr)
return nil, aerrors.Newf(1, "no such actor: %s", addr)
default:
return nil, fmt.Errorf("address has unsupported protocol: %d", addr.Protocol())
return nil, aerrors.Newf(1, "address has unsupported protocol: %d", addr.Protocol())
}
}
func NewBLSAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
func NewBLSAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
var acstate actors.AccountActorState
acstate.Address = addr
c, err := st.Store.Put(context.TODO(), acstate)
c, err := st.Store.Put(context.TODO(), &acstate)
if err != nil {
return nil, err
return nil, aerrors.Escalate(err, "serializing account actor state")
}
nact := &types.Actor{
@ -74,7 +73,7 @@ func NewBLSAccountActor(st *state.StateTree, addr address.Address) (*types.Actor
return nact, nil
}
func NewSecp256k1AccountActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
func NewSecp256k1AccountActor(st *state.StateTree, addr address.Address) (*types.Actor, aerrors.ActorError) {
nact := &types.Actor{
Code: actors.AccountActorCodeCid,
Balance: types.NewInt(0),

View File

@ -11,6 +11,7 @@ import (
"github.com/filecoin-project/go-lotus/chain/store"
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/filecoin-project/go-lotus/lib/bufbstore"
cbg "github.com/whyrusleeping/cbor-gen"
"go.opencensus.io/trace"
block "github.com/ipfs/go-block-format"
@ -67,18 +68,18 @@ func (vmc *VMContext) Message() *types.Message {
// Storage interface
func (vmc *VMContext) Put(i interface{}) (cid.Cid, aerrors.ActorError) {
func (vmc *VMContext) Put(i cbg.CBORMarshaler) (cid.Cid, aerrors.ActorError) {
c, err := vmc.cst.Put(context.TODO(), i)
if err != nil {
if aerr := vmc.ChargeGas(0); aerr != nil {
return cid.Undef, aerrors.Absorb(err, outOfGasErrCode, "Put out of gas")
}
return cid.Undef, aerrors.Escalate(err, "putting cid")
return cid.Undef, aerrors.Escalate(err, fmt.Sprintf("putting object %T", i))
}
return c, nil
}
func (vmc *VMContext) Get(c cid.Cid, out interface{}) aerrors.ActorError {
func (vmc *VMContext) Get(c cid.Cid, out cbg.CBORUnmarshaler) aerrors.ActorError {
err := vmc.cst.Get(context.TODO(), c, out)
if err != nil {
if aerr := vmc.ChargeGas(0); aerr != nil {

View File

@ -62,7 +62,7 @@ var createMinerCmd = &cli.Command{
return xerrors.Errorf("failed to get default address: %w", err)
}
params, err := actors.SerializeParams(createMinerArgs)
params, err := actors.SerializeParams(&createMinerArgs)
if err != nil {
return err
}

View File

@ -224,7 +224,7 @@ func createStorageMiner(ctx context.Context, api api.FullNode, peerid peer.ID) (
collateral := types.NewInt(1000) // TODO: Get this from params
params, err := actors.SerializeParams(actors.CreateStorageMinerParams{
params, err := actors.SerializeParams(&actors.CreateStorageMinerParams{
Owner: defOwner,
Worker: k,
SectorSize: types.NewInt(build.SectorSize),

View File

@ -4,66 +4,75 @@ import (
"fmt"
"os"
"github.com/filecoin-project/go-lotus/chain"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/types"
gen "github.com/whyrusleeping/cbor-gen"
)
func main() {
{
fi, err := os.Create("./chain/types/cbor_gen.go")
if err != nil {
fmt.Println("failed to open file: ", err)
os.Exit(1)
}
defer fi.Close()
if err := gen.PrintHeaderAndUtilityMethods(fi, "types"); err != nil {
fmt.Println("failed to write header: ", err)
os.Exit(1)
}
types := []interface{}{
err := gen.WriteTupleEncodersToFile("./chain/types/cbor_gen.go", "types",
types.BlockHeader{},
types.Ticket{},
types.Message{},
types.SignedMessage{},
types.MsgMeta{},
}
for _, t := range types {
if err := gen.GenTupleEncodersForType(t, fi); err != nil {
fmt.Println("failed to generate encoders: ", err)
os.Exit(1)
}
}
}
{
fi, err := os.Create("./chain/cbor_gen.go")
types.SignedVoucher{},
types.ModVerifyParams{},
types.Merge{},
)
if err != nil {
fmt.Println("failed to open file: ", err)
os.Exit(1)
}
defer fi.Close()
if err := gen.PrintHeaderAndUtilityMethods(fi, "chain"); err != nil {
fmt.Println("failed to write header: ", err)
fmt.Println(err)
os.Exit(1)
}
types := []interface{}{
/*
err = gen.WriteTupleEncodersToFile("./chain/cbor_gen.go", "chain",
chain.BlockSyncRequest{},
chain.BlockSyncResponse{},
chain.BSTipSet{},
chain.BlockMsg{},
}
for _, t := range types {
if err := gen.GenTupleEncodersForType(t, fi); err != nil {
fmt.Println("failed to generate encoders: ", err)
)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
*/
err = gen.WriteTupleEncodersToFile("./chain/actors/cbor_gen.go", "actors",
actors.InitActorState{},
actors.ExecParams{},
actors.AccountActorState{},
actors.StorageMinerActorState{},
actors.StorageMinerConstructorParams{},
actors.CommitSectorParams{},
actors.MinerInfo{},
actors.SubmitPoStParams{},
actors.PieceInclVoucherData{},
actors.InclusionProof{},
actors.PaymentVerifyParams{},
actors.UpdatePeerIDParams{},
actors.MultiSigActorState{},
actors.MultiSigConstructorParams{},
actors.MultiSigProposeParams{},
actors.MultiSigTxID{},
actors.MultiSigSwapSignerParams{},
actors.MultiSigChangeReqParams{},
actors.MTransaction{},
actors.MultiSigRemoveSignerParam{},
actors.MultiSigAddSignerParam{},
actors.PaymentChannelActorState{},
actors.PCAConstructorParams{},
actors.LaneState{},
actors.PCAUpdateChannelStateParams{},
actors.PaymentInfo{},
actors.StorageMarketState{},
actors.CreateStorageMinerParams{},
actors.IsMinerParam{},
actors.PowerLookupParams{},
actors.UpdateStorageParams{},
)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}

4
go.mod
View File

@ -22,7 +22,7 @@ require (
github.com/ipfs/go-ds-badger v0.0.5
github.com/ipfs/go-filestore v0.0.2
github.com/ipfs/go-fs-lock v0.0.1
github.com/ipfs/go-hamt-ipld v0.0.12-0.20190830015840-8aabc0c74ac6
github.com/ipfs/go-hamt-ipld v0.0.12-0.20190910032255-ee6e898f0456
github.com/ipfs/go-ipfs-blockstore v0.1.0
github.com/ipfs/go-ipfs-chunker v0.0.1
github.com/ipfs/go-ipfs-ds-help v0.0.1
@ -67,7 +67,7 @@ require (
github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a
github.com/stretchr/testify v1.4.0
github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba
github.com/whyrusleeping/cbor-gen v0.0.0-20190906235522-125fcd082c67
github.com/whyrusleeping/cbor-gen v0.0.0-20190910224804-fde80d83b106
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d
github.com/whyrusleeping/sharray v0.0.0-20190718051354-e41931821e33

19
go.sum
View File

@ -138,7 +138,6 @@ github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyq
github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0=
github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs=
github.com/ipfs/go-bitswap v0.1.3/go.mod h1:YEQlFy0kkxops5Vy+OxWdRSEZIoS7I7KDIwoa5Chkps=
github.com/ipfs/go-bitswap v0.1.6 h1:3jj6/69bsqAFmNViEXU8MWUDE8iE1mrqVPaKaIChu7k=
github.com/ipfs/go-bitswap v0.1.6/go.mod h1:oRNdV7SkA9glUUMHd6O2ztSwimBDLFdIF0fYIuDEzVo=
github.com/ipfs/go-bitswap v0.1.8 h1:38X1mKXkiU6Nzw4TOSWD8eTVY5eX3slQunv3QEWfXKg=
github.com/ipfs/go-bitswap v0.1.8/go.mod h1:TOWoxllhccevbWFUR2N7B1MTSVVge1s6XSMiCSA4MzM=
@ -146,7 +145,6 @@ github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/
github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE=
github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=
github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M=
github.com/ipfs/go-blockservice v0.1.2 h1:fqFeeu1EG0lGVrqUo+BVJv7LZV31I4ZsyNthCOMAJRc=
github.com/ipfs/go-blockservice v0.1.2/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I=
github.com/ipfs/go-blockservice v0.1.3-0.20190908200855-f22eea50656c h1:lN5IQA07VtLiTLAp/Scezp1ljFhXErC6yq4O1cu+yJ0=
github.com/ipfs/go-blockservice v0.1.3-0.20190908200855-f22eea50656c/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I=
@ -170,8 +168,8 @@ github.com/ipfs/go-filestore v0.0.2 h1:pcYwpjtXXwirtbjBXKVJM9CTa9F7/8v1EkfnDaHTO
github.com/ipfs/go-filestore v0.0.2/go.mod h1:KnZ41qJsCt2OX2mxZS0xsK3Psr0/oB93HMMssLujjVc=
github.com/ipfs/go-fs-lock v0.0.1 h1:XHX8uW4jQBYWHj59XXcjg7BHlHxV9ZOYs6Y43yb7/l0=
github.com/ipfs/go-fs-lock v0.0.1/go.mod h1:DNBekbboPKcxs1aukPSaOtFA3QfSdi5C855v0i9XJ8Y=
github.com/ipfs/go-hamt-ipld v0.0.12-0.20190830015840-8aabc0c74ac6 h1:qVk+425ErvzJEz/9f38lhjPfmmu0GAj/BSNt56SW4xQ=
github.com/ipfs/go-hamt-ipld v0.0.12-0.20190830015840-8aabc0c74ac6/go.mod h1:UPmViPxLn1GGxxnllIww8yWUVO60qEYLFFfF9e3ojgo=
github.com/ipfs/go-hamt-ipld v0.0.12-0.20190910032255-ee6e898f0456 h1:I0DHyyygfm9fxWK3dZ6XAXBHVY2u93ske4kprAmm4og=
github.com/ipfs/go-hamt-ipld v0.0.12-0.20190910032255-ee6e898f0456/go.mod h1:oVAOWGetjaaAPloFDCudyhxofsSG/WijXMJLTA0kRhM=
github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08=
github.com/ipfs/go-ipfs-blockstore v0.0.2/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08=
github.com/ipfs/go-ipfs-blockstore v0.1.0 h1:V1GZorHFUIB6YgTJQdq7mcaIpUfCM3fCyVi+MTo9O88=
@ -206,7 +204,6 @@ github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA
github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms=
github.com/ipfs/go-ipld-format v0.0.2 h1:OVAGlyYT6JPZ0pEfGntFPS40lfrDmaDbQwNHEY2G9Zs=
github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k=
github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc=
github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM=
github.com/ipfs/go-log v0.0.2-0.20190905183954-62f287c7db59 h1:gUmFTK1r79usWs8LQJsoMw+yba2qs/EVj9kmPRvSrYM=
github.com/ipfs/go-log v0.0.2-0.20190905183954-62f287c7db59/go.mod h1:azGN5dH7ailfREknDDNYB0Eq4qZ/4I4Y3gO0ivjJNyM=
@ -386,12 +383,10 @@ github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNA
github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
@ -526,15 +521,15 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM=
github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba h1:X4n8JG2e2biEZZXdBKt9HX7DN3bYGFUqljqqy0DqgnY=
github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba/go.mod h1:CHQnYnQUEPydYCwuy8lmTHfGmdw9TKrhWV0xLx8l0oM=
github.com/whyrusleeping/cbor-gen v0.0.0-20190822231004-8db835b09a5a h1:9oEQR9eq2H2JDmglMcrCa+TxUEYy3HKSiNoLIkPNy/U=
github.com/whyrusleeping/cbor-gen v0.0.0-20190822231004-8db835b09a5a/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY=
github.com/whyrusleeping/cbor-gen v0.0.0-20190906235522-125fcd082c67 h1:1JDNlhJZDMCdB/8KH7w7Aq0yvBYRA8pVdhzPZluDBHU=
github.com/whyrusleeping/cbor-gen v0.0.0-20190906235522-125fcd082c67/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY=
github.com/whyrusleeping/cbor-gen v0.0.0-20190910031516-c1cbffdb01bb h1:8yBVx6dgk1GfkiWOQ+RbeDDBLCOZxOtmZ949O2uj5H4=
github.com/whyrusleeping/cbor-gen v0.0.0-20190910031516-c1cbffdb01bb/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY=
github.com/whyrusleeping/cbor-gen v0.0.0-20190910224804-fde80d83b106 h1:PRWDVakEjB5ju0toKWbXSExfi5BB+oU87/8GhBKXIWE=
github.com/whyrusleeping/cbor-gen v0.0.0-20190910224804-fde80d83b106/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY=
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc=
github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo=
github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM=
github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg=
github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8=
@ -585,7 +580,6 @@ golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM=
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -645,7 +639,6 @@ golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=