merge
This commit is contained in:
commit
15481e63dd
@ -19,7 +19,7 @@ All work is tracked via issues. An attempt at keeping an up-to-date view on rema
|
|||||||
The main branches under development at the moment are:
|
The main branches under development at the moment are:
|
||||||
* [`master`](https://github.com/filecoin-project/lotus): current testnet.
|
* [`master`](https://github.com/filecoin-project/lotus): current testnet.
|
||||||
* [`next`](https://github.com/filecoin-project/lotus/tree/next): working branch with chain-breaking changes.
|
* [`next`](https://github.com/filecoin-project/lotus/tree/next): working branch with chain-breaking changes.
|
||||||
* [`interopnet`](https://github.com/filecoin-project/lotus/tree/interopnet): devnet running one of `next` commits.
|
* [`ntwk-calibration`](https://github.com/filecoin-project/lotus/tree/ntwk-calibration): devnet running one of `next` commits.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
@ -367,7 +367,8 @@ type FullNode interface {
|
|||||||
PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error)
|
PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error)
|
||||||
PaychList(context.Context) ([]address.Address, error)
|
PaychList(context.Context) ([]address.Address, error)
|
||||||
PaychStatus(context.Context, address.Address) (*PaychStatus, error)
|
PaychStatus(context.Context, address.Address) (*PaychStatus, error)
|
||||||
PaychClose(context.Context, address.Address) (cid.Cid, error)
|
PaychSettle(context.Context, address.Address) (cid.Cid, error)
|
||||||
|
PaychCollect(context.Context, address.Address) (cid.Cid, error)
|
||||||
PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error)
|
PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error)
|
||||||
PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []VoucherSpec) (*PaymentInfo, error)
|
PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []VoucherSpec) (*PaymentInfo, error)
|
||||||
PaychVoucherCheckValid(context.Context, address.Address, *paych.SignedVoucher) error
|
PaychVoucherCheckValid(context.Context, address.Address, *paych.SignedVoucher) error
|
||||||
@ -506,6 +507,7 @@ type QueryOffer struct {
|
|||||||
|
|
||||||
Size uint64
|
Size uint64
|
||||||
MinPrice types.BigInt
|
MinPrice types.BigInt
|
||||||
|
UnsealPrice types.BigInt
|
||||||
PaymentInterval uint64
|
PaymentInterval uint64
|
||||||
PaymentIntervalIncrease uint64
|
PaymentIntervalIncrease uint64
|
||||||
Miner address.Address
|
Miner address.Address
|
||||||
@ -518,6 +520,7 @@ func (o *QueryOffer) Order(client address.Address) RetrievalOrder {
|
|||||||
Piece: o.Piece,
|
Piece: o.Piece,
|
||||||
Size: o.Size,
|
Size: o.Size,
|
||||||
Total: o.MinPrice,
|
Total: o.MinPrice,
|
||||||
|
UnsealPrice: o.UnsealPrice,
|
||||||
PaymentInterval: o.PaymentInterval,
|
PaymentInterval: o.PaymentInterval,
|
||||||
PaymentIntervalIncrease: o.PaymentIntervalIncrease,
|
PaymentIntervalIncrease: o.PaymentIntervalIncrease,
|
||||||
Client: client,
|
Client: client,
|
||||||
@ -544,6 +547,7 @@ type RetrievalOrder struct {
|
|||||||
Size uint64
|
Size uint64
|
||||||
// TODO: support offset
|
// TODO: support offset
|
||||||
Total types.BigInt
|
Total types.BigInt
|
||||||
|
UnsealPrice types.BigInt
|
||||||
PaymentInterval uint64
|
PaymentInterval uint64
|
||||||
PaymentIntervalIncrease uint64
|
PaymentIntervalIncrease uint64
|
||||||
Client address.Address
|
Client address.Address
|
||||||
|
@ -61,6 +61,7 @@ type StorageMiner interface {
|
|||||||
// WorkerConnect tells the node to connect to workers RPC
|
// WorkerConnect tells the node to connect to workers RPC
|
||||||
WorkerConnect(context.Context, string) error
|
WorkerConnect(context.Context, string) error
|
||||||
WorkerStats(context.Context) (map[uint64]storiface.WorkerStats, error)
|
WorkerStats(context.Context) (map[uint64]storiface.WorkerStats, error)
|
||||||
|
WorkerJobs(context.Context) (map[uint64][]storiface.WorkerJob, error)
|
||||||
|
|
||||||
stores.SectorIndex
|
stores.SectorIndex
|
||||||
|
|
||||||
|
@ -180,7 +180,8 @@ type FullNodeStruct struct {
|
|||||||
PaychGet func(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*api.ChannelInfo, error) `perm:"sign"`
|
PaychGet func(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*api.ChannelInfo, error) `perm:"sign"`
|
||||||
PaychList func(context.Context) ([]address.Address, error) `perm:"read"`
|
PaychList func(context.Context) ([]address.Address, error) `perm:"read"`
|
||||||
PaychStatus func(context.Context, address.Address) (*api.PaychStatus, error) `perm:"read"`
|
PaychStatus func(context.Context, address.Address) (*api.PaychStatus, error) `perm:"read"`
|
||||||
PaychClose func(context.Context, address.Address) (cid.Cid, error) `perm:"sign"`
|
PaychSettle func(context.Context, address.Address) (cid.Cid, error) `perm:"sign"`
|
||||||
|
PaychCollect func(context.Context, address.Address) (cid.Cid, error) `perm:"sign"`
|
||||||
PaychAllocateLane func(context.Context, address.Address) (uint64, error) `perm:"sign"`
|
PaychAllocateLane func(context.Context, address.Address) (uint64, error) `perm:"sign"`
|
||||||
PaychNewPayment func(ctx context.Context, from, to address.Address, vouchers []api.VoucherSpec) (*api.PaymentInfo, error) `perm:"sign"`
|
PaychNewPayment func(ctx context.Context, from, to address.Address, vouchers []api.VoucherSpec) (*api.PaymentInfo, error) `perm:"sign"`
|
||||||
PaychVoucherCheck func(context.Context, *paych.SignedVoucher) error `perm:"read"`
|
PaychVoucherCheck func(context.Context, *paych.SignedVoucher) error `perm:"read"`
|
||||||
@ -228,6 +229,7 @@ type StorageMinerStruct struct {
|
|||||||
|
|
||||||
WorkerConnect func(context.Context, string) error `perm:"admin"` // TODO: worker perm
|
WorkerConnect func(context.Context, string) error `perm:"admin"` // TODO: worker perm
|
||||||
WorkerStats func(context.Context) (map[uint64]storiface.WorkerStats, error) `perm:"admin"`
|
WorkerStats func(context.Context) (map[uint64]storiface.WorkerStats, error) `perm:"admin"`
|
||||||
|
WorkerJobs func(context.Context) (map[uint64][]storiface.WorkerJob, error) `perm:"admin"`
|
||||||
|
|
||||||
StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"`
|
StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"`
|
||||||
StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"`
|
StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"`
|
||||||
@ -804,8 +806,12 @@ func (c *FullNodeStruct) PaychVoucherList(ctx context.Context, pch address.Addre
|
|||||||
return c.Internal.PaychVoucherList(ctx, pch)
|
return c.Internal.PaychVoucherList(ctx, pch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) PaychClose(ctx context.Context, a address.Address) (cid.Cid, error) {
|
func (c *FullNodeStruct) PaychSettle(ctx context.Context, a address.Address) (cid.Cid, error) {
|
||||||
return c.Internal.PaychClose(ctx, a)
|
return c.Internal.PaychSettle(ctx, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) PaychCollect(ctx context.Context, a address.Address) (cid.Cid, error) {
|
||||||
|
return c.Internal.PaychCollect(ctx, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error) {
|
func (c *FullNodeStruct) PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error) {
|
||||||
@ -892,6 +898,10 @@ func (c *StorageMinerStruct) WorkerStats(ctx context.Context) (map[uint64]storif
|
|||||||
return c.Internal.WorkerStats(ctx)
|
return c.Internal.WorkerStats(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *StorageMinerStruct) WorkerJobs(ctx context.Context) (map[uint64][]storiface.WorkerJob, error) {
|
||||||
|
return c.Internal.WorkerJobs(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *StorageMinerStruct) StorageAttach(ctx context.Context, si stores.StorageInfo, st fsutil.FsStat) error {
|
func (c *StorageMinerStruct) StorageAttach(ctx context.Context, si stores.StorageInfo, st fsutil.FsStat) error {
|
||||||
return c.Internal.StorageAttach(ctx, si, st)
|
return c.Internal.StorageAttach(ctx, si, st)
|
||||||
}
|
}
|
||||||
|
286
api/test/paych.go
Normal file
286
api/test/paych.go
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sync/atomic"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/events"
|
||||||
|
"github.com/filecoin-project/lotus/chain/events/state"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/chain/wallet"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
|
initactor "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||||
|
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
n, sn := b(t, 2, oneMiner)
|
||||||
|
|
||||||
|
paymentCreator := n[0]
|
||||||
|
paymentReceiver := n[1]
|
||||||
|
miner := sn[0]
|
||||||
|
|
||||||
|
// get everyone connected
|
||||||
|
addrs, err := paymentCreator.NetAddrsListen(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := paymentReceiver.NetConnect(ctx, addrs); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := miner.NetConnect(ctx, addrs); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// start mining blocks
|
||||||
|
bm := newBlockMiner(ctx, t, miner, blocktime)
|
||||||
|
bm.mineBlocks()
|
||||||
|
|
||||||
|
// send some funds to register the receiver
|
||||||
|
receiverAddr, err := paymentReceiver.WalletNew(ctx, wallet.ActSigType("secp256k1"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sendFunds(ctx, t, paymentCreator, receiverAddr, abi.NewTokenAmount(1e10))
|
||||||
|
|
||||||
|
// setup the payment channel
|
||||||
|
createrAddr, err := paymentCreator.WalletDefaultAddress(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
channelAmt := int64(100000)
|
||||||
|
channelInfo, err := paymentCreator.PaychGet(ctx, createrAddr, receiverAddr, abi.NewTokenAmount(channelAmt))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := waitForMessage(ctx, t, paymentCreator, channelInfo.ChannelMessage, time.Second, "channel create")
|
||||||
|
var params initactor.ExecReturn
|
||||||
|
err = params.UnmarshalCBOR(bytes.NewReader(res.Receipt.Return))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
channel := params.RobustAddress
|
||||||
|
|
||||||
|
// allocate three lanes
|
||||||
|
var lanes []uint64
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
lane, err := paymentCreator.PaychAllocateLane(ctx, channel)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
lanes = append(lanes, lane)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make two vouchers each for each lane, then save on the other side
|
||||||
|
// Note that the voucher with a value of 2000 has a higher nonce, so it
|
||||||
|
// supersedes the voucher with a value of 1000
|
||||||
|
for _, lane := range lanes {
|
||||||
|
vouch1, err := paymentCreator.PaychVoucherCreate(ctx, channel, abi.NewTokenAmount(1000), lane)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
vouch2, err := paymentCreator.PaychVoucherCreate(ctx, channel, abi.NewTokenAmount(2000), lane)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
delta1, err := paymentReceiver.PaychVoucherAdd(ctx, channel, vouch1, nil, abi.NewTokenAmount(1000))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !delta1.Equals(abi.NewTokenAmount(1000)) {
|
||||||
|
t.Fatal("voucher didn't have the right amount")
|
||||||
|
}
|
||||||
|
delta2, err := paymentReceiver.PaychVoucherAdd(ctx, channel, vouch2, nil, abi.NewTokenAmount(1000))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !delta2.Equals(abi.NewTokenAmount(1000)) {
|
||||||
|
t.Fatal("voucher didn't have the right amount")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// settle the payment channel
|
||||||
|
settleMsgCid, err := paymentCreator.PaychSettle(ctx, channel)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res = waitForMessage(ctx, t, paymentCreator, settleMsgCid, time.Second*10, "settle")
|
||||||
|
if res.Receipt.ExitCode != 0 {
|
||||||
|
t.Fatal("Unable to settle payment channel")
|
||||||
|
}
|
||||||
|
|
||||||
|
creatorPreCollectBalance, err := paymentCreator.WalletBalance(ctx, createrAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for the receiver to submit their vouchers
|
||||||
|
ev := events.NewEvents(ctx, paymentCreator)
|
||||||
|
preds := state.NewStatePredicates(paymentCreator)
|
||||||
|
finished := make(chan struct{})
|
||||||
|
err = ev.StateChanged(func(ts *types.TipSet) (done bool, more bool, err error) {
|
||||||
|
act, err := paymentCreator.StateReadState(ctx, channel, ts.Key())
|
||||||
|
if err != nil {
|
||||||
|
return false, false, err
|
||||||
|
}
|
||||||
|
state := act.State.(paych.State)
|
||||||
|
if state.ToSend.GreaterThanEqual(abi.NewTokenAmount(6000)) {
|
||||||
|
return true, false, nil
|
||||||
|
}
|
||||||
|
return false, true, nil
|
||||||
|
}, func(oldTs, newTs *types.TipSet, states events.StateChange, curH abi.ChainEpoch) (more bool, err error) {
|
||||||
|
toSendChange := states.(*state.PayChToSendChange)
|
||||||
|
if toSendChange.NewToSend.GreaterThanEqual(abi.NewTokenAmount(6000)) {
|
||||||
|
close(finished)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}, func(ctx context.Context, ts *types.TipSet) error {
|
||||||
|
return nil
|
||||||
|
}, int(build.MessageConfidence)+1, build.SealRandomnessLookbackLimit, func(oldTs, newTs *types.TipSet) (bool, events.StateChange, error) {
|
||||||
|
return preds.OnPaymentChannelActorChanged(channel, preds.OnToSendAmountChanges())(ctx, oldTs.Key(), newTs.Key())
|
||||||
|
})
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-finished:
|
||||||
|
case <-time.After(time.Second):
|
||||||
|
t.Fatal("Timed out waiting for receiver to submit vouchers")
|
||||||
|
}
|
||||||
|
|
||||||
|
// collect funds (from receiver, though either party can do it)
|
||||||
|
collectMsg, err := paymentReceiver.PaychCollect(ctx, channel)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
res, err = paymentReceiver.StateWaitMsg(ctx, collectMsg, 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if res.Receipt.ExitCode != 0 {
|
||||||
|
t.Fatal("unable to collect on payment channel")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, check the balance for the creator
|
||||||
|
currentCreatorBalance, err := paymentCreator.WalletBalance(ctx, createrAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The highest nonce voucher that the creator sent on each lane is 2000
|
||||||
|
totalVouchers := int64(len(lanes) * 2000)
|
||||||
|
// When receiver submits the tokens to the chain, creator should get a
|
||||||
|
// refund on the remaining balance, which is
|
||||||
|
// channel amount - total voucher value
|
||||||
|
expectedRefund := channelAmt - totalVouchers
|
||||||
|
delta := big.Sub(currentCreatorBalance, creatorPreCollectBalance)
|
||||||
|
if !delta.Equals(abi.NewTokenAmount(expectedRefund)) {
|
||||||
|
t.Fatalf("did not send correct funds from creator: expected %d, got %d", expectedRefund, delta)
|
||||||
|
}
|
||||||
|
|
||||||
|
// shut down mining
|
||||||
|
bm.stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func waitForMessage(ctx context.Context, t *testing.T, paymentCreator TestNode, msgCid cid.Cid, duration time.Duration, desc string) *api.MsgLookup {
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, duration)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
fmt.Println("Waiting for", desc)
|
||||||
|
res, err := paymentCreator.StateWaitMsg(ctx, msgCid, 1)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error waiting for", desc, err)
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if res.Receipt.ExitCode != 0 {
|
||||||
|
t.Fatalf("did not successfully send %s", desc)
|
||||||
|
}
|
||||||
|
fmt.Println("Confirmed", desc)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
type blockMiner struct {
|
||||||
|
ctx context.Context
|
||||||
|
t *testing.T
|
||||||
|
miner TestStorageNode
|
||||||
|
blocktime time.Duration
|
||||||
|
mine int64
|
||||||
|
done chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBlockMiner(ctx context.Context, t *testing.T, miner TestStorageNode, blocktime time.Duration) *blockMiner {
|
||||||
|
return &blockMiner{
|
||||||
|
ctx: ctx,
|
||||||
|
t: t,
|
||||||
|
miner: miner,
|
||||||
|
blocktime: blocktime,
|
||||||
|
mine: int64(1),
|
||||||
|
done: make(chan struct{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bm *blockMiner) mineBlocks() {
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
go func() {
|
||||||
|
defer close(bm.done)
|
||||||
|
for atomic.LoadInt64(&bm.mine) == 1 {
|
||||||
|
time.Sleep(bm.blocktime)
|
||||||
|
if err := bm.miner.MineOne(bm.ctx, func(bool, error) {}); err != nil {
|
||||||
|
bm.t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bm *blockMiner) stop() {
|
||||||
|
atomic.AddInt64(&bm.mine, -1)
|
||||||
|
fmt.Println("shutting down mining")
|
||||||
|
<-bm.done
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address.Address, amount abi.TokenAmount) {
|
||||||
|
|
||||||
|
senderAddr, err := sender.WalletDefaultAddress(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := &types.Message{
|
||||||
|
From: senderAddr,
|
||||||
|
To: addr,
|
||||||
|
Value: amount,
|
||||||
|
GasLimit: 0,
|
||||||
|
GasPrice: abi.NewTokenAmount(0),
|
||||||
|
}
|
||||||
|
|
||||||
|
sm, err := sender.MpoolPushMessage(ctx, msg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
res, err := sender.StateWaitMsg(ctx, sm.Cid(), 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if res.Receipt.ExitCode != 0 {
|
||||||
|
t.Fatal("did not successfully send money")
|
||||||
|
}
|
||||||
|
}
|
@ -175,7 +175,65 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
|||||||
require.Equal(t, p.MinerPower, p.TotalPower)
|
require.Equal(t, p.MinerPower, p.TotalPower)
|
||||||
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*uint64(nSectors+GenesisPreseals)))
|
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*uint64(nSectors+GenesisPreseals)))
|
||||||
|
|
||||||
// TODO: Inject faults here
|
// Drop 2 sectors from deadline 2 partition 0 (full partition / deadline)
|
||||||
|
{
|
||||||
|
parts, err := client.StateMinerPartitions(ctx, maddr, 2, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, len(parts), 0)
|
||||||
|
|
||||||
|
n, err := parts[0].Sectors.Count()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, uint64(2), n)
|
||||||
|
|
||||||
|
// Drop the partition
|
||||||
|
err = parts[0].Sectors.ForEach(func(sid uint64) error {
|
||||||
|
return miner.SectorRemove(ctx, abi.SectorNumber(sid))
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop 1 sectors from deadline 3 partition 0
|
||||||
|
{
|
||||||
|
parts, err := client.StateMinerPartitions(ctx, maddr, 3, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, len(parts), 0)
|
||||||
|
|
||||||
|
n, err := parts[0].Sectors.Count()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, uint64(2), n)
|
||||||
|
|
||||||
|
// Drop the sector
|
||||||
|
s, err := parts[0].Sectors.First()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = miner.SectorRemove(ctx, abi.SectorNumber(s))
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
for {
|
||||||
|
head, err := client.ChainHead(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if head.Height() > di.PeriodStart+(miner2.WPoStProvingPeriod)+2 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if head.Height()%100 == 0 {
|
||||||
|
fmt.Printf("@%d\n", head.Height())
|
||||||
|
}
|
||||||
|
build.Clock.Sleep(blocktime)
|
||||||
|
}
|
||||||
|
|
||||||
|
p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, p.MinerPower, p.TotalPower)
|
||||||
|
|
||||||
|
sectors := p.MinerPower.RawBytePower.Uint64() / uint64(ssz)
|
||||||
|
require.Equal(t, nSectors+GenesisPreseals - 3, int(sectors)) // -3 just removed sectors
|
||||||
|
|
||||||
mine = false
|
mine = false
|
||||||
<-done
|
<-done
|
||||||
|
@ -38,12 +38,3 @@ func BuiltinBootstrap() ([]peer.AddrInfo, error) {
|
|||||||
})
|
})
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func DrandBootstrap() ([]peer.AddrInfo, error) {
|
|
||||||
addrs := []string{
|
|
||||||
"/dnsaddr/pl-eu.testnet.drand.sh/",
|
|
||||||
"/dnsaddr/pl-us.testnet.drand.sh/",
|
|
||||||
"/dnsaddr/pl-sin.testnet.drand.sh/",
|
|
||||||
}
|
|
||||||
return addrutil.ParseAddresses(context.TODO(), addrs)
|
|
||||||
}
|
|
||||||
|
58
build/drand.go
Normal file
58
build/drand.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package build
|
||||||
|
|
||||||
|
import "github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
|
|
||||||
|
var DrandNetwork = DrandTestnet
|
||||||
|
|
||||||
|
func DrandConfig() dtypes.DrandConfig {
|
||||||
|
return DrandConfigs[DrandNetwork]
|
||||||
|
}
|
||||||
|
|
||||||
|
type DrandEnum int
|
||||||
|
|
||||||
|
const (
|
||||||
|
DrandMainnet DrandEnum = iota + 1
|
||||||
|
DrandTestnet
|
||||||
|
DrandDevnet
|
||||||
|
DrandLocalnet
|
||||||
|
)
|
||||||
|
|
||||||
|
var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
|
||||||
|
DrandMainnet: {
|
||||||
|
Servers: []string{
|
||||||
|
"https://api.drand.sh",
|
||||||
|
"https://api2.drand.sh",
|
||||||
|
"https://api3.drand.sh",
|
||||||
|
},
|
||||||
|
Relays: []string{
|
||||||
|
"/dnsaddr/api.drand.sh/",
|
||||||
|
"/dnsaddr/api2.drand.sh/",
|
||||||
|
"/dnsaddr/api3.drand.sh/",
|
||||||
|
},
|
||||||
|
ChainInfoJSON: `{"public_key":"868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31","period":30,"genesis_time":1595431050,"hash":"8990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce","groupHash":"176f93498eac9ca337150b46d21dd58673ea4e3581185f869672e59fa4cb390a"}`,
|
||||||
|
},
|
||||||
|
DrandTestnet: {
|
||||||
|
Servers: []string{
|
||||||
|
"https://pl-eu.testnet.drand.sh",
|
||||||
|
"https://pl-us.testnet.drand.sh",
|
||||||
|
"https://pl-sin.testnet.drand.sh",
|
||||||
|
},
|
||||||
|
Relays: []string{
|
||||||
|
"/dnsaddr/pl-eu.testnet.drand.sh/",
|
||||||
|
"/dnsaddr/pl-us.testnet.drand.sh/",
|
||||||
|
"/dnsaddr/pl-sin.testnet.drand.sh/",
|
||||||
|
},
|
||||||
|
ChainInfoJSON: `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"84b2234fb34e835dccd048255d7ad3194b81af7d978c3bf157e3469592ae4e02","groupHash":"4dd408e5fdff9323c76a9b6f087ba8fdc5a6da907bd9217d9d10f2287d081957"}`,
|
||||||
|
},
|
||||||
|
DrandDevnet: {
|
||||||
|
Servers: []string{
|
||||||
|
"https://dev1.drand.sh",
|
||||||
|
"https://dev2.drand.sh",
|
||||||
|
},
|
||||||
|
Relays: []string{
|
||||||
|
"/dnsaddr/dev1.drand.sh/",
|
||||||
|
"/dnsaddr/dev2.drand.sh/",
|
||||||
|
},
|
||||||
|
ChainInfoJSON: `{"public_key":"8cda589f88914aa728fd183f383980b35789ce81b274e5daee1f338b77d02566ef4d3fb0098af1f844f10f9c803c1827","period":25,"genesis_time":1595348225,"hash":"e73b7dc3c4f6a236378220c0dd6aa110eb16eed26c11259606e07ee122838d4f","groupHash":"567d4785122a5a3e75a9bc9911d7ea807dd85ff76b78dc4ff06b075712898607"}`,
|
||||||
|
},
|
||||||
|
}
|
@ -8,8 +8,6 @@ import (
|
|||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// /////
|
// /////
|
||||||
@ -92,12 +90,3 @@ const VerifSigCacheSize = 32000
|
|||||||
// TODO: If this is gonna stay, it should move to specs-actors
|
// TODO: If this is gonna stay, it should move to specs-actors
|
||||||
const BlockMessageLimit = 512
|
const BlockMessageLimit = 512
|
||||||
const BlockGasLimit = 7_500_000_000
|
const BlockGasLimit = 7_500_000_000
|
||||||
|
|
||||||
var DrandConfig = dtypes.DrandConfig{
|
|
||||||
Servers: []string{
|
|
||||||
"https://pl-eu.testnet.drand.sh",
|
|
||||||
"https://pl-us.testnet.drand.sh",
|
|
||||||
"https://pl-sin.testnet.drand.sh",
|
|
||||||
},
|
|
||||||
ChainInfoJSON: `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"84b2234fb34e835dccd048255d7ad3194b81af7d978c3bf157e3469592ae4e02","groupHash":"4dd408e5fdff9323c76a9b6f087ba8fdc5a6da907bd9217d9d10f2287d081957"}`,
|
|
||||||
}
|
|
||||||
|
@ -10,8 +10,6 @@ package build
|
|||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
@ -61,13 +59,4 @@ var (
|
|||||||
v = v.Mul(v, big.NewInt(int64(FilecoinPrecision)))
|
v = v.Mul(v, big.NewInt(int64(FilecoinPrecision)))
|
||||||
return v
|
return v
|
||||||
}()
|
}()
|
||||||
|
|
||||||
DrandConfig = dtypes.DrandConfig{
|
|
||||||
Servers: []string{
|
|
||||||
"https://pl-eu.testnet.drand.sh",
|
|
||||||
"https://pl-us.testnet.drand.sh",
|
|
||||||
"https://pl-sin.testnet.drand.sh",
|
|
||||||
},
|
|
||||||
ChainInfoJSON: `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"138a324aa6540f93d0dad002aa89454b1bec2b6e948682cde6bd4db40f4b7c9b"}`,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestPrintGroupInfo(t *testing.T) {
|
func TestPrintGroupInfo(t *testing.T) {
|
||||||
server := build.DrandConfig.Servers[0]
|
server := build.DrandConfig().Servers[0]
|
||||||
c, err := hclient.New(server, nil, nil)
|
c, err := hclient.New(server, nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
cg := c.(interface {
|
cg := c.(interface {
|
||||||
|
@ -3,6 +3,7 @@ package state
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
@ -12,6 +13,7 @@ import (
|
|||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api/apibstore"
|
"github.com/filecoin-project/lotus/api/apibstore"
|
||||||
@ -493,3 +495,40 @@ func (sp *StatePredicates) OnMinerPreCommitChange() DiffMinerActorStateFunc {
|
|||||||
return true, precommitChanges, nil
|
return true, precommitChanges, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DiffPaymentChannelStateFunc is function that compares two states for the payment channel
|
||||||
|
type DiffPaymentChannelStateFunc func(ctx context.Context, oldState *paych.State, newState *paych.State) (changed bool, user UserData, err error)
|
||||||
|
|
||||||
|
// OnPaymentChannelActorChanged calls diffPaymentChannelState when the state changes for the the payment channel actor
|
||||||
|
func (sp *StatePredicates) OnPaymentChannelActorChanged(paychAddr address.Address, diffPaymentChannelState DiffPaymentChannelStateFunc) DiffTipSetKeyFunc {
|
||||||
|
return sp.OnActorStateChanged(paychAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) {
|
||||||
|
var oldState paych.State
|
||||||
|
if err := sp.cst.Get(ctx, oldActorStateHead, &oldState); err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
var newState paych.State
|
||||||
|
if err := sp.cst.Get(ctx, newActorStateHead, &newState); err != nil {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
return diffPaymentChannelState(ctx, &oldState, &newState)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// PayChToSendChange is a difference in the amount to send on a payment channel when the money is collected
|
||||||
|
type PayChToSendChange struct {
|
||||||
|
OldToSend abi.TokenAmount
|
||||||
|
NewToSend abi.TokenAmount
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnToSendAmountChanges monitors changes on the total amount to send from one party to the other on a payment channel
|
||||||
|
func (sp *StatePredicates) OnToSendAmountChanges() DiffPaymentChannelStateFunc {
|
||||||
|
return func(ctx context.Context, oldState *paych.State, newState *paych.State) (changed bool, user UserData, err error) {
|
||||||
|
if oldState.ToSend.Equals(newState.ToSend) {
|
||||||
|
return false, nil, nil
|
||||||
|
}
|
||||||
|
return true, &PayChToSendChange{
|
||||||
|
OldToSend: oldState.ToSend,
|
||||||
|
NewToSend: newState.ToSend,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,12 +10,10 @@ import (
|
|||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
ds "github.com/ipfs/go-datastore"
|
ds "github.com/ipfs/go-datastore"
|
||||||
ds_sync "github.com/ipfs/go-datastore/sync"
|
ds_sync "github.com/ipfs/go-datastore/sync"
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
|
||||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
cbornode "github.com/ipfs/go-ipld-cbor"
|
cbornode "github.com/ipfs/go-ipld-cbor"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-amt-ipld/v2"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
@ -69,7 +67,7 @@ func (m mockAPI) setActor(tsk types.TipSetKey, act *types.Actor) {
|
|||||||
func TestMarketPredicates(t *testing.T) {
|
func TestMarketPredicates(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
bs := bstore.NewBlockstore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
bs := bstore.NewBlockstore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
||||||
store := cbornode.NewCborStore(bs)
|
store := adt.WrapStore(ctx, cbornode.NewCborStore(bs))
|
||||||
|
|
||||||
oldDeal1 := &market.DealState{
|
oldDeal1 := &market.DealState{
|
||||||
SectorStartEpoch: 1,
|
SectorStartEpoch: 1,
|
||||||
@ -284,7 +282,7 @@ func TestMarketPredicates(t *testing.T) {
|
|||||||
func TestMinerSectorChange(t *testing.T) {
|
func TestMinerSectorChange(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
bs := bstore.NewBlockstore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
bs := bstore.NewBlockstore(ds_sync.MutexWrap(ds.NewMapDatastore()))
|
||||||
store := cbornode.NewCborStore(bs)
|
store := adt.WrapStore(ctx, cbornode.NewCborStore(bs))
|
||||||
|
|
||||||
nextID := uint64(0)
|
nextID := uint64(0)
|
||||||
nextIDAddrF := func() address.Address {
|
nextIDAddrF := func() address.Address {
|
||||||
@ -376,7 +374,7 @@ func mockTipset(minerAddr address.Address, timestamp uint64) (*types.TipSet, err
|
|||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMarketState(ctx context.Context, t *testing.T, store *cbornode.BasicIpldStore, deals map[abi.DealID]*market.DealState, props map[abi.DealID]*market.DealProposal) cid.Cid {
|
func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market.DealState, props map[abi.DealID]*market.DealProposal) cid.Cid {
|
||||||
dealRootCid := createDealAMT(ctx, t, store, deals)
|
dealRootCid := createDealAMT(ctx, t, store, deals)
|
||||||
propRootCid := createProposalAMT(ctx, t, store, props)
|
propRootCid := createProposalAMT(ctx, t, store, props)
|
||||||
|
|
||||||
@ -389,37 +387,37 @@ func createMarketState(ctx context.Context, t *testing.T, store *cbornode.BasicI
|
|||||||
return stateC
|
return stateC
|
||||||
}
|
}
|
||||||
|
|
||||||
func createEmptyMarketState(t *testing.T, store *cbornode.BasicIpldStore) *market.State {
|
func createEmptyMarketState(t *testing.T, store adt.Store) *market.State {
|
||||||
emptyArrayCid, err := amt.NewAMT(store).Flush(context.TODO())
|
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
emptyMap, err := store.Put(context.TODO(), hamt.NewNode(store, hamt.UseTreeBitWidth(5)))
|
emptyMap, err := adt.MakeEmptyMap(store).Root()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return market.ConstructState(emptyArrayCid, emptyMap, emptyMap)
|
return market.ConstructState(emptyArrayCid, emptyMap, emptyMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDealAMT(ctx context.Context, t *testing.T, store *cbornode.BasicIpldStore, deals map[abi.DealID]*market.DealState) cid.Cid {
|
func createDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market.DealState) cid.Cid {
|
||||||
root := amt.NewAMT(store)
|
root := adt.MakeEmptyArray(store)
|
||||||
for dealID, dealState := range deals {
|
for dealID, dealState := range deals {
|
||||||
err := root.Set(ctx, uint64(dealID), dealState)
|
err := root.Set(uint64(dealID), dealState)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
rootCid, err := root.Flush(ctx)
|
rootCid, err := root.Root()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return rootCid
|
return rootCid
|
||||||
}
|
}
|
||||||
|
|
||||||
func createProposalAMT(ctx context.Context, t *testing.T, store *cbornode.BasicIpldStore, props map[abi.DealID]*market.DealProposal) cid.Cid {
|
func createProposalAMT(ctx context.Context, t *testing.T, store adt.Store, props map[abi.DealID]*market.DealProposal) cid.Cid {
|
||||||
root := amt.NewAMT(store)
|
root := adt.MakeEmptyArray(store)
|
||||||
for dealID, prop := range props {
|
for dealID, prop := range props {
|
||||||
err := root.Set(ctx, uint64(dealID), prop)
|
err := root.Set(uint64(dealID), prop)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
rootCid, err := root.Flush(ctx)
|
rootCid, err := root.Root()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return rootCid
|
return rootCid
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMinerState(ctx context.Context, t *testing.T, store *cbornode.BasicIpldStore, owner, worker address.Address, sectors []miner.SectorOnChainInfo) cid.Cid {
|
func createMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address, sectors []miner.SectorOnChainInfo) cid.Cid {
|
||||||
rootCid := createSectorsAMT(ctx, t, store, sectors)
|
rootCid := createSectorsAMT(ctx, t, store, sectors)
|
||||||
|
|
||||||
state := createEmptyMinerState(ctx, t, store, owner, worker)
|
state := createEmptyMinerState(ctx, t, store, owner, worker)
|
||||||
@ -430,10 +428,10 @@ func createMinerState(ctx context.Context, t *testing.T, store *cbornode.BasicIp
|
|||||||
return stateC
|
return stateC
|
||||||
}
|
}
|
||||||
|
|
||||||
func createEmptyMinerState(ctx context.Context, t *testing.T, store *cbornode.BasicIpldStore, owner, worker address.Address) *miner.State {
|
func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address) *miner.State {
|
||||||
emptyArrayCid, err := amt.NewAMT(store).Flush(context.TODO())
|
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
emptyMap, err := store.Put(context.TODO(), hamt.NewNode(store, hamt.UseTreeBitWidth(5)))
|
emptyMap, err := adt.MakeEmptyMap(store).Root()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
emptyDeadline, err := store.Put(context.TODO(), &miner.Deadline{
|
emptyDeadline, err := store.Put(context.TODO(), &miner.Deadline{
|
||||||
@ -457,14 +455,14 @@ func createEmptyMinerState(ctx context.Context, t *testing.T, store *cbornode.Ba
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSectorsAMT(ctx context.Context, t *testing.T, store *cbornode.BasicIpldStore, sectors []miner.SectorOnChainInfo) cid.Cid {
|
func createSectorsAMT(ctx context.Context, t *testing.T, store adt.Store, sectors []miner.SectorOnChainInfo) cid.Cid {
|
||||||
root := amt.NewAMT(store)
|
root := adt.MakeEmptyArray(store)
|
||||||
for _, sector := range sectors {
|
for _, sector := range sectors {
|
||||||
sector := sector
|
sector := sector
|
||||||
err := root.Set(ctx, uint64(sector.SectorNumber), §or)
|
err := root.Set(uint64(sector.SectorNumber), §or)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
rootCid, err := root.Flush(ctx)
|
rootCid, err := root.Root()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return rootCid
|
return rootCid
|
||||||
}
|
}
|
||||||
|
@ -378,6 +378,10 @@ func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) {
|
|||||||
return mts, nil
|
return mts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cg *ChainGen) SetWinningPoStProver(m address.Address, wpp WinningPoStProver) {
|
||||||
|
cg.eppProvs[m] = wpp
|
||||||
|
}
|
||||||
|
|
||||||
func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Address) (*MinedTipSet, error) {
|
func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Address) (*MinedTipSet, error) {
|
||||||
var blks []*types.FullBlock
|
var blks []*types.FullBlock
|
||||||
|
|
||||||
|
@ -4,15 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-amt-ipld/v2"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-datastore"
|
"github.com/ipfs/go-datastore"
|
||||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
@ -22,11 +13,21 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/state"
|
"github.com/filecoin-project/lotus/chain/state"
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/vm"
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
"github.com/filecoin-project/lotus/genesis"
|
"github.com/filecoin-project/lotus/genesis"
|
||||||
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
)
|
)
|
||||||
|
|
||||||
const AccountStart = 100
|
const AccountStart = 100
|
||||||
@ -224,6 +225,43 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup the first verifier as ID-address 81
|
||||||
|
// TODO: remove this
|
||||||
|
skBytes, err := sigs.Generate(crypto.SigTypeBLS)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("creating random verifier secret key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
verifierPk, err := sigs.ToPublic(crypto.SigTypeBLS, skBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("creating random verifier public key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
verifierAd, err := address.NewBLSAddress(verifierPk)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("creating random verifier address: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
verifierId, err := address.NewIDAddress(81)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
verifierState, err := cst.Put(ctx, &account.State{Address: verifierAd})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = state.SetActor(verifierId, &types.Actor{
|
||||||
|
Code: builtin.AccountActorCodeID,
|
||||||
|
Balance: types.NewInt(0),
|
||||||
|
Head: verifierState,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("setting account from actmap: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return state, nil
|
return state, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,17 +328,22 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verifier, err := address.NewIDAddress(80)
|
verifregRoot, err := address.NewIDAddress(80)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
vm, err := vm.NewVM(stateroot, 0, &fakeRand{}, cs.Blockstore(), &fakedSigSyscalls{cs.VMSys()})
|
verifier, err := address.NewIDAddress(81)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
|
||||||
|
vm, err := vm.NewVM(stateroot, 0, &fakeRand{}, cs.Blockstore(), mkFakedSigSyscalls(cs.VMSys()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = doExecValue(ctx, vm, builtin.VerifiedRegistryActorAddr, verifier, types.NewInt(0), builtin.MethodsVerifiedRegistry.AddVerifier, mustEnc(&verifreg.AddVerifierParams{
|
_, err = doExecValue(ctx, vm, builtin.VerifiedRegistryActorAddr, verifregRoot, types.NewInt(0), builtin.MethodsVerifiedRegistry.AddVerifier, mustEnc(&verifreg.AddVerifierParams{
|
||||||
Address: verifier,
|
Address: verifier,
|
||||||
Allowance: abi.NewStoragePower(int64(sum)), // eh, close enough
|
Allowance: abi.NewStoragePower(int64(sum)), // eh, close enough
|
||||||
|
|
||||||
@ -327,7 +370,7 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
|||||||
return st, nil
|
return st, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys runtime.Syscalls, template genesis.Template) (*GenesisBootstrap, error) {
|
func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys vm.SyscallBuilder, template genesis.Template) (*GenesisBootstrap, error) {
|
||||||
st, err := MakeInitialStateTree(ctx, bs, template)
|
st, err := MakeInitialStateTree(ctx, bs, template)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("make initial state tree failed: %w", err)
|
return nil, xerrors.Errorf("make initial state tree failed: %w", err)
|
||||||
@ -352,9 +395,8 @@ func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys runtime.Sys
|
|||||||
return nil, xerrors.Errorf("setup miners failed: %w", err)
|
return nil, xerrors.Errorf("setup miners failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cst := cbor.NewCborStore(bs)
|
store := adt.WrapStore(ctx, cbor.NewCborStore(bs))
|
||||||
|
emptyroot, err := adt.MakeEmptyArray(store).Root()
|
||||||
emptyroot, err := amt.FromArray(ctx, cst, nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("amt build failed: %w", err)
|
return nil, xerrors.Errorf("amt build failed: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/state"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
@ -46,8 +47,16 @@ func (fss *fakedSigSyscalls) VerifySignature(signature crypto.Signature, signer
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder {
|
||||||
|
return func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime.Syscalls {
|
||||||
|
return &fakedSigSyscalls{
|
||||||
|
base(ctx, cstate, cst),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner) (cid.Cid, error) {
|
func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner) (cid.Cid, error) {
|
||||||
vm, err := vm.NewVM(sroot, 0, &fakeRand{}, cs.Blockstore(), &fakedSigSyscalls{cs.VMSys()})
|
vm, err := vm.NewVM(sroot, 0, &fakeRand{}, cs.Blockstore(), mkFakedSigSyscalls(cs.VMSys()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
|
||||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -26,8 +27,8 @@ func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesi
|
|||||||
ias.NextID = MinerStart
|
ias.NextID = MinerStart
|
||||||
ias.NetworkName = netname
|
ias.NetworkName = netname
|
||||||
|
|
||||||
cst := cbor.NewCborStore(bs)
|
store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs))
|
||||||
amap := hamt.NewNode(cst, hamt.UseTreeBitWidth(5)) // TODO: use spec adt map
|
amap := adt.MakeEmptyMap(store)
|
||||||
|
|
||||||
for i, a := range initialActors {
|
for i, a := range initialActors {
|
||||||
if a.Type == genesis.TMultisig {
|
if a.Type == genesis.TMultisig {
|
||||||
@ -43,9 +44,10 @@ func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesi
|
|||||||
return nil, xerrors.Errorf("unmarshaling account meta: %w", err)
|
return nil, xerrors.Errorf("unmarshaling account meta: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("init set %s t0%d\n", ainfo.Owner, AccountStart+uint64(i))
|
fmt.Printf("init set %s t0%d\n", ainfo.Owner, AccountStart+int64(i))
|
||||||
|
|
||||||
if err := amap.Set(context.TODO(), string(ainfo.Owner.Bytes()), AccountStart+uint64(i)); err != nil {
|
value := cbg.CborInt(AccountStart + int64(i))
|
||||||
|
if err := amap.Put(adt.AddrKey(ainfo.Owner), &value); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,22 +57,19 @@ func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesi
|
|||||||
if err := json.Unmarshal(rootVerifier.Meta, &ainfo); err != nil {
|
if err := json.Unmarshal(rootVerifier.Meta, &ainfo); err != nil {
|
||||||
return nil, xerrors.Errorf("unmarshaling account meta: %w", err)
|
return nil, xerrors.Errorf("unmarshaling account meta: %w", err)
|
||||||
}
|
}
|
||||||
if err := amap.Set(context.TODO(), string(ainfo.Owner.Bytes()), 80); err != nil {
|
value := cbg.CborInt(80)
|
||||||
|
if err := amap.Put(adt.AddrKey(ainfo.Owner), &value); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := amap.Flush(context.TODO()); err != nil {
|
amapaddr, err := amap.Root()
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
amapcid, err := cst.Put(context.TODO(), amap)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
ias.AddressMap = amapaddr
|
||||||
|
|
||||||
ias.AddressMap = amapcid
|
statecid, err := store.Put(store.Context(), &ias)
|
||||||
|
|
||||||
statecid, err := cst.Put(context.TODO(), &ias)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,12 @@ package genesis
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
|
||||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
|
||||||
@ -14,10 +15,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) {
|
func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) {
|
||||||
ctx := context.TODO()
|
store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs))
|
||||||
cst := cbor.NewCborStore(bs)
|
emptyhamt, err := adt.MakeEmptyMap(store).Root()
|
||||||
nd := hamt.NewNode(cst, hamt.UseTreeBitWidth(5))
|
|
||||||
emptyhamt, err := cst.Put(ctx, nd)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -36,7 +35,7 @@ func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) {
|
|||||||
ProofValidationBatch: nil,
|
ProofValidationBatch: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
stcid, err := cst.Put(ctx, sms)
|
stcid, err := store.Put(store.Context(), sms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,10 @@ package genesis
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-amt-ipld/v2"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
|
||||||
@ -14,20 +13,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) {
|
func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) {
|
||||||
cst := cbor.NewCborStore(bs)
|
store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs))
|
||||||
|
|
||||||
a, err := amt.NewAMT(cst).Flush(context.TODO())
|
a, err := adt.MakeEmptyArray(store).Root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
h, err := cst.Put(context.TODO(), hamt.NewNode(cst, hamt.UseTreeBitWidth(5)))
|
h, err := adt.MakeEmptyMap(store).Root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sms := market.ConstructState(a, h, h)
|
sms := market.ConstructState(a, h, h)
|
||||||
|
|
||||||
stcid, err := cst.Put(context.TODO(), sms)
|
stcid, err := store.Put(store.Context(), sms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
|
||||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
@ -27,16 +27,16 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SetupVerifiedRegistryActor(bs bstore.Blockstore) (*types.Actor, error) {
|
func SetupVerifiedRegistryActor(bs bstore.Blockstore) (*types.Actor, error) {
|
||||||
cst := cbor.NewCborStore(bs)
|
store := adt.WrapStore(context.TODO(), cbor.NewCborStore(bs))
|
||||||
|
|
||||||
h, err := cst.Put(context.TODO(), hamt.NewNode(cst, hamt.UseTreeBitWidth(5)))
|
h, err := adt.MakeEmptyMap(store).Root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sms := verifreg.ConstructState(h, RootVerifierID)
|
sms := verifreg.ConstructState(h, RootVerifierID)
|
||||||
|
|
||||||
stcid, err := cst.Put(context.TODO(), sms)
|
stcid, err := store.Put(store.Context(), sms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
bls "github.com/filecoin-project/filecoin-ffi"
|
bls "github.com/filecoin-project/filecoin-ffi"
|
||||||
amt "github.com/filecoin-project/go-amt-ipld/v2"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
@ -78,17 +78,17 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bs := cbor.NewCborStore(sm.ChainStore().Blockstore())
|
store := sm.ChainStore().Store(ctx)
|
||||||
blsmsgroot, err := amt.FromArray(ctx, bs, toIfArr(blsMsgCids))
|
blsmsgroot, err := toArray(store, blsMsgCids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("building bls amt: %w", err)
|
return nil, xerrors.Errorf("building bls amt: %w", err)
|
||||||
}
|
}
|
||||||
secpkmsgroot, err := amt.FromArray(ctx, bs, toIfArr(secpkMsgCids))
|
secpkmsgroot, err := toArray(store, secpkMsgCids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("building secpk amt: %w", err)
|
return nil, xerrors.Errorf("building secpk amt: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mmcid, err := bs.Put(ctx, &types.MsgMeta{
|
mmcid, err := store.Put(store.Context(), &types.MsgMeta{
|
||||||
BlsMessages: blsmsgroot,
|
BlsMessages: blsmsgroot,
|
||||||
SecpkMessages: secpkmsgroot,
|
SecpkMessages: secpkmsgroot,
|
||||||
})
|
})
|
||||||
@ -167,11 +167,13 @@ func aggregateSignatures(sigs []crypto.Signature) (*crypto.Signature, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toIfArr(cids []cid.Cid) []cbg.CBORMarshaler {
|
func toArray(store adt.Store, cids []cid.Cid) (cid.Cid, error) {
|
||||||
out := make([]cbg.CBORMarshaler, 0, len(cids))
|
arr := adt.MakeEmptyArray(store)
|
||||||
for _, c := range cids {
|
for i, c := range cids {
|
||||||
oc := cbg.CborCid(c)
|
oc := cbg.CborCid(c)
|
||||||
out = append(out, &oc)
|
if err := arr.Set(uint64(i), &oc); err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
return out
|
}
|
||||||
|
return arr.Root()
|
||||||
}
|
}
|
||||||
|
@ -117,12 +117,14 @@ func (ms *msgSet) add(m *types.SignedMessage) error {
|
|||||||
minPrice := exms.Message.GasPrice
|
minPrice := exms.Message.GasPrice
|
||||||
minPrice = types.BigAdd(minPrice, types.BigDiv(types.BigMul(minPrice, rbfNum), rbfDenom))
|
minPrice = types.BigAdd(minPrice, types.BigDiv(types.BigMul(minPrice, rbfNum), rbfDenom))
|
||||||
minPrice = types.BigAdd(minPrice, types.NewInt(1))
|
minPrice = types.BigAdd(minPrice, types.NewInt(1))
|
||||||
if types.BigCmp(m.Message.GasPrice, minPrice) > 0 {
|
if types.BigCmp(m.Message.GasPrice, minPrice) >= 0 {
|
||||||
log.Infow("add with RBF", "oldprice", exms.Message.GasPrice,
|
log.Infow("add with RBF", "oldprice", exms.Message.GasPrice,
|
||||||
"newprice", m.Message.GasPrice, "addr", m.Message.From, "nonce", m.Message.Nonce)
|
"newprice", m.Message.GasPrice, "addr", m.Message.From, "nonce", m.Message.Nonce)
|
||||||
} else {
|
} else {
|
||||||
log.Info("add with duplicate nonce")
|
log.Info("add with duplicate nonce")
|
||||||
return xerrors.Errorf("message to %s with nonce %d already in mpool", m.Message.To, m.Message.Nonce)
|
return xerrors.Errorf("message from %s with nonce %d already in mpool,"+
|
||||||
|
" increase GasPrice to %s from %s to trigger replace by fee",
|
||||||
|
m.Message.From, m.Message.Nonce, minPrice, m.Message.GasPrice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -617,6 +619,14 @@ func (mp *MessagePool) Pending() ([]*types.SignedMessage, *types.TipSet) {
|
|||||||
|
|
||||||
return out, mp.curTs
|
return out, mp.curTs
|
||||||
}
|
}
|
||||||
|
func (mp *MessagePool) PendingFor(a address.Address) ([]*types.SignedMessage, *types.TipSet) {
|
||||||
|
mp.curTsLk.Lock()
|
||||||
|
defer mp.curTsLk.Unlock()
|
||||||
|
|
||||||
|
mp.lk.Lock()
|
||||||
|
defer mp.lk.Unlock()
|
||||||
|
return mp.pendingFor(a), mp.curTs
|
||||||
|
}
|
||||||
|
|
||||||
func (mp *MessagePool) pendingFor(a address.Address) []*types.SignedMessage {
|
func (mp *MessagePool) pendingFor(a address.Address) []*types.SignedMessage {
|
||||||
mset := mp.pending[a]
|
mset := mp.pending[a]
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
hamt "github.com/ipfs/go-hamt-ipld"
|
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
@ -23,7 +22,7 @@ var log = logging.Logger("statetree")
|
|||||||
|
|
||||||
// StateTree stores actors state by their ID.
|
// StateTree stores actors state by their ID.
|
||||||
type StateTree struct {
|
type StateTree struct {
|
||||||
root *hamt.Node
|
root *adt.Map
|
||||||
Store cbor.IpldStore
|
Store cbor.IpldStore
|
||||||
|
|
||||||
snaps *stateSnaps
|
snaps *stateSnaps
|
||||||
@ -117,15 +116,16 @@ func (ss *stateSnaps) deleteActor(addr address.Address) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewStateTree(cst cbor.IpldStore) (*StateTree, error) {
|
func NewStateTree(cst cbor.IpldStore) (*StateTree, error) {
|
||||||
|
|
||||||
return &StateTree{
|
return &StateTree{
|
||||||
root: hamt.NewNode(cst, hamt.UseTreeBitWidth(5)),
|
root: adt.MakeEmptyMap(adt.WrapStore(context.TODO(), cst)),
|
||||||
Store: cst,
|
Store: cst,
|
||||||
snaps: newStateSnaps(),
|
snaps: newStateSnaps(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) {
|
func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) {
|
||||||
nd, err := hamt.LoadNode(context.Background(), cst, c, hamt.UseTreeBitWidth(5))
|
nd, err := adt.AsMap(adt.WrapStore(context.TODO(), cst), c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("loading hamt node %s failed: %s", c, err)
|
log.Errorf("loading hamt node %s failed: %s", c, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -206,12 +206,10 @@ func (st *StateTree) GetActor(addr address.Address) (*types.Actor, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var act types.Actor
|
var act types.Actor
|
||||||
err = st.root.Find(context.TODO(), string(addr.Bytes()), &act)
|
if found, err := st.root.Get(adt.AddrKey(addr), &act); err != nil {
|
||||||
if err != nil {
|
|
||||||
if err == hamt.ErrNotFound {
|
|
||||||
return nil, types.ErrActorNotFound
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("hamt find failed: %w", err)
|
return nil, xerrors.Errorf("hamt find failed: %w", err)
|
||||||
|
} else if !found {
|
||||||
|
return nil, types.ErrActorNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
st.snaps.setActor(addr, &act)
|
st.snaps.setActor(addr, &act)
|
||||||
@ -253,21 +251,17 @@ func (st *StateTree) Flush(ctx context.Context) (cid.Cid, error) {
|
|||||||
|
|
||||||
for addr, sto := range st.snaps.layers[0].actors {
|
for addr, sto := range st.snaps.layers[0].actors {
|
||||||
if sto.Delete {
|
if sto.Delete {
|
||||||
if err := st.root.Delete(ctx, string(addr.Bytes())); err != nil {
|
if err := st.root.Delete(adt.AddrKey(addr)); err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := st.root.Set(ctx, string(addr.Bytes()), &sto.Act); err != nil {
|
if err := st.root.Put(adt.AddrKey(addr), &sto.Act); err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := st.root.Flush(ctx); err != nil {
|
return st.root.Root()
|
||||||
return cid.Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return st.Store.Put(ctx, st.root)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *StateTree) Snapshot(ctx context.Context) error {
|
func (st *StateTree) Snapshot(ctx context.Context) error {
|
||||||
|
@ -272,7 +272,7 @@ func TestStateTreeConsistency(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("root is: ", root)
|
fmt.Println("root is: ", root)
|
||||||
if root.String() != "bafy2bzaceadyjnrv3sbjvowfl3jr4pdn5p2bf3exjjie2f3shg4oy5sub7h34" {
|
if root.String() != "bafy2bzaceb2bhqw75pqp44efoxvlnm73lnctq6djair56bfn5x3gw56epcxbi" {
|
||||||
t.Fatal("MISMATCH!")
|
t.Fatal("MISMATCH!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
|
|||||||
return sm.CallRaw(ctx, msg, state, r, ts.Height())
|
return sm.CallRaw(ctx, msg, state, r, ts.Height())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.InvocResult, error) {
|
func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, priorMsgs []types.ChainMsg, ts *types.TipSet) (*api.InvocResult, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "statemanager.CallWithGas")
|
ctx, span := trace.StartSpan(ctx, "statemanager.CallWithGas")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
@ -110,6 +110,13 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, ts
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
||||||
}
|
}
|
||||||
|
for i, m := range priorMsgs {
|
||||||
|
_, err := vmi.ApplyMessage(ctx, m)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("applying prior message (%d, %s): %w", i, m.Cid(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fromActor, err := vmi.StateTree().GetActor(msg.From)
|
fromActor, err := vmi.StateTree().GetActor(msg.From)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("call raw get actor: %s", err)
|
return nil, xerrors.Errorf("call raw get actor: %s", err)
|
||||||
|
@ -156,7 +156,7 @@ func TestForkHeightTriggers(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inv.Register(builtin.PaymentChannelActorCodeID, &testActor{}, &testActorState{})
|
inv.Register(builtin.PaymentChannelActorCodeID, &testActor{}, &testActorState{})
|
||||||
sm.SetVMConstructor(func(c cid.Cid, h abi.ChainEpoch, r vm.Rand, b blockstore.Blockstore, s runtime.Syscalls) (*vm.VM, error) {
|
sm.SetVMConstructor(func(c cid.Cid, h abi.ChainEpoch, r vm.Rand, b blockstore.Blockstore, s vm.SyscallBuilder) (*vm.VM, error) {
|
||||||
nvm, err := vm.NewVM(c, h, r, b, s)
|
nvm, err := vm.NewVM(c, h, r, b, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
amt "github.com/filecoin-project/go-amt-ipld/v2"
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
@ -19,14 +18,12 @@ import (
|
|||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
bls "github.com/filecoin-project/filecoin-ffi"
|
bls "github.com/filecoin-project/filecoin-ffi"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
hamt "github.com/ipfs/go-hamt-ipld"
|
|
||||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
@ -41,7 +38,7 @@ type StateManager struct {
|
|||||||
stCache map[string][]cid.Cid
|
stCache map[string][]cid.Cid
|
||||||
compWait map[string]chan struct{}
|
compWait map[string]chan struct{}
|
||||||
stlk sync.Mutex
|
stlk sync.Mutex
|
||||||
newVM func(cid.Cid, abi.ChainEpoch, vm.Rand, blockstore.Blockstore, runtime.Syscalls) (*vm.VM, error)
|
newVM func(cid.Cid, abi.ChainEpoch, vm.Rand, blockstore.Blockstore, vm.SyscallBuilder) (*vm.VM, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStateManager(cs *store.ChainStore) *StateManager {
|
func NewStateManager(cs *store.ChainStore) *StateManager {
|
||||||
@ -254,8 +251,13 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, pstate cid.Cid, bms []B
|
|||||||
return cid.Undef, cid.Undef, xerrors.Errorf("CheckProofSubmissions exit was non-zero: %d", ret.ExitCode)
|
return cid.Undef, cid.Undef, xerrors.Errorf("CheckProofSubmissions exit was non-zero: %d", ret.ExitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
bs := cbor.NewCborStore(sm.cs.Blockstore())
|
rectarr := adt.MakeEmptyArray(sm.cs.Store(ctx))
|
||||||
rectroot, err := amt.FromArray(ctx, bs, receipts)
|
for i, receipt := range receipts {
|
||||||
|
if err := rectarr.Set(uint64(i), receipt); err != nil {
|
||||||
|
return cid.Undef, cid.Undef, xerrors.Errorf("failed to build receipts amt: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rectroot, err := rectarr.Root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, cid.Undef, xerrors.Errorf("failed to build receipts amt: %w", err)
|
return cid.Undef, cid.Undef, xerrors.Errorf("failed to build receipts amt: %w", err)
|
||||||
}
|
}
|
||||||
@ -652,14 +654,13 @@ func (sm *StateManager) ListAllActors(ctx context.Context, ts *types.TipSet) ([]
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cst := cbor.NewCborStore(sm.cs.Blockstore())
|
r, err := adt.AsMap(sm.cs.Store(ctx), st)
|
||||||
r, err := hamt.LoadNode(ctx, cst, st, hamt.UseTreeBitWidth(5))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var out []address.Address
|
var out []address.Address
|
||||||
err = r.ForEach(ctx, func(k string, val interface{}) error {
|
err = r.ForEach(nil, func(k string) error {
|
||||||
addr, err := address.NewFromBytes([]byte(k))
|
addr, err := address.NewFromBytes([]byte(k))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("address in state tree was not valid: %w", err)
|
return xerrors.Errorf("address in state tree was not valid: %w", err)
|
||||||
@ -754,6 +755,6 @@ func (sm *StateManager) ValidateChain(ctx context.Context, ts *types.TipSet) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) SetVMConstructor(nvm func(cid.Cid, abi.ChainEpoch, vm.Rand, blockstore.Blockstore, runtime.Syscalls) (*vm.VM, error)) {
|
func (sm *StateManager) SetVMConstructor(nvm func(cid.Cid, abi.ChainEpoch, vm.Rand, blockstore.Blockstore, vm.SyscallBuilder) (*vm.VM, error)) {
|
||||||
sm.newVM = nvm
|
sm.newVM = nvm
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
amt "github.com/filecoin-project/go-amt-ipld/v2"
|
|
||||||
"github.com/filecoin-project/go-bitfield"
|
"github.com/filecoin-project/go-bitfield"
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
@ -258,7 +257,7 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
|
|||||||
return nil, xerrors.Errorf("failed to enumerate all sector IDs: %w", err)
|
return nil, xerrors.Errorf("failed to enumerate all sector IDs: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sectorAmt, err := amt.LoadAMT(ctx, sm.cs.Store(ctx), mas.Sectors)
|
sectorAmt, err := adt.AsArray(sm.cs.Store(ctx), mas.Sectors)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to load sectors amt: %w", err)
|
return nil, xerrors.Errorf("failed to load sectors amt: %w", err)
|
||||||
}
|
}
|
||||||
@ -268,8 +267,10 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
|
|||||||
sid := sectors[n]
|
sid := sectors[n]
|
||||||
|
|
||||||
var sinfo miner.SectorOnChainInfo
|
var sinfo miner.SectorOnChainInfo
|
||||||
if err := sectorAmt.Get(ctx, sid, &sinfo); err != nil {
|
if found, err := sectorAmt.Get(sid, &sinfo); err != nil {
|
||||||
return nil, xerrors.Errorf("failed to get sector %d: %w", sid, err)
|
return nil, xerrors.Errorf("failed to get sector %d: %w", sid, err)
|
||||||
|
} else if !found {
|
||||||
|
return nil, xerrors.Errorf("failed to find sector %d", sid)
|
||||||
}
|
}
|
||||||
|
|
||||||
out[i] = abi.SectorInfo{
|
out[i] = abi.SectorInfo{
|
||||||
@ -328,18 +329,21 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealID abi.DealID, ts
|
|||||||
if _, err := sm.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts); err != nil {
|
if _, err := sm.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
store := sm.ChainStore().Store(ctx)
|
||||||
|
|
||||||
da, err := amt.LoadAMT(ctx, cbor.NewCborStore(sm.ChainStore().Blockstore()), state.Proposals)
|
da, err := adt.AsArray(store, state.Proposals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var dp market.DealProposal
|
var dp market.DealProposal
|
||||||
if err := da.Get(ctx, uint64(dealID), &dp); err != nil {
|
if found, err := da.Get(uint64(dealID), &dp); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
} else if !found {
|
||||||
|
return nil, xerrors.Errorf("deal %d not found", dealID)
|
||||||
}
|
}
|
||||||
|
|
||||||
sa, err := market.AsDealStateArray(sm.ChainStore().Store(ctx), state.States)
|
sa, err := market.AsDealStateArray(store, state.States)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -391,15 +395,16 @@ func ListMinerActors(ctx context.Context, sm *StateManager, ts *types.TipSet) ([
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid, filter *abi.BitField, filterOut bool) ([]*api.ChainSectorInfo, error) {
|
func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid, filter *abi.BitField, filterOut bool) ([]*api.ChainSectorInfo, error) {
|
||||||
a, err := amt.LoadAMT(ctx, cbor.NewCborStore(bs), ssc)
|
a, err := adt.AsArray(store.ActorStore(ctx, bs), ssc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var sset []*api.ChainSectorInfo
|
var sset []*api.ChainSectorInfo
|
||||||
if err := a.ForEach(ctx, func(i uint64, v *cbg.Deferred) error {
|
var v cbg.Deferred
|
||||||
|
if err := a.ForEach(&v, func(i int64) error {
|
||||||
if filter != nil {
|
if filter != nil {
|
||||||
set, err := filter.IsSet(i)
|
set, err := filter.IsSet(uint64(i))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("filter check error: %w", err)
|
return xerrors.Errorf("filter check error: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,11 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/lib/adtutil"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
"github.com/minio/blake2b-simd"
|
"github.com/minio/blake2b-simd"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
@ -28,8 +25,6 @@ import (
|
|||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
"go.uber.org/multierr"
|
"go.uber.org/multierr"
|
||||||
|
|
||||||
amt "github.com/filecoin-project/go-amt-ipld/v2"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
|
||||||
lru "github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
@ -85,10 +80,10 @@ type ChainStore struct {
|
|||||||
mmCache *lru.ARCCache
|
mmCache *lru.ARCCache
|
||||||
tsCache *lru.ARCCache
|
tsCache *lru.ARCCache
|
||||||
|
|
||||||
vmcalls runtime.Syscalls
|
vmcalls vm.SyscallBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewChainStore(bs bstore.Blockstore, ds dstore.Batching, vmcalls runtime.Syscalls) *ChainStore {
|
func NewChainStore(bs bstore.Blockstore, ds dstore.Batching, vmcalls vm.SyscallBuilder) *ChainStore {
|
||||||
c, _ := lru.NewARC(2048)
|
c, _ := lru.NewARC(2048)
|
||||||
tsc, _ := lru.NewARC(4096)
|
tsc, _ := lru.NewARC(4096)
|
||||||
cs := &ChainStore{
|
cs := &ChainStore{
|
||||||
@ -688,20 +683,25 @@ func (cs *ChainStore) GetSignedMessage(c cid.Cid) (*types.SignedMessage, error)
|
|||||||
|
|
||||||
func (cs *ChainStore) readAMTCids(root cid.Cid) ([]cid.Cid, error) {
|
func (cs *ChainStore) readAMTCids(root cid.Cid) ([]cid.Cid, error) {
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
bs := cbor.NewCborStore(cs.bs)
|
a, err := adt.AsArray(cs.Store(ctx), root)
|
||||||
a, err := amt.LoadAMT(ctx, bs, root)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("amt load: %w", err)
|
return nil, xerrors.Errorf("amt load: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var cids []cid.Cid
|
var (
|
||||||
for i := uint64(0); i < a.Count; i++ {
|
cids []cid.Cid
|
||||||
var c cbg.CborCid
|
cborCid cbg.CborCid
|
||||||
if err := a.Get(ctx, i, &c); err != nil {
|
)
|
||||||
return nil, xerrors.Errorf("failed to load cid from amt: %w", err)
|
if err := a.ForEach(&cborCid, func(i int64) error {
|
||||||
|
c := cid.Cid(cborCid)
|
||||||
|
cids = append(cids, c)
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to traverse amt: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cids = append(cids, cid.Cid(c))
|
if uint64(len(cids)) != a.Length() {
|
||||||
|
return nil, xerrors.Errorf("found %d cids, expected %d", len(cids), a.Length())
|
||||||
}
|
}
|
||||||
|
|
||||||
return cids, nil
|
return cids, nil
|
||||||
@ -849,15 +849,16 @@ func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message,
|
|||||||
|
|
||||||
func (cs *ChainStore) GetParentReceipt(b *types.BlockHeader, i int) (*types.MessageReceipt, error) {
|
func (cs *ChainStore) GetParentReceipt(b *types.BlockHeader, i int) (*types.MessageReceipt, error) {
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
bs := cbor.NewCborStore(cs.bs)
|
a, err := adt.AsArray(cs.Store(ctx), b.ParentMessageReceipts)
|
||||||
a, err := amt.LoadAMT(ctx, bs, b.ParentMessageReceipts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("amt load: %w", err)
|
return nil, xerrors.Errorf("amt load: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var r types.MessageReceipt
|
var r types.MessageReceipt
|
||||||
if err := a.Get(ctx, uint64(i), &r); err != nil {
|
if found, err := a.Get(uint64(i), &r); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
} else if !found {
|
||||||
|
return nil, xerrors.Errorf("failed to find receipt %d", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &r, nil
|
return &r, nil
|
||||||
@ -896,14 +897,14 @@ func (cs *ChainStore) Blockstore() bstore.Blockstore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ActorStore(ctx context.Context, bs blockstore.Blockstore) adt.Store {
|
func ActorStore(ctx context.Context, bs blockstore.Blockstore) adt.Store {
|
||||||
return adtutil.NewStore(ctx, cbor.NewCborStore(bs))
|
return adt.WrapStore(ctx, cbor.NewCborStore(bs))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) Store(ctx context.Context) adt.Store {
|
func (cs *ChainStore) Store(ctx context.Context) adt.Store {
|
||||||
return ActorStore(ctx, cs.bs)
|
return ActorStore(ctx, cs.bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) VMSys() runtime.Syscalls {
|
func (cs *ChainStore) VMSys() vm.SyscallBuilder {
|
||||||
return cs.vmcalls
|
return cs.vmcalls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,15 +4,14 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/filecoin-project/lotus/lib/adtutil"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
address "github.com/filecoin-project/go-address"
|
address "github.com/filecoin-project/go-address"
|
||||||
amt "github.com/filecoin-project/go-amt-ipld/v2"
|
|
||||||
miner "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
miner "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
dstore "github.com/ipfs/go-datastore"
|
dstore "github.com/ipfs/go-datastore"
|
||||||
@ -239,31 +238,36 @@ func (bv *BlockValidator) isChainNearSynced() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bv *BlockValidator) validateMsgMeta(ctx context.Context, msg *types.BlockMsg) error {
|
func (bv *BlockValidator) validateMsgMeta(ctx context.Context, msg *types.BlockMsg) error {
|
||||||
var bcids, scids []cbg.CBORMarshaler
|
|
||||||
for _, m := range msg.BlsMessages {
|
|
||||||
c := cbg.CborCid(m)
|
|
||||||
bcids = append(bcids, &c)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, m := range msg.SecpkMessages {
|
|
||||||
c := cbg.CborCid(m)
|
|
||||||
scids = append(scids, &c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO there has to be a simpler way to do this without the blockstore dance
|
// TODO there has to be a simpler way to do this without the blockstore dance
|
||||||
bs := cbor.NewCborStore(bstore.NewBlockstore(dstore.NewMapDatastore()))
|
store := adt.WrapStore(ctx, cbor.NewCborStore(bstore.NewBlockstore(dstore.NewMapDatastore())))
|
||||||
|
bmArr := adt.MakeEmptyArray(store)
|
||||||
|
smArr := adt.MakeEmptyArray(store)
|
||||||
|
|
||||||
bmroot, err := amt.FromArray(ctx, bs, bcids)
|
for i, m := range msg.BlsMessages {
|
||||||
|
c := cbg.CborCid(m)
|
||||||
|
if err := bmArr.Set(uint64(i), &c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, m := range msg.SecpkMessages {
|
||||||
|
c := cbg.CborCid(m)
|
||||||
|
if err := smArr.Set(uint64(i), &c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bmroot, err := bmArr.Root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
smroot, err := amt.FromArray(ctx, bs, scids)
|
smroot, err := smArr.Root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mrcid, err := bs.Put(ctx, &types.MsgMeta{
|
mrcid, err := store.Put(store.Context(), &types.MsgMeta{
|
||||||
BlsMessages: bmroot,
|
BlsMessages: bmroot,
|
||||||
SecpkMessages: smroot,
|
SecpkMessages: smroot,
|
||||||
})
|
})
|
||||||
@ -318,7 +322,7 @@ func (bv *BlockValidator) getMinerWorkerKey(ctx context.Context, msg *types.Bloc
|
|||||||
return address.Undef, err
|
return address.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := mst.GetInfo(adtutil.NewStore(ctx, cst))
|
info, err := mst.GetInfo(adt.WrapStore(ctx, cst))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Undef, err
|
return address.Undef, err
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import (
|
|||||||
|
|
||||||
bls "github.com/filecoin-project/filecoin-ffi"
|
bls "github.com/filecoin-project/filecoin-ffi"
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
amt "github.com/filecoin-project/go-amt-ipld/v2"
|
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
@ -256,15 +255,13 @@ func (syncer *Syncer) ValidateMsgMeta(fblk *types.FullBlock) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Collect the CIDs of both types of messages separately: BLS and Secpk.
|
// Collect the CIDs of both types of messages separately: BLS and Secpk.
|
||||||
var bcids, scids []cbg.CBORMarshaler
|
var bcids, scids []cid.Cid
|
||||||
for _, m := range fblk.BlsMessages {
|
for _, m := range fblk.BlsMessages {
|
||||||
c := cbg.CborCid(m.Cid())
|
bcids = append(bcids, m.Cid())
|
||||||
bcids = append(bcids, &c)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, m := range fblk.SecpkMessages {
|
for _, m := range fblk.SecpkMessages {
|
||||||
c := cbg.CborCid(m.Cid())
|
scids = append(scids, m.Cid())
|
||||||
scids = append(scids, &c)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: IMPORTANT(GARBAGE). These message puts and the msgmeta
|
// TODO: IMPORTANT(GARBAGE). These message puts and the msgmeta
|
||||||
@ -354,19 +351,17 @@ func zipTipSetAndMessages(bs cbor.IpldStore, ts *types.TipSet, allbmsgs []*types
|
|||||||
}
|
}
|
||||||
|
|
||||||
var smsgs []*types.SignedMessage
|
var smsgs []*types.SignedMessage
|
||||||
var smsgCids []cbg.CBORMarshaler
|
var smsgCids []cid.Cid
|
||||||
for _, m := range smi[bi] {
|
for _, m := range smi[bi] {
|
||||||
smsgs = append(smsgs, allsmsgs[m])
|
smsgs = append(smsgs, allsmsgs[m])
|
||||||
c := cbg.CborCid(allsmsgs[m].Cid())
|
smsgCids = append(smsgCids, allsmsgs[m].Cid())
|
||||||
smsgCids = append(smsgCids, &c)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var bmsgs []*types.Message
|
var bmsgs []*types.Message
|
||||||
var bmsgCids []cbg.CBORMarshaler
|
var bmsgCids []cid.Cid
|
||||||
for _, m := range bmi[bi] {
|
for _, m := range bmi[bi] {
|
||||||
bmsgs = append(bmsgs, allbmsgs[m])
|
bmsgs = append(bmsgs, allbmsgs[m])
|
||||||
c := cbg.CborCid(allbmsgs[m].Cid())
|
bmsgCids = append(bmsgCids, allbmsgs[m].Cid())
|
||||||
bmsgCids = append(bmsgCids, &c)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mrcid, err := computeMsgMeta(bs, bmsgCids, smsgCids)
|
mrcid, err := computeMsgMeta(bs, bmsgCids, smsgCids)
|
||||||
@ -392,19 +387,36 @@ func zipTipSetAndMessages(bs cbor.IpldStore, ts *types.TipSet, allbmsgs []*types
|
|||||||
|
|
||||||
// computeMsgMeta computes the root CID of the combined arrays of message CIDs
|
// computeMsgMeta computes the root CID of the combined arrays of message CIDs
|
||||||
// of both types (BLS and Secpk).
|
// of both types (BLS and Secpk).
|
||||||
func computeMsgMeta(bs cbor.IpldStore, bmsgCids, smsgCids []cbg.CBORMarshaler) (cid.Cid, error) {
|
func computeMsgMeta(bs cbor.IpldStore, bmsgCids, smsgCids []cid.Cid) (cid.Cid, error) {
|
||||||
ctx := context.TODO()
|
store := adt.WrapStore(context.TODO(), bs)
|
||||||
bmroot, err := amt.FromArray(ctx, bs, bmsgCids)
|
bmArr := adt.MakeEmptyArray(store)
|
||||||
|
smArr := adt.MakeEmptyArray(store)
|
||||||
|
|
||||||
|
for i, m := range bmsgCids {
|
||||||
|
c := cbg.CborCid(m)
|
||||||
|
if err := bmArr.Set(uint64(i), &c); err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, m := range smsgCids {
|
||||||
|
c := cbg.CborCid(m)
|
||||||
|
if err := smArr.Set(uint64(i), &c); err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bmroot, err := bmArr.Root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
smroot, err := amt.FromArray(ctx, bs, smsgCids)
|
smroot, err := smArr.Root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
mrcid, err := bs.Put(ctx, &types.MsgMeta{
|
mrcid, err := store.Put(store.Context(), &types.MsgMeta{
|
||||||
BlsMessages: bmroot,
|
BlsMessages: bmroot,
|
||||||
SecpkMessages: smroot,
|
SecpkMessages: smroot,
|
||||||
})
|
})
|
||||||
@ -851,6 +863,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
|
|||||||
"%d errors occurred:\n\t%s\n\n",
|
"%d errors occurred:\n\t%s\n\n",
|
||||||
len(es), strings.Join(points, "\n\t"))
|
len(es), strings.Join(points, "\n\t"))
|
||||||
}
|
}
|
||||||
|
return mulErr
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := syncer.store.MarkBlockAsValidated(ctx, b.Cid()); err != nil {
|
if err := syncer.store.MarkBlockAsValidated(ctx, b.Cid()); err != nil {
|
||||||
@ -908,7 +921,7 @@ func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.Block
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Errorf("invalid winning post (%x; %v)", rand, sectors)
|
log.Errorf("invalid winning post (block: %s, %x; %v)", h.Cid(), rand, sectors)
|
||||||
return xerrors.Errorf("winning post was invalid")
|
return xerrors.Errorf("winning post was invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -992,18 +1005,21 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var blsCids []cbg.CBORMarshaler
|
store := adt.WrapStore(ctx, cst)
|
||||||
|
|
||||||
|
bmArr := adt.MakeEmptyArray(store)
|
||||||
for i, m := range b.BlsMessages {
|
for i, m := range b.BlsMessages {
|
||||||
if err := checkMsg(m); err != nil {
|
if err := checkMsg(m); err != nil {
|
||||||
return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err)
|
return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c := cbg.CborCid(m.Cid())
|
c := cbg.CborCid(m.Cid())
|
||||||
blsCids = append(blsCids, &c)
|
if err := bmArr.Set(uint64(i), &c); err != nil {
|
||||||
|
return xerrors.Errorf("failed to put bls message at index %d: %w", i, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var secpkCids []cbg.CBORMarshaler
|
smArr := adt.MakeEmptyArray(store)
|
||||||
for i, m := range b.SecpkMessages {
|
for i, m := range b.SecpkMessages {
|
||||||
if err := checkMsg(m); err != nil {
|
if err := checkMsg(m); err != nil {
|
||||||
return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err)
|
return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err)
|
||||||
@ -1021,17 +1037,19 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock
|
|||||||
}
|
}
|
||||||
|
|
||||||
c := cbg.CborCid(m.Cid())
|
c := cbg.CborCid(m.Cid())
|
||||||
secpkCids = append(secpkCids, &c)
|
if err := smArr.Set(uint64(i), &c); err != nil {
|
||||||
|
return xerrors.Errorf("failed to put secpk message at index %d: %w", i, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bmroot, err := amt.FromArray(ctx, cst, blsCids)
|
bmroot, err := bmArr.Root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to build amt from bls msg cids: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
smroot, err := amt.FromArray(ctx, cst, secpkCids)
|
smroot, err := smArr.Root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to build amt from bls msg cids: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mrcid, err := cst.Put(ctx, &types.MsgMeta{
|
mrcid, err := cst.Put(ctx, &types.MsgMeta{
|
||||||
@ -1056,6 +1074,10 @@ func (syncer *Syncer) verifyBlsAggregate(ctx context.Context, sig *crypto.Signat
|
|||||||
trace.Int64Attribute("msgCount", int64(len(msgs))),
|
trace.Int64Attribute("msgCount", int64(len(msgs))),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if len(msgs) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
bmsgs := make([]bls.Message, len(msgs))
|
bmsgs := make([]bls.Message, len(msgs))
|
||||||
for i, m := range msgs {
|
for i, m := range msgs {
|
||||||
bmsgs[i] = m.Bytes()
|
bmsgs[i] = m.Bytes()
|
||||||
|
@ -170,7 +170,7 @@ func (tu *syncTestUtil) pushTsExpectErr(to int, fts *store.FullTipSet, experr bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, src int, miners []int, wait, fail bool) *store.FullTipSet {
|
func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int, wait, fail bool) *store.FullTipSet {
|
||||||
if miners == nil {
|
if miners == nil {
|
||||||
for i := range tu.g.Miners {
|
for i := range tu.g.Miners {
|
||||||
miners = append(miners, i)
|
miners = append(miners, i)
|
||||||
@ -188,9 +188,9 @@ func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, src int, miners []int
|
|||||||
require.NoError(tu.t, err)
|
require.NoError(tu.t, err)
|
||||||
|
|
||||||
if fail {
|
if fail {
|
||||||
tu.pushTsExpectErr(src, mts.TipSet, true)
|
tu.pushTsExpectErr(to, mts.TipSet, true)
|
||||||
} else {
|
} else {
|
||||||
tu.pushFtsAndWait(src, mts.TipSet, wait)
|
tu.pushFtsAndWait(to, mts.TipSet, wait)
|
||||||
}
|
}
|
||||||
|
|
||||||
return mts.TipSet
|
return mts.TipSet
|
||||||
@ -433,6 +433,41 @@ func TestSyncBadTimestamp(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type badWpp struct{}
|
||||||
|
|
||||||
|
func (wpp badWpp) GenerateCandidates(context.Context, abi.PoStRandomness, uint64) ([]uint64, error) {
|
||||||
|
return []uint64{1}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wpp badWpp) ComputeProof(context.Context, []abi.SectorInfo, abi.PoStRandomness) ([]abi.PoStProof, error) {
|
||||||
|
return []abi.PoStProof{
|
||||||
|
abi.PoStProof{
|
||||||
|
PoStProof: abi.RegisteredPoStProof_StackedDrgWinning2KiBV1,
|
||||||
|
ProofBytes: []byte("evil"),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSyncBadWinningPoSt(t *testing.T) {
|
||||||
|
H := 15
|
||||||
|
tu := prepSyncTest(t, H)
|
||||||
|
|
||||||
|
client := tu.addClientNode()
|
||||||
|
|
||||||
|
require.NoError(t, tu.mn.LinkAll())
|
||||||
|
tu.connect(client, 0)
|
||||||
|
tu.waitUntilSync(0, client)
|
||||||
|
|
||||||
|
base := tu.g.CurTipset
|
||||||
|
|
||||||
|
// both miners now produce invalid winning posts
|
||||||
|
tu.g.SetWinningPoStProver(tu.g.Miners[0], &badWpp{})
|
||||||
|
tu.g.SetWinningPoStProver(tu.g.Miners[1], &badWpp{})
|
||||||
|
|
||||||
|
// now ensure that new blocks are not accepted
|
||||||
|
tu.mineOnBlock(base, client, nil, false, true)
|
||||||
|
}
|
||||||
|
|
||||||
func (tu *syncTestUtil) loadChainToNode(to int) {
|
func (tu *syncTestUtil) loadChainToNode(to int) {
|
||||||
// utility to simulate incoming blocks without miner process
|
// utility to simulate incoming blocks without miner process
|
||||||
// TODO: should call syncer directly, this won't work correctly in all cases
|
// TODO: should call syncer directly, this won't work correctly in all cases
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
"github.com/filecoin-project/specs-actors/actors/puppet"
|
"github.com/filecoin-project/specs-actors/actors/puppet"
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
vtypes "github.com/filecoin-project/chain-validation/chain/types"
|
vtypes "github.com/filecoin-project/chain-validation/chain/types"
|
||||||
@ -25,12 +24,12 @@ import (
|
|||||||
// Applier applies messages to state trees and storage.
|
// Applier applies messages to state trees and storage.
|
||||||
type Applier struct {
|
type Applier struct {
|
||||||
stateWrapper *StateWrapper
|
stateWrapper *StateWrapper
|
||||||
syscalls runtime.Syscalls
|
syscalls vm.SyscallBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ vstate.Applier = &Applier{}
|
var _ vstate.Applier = &Applier{}
|
||||||
|
|
||||||
func NewApplier(sw *StateWrapper, syscalls runtime.Syscalls) *Applier {
|
func NewApplier(sw *StateWrapper, syscalls vm.SyscallBuilder) *Applier {
|
||||||
return &Applier{sw, syscalls}
|
return &Applier{sw, syscalls}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package validation
|
package validation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/filecoin-project/lotus/chain/state"
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||||
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
|
||||||
vstate "github.com/filecoin-project/chain-validation/state"
|
vstate "github.com/filecoin-project/chain-validation/state"
|
||||||
)
|
)
|
||||||
@ -18,7 +21,9 @@ func NewFactories() *Factories {
|
|||||||
|
|
||||||
func (f *Factories) NewStateAndApplier(syscalls runtime.Syscalls) (vstate.VMWrapper, vstate.Applier) {
|
func (f *Factories) NewStateAndApplier(syscalls runtime.Syscalls) (vstate.VMWrapper, vstate.Applier) {
|
||||||
st := NewState()
|
st := NewState()
|
||||||
return st, NewApplier(st, syscalls)
|
return st, NewApplier(st, func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime.Syscalls {
|
||||||
|
return syscalls
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Factories) NewKeyManager() vstate.KeyManager {
|
func (f *Factories) NewKeyManager() vstate.KeyManager {
|
||||||
|
@ -18,6 +18,7 @@ func LoadVector(t *testing.T, f string, out interface{}) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
defer fi.Close()
|
||||||
|
|
||||||
if err := json.NewDecoder(fi).Decode(out); err != nil {
|
if err := json.NewDecoder(fi).Decode(out); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
GasStorageMulti = 1
|
GasStorageMulti = 1000
|
||||||
GasComputeMulti = 1
|
GasComputeMulti = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -85,10 +85,10 @@ type Pricelist interface {
|
|||||||
var prices = map[abi.ChainEpoch]Pricelist{
|
var prices = map[abi.ChainEpoch]Pricelist{
|
||||||
abi.ChainEpoch(0): &pricelistV0{
|
abi.ChainEpoch(0): &pricelistV0{
|
||||||
onChainMessageComputeBase: 137137,
|
onChainMessageComputeBase: 137137,
|
||||||
onChainMessageStorageBase: 0, // TODO gas
|
onChainMessageStorageBase: 36,
|
||||||
onChainMessageStoragePerByte: 2, // TODO gas
|
onChainMessageStoragePerByte: 1,
|
||||||
|
|
||||||
onChainReturnValuePerByte: 8, // TODO gas
|
onChainReturnValuePerByte: 1,
|
||||||
|
|
||||||
sendBase: 97236,
|
sendBase: 97236,
|
||||||
sendTransferFunds: 96812,
|
sendTransferFunds: 96812,
|
||||||
@ -97,11 +97,11 @@ var prices = map[abi.ChainEpoch]Pricelist{
|
|||||||
|
|
||||||
ipldGetBase: 417230,
|
ipldGetBase: 417230,
|
||||||
ipldPutBase: 396100,
|
ipldPutBase: 396100,
|
||||||
ipldPutPerByte: 2, // TODO gas
|
ipldPutPerByte: 1,
|
||||||
|
|
||||||
createActorCompute: 750011,
|
createActorCompute: 750011,
|
||||||
createActorStorage: 500, // TODO gas
|
createActorStorage: 36 + 40,
|
||||||
deleteActor: -500, // -createActorStorage
|
deleteActor: -(36 + 40), // -createActorStorage
|
||||||
|
|
||||||
verifySignature: map[crypto.SigType]int64{
|
verifySignature: map[crypto.SigType]int64{
|
||||||
crypto.SigTypeBLS: 219946580,
|
crypto.SigTypeBLS: 219946580,
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
hamt "github.com/ipfs/go-hamt-ipld"
|
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
@ -464,7 +463,7 @@ func (rt *Runtime) GetBalance(a address.Address) (types.BigInt, aerrors.ActorErr
|
|||||||
switch err {
|
switch err {
|
||||||
default:
|
default:
|
||||||
return types.EmptyInt, aerrors.Escalate(err, "failed to look up actor balance")
|
return types.EmptyInt, aerrors.Escalate(err, "failed to look up actor balance")
|
||||||
case hamt.ErrNotFound:
|
case types.ErrActorNotFound:
|
||||||
return types.NewInt(0), nil
|
return types.NewInt(0), nil
|
||||||
case nil:
|
case nil:
|
||||||
return act.Balance, nil
|
return act.Balance, nil
|
||||||
@ -582,12 +581,12 @@ func (rt *Runtime) abortIfAlreadyValidated() {
|
|||||||
func (rt *Runtime) Log(level vmr.LogLevel, msg string, args ...interface{}) {
|
func (rt *Runtime) Log(level vmr.LogLevel, msg string, args ...interface{}) {
|
||||||
switch level {
|
switch level {
|
||||||
case vmr.DEBUG:
|
case vmr.DEBUG:
|
||||||
actorLog.Debugf(msg, args)
|
actorLog.Debugf(msg, args...)
|
||||||
case vmr.INFO:
|
case vmr.INFO:
|
||||||
actorLog.Infof(msg, args)
|
actorLog.Infof(msg, args...)
|
||||||
case vmr.WARN:
|
case vmr.WARN:
|
||||||
actorLog.Warnf(msg, args)
|
actorLog.Warnf(msg, args...)
|
||||||
case vmr.ERROR:
|
case vmr.ERROR:
|
||||||
actorLog.Errorf(msg, args)
|
actorLog.Errorf(msg, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,12 +16,12 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/state"
|
"github.com/filecoin-project/lotus/chain/state"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/lib/adtutil"
|
|
||||||
"github.com/filecoin-project/lotus/lib/sigs"
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
)
|
)
|
||||||
@ -32,15 +32,26 @@ func init() {
|
|||||||
|
|
||||||
// Actual type is defined in chain/types/vmcontext.go because the VMContext interface is there
|
// Actual type is defined in chain/types/vmcontext.go because the VMContext interface is there
|
||||||
|
|
||||||
func Syscalls(verifier ffiwrapper.Verifier) runtime.Syscalls {
|
type SyscallBuilder func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime.Syscalls
|
||||||
return &syscallShim{verifier: verifier}
|
|
||||||
|
func Syscalls(verifier ffiwrapper.Verifier) SyscallBuilder {
|
||||||
|
return func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime.Syscalls {
|
||||||
|
return &syscallShim{
|
||||||
|
ctx: ctx,
|
||||||
|
|
||||||
|
cstate: cstate,
|
||||||
|
cst: cst,
|
||||||
|
|
||||||
|
verifier: verifier,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type syscallShim struct {
|
type syscallShim struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
|
||||||
cstate *state.StateTree
|
cstate *state.StateTree
|
||||||
cst *cbor.BasicIpldStore
|
cst cbor.IpldStore
|
||||||
verifier ffiwrapper.Verifier
|
verifier ffiwrapper.Verifier
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +191,7 @@ func (ss *syscallShim) VerifyBlockSig(blk *types.BlockHeader) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := mas.GetInfo(adtutil.NewStore(ss.ctx, ss.cst))
|
info, err := mas.GetInfo(adt.WrapStore(ss.ctx, ss.cst))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ import (
|
|||||||
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
@ -115,7 +114,7 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres
|
|||||||
Atlas: vm.cst.Atlas,
|
Atlas: vm.cst.Atlas,
|
||||||
}
|
}
|
||||||
rt.sys = pricedSyscalls{
|
rt.sys = pricedSyscalls{
|
||||||
under: vm.Syscalls,
|
under: vm.Syscalls(ctx, vm.cstate, rt.cst),
|
||||||
chargeGas: rt.chargeGasFunc(1),
|
chargeGas: rt.chargeGasFunc(1),
|
||||||
pl: rt.pricelist,
|
pl: rt.pricelist,
|
||||||
}
|
}
|
||||||
@ -148,10 +147,10 @@ type VM struct {
|
|||||||
inv *Invoker
|
inv *Invoker
|
||||||
rand Rand
|
rand Rand
|
||||||
|
|
||||||
Syscalls runtime.Syscalls
|
Syscalls SyscallBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVM(base cid.Cid, height abi.ChainEpoch, r Rand, cbs blockstore.Blockstore, syscalls runtime.Syscalls) (*VM, error) {
|
func NewVM(base cid.Cid, height abi.ChainEpoch, r Rand, cbs blockstore.Blockstore, syscalls SyscallBuilder) (*VM, error) {
|
||||||
buf := bufbstore.NewBufferedBstore(cbs)
|
buf := bufbstore.NewBufferedBstore(cbs)
|
||||||
cst := cbor.NewCborStore(buf)
|
cst := cbor.NewCborStore(buf)
|
||||||
state, err := state.LoadStateTree(cst, base)
|
state, err := state.LoadStateTree(cst, base)
|
||||||
@ -347,6 +346,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
ExitCode: exitcode.SysErrSenderInvalid,
|
ExitCode: exitcode.SysErrSenderInvalid,
|
||||||
GasUsed: 0,
|
GasUsed: 0,
|
||||||
},
|
},
|
||||||
|
ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "actor not found: %s", msg.From),
|
||||||
Penalty: minerPenaltyAmount,
|
Penalty: minerPenaltyAmount,
|
||||||
Duration: time.Since(start),
|
Duration: time.Since(start),
|
||||||
}, nil
|
}, nil
|
||||||
@ -361,6 +361,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
ExitCode: exitcode.SysErrSenderInvalid,
|
ExitCode: exitcode.SysErrSenderInvalid,
|
||||||
GasUsed: 0,
|
GasUsed: 0,
|
||||||
},
|
},
|
||||||
|
ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "send from not account actor: %s", fromActor.Code),
|
||||||
Penalty: minerPenaltyAmount,
|
Penalty: minerPenaltyAmount,
|
||||||
Duration: time.Since(start),
|
Duration: time.Since(start),
|
||||||
}, nil
|
}, nil
|
||||||
@ -373,6 +374,8 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
ExitCode: exitcode.SysErrSenderStateInvalid,
|
ExitCode: exitcode.SysErrSenderStateInvalid,
|
||||||
GasUsed: 0,
|
GasUsed: 0,
|
||||||
},
|
},
|
||||||
|
ActorErr: aerrors.Newf(exitcode.SysErrSenderStateInvalid,
|
||||||
|
"actor nonce invalid: msg:%d != state:%d", msg.Nonce, fromActor.Nonce),
|
||||||
Penalty: minerPenaltyAmount,
|
Penalty: minerPenaltyAmount,
|
||||||
Duration: time.Since(start),
|
Duration: time.Since(start),
|
||||||
}, nil
|
}, nil
|
||||||
@ -386,6 +389,8 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
ExitCode: exitcode.SysErrSenderStateInvalid,
|
ExitCode: exitcode.SysErrSenderStateInvalid,
|
||||||
GasUsed: 0,
|
GasUsed: 0,
|
||||||
},
|
},
|
||||||
|
ActorErr: aerrors.Newf(exitcode.SysErrSenderStateInvalid,
|
||||||
|
"actor balance less than needed: %s < %s", types.FIL(fromActor.Balance), types.FIL(totalCost)),
|
||||||
Penalty: minerPenaltyAmount,
|
Penalty: minerPenaltyAmount,
|
||||||
Duration: time.Since(start),
|
Duration: time.Since(start),
|
||||||
}, nil
|
}, nil
|
||||||
|
30
cli/cmd.go
30
cli/cmd.go
@ -242,24 +242,24 @@ var CommonCommands = []*cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var Commands = []*cli.Command{
|
var Commands = []*cli.Command{
|
||||||
withCategory("basic", sendCmd),
|
WithCategory("basic", sendCmd),
|
||||||
withCategory("basic", walletCmd),
|
WithCategory("basic", walletCmd),
|
||||||
withCategory("basic", clientCmd),
|
WithCategory("basic", clientCmd),
|
||||||
withCategory("basic", multisigCmd),
|
WithCategory("basic", multisigCmd),
|
||||||
withCategory("basic", paychCmd),
|
WithCategory("basic", paychCmd),
|
||||||
withCategory("developer", authCmd),
|
WithCategory("developer", authCmd),
|
||||||
withCategory("developer", mpoolCmd),
|
WithCategory("developer", mpoolCmd),
|
||||||
withCategory("developer", stateCmd),
|
WithCategory("developer", stateCmd),
|
||||||
withCategory("developer", chainCmd),
|
WithCategory("developer", chainCmd),
|
||||||
withCategory("developer", logCmd),
|
WithCategory("developer", logCmd),
|
||||||
withCategory("developer", waitApiCmd),
|
WithCategory("developer", waitApiCmd),
|
||||||
withCategory("developer", fetchParamCmd),
|
WithCategory("developer", fetchParamCmd),
|
||||||
withCategory("network", netCmd),
|
WithCategory("network", netCmd),
|
||||||
withCategory("network", syncCmd),
|
WithCategory("network", syncCmd),
|
||||||
versionCmd,
|
versionCmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
func withCategory(cat string, cmd *cli.Command) *cli.Command {
|
func WithCategory(cat string, cmd *cli.Command) *cli.Command {
|
||||||
cmd.Category = cat
|
cmd.Category = cat
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
46
cli/helper.go
Normal file
46
cli/helper.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PrintHelpErr struct {
|
||||||
|
Err error
|
||||||
|
Ctx *cli.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PrintHelpErr) Error() string {
|
||||||
|
return e.Err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PrintHelpErr) Unwrap() error {
|
||||||
|
return e.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *PrintHelpErr) Is(o error) bool {
|
||||||
|
_, ok := o.(*PrintHelpErr)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func ShowHelp(cctx *cli.Context, err error) error {
|
||||||
|
return &PrintHelpErr{Err: err, Ctx: cctx}
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunApp(app *cli.App) {
|
||||||
|
if err := app.Run(os.Args); err != nil {
|
||||||
|
if os.Getenv("LOTUS_DEV") != "" {
|
||||||
|
log.Warnf("%+v", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("ERROR: %s\n\n", err)
|
||||||
|
}
|
||||||
|
var phe *PrintHelpErr
|
||||||
|
if xerrors.As(err, &phe) {
|
||||||
|
cli.ShowCommandHelp(phe.Ctx, phe.Ctx.Command.Name)
|
||||||
|
}
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
166
cli/mpool.go
166
cli/mpool.go
@ -4,11 +4,13 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
@ -20,6 +22,8 @@ var mpoolCmd = &cli.Command{
|
|||||||
mpoolPending,
|
mpoolPending,
|
||||||
mpoolSub,
|
mpoolSub,
|
||||||
mpoolStat,
|
mpoolStat,
|
||||||
|
mpoolReplaceCmd,
|
||||||
|
mpoolFindCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,3 +232,165 @@ var mpoolStat = &cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var mpoolReplaceCmd = &cli.Command{
|
||||||
|
Name: "replace",
|
||||||
|
Usage: "replace a message in the mempool",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.Int64Flag{
|
||||||
|
Name: "gas-price",
|
||||||
|
Usage: "gas price for new message",
|
||||||
|
},
|
||||||
|
&cli.Int64Flag{
|
||||||
|
Name: "gas-limit",
|
||||||
|
Usage: "gas price for new message",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ArgsUsage: "[from] [nonce]",
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() < 2 {
|
||||||
|
return cli.ShowCommandHelp(cctx, cctx.Command.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
from, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nonce, err := strconv.ParseUint(cctx.Args().Get(1), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
ts, err := api.ChainHead(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting chain head: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pending, err := api.MpoolPending(ctx, ts.Key())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var found *types.SignedMessage
|
||||||
|
for _, p := range pending {
|
||||||
|
if p.Message.From == from && p.Message.Nonce == nonce {
|
||||||
|
found = p
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found == nil {
|
||||||
|
return fmt.Errorf("no pending message found from %s with nonce %d", from, nonce)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := found.Message
|
||||||
|
|
||||||
|
msg.GasLimit = cctx.Int64("gas-limit")
|
||||||
|
msg.GasPrice = types.NewInt(uint64(cctx.Int64("gas-price")))
|
||||||
|
|
||||||
|
smsg, err := api.WalletSignMessage(ctx, msg.From, &msg)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to sign message: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cid, err := api.MpoolPush(ctx, smsg)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to push new message to mempool: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("new message cid: ", cid)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var mpoolFindCmd = &cli.Command{
|
||||||
|
Name: "find",
|
||||||
|
Usage: "find a message in the mempool",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "from",
|
||||||
|
Usage: "search for messages with given 'from' address",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "to",
|
||||||
|
Usage: "search for messages with given 'to' address",
|
||||||
|
},
|
||||||
|
&cli.Int64Flag{
|
||||||
|
Name: "method",
|
||||||
|
Usage: "search for messages with given method",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
pending, err := api.MpoolPending(ctx, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var toFilter, fromFilter address.Address
|
||||||
|
if cctx.IsSet("to") {
|
||||||
|
a, err := address.NewFromString(cctx.String("to"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("'to' address was invalid: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
toFilter = a
|
||||||
|
}
|
||||||
|
|
||||||
|
if cctx.IsSet("from") {
|
||||||
|
a, err := address.NewFromString(cctx.String("from"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("'from' address was invalid: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fromFilter = a
|
||||||
|
}
|
||||||
|
|
||||||
|
var methodFilter *abi.MethodNum
|
||||||
|
if cctx.IsSet("method") {
|
||||||
|
m := abi.MethodNum(cctx.Int64("method"))
|
||||||
|
methodFilter = &m
|
||||||
|
}
|
||||||
|
|
||||||
|
var out []*types.SignedMessage
|
||||||
|
for _, m := range pending {
|
||||||
|
if toFilter != address.Undef && m.Message.To != toFilter {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if fromFilter != address.Undef && m.Message.From != fromFilter {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if methodFilter != nil && *methodFilter != m.Message.Method {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
out = append(out, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.MarshalIndent(out, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(string(b))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -12,15 +12,14 @@ import (
|
|||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||||
samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
@ -68,6 +67,10 @@ var msigCreateCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() < 1 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("multisigs must have at least one signer"))
|
||||||
|
}
|
||||||
|
|
||||||
api, closer, err := GetFullNodeAPI(cctx)
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -75,10 +78,6 @@ var msigCreateCmd = &cli.Command{
|
|||||||
defer closer()
|
defer closer()
|
||||||
ctx := ReqContext(cctx)
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
if cctx.Args().Len() < 1 {
|
|
||||||
return fmt.Errorf("multisigs must have at least one signer")
|
|
||||||
}
|
|
||||||
|
|
||||||
var addrs []address.Address
|
var addrs []address.Address
|
||||||
for _, a := range cctx.Args().Slice() {
|
for _, a := range cctx.Args().Slice() {
|
||||||
addr, err := address.NewFromString(a)
|
addr, err := address.NewFromString(a)
|
||||||
@ -159,6 +158,10 @@ var msigInspectCmd = &cli.Command{
|
|||||||
ArgsUsage: "[address]",
|
ArgsUsage: "[address]",
|
||||||
Flags: []cli.Flag{},
|
Flags: []cli.Flag{},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if !cctx.Args().Present() {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("must specify address of multisig to inspect"))
|
||||||
|
}
|
||||||
|
|
||||||
api, closer, err := GetFullNodeAPI(cctx)
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -166,10 +169,6 @@ var msigInspectCmd = &cli.Command{
|
|||||||
defer closer()
|
defer closer()
|
||||||
ctx := ReqContext(cctx)
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
if !cctx.Args().Present() {
|
|
||||||
return fmt.Errorf("must specify address of multisig to inspect")
|
|
||||||
}
|
|
||||||
|
|
||||||
maddr, err := address.NewFromString(cctx.Args().First())
|
maddr, err := address.NewFromString(cctx.Args().First())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -237,24 +236,20 @@ var msigInspectCmd = &cli.Command{
|
|||||||
|
|
||||||
func GetMultisigPending(ctx context.Context, lapi api.FullNode, hroot cid.Cid) (map[int64]*samsig.Transaction, error) {
|
func GetMultisigPending(ctx context.Context, lapi api.FullNode, hroot cid.Cid) (map[int64]*samsig.Transaction, error) {
|
||||||
bs := apibstore.NewAPIBlockstore(lapi)
|
bs := apibstore.NewAPIBlockstore(lapi)
|
||||||
cst := cbor.NewCborStore(bs)
|
store := adt.WrapStore(ctx, cbor.NewCborStore(bs))
|
||||||
|
|
||||||
nd, err := hamt.LoadNode(ctx, cst, hroot, hamt.UseTreeBitWidth(5))
|
nd, err := adt.AsMap(store, hroot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
txs := make(map[int64]*samsig.Transaction)
|
txs := make(map[int64]*samsig.Transaction)
|
||||||
err = nd.ForEach(ctx, func(k string, val interface{}) error {
|
|
||||||
d := val.(*cbg.Deferred)
|
|
||||||
var tx samsig.Transaction
|
var tx samsig.Transaction
|
||||||
if err := tx.UnmarshalCBOR(bytes.NewReader(d.Raw)); err != nil {
|
err = nd.ForEach(&tx, func(k string) error {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
txid, _ := binary.Varint([]byte(k))
|
txid, _ := binary.Varint([]byte(k))
|
||||||
|
|
||||||
txs[txid] = &tx
|
cpy := tx // copy so we don't clobber on future iterations.
|
||||||
|
txs[txid] = &cpy
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -287,6 +282,14 @@ var msigProposeCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() < 3 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("must pass at least multisig address, destination, and value"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if cctx.Args().Len() > 3 && cctx.Args().Len() != 5 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("must either pass three or five arguments"))
|
||||||
|
}
|
||||||
|
|
||||||
api, closer, err := GetFullNodeAPI(cctx)
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -294,14 +297,6 @@ var msigProposeCmd = &cli.Command{
|
|||||||
defer closer()
|
defer closer()
|
||||||
ctx := ReqContext(cctx)
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
if cctx.Args().Len() < 3 {
|
|
||||||
return fmt.Errorf("must pass multisig address, destination, and value")
|
|
||||||
}
|
|
||||||
|
|
||||||
if cctx.Args().Len() > 3 && cctx.Args().Len() != 5 {
|
|
||||||
return fmt.Errorf("usage: msig propose <msig addr> <desination> <value> [ <method> <params> ]")
|
|
||||||
}
|
|
||||||
|
|
||||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -391,6 +386,14 @@ var msigApproveCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() < 5 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, message ID, proposer address, destination, and value"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if cctx.Args().Len() > 5 && cctx.Args().Len() != 7 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("usage: msig approve <msig addr> <message ID> <proposer address> <desination> <value> [ <method> <params> ]"))
|
||||||
|
}
|
||||||
|
|
||||||
api, closer, err := GetFullNodeAPI(cctx)
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -398,14 +401,6 @@ var msigApproveCmd = &cli.Command{
|
|||||||
defer closer()
|
defer closer()
|
||||||
ctx := ReqContext(cctx)
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
if cctx.Args().Len() < 5 {
|
|
||||||
return fmt.Errorf("must pass multisig address, message ID, proposer address, destination, and value")
|
|
||||||
}
|
|
||||||
|
|
||||||
if cctx.Args().Len() > 5 && cctx.Args().Len() != 7 {
|
|
||||||
return fmt.Errorf("usage: msig approve <msig addr> <message ID> <proposer address> <desination> <value> [ <method> <params> ]")
|
|
||||||
}
|
|
||||||
|
|
||||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -500,6 +495,10 @@ var msigSwapProposeCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() != 3 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, old signer address, new signer address"))
|
||||||
|
}
|
||||||
|
|
||||||
api, closer, err := GetFullNodeAPI(cctx)
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -507,10 +506,6 @@ var msigSwapProposeCmd = &cli.Command{
|
|||||||
defer closer()
|
defer closer()
|
||||||
ctx := ReqContext(cctx)
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
if cctx.Args().Len() != 3 {
|
|
||||||
return fmt.Errorf("must pass multisig address, old signer address, new signer address")
|
|
||||||
}
|
|
||||||
|
|
||||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -572,6 +567,10 @@ var msigSwapApproveCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() != 5 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, proposer address, transaction id, old signer address, new signer address"))
|
||||||
|
}
|
||||||
|
|
||||||
api, closer, err := GetFullNodeAPI(cctx)
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -579,10 +578,6 @@ var msigSwapApproveCmd = &cli.Command{
|
|||||||
defer closer()
|
defer closer()
|
||||||
ctx := ReqContext(cctx)
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
if cctx.Args().Len() != 5 {
|
|
||||||
return fmt.Errorf("must pass multisig address, proposer address, transaction id, old signer address, new signer address")
|
|
||||||
}
|
|
||||||
|
|
||||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -654,6 +649,10 @@ var msigSwapCancelCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() != 4 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, transaction id, old signer address, new signer address"))
|
||||||
|
}
|
||||||
|
|
||||||
api, closer, err := GetFullNodeAPI(cctx)
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -661,10 +660,6 @@ var msigSwapCancelCmd = &cli.Command{
|
|||||||
defer closer()
|
defer closer()
|
||||||
ctx := ReqContext(cctx)
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
if cctx.Args().Len() != 4 {
|
|
||||||
return fmt.Errorf("must pass multisig address, transaction id, old signer address, new signer address")
|
|
||||||
}
|
|
||||||
|
|
||||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
103
cli/paych.go
103
cli/paych.go
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
@ -20,6 +21,8 @@ var paychCmd = &cli.Command{
|
|||||||
paychGetCmd,
|
paychGetCmd,
|
||||||
paychListCmd,
|
paychListCmd,
|
||||||
paychVoucherCmd,
|
paychVoucherCmd,
|
||||||
|
paychSettleCmd,
|
||||||
|
paychCloseCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,22 +32,22 @@ var paychGetCmd = &cli.Command{
|
|||||||
ArgsUsage: "[fromAddress toAddress amount]",
|
ArgsUsage: "[fromAddress toAddress amount]",
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
if cctx.Args().Len() != 3 {
|
if cctx.Args().Len() != 3 {
|
||||||
return fmt.Errorf("must pass three arguments: <from> <to> <available funds>")
|
return ShowHelp(cctx, fmt.Errorf("must pass three arguments: <from> <to> <available funds>"))
|
||||||
}
|
}
|
||||||
|
|
||||||
from, err := address.NewFromString(cctx.Args().Get(0))
|
from, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to parse from address: %s", err)
|
return ShowHelp(cctx, fmt.Errorf("failed to parse from address: %s", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
to, err := address.NewFromString(cctx.Args().Get(1))
|
to, err := address.NewFromString(cctx.Args().Get(1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to parse to address: %s", err)
|
return ShowHelp(cctx, fmt.Errorf("failed to parse to address: %s", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
amt, err := types.BigFromString(cctx.Args().Get(2))
|
amt, err := types.BigFromString(cctx.Args().Get(2))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("parsing amount failed: %s", err)
|
return ShowHelp(cctx, fmt.Errorf("parsing amount failed: %s", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
api, closer, err := GetFullNodeAPI(cctx)
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
@ -89,6 +92,86 @@ var paychListCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var paychSettleCmd = &cli.Command{
|
||||||
|
Name: "settle",
|
||||||
|
Usage: "Settle a payment channel",
|
||||||
|
ArgsUsage: "[channelAddress]",
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() != 1 {
|
||||||
|
return fmt.Errorf("must pass payment channel address")
|
||||||
|
}
|
||||||
|
|
||||||
|
ch, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to parse payment channel address: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
mcid, err := api.PaychSettle(ctx, ch)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
mwait, err := api.StateWaitMsg(ctx, mcid, build.MessageConfidence)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if mwait.Receipt.ExitCode != 0 {
|
||||||
|
return fmt.Errorf("settle message execution failed (exit code %d)", mwait.Receipt.ExitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Settled channel %s\n", ch)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var paychCloseCmd = &cli.Command{
|
||||||
|
Name: "collect",
|
||||||
|
Usage: "Collect funds for a payment channel",
|
||||||
|
ArgsUsage: "[channelAddress]",
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() != 1 {
|
||||||
|
return fmt.Errorf("must pass payment channel address")
|
||||||
|
}
|
||||||
|
|
||||||
|
ch, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to parse payment channel address: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
mcid, err := api.PaychCollect(ctx, ch)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
mwait, err := api.StateWaitMsg(ctx, mcid, build.MessageConfidence)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if mwait.Receipt.ExitCode != 0 {
|
||||||
|
return fmt.Errorf("collect message execution failed (exit code %d)", mwait.Receipt.ExitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Collected funds for channel %s\n", ch)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
var paychVoucherCmd = &cli.Command{
|
var paychVoucherCmd = &cli.Command{
|
||||||
Name: "voucher",
|
Name: "voucher",
|
||||||
Usage: "Interact with payment channel vouchers",
|
Usage: "Interact with payment channel vouchers",
|
||||||
@ -115,7 +198,7 @@ var paychVoucherCreateCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
if cctx.Args().Len() != 2 {
|
if cctx.Args().Len() != 2 {
|
||||||
return fmt.Errorf("must pass two arguments: <channel> <amount>")
|
return ShowHelp(cctx, fmt.Errorf("must pass two arguments: <channel> <amount>"))
|
||||||
}
|
}
|
||||||
|
|
||||||
ch, err := address.NewFromString(cctx.Args().Get(0))
|
ch, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
@ -159,7 +242,7 @@ var paychVoucherCheckCmd = &cli.Command{
|
|||||||
ArgsUsage: "[channelAddress voucher]",
|
ArgsUsage: "[channelAddress voucher]",
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
if cctx.Args().Len() != 2 {
|
if cctx.Args().Len() != 2 {
|
||||||
return fmt.Errorf("must pass payment channel address and voucher to validate")
|
return ShowHelp(cctx, fmt.Errorf("must pass payment channel address and voucher to validate"))
|
||||||
}
|
}
|
||||||
|
|
||||||
ch, err := address.NewFromString(cctx.Args().Get(0))
|
ch, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
@ -195,7 +278,7 @@ var paychVoucherAddCmd = &cli.Command{
|
|||||||
ArgsUsage: "[channelAddress voucher]",
|
ArgsUsage: "[channelAddress voucher]",
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
if cctx.Args().Len() != 2 {
|
if cctx.Args().Len() != 2 {
|
||||||
return fmt.Errorf("must pass payment channel address and voucher")
|
return ShowHelp(cctx, fmt.Errorf("must pass payment channel address and voucher"))
|
||||||
}
|
}
|
||||||
|
|
||||||
ch, err := address.NewFromString(cctx.Args().Get(0))
|
ch, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
@ -237,7 +320,7 @@ var paychVoucherListCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
if cctx.Args().Len() != 1 {
|
if cctx.Args().Len() != 1 {
|
||||||
return fmt.Errorf("must pass payment channel address")
|
return ShowHelp(cctx, fmt.Errorf("must pass payment channel address"))
|
||||||
}
|
}
|
||||||
|
|
||||||
ch, err := address.NewFromString(cctx.Args().Get(0))
|
ch, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
@ -281,7 +364,7 @@ var paychVoucherBestSpendableCmd = &cli.Command{
|
|||||||
ArgsUsage: "[channelAddress]",
|
ArgsUsage: "[channelAddress]",
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
if cctx.Args().Len() != 1 {
|
if cctx.Args().Len() != 1 {
|
||||||
return fmt.Errorf("must pass payment channel address")
|
return ShowHelp(cctx, fmt.Errorf("must pass payment channel address"))
|
||||||
}
|
}
|
||||||
|
|
||||||
ch, err := address.NewFromString(cctx.Args().Get(0))
|
ch, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
@ -336,7 +419,7 @@ var paychVoucherSubmitCmd = &cli.Command{
|
|||||||
ArgsUsage: "[channelAddress voucher]",
|
ArgsUsage: "[channelAddress voucher]",
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
if cctx.Args().Len() != 2 {
|
if cctx.Args().Len() != 2 {
|
||||||
return fmt.Errorf("must pass payment channel address and voucher")
|
return ShowHelp(cctx, fmt.Errorf("must pass payment channel address and voucher"))
|
||||||
}
|
}
|
||||||
|
|
||||||
ch, err := address.NewFromString(cctx.Args().Get(0))
|
ch, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
|
82
cli/send.go
82
cli/send.go
@ -1,11 +1,20 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
var sendCmd = &cli.Command{
|
var sendCmd = &cli.Command{
|
||||||
@ -22,13 +31,35 @@ var sendCmd = &cli.Command{
|
|||||||
Usage: "specify gas price to use in AttoFIL",
|
Usage: "specify gas price to use in AttoFIL",
|
||||||
Value: "0",
|
Value: "0",
|
||||||
},
|
},
|
||||||
|
&cli.Int64Flag{
|
||||||
|
Name: "gas-limit",
|
||||||
|
Usage: "specify gas limit",
|
||||||
|
Value: 0,
|
||||||
|
},
|
||||||
&cli.Int64Flag{
|
&cli.Int64Flag{
|
||||||
Name: "nonce",
|
Name: "nonce",
|
||||||
Usage: "specify the nonce to use",
|
Usage: "specify the nonce to use",
|
||||||
Value: -1,
|
Value: -1,
|
||||||
},
|
},
|
||||||
|
&cli.Uint64Flag{
|
||||||
|
Name: "method",
|
||||||
|
Usage: "specify method to invoke",
|
||||||
|
Value: 0,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "params-json",
|
||||||
|
Usage: "specify invocation parameters in json",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "params-hex",
|
||||||
|
Usage: "specify invocation parameters in hex",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() != 2 {
|
||||||
|
return ShowHelp(cctx, fmt.Errorf("'send' expects two arguments, target and amount"))
|
||||||
|
}
|
||||||
|
|
||||||
api, closer, err := GetFullNodeAPI(cctx)
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -37,18 +68,14 @@ var sendCmd = &cli.Command{
|
|||||||
|
|
||||||
ctx := ReqContext(cctx)
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
if cctx.Args().Len() != 2 {
|
|
||||||
return fmt.Errorf("'send' expects two arguments, target and amount")
|
|
||||||
}
|
|
||||||
|
|
||||||
toAddr, err := address.NewFromString(cctx.Args().Get(0))
|
toAddr, err := address.NewFromString(cctx.Args().Get(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return ShowHelp(cctx, fmt.Errorf("failed to parse target address: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
val, err := types.ParseFIL(cctx.Args().Get(1))
|
val, err := types.ParseFIL(cctx.Args().Get(1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return ShowHelp(cctx, fmt.Errorf("failed to parse amount: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
var fromAddr address.Address
|
var fromAddr address.Address
|
||||||
@ -73,11 +100,35 @@ var sendCmd = &cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method := abi.MethodNum(cctx.Uint64("method"))
|
||||||
|
|
||||||
|
var params []byte
|
||||||
|
if cctx.IsSet("params-json") {
|
||||||
|
decparams, err := decodeTypedParams(ctx, api, toAddr, method, cctx.String("params-json"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to decode json params: %w", err)
|
||||||
|
}
|
||||||
|
params = decparams
|
||||||
|
}
|
||||||
|
if cctx.IsSet("params-hex") {
|
||||||
|
if params != nil {
|
||||||
|
return fmt.Errorf("can only specify one of 'params-json' and 'params-hex'")
|
||||||
|
}
|
||||||
|
decparams, err := hex.DecodeString(cctx.String("params-hex"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to decode hex params: %w", err)
|
||||||
|
}
|
||||||
|
params = decparams
|
||||||
|
}
|
||||||
|
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
From: fromAddr,
|
From: fromAddr,
|
||||||
To: toAddr,
|
To: toAddr,
|
||||||
Value: types.BigInt(val),
|
Value: types.BigInt(val),
|
||||||
GasPrice: gp,
|
GasPrice: gp,
|
||||||
|
GasLimit: cctx.Int64("gas-limit"),
|
||||||
|
Method: method,
|
||||||
|
Params: params,
|
||||||
}
|
}
|
||||||
|
|
||||||
if cctx.Int64("nonce") > 0 {
|
if cctx.Int64("nonce") > 0 {
|
||||||
@ -103,3 +154,22 @@ var sendCmd = &cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeTypedParams(ctx context.Context, fapi api.FullNode, to address.Address, method abi.MethodNum, paramstr string) ([]byte, error) {
|
||||||
|
act, err := fapi.StateGetActor(ctx, to, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
p := reflect.New(stmgr.MethodsMap[act.Code][method].Params.Elem()).Interface().(cbg.CBORMarshaler)
|
||||||
|
|
||||||
|
if err := json.Unmarshal([]byte(paramstr), p); err != nil {
|
||||||
|
return nil, fmt.Errorf("unmarshaling input into params type: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
if err := p.MarshalCBOR(buf); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
@ -466,6 +466,7 @@ var importAnalyzeCmd = &cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer fi.Close() //nolint:errcheck
|
||||||
|
|
||||||
const nWorkers = 16
|
const nWorkers = 16
|
||||||
jsonIn := make(chan []byte, 2*nWorkers)
|
jsonIn := make(chan []byte, 2*nWorkers)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "net/http/pprof"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
@ -207,7 +207,8 @@ create temp table iam (like id_address_map excluding constraints) on commit drop
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := tx.Exec(`insert into id_address_map select * from iam on conflict do nothing `); err != nil {
|
// HACK until chain watch can handle reorgs we need to update this table when ID -> PubKey mappings change
|
||||||
|
if _, err := tx.Exec(`insert into id_address_map select * from iam on conflict (id) do update set address = EXCLUDED.address`); err != nil {
|
||||||
return xerrors.Errorf("actor put: %w", err)
|
return xerrors.Errorf("actor put: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"net/http"
|
||||||
|
_ "net/http/pprof"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
@ -12,6 +14,7 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/cmd/lotus-chainwatch/processor"
|
"github.com/filecoin-project/lotus/cmd/lotus-chainwatch/processor"
|
||||||
|
"github.com/filecoin-project/lotus/cmd/lotus-chainwatch/scheduler"
|
||||||
"github.com/filecoin-project/lotus/cmd/lotus-chainwatch/syncer"
|
"github.com/filecoin-project/lotus/cmd/lotus-chainwatch/syncer"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ var runCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
|
go func() {
|
||||||
|
http.ListenAndServe(":6060", nil)
|
||||||
|
}()
|
||||||
ll := cctx.String("log-level")
|
ll := cctx.String("log-level")
|
||||||
if err := logging.SetLogLevel("*", ll); err != nil {
|
if err := logging.SetLogLevel("*", ll); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -70,6 +76,9 @@ var runCmd = &cli.Command{
|
|||||||
proc := processor.NewProcessor(db, api, maxBatch)
|
proc := processor.NewProcessor(db, api, maxBatch)
|
||||||
proc.Start(ctx)
|
proc.Start(ctx)
|
||||||
|
|
||||||
|
sched := scheduler.PrepareScheduler(db)
|
||||||
|
sched.Start(ctx)
|
||||||
|
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
return nil
|
return nil
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package scheduler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func refreshTopMinerByBaseReward(ctx context.Context, db *sql.DB) error {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
t := time.Now()
|
||||||
|
defer func() {
|
||||||
|
log.Debugw("refresh top_miners_by_base_reward", "duration", time.Since(t).String())
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, err := db.Exec("REFRESH MATERIALIZED VIEW top_miners_by_base_reward;")
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("refresh top_miners_by_base_reward: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
47
cmd/lotus-chainwatch/scheduler/scheduler.go
Normal file
47
cmd/lotus-chainwatch/scheduler/scheduler.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package scheduler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
logging "github.com/ipfs/go-log/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var log = logging.Logger("scheduler")
|
||||||
|
|
||||||
|
// Scheduler manages the execution of jobs triggered
|
||||||
|
// by tickers. Not externally configuable at runtime.
|
||||||
|
type Scheduler struct {
|
||||||
|
db *sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrepareScheduler returns a ready-to-run Scheduler
|
||||||
|
func PrepareScheduler(db *sql.DB) *Scheduler {
|
||||||
|
return &Scheduler{db}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the scheduler jobs at the defined intervals
|
||||||
|
func (s *Scheduler) Start(ctx context.Context) {
|
||||||
|
log.Debug("Starting Scheduler")
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
// run once on start after schema has initialized
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
if err := refreshTopMinerByBaseReward(ctx, s.db); err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
refreshTopMinerCh := time.NewTicker(6 * time.Hour)
|
||||||
|
defer refreshTopMinerCh.Stop()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-refreshTopMinerCh.C:
|
||||||
|
if err := refreshTopMinerByBaseReward(ctx, s.db); err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
@ -9,6 +9,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -93,7 +94,8 @@ var runCmd = &cli.Command{
|
|||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "address",
|
Name: "address",
|
||||||
Usage: "Locally reachable address",
|
Usage: "locally reachable address",
|
||||||
|
Value: "0.0.0.0",
|
||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "no-local-storage",
|
Name: "no-local-storage",
|
||||||
@ -114,6 +116,11 @@ var runCmd = &cli.Command{
|
|||||||
Usage: "enable commit (32G sectors: all cores or GPUs, 128GiB Memory + 64GiB swap)",
|
Usage: "enable commit (32G sectors: all cores or GPUs, 128GiB Memory + 64GiB swap)",
|
||||||
Value: true,
|
Value: true,
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "timeout",
|
||||||
|
Usage: "used when address is unspecified. must be a valid duration recognized by golang's time.ParseDuration function",
|
||||||
|
Value: "30m",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
if !cctx.Bool("enable-gpu-proving") {
|
if !cctx.Bool("enable-gpu-proving") {
|
||||||
@ -122,10 +129,6 @@ var runCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cctx.String("address") == "" {
|
|
||||||
return xerrors.Errorf("--address flag is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect to storage-miner
|
// Connect to storage-miner
|
||||||
var nodeApi api.StorageMiner
|
var nodeApi api.StorageMiner
|
||||||
var closer func()
|
var closer func()
|
||||||
@ -259,8 +262,24 @@ var runCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Opening local storage; connecting to master")
|
log.Info("Opening local storage; connecting to master")
|
||||||
|
const unspecifiedAddress = "0.0.0.0"
|
||||||
|
address := cctx.String("address")
|
||||||
|
addressSlice := strings.Split(address, ":")
|
||||||
|
if ip := net.ParseIP(addressSlice[0]); ip != nil {
|
||||||
|
if ip.String() == unspecifiedAddress {
|
||||||
|
timeout, err := time.ParseDuration(cctx.String("timeout"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rip, err := extractRoutableIP(timeout)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
address = rip + ":" + addressSlice[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
localStore, err := stores.NewLocal(ctx, lr, nodeApi, []string{"http://" + cctx.String("address") + "/remote"})
|
localStore, err := stores.NewLocal(ctx, lr, nodeApi, []string{"http://" + address + "/remote"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -289,7 +308,7 @@ var runCmd = &cli.Command{
|
|||||||
|
|
||||||
mux := mux.NewRouter()
|
mux := mux.NewRouter()
|
||||||
|
|
||||||
log.Info("Setting up control endpoint at " + cctx.String("address"))
|
log.Info("Setting up control endpoint at " + address)
|
||||||
|
|
||||||
rpcServer := jsonrpc.NewServer()
|
rpcServer := jsonrpc.NewServer()
|
||||||
rpcServer.Register("Filecoin", apistruct.PermissionedWorkerAPI(workerApi))
|
rpcServer.Register("Filecoin", apistruct.PermissionedWorkerAPI(workerApi))
|
||||||
@ -319,7 +338,7 @@ var runCmd = &cli.Command{
|
|||||||
log.Warn("Graceful shutdown successful")
|
log.Warn("Graceful shutdown successful")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
nl, err := net.Listen("tcp", cctx.String("address"))
|
nl, err := net.Listen("tcp", address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -327,7 +346,7 @@ var runCmd = &cli.Command{
|
|||||||
log.Info("Waiting for tasks")
|
log.Info("Waiting for tasks")
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if err := nodeApi.WorkerConnect(ctx, "ws://"+cctx.String("address")+"/rpc/v0"); err != nil {
|
if err := nodeApi.WorkerConnect(ctx, "ws://"+address+"/rpc/v0"); err != nil {
|
||||||
log.Errorf("Registering worker failed: %+v", err)
|
log.Errorf("Registering worker failed: %+v", err)
|
||||||
cancel()
|
cancel()
|
||||||
return
|
return
|
||||||
@ -376,3 +395,27 @@ func watchMinerConn(ctx context.Context, cctx *cli.Context, nodeApi api.StorageM
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractRoutableIP(timeout time.Duration) (string, error) {
|
||||||
|
minerMultiAddrKey := "MINER_API_INFO"
|
||||||
|
deprecatedMinerMultiAddrKey := "STORAGE_API_INFO"
|
||||||
|
env, ok := os.LookupEnv(minerMultiAddrKey)
|
||||||
|
if !ok {
|
||||||
|
// TODO remove after deprecation period
|
||||||
|
env, ok = os.LookupEnv(deprecatedMinerMultiAddrKey)
|
||||||
|
if ok {
|
||||||
|
log.Warnf("Using a deprecated env(%s) value, please use env(%s) instead.", deprecatedMinerMultiAddrKey, minerMultiAddrKey)
|
||||||
|
}
|
||||||
|
return "", xerrors.New("MINER_API_INFO environment variable required to extract IP")
|
||||||
|
}
|
||||||
|
minerAddr := strings.Split(env, "/")
|
||||||
|
conn, err := net.DialTimeout("tcp", minerAddr[2]+":"+minerAddr[4], timeout)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
localAddr := conn.LocalAddr().(*net.TCPAddr)
|
||||||
|
|
||||||
|
return strings.Split(localAddr.IP.String(), ":")[0], nil
|
||||||
|
}
|
||||||
|
@ -241,6 +241,7 @@ func parseMultisigCsv(csvf string) ([]GenAccountEntry, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("read multisig csv: %w", err)
|
return nil, xerrors.Errorf("read multisig csv: %w", err)
|
||||||
}
|
}
|
||||||
|
defer fileReader.Close() //nolint:errcheck
|
||||||
r := csv.NewReader(fileReader)
|
r := csv.NewReader(fileReader)
|
||||||
records, err := r.ReadAll()
|
records, err := r.ReadAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -155,6 +155,9 @@ var aggregateManifestsCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
inputs = append(inputs, val)
|
inputs = append(inputs, val)
|
||||||
|
if err := fi.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
output := make(map[string]genesis.Miner)
|
output := make(map[string]genesis.Miner)
|
||||||
|
@ -65,11 +65,17 @@ var importCarCmd = &cli.Command{
|
|||||||
fmt.Println()
|
fmt.Println()
|
||||||
return ds.Close()
|
return ds.Close()
|
||||||
default:
|
default:
|
||||||
|
if err := f.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
return err
|
return err
|
||||||
case nil:
|
case nil:
|
||||||
fmt.Printf("\r%s", blk.Cid())
|
fmt.Printf("\r%s", blk.Cid())
|
||||||
if err := bs.Put(blk); err != nil {
|
if err := bs.Put(blk); err != nil {
|
||||||
|
if err := f.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return xerrors.Errorf("put %s: %w", blk.Cid(), err)
|
return xerrors.Errorf("put %s: %w", blk.Cid(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -64,10 +65,12 @@ var keyinfoImportCmd = &cli.Command{
|
|||||||
input = os.Stdin
|
input = os.Stdin
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
input, err = os.Open(cctx.Args().First())
|
inputFile, err := os.Open(cctx.Args().First())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer inputFile.Close()
|
||||||
|
input = bufio.NewReader(inputFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
encoded, err := ioutil.ReadAll(input)
|
encoded, err := ioutil.ReadAll(input)
|
||||||
@ -174,10 +177,12 @@ var keyinfoInfoCmd = &cli.Command{
|
|||||||
input = os.Stdin
|
input = os.Stdin
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
input, err = os.Open(cctx.Args().First())
|
inputFile, err := os.Open(cctx.Args().First())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer inputFile.Close()
|
||||||
|
input = bufio.NewReader(inputFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
encoded, err := ioutil.ReadAll(input)
|
encoded, err := ioutil.ReadAll(input)
|
||||||
|
@ -27,6 +27,8 @@ func main() {
|
|||||||
fetchParamCmd,
|
fetchParamCmd,
|
||||||
proofsCmd,
|
proofsCmd,
|
||||||
verifRegCmd,
|
verifRegCmd,
|
||||||
|
miscCmd,
|
||||||
|
mpoolCmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
app := &cli.App{
|
app := &cli.App{
|
||||||
|
39
cmd/lotus-shed/misc.go
Normal file
39
cmd/lotus-shed/misc.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var miscCmd = &cli.Command{
|
||||||
|
Name: "misc",
|
||||||
|
Usage: "Assorted unsorted commands for various purposes",
|
||||||
|
Flags: []cli.Flag{},
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
dealStateMappingCmd,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var dealStateMappingCmd = &cli.Command{
|
||||||
|
Name: "deal-state",
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if !cctx.Args().Present() {
|
||||||
|
return cli.ShowCommandHelp(cctx, cctx.Command.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
num, err := strconv.Atoi(cctx.Args().First())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ststr, ok := storagemarket.DealStates[uint64(num)]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("no such deal state %d", num)
|
||||||
|
}
|
||||||
|
fmt.Println(ststr)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
50
cmd/lotus-shed/mpool.go
Normal file
50
cmd/lotus-shed/mpool.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
|
"github.com/filecoin-project/lotus/miner"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var mpoolCmd = &cli.Command{
|
||||||
|
Name: "mpool",
|
||||||
|
Usage: "Tools for diagnosing mempool issues",
|
||||||
|
Flags: []cli.Flag{},
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
minerSelectMsgsCmd,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var minerSelectMsgsCmd = &cli.Command{
|
||||||
|
Name: "miner-select-msgs",
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer closer()
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
|
head, err := api.ChainHead(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
msgs, err := api.MpoolPending(ctx, head.Key())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
filtered, err := miner.SelectMessages(ctx, api.StateGetActor, head, msgs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("mempool input messages: ", len(msgs))
|
||||||
|
fmt.Println("filtered messages: ", len(filtered))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
@ -16,10 +15,8 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var verifRegCmd = &cli.Command{
|
var verifRegCmd = &cli.Command{
|
||||||
@ -193,27 +190,22 @@ var verifRegListVerifiersCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
apibs := apibstore.NewAPIBlockstore(api)
|
apibs := apibstore.NewAPIBlockstore(api)
|
||||||
cst := cbor.NewCborStore(apibs)
|
store := adt.WrapStore(ctx, cbor.NewCborStore(apibs))
|
||||||
|
|
||||||
var st verifreg.State
|
var st verifreg.State
|
||||||
if err := cst.Get(ctx, act.Head, &st); err != nil {
|
if err := store.Get(ctx, act.Head, &st); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
vh, err := hamt.LoadNode(ctx, cst, st.Verifiers, hamt.UseTreeBitWidth(5))
|
vh, err := adt.AsMap(store, st.Verifiers)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := vh.ForEach(ctx, func(k string, val interface{}) error {
|
|
||||||
addr, err := address.NewFromBytes([]byte(k))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var dcap verifreg.DataCap
|
var dcap verifreg.DataCap
|
||||||
|
if err := vh.ForEach(&dcap, func(k string) error {
|
||||||
if err := dcap.UnmarshalCBOR(bytes.NewReader(val.(*cbg.Deferred).Raw)); err != nil {
|
addr, err := address.NewFromBytes([]byte(k))
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,27 +237,22 @@ var verifRegListClientsCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
apibs := apibstore.NewAPIBlockstore(api)
|
apibs := apibstore.NewAPIBlockstore(api)
|
||||||
cst := cbor.NewCborStore(apibs)
|
store := adt.WrapStore(ctx, cbor.NewCborStore(apibs))
|
||||||
|
|
||||||
var st verifreg.State
|
var st verifreg.State
|
||||||
if err := cst.Get(ctx, act.Head, &st); err != nil {
|
if err := store.Get(ctx, act.Head, &st); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
vh, err := hamt.LoadNode(ctx, cst, st.VerifiedClients, hamt.UseTreeBitWidth(5))
|
vh, err := adt.AsMap(store, st.VerifiedClients)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := vh.ForEach(ctx, func(k string, val interface{}) error {
|
|
||||||
addr, err := address.NewFromBytes([]byte(k))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var dcap verifreg.DataCap
|
var dcap verifreg.DataCap
|
||||||
|
if err := vh.ForEach(&dcap, func(k string) error {
|
||||||
if err := dcap.UnmarshalCBOR(bytes.NewReader(val.(*cbg.Deferred).Raw)); err != nil {
|
addr, err := address.NewFromBytes([]byte(k))
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,21 +327,23 @@ var verifRegCheckVerifierCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
apibs := apibstore.NewAPIBlockstore(api)
|
apibs := apibstore.NewAPIBlockstore(api)
|
||||||
cst := cbor.NewCborStore(apibs)
|
store := adt.WrapStore(ctx, cbor.NewCborStore(apibs))
|
||||||
|
|
||||||
var st verifreg.State
|
var st verifreg.State
|
||||||
if err := cst.Get(ctx, act.Head, &st); err != nil {
|
if err := store.Get(ctx, act.Head, &st); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
vh, err := hamt.LoadNode(ctx, cst, st.Verifiers, hamt.UseTreeBitWidth(5))
|
vh, err := adt.AsMap(store, st.Verifiers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var dcap verifreg.DataCap
|
var dcap verifreg.DataCap
|
||||||
if err := vh.Find(ctx, string(vaddr.Bytes()), &dcap); err != nil {
|
if found, err := vh.Get(adt.AddrKey(vaddr), &dcap); err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else if !found {
|
||||||
|
return fmt.Errorf("not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(dcap)
|
fmt.Println(dcap)
|
||||||
|
@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
|
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@ -30,18 +29,18 @@ func main() {
|
|||||||
lotuslog.SetupLogLevels()
|
lotuslog.SetupLogLevels()
|
||||||
|
|
||||||
local := []*cli.Command{
|
local := []*cli.Command{
|
||||||
actorCmd,
|
|
||||||
storageDealsCmd,
|
|
||||||
retrievalDealsCmd,
|
|
||||||
infoCmd,
|
|
||||||
initCmd,
|
initCmd,
|
||||||
rewardsCmd,
|
|
||||||
runCmd,
|
runCmd,
|
||||||
stopCmd,
|
stopCmd,
|
||||||
sectorsCmd,
|
lcli.WithCategory("chain", actorCmd),
|
||||||
storageCmd,
|
lcli.WithCategory("chain", rewardsCmd),
|
||||||
workersCmd,
|
lcli.WithCategory("chain", infoCmd),
|
||||||
provingCmd,
|
lcli.WithCategory("market", storageDealsCmd),
|
||||||
|
lcli.WithCategory("market", retrievalDealsCmd),
|
||||||
|
lcli.WithCategory("storage", sectorsCmd),
|
||||||
|
lcli.WithCategory("storage", provingCmd),
|
||||||
|
lcli.WithCategory("storage", storageCmd),
|
||||||
|
lcli.WithCategory("storage", sealingCmd),
|
||||||
}
|
}
|
||||||
jaeger := tracing.SetupJaegerTracing("lotus")
|
jaeger := tracing.SetupJaegerTracing("lotus")
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -96,10 +95,7 @@ func main() {
|
|||||||
app.Setup()
|
app.Setup()
|
||||||
app.Metadata["repoType"] = repo.StorageMiner
|
app.Metadata["repoType"] = repo.StorageMiner
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
lcli.RunApp(app)
|
||||||
log.Warnf("%+v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getActorAddress(ctx context.Context, nodeAPI api.StorageMiner, overrideMaddr string) (maddr address.Address, err error) {
|
func getActorAddress(ctx context.Context, nodeAPI api.StorageMiner, overrideMaddr string) (maddr address.Address, err error) {
|
||||||
|
@ -2,8 +2,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"text/tabwriter"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@ -14,16 +18,17 @@ import (
|
|||||||
lcli "github.com/filecoin-project/lotus/cli"
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
var workersCmd = &cli.Command{
|
var sealingCmd = &cli.Command{
|
||||||
Name: "workers",
|
Name: "sealing",
|
||||||
Usage: "interact with workers",
|
Usage: "interact with sealing pipeline",
|
||||||
Subcommands: []*cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
workersListCmd,
|
sealingJobsCmd,
|
||||||
|
sealingWorkersCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var workersListCmd = &cli.Command{
|
var sealingWorkersCmd = &cli.Command{
|
||||||
Name: "list",
|
Name: "workers",
|
||||||
Usage: "list workers",
|
Usage: "list workers",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.BoolFlag{Name: "color"},
|
&cli.BoolFlag{Name: "color"},
|
||||||
@ -106,3 +111,68 @@ var workersListCmd = &cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sealingJobsCmd = &cli.Command{
|
||||||
|
Name: "jobs",
|
||||||
|
Usage: "list workers",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.BoolFlag{Name: "color"},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
color.NoColor = !cctx.Bool("color")
|
||||||
|
|
||||||
|
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
|
jobs, err := nodeApi.WorkerJobs(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting worker jobs: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type line struct {
|
||||||
|
storiface.WorkerJob
|
||||||
|
wid uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := make([]line, 0)
|
||||||
|
|
||||||
|
for wid, jobs := range jobs {
|
||||||
|
for _, job := range jobs {
|
||||||
|
lines = append(lines, line{
|
||||||
|
WorkerJob: job,
|
||||||
|
wid: wid,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// oldest first
|
||||||
|
sort.Slice(lines, func(i, j int) bool {
|
||||||
|
return lines[i].Start.Before(lines[j].Start)
|
||||||
|
})
|
||||||
|
|
||||||
|
workerHostnames := map[uint64]string{}
|
||||||
|
|
||||||
|
wst, err := nodeApi.WorkerStats(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting worker stats: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for wid, st := range wst {
|
||||||
|
workerHostnames[wid] = st.Info.Hostname
|
||||||
|
}
|
||||||
|
|
||||||
|
tw := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
|
||||||
|
_, _ = fmt.Fprintf(tw, "ID\tSector\tWorker\tHostname\tTask\tTime\n")
|
||||||
|
|
||||||
|
for _, l := range lines {
|
||||||
|
_, _ = fmt.Fprintf(tw, "%d\t%d\t%d\t%s\t%s\t%s\n", l.ID, l.Sector.Number, l.wid, workerHostnames[l.wid], l.Task.Short(), time.Now().Sub(l.Start).Truncate(time.Millisecond*100))
|
||||||
|
}
|
||||||
|
|
||||||
|
return tw.Flush()
|
||||||
|
},
|
||||||
|
}
|
@ -82,16 +82,16 @@ var sectorsStatusCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("SectorID:\t%d\n", status.SectorID)
|
fmt.Printf("SectorID:\t%d\n", status.SectorID)
|
||||||
fmt.Printf("Status:\t%s\n", status.State)
|
fmt.Printf("Status:\t\t%s\n", status.State)
|
||||||
fmt.Printf("CommD:\t\t%x\n", status.CommD)
|
fmt.Printf("CIDcommD:\t%s\n", status.CommD)
|
||||||
fmt.Printf("CommR:\t\t%x\n", status.CommR)
|
fmt.Printf("CIDcommR:\t%s\n", status.CommR)
|
||||||
fmt.Printf("Ticket:\t\t%x\n", status.Ticket.Value)
|
fmt.Printf("Ticket:\t\t%x\n", status.Ticket.Value)
|
||||||
fmt.Printf("TicketH:\t\t%d\n", status.Ticket.Epoch)
|
fmt.Printf("TicketH:\t%d\n", status.Ticket.Epoch)
|
||||||
fmt.Printf("Seed:\t\t%x\n", status.Seed.Value)
|
fmt.Printf("Seed:\t\t%x\n", status.Seed.Value)
|
||||||
fmt.Printf("SeedH:\t\t%d\n", status.Seed.Epoch)
|
fmt.Printf("SeedH:\t\t%d\n", status.Seed.Epoch)
|
||||||
fmt.Printf("Proof:\t\t%x\n", status.Proof)
|
fmt.Printf("Proof:\t\t%x\n", status.Proof)
|
||||||
fmt.Printf("Deals:\t\t%v\n", status.Deals)
|
fmt.Printf("Deals:\t\t%v\n", status.Deals)
|
||||||
fmt.Printf("Retries:\t\t%d\n", status.Retries)
|
fmt.Printf("Retries:\t%d\n", status.Retries)
|
||||||
if status.LastErr != "" {
|
if status.LastErr != "" {
|
||||||
fmt.Printf("Last Error:\t\t%s\n", status.LastErr)
|
fmt.Printf("Last Error:\t\t%s\n", status.LastErr)
|
||||||
}
|
}
|
||||||
@ -251,15 +251,16 @@ var sectorsMarkForUpgradeCmd = &cli.Command{
|
|||||||
Usage: "Mark a committed capacity sector for replacement by a sector with deals",
|
Usage: "Mark a committed capacity sector for replacement by a sector with deals",
|
||||||
ArgsUsage: "<sectorNum>",
|
ArgsUsage: "<sectorNum>",
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.Args().Len() != 1 {
|
||||||
|
return lcli.ShowHelp(cctx, xerrors.Errorf("must pass sector number"))
|
||||||
|
}
|
||||||
|
|
||||||
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer closer()
|
defer closer()
|
||||||
ctx := lcli.ReqContext(cctx)
|
ctx := lcli.ReqContext(cctx)
|
||||||
if cctx.Args().Len() != 1 {
|
|
||||||
return xerrors.Errorf("must pass sector number")
|
|
||||||
}
|
|
||||||
|
|
||||||
id, err := strconv.ParseUint(cctx.Args().Get(0), 10, 64)
|
id, err := strconv.ParseUint(cctx.Args().Get(0), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -317,6 +317,7 @@ func ImportChain(r repo.Repo, fname string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer fi.Close() //nolint:errcheck
|
||||||
|
|
||||||
lr, err := r.Lock(repo.FullNode)
|
lr, err := r.Lock(repo.FullNode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
@ -69,17 +68,5 @@ func main() {
|
|||||||
app.Metadata["traceContext"] = ctx
|
app.Metadata["traceContext"] = ctx
|
||||||
app.Metadata["repoType"] = repo.FullNode
|
app.Metadata["repoType"] = repo.FullNode
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
lcli.RunApp(app)
|
||||||
span.SetStatus(trace.Status{
|
|
||||||
Code: trace.StatusCodeFailedPrecondition,
|
|
||||||
Message: err.Error(),
|
|
||||||
})
|
|
||||||
_, ok := err.(*lcli.ErrCmdFailed)
|
|
||||||
if ok {
|
|
||||||
log.Debugf("%+v", err)
|
|
||||||
} else {
|
|
||||||
log.Warnf("%+v", err)
|
|
||||||
}
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
18
go.mod
18
go.mod
@ -15,22 +15,21 @@ require (
|
|||||||
github.com/drand/drand v1.0.3-0.20200714175734-29705eaf09d4
|
github.com/drand/drand v1.0.3-0.20200714175734-29705eaf09d4
|
||||||
github.com/drand/kyber v1.1.1
|
github.com/drand/kyber v1.1.1
|
||||||
github.com/fatih/color v1.8.0
|
github.com/fatih/color v1.8.0
|
||||||
github.com/filecoin-project/chain-validation v0.0.6-0.20200720093255-843129967fdf
|
github.com/filecoin-project/chain-validation v0.0.6-0.20200723211224-ffdcb7a20fe8
|
||||||
github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200716204036-cddc56607e1d
|
github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200716204036-cddc56607e1d
|
||||||
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef
|
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef
|
||||||
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2
|
github.com/filecoin-project/go-bitfield v0.1.0
|
||||||
github.com/filecoin-project/go-bitfield v0.0.4-0.20200703174658-f4a5758051a1
|
|
||||||
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2
|
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2
|
||||||
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03
|
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03
|
||||||
github.com/filecoin-project/go-data-transfer v0.4.1-0.20200715144713-b3311844e1a5
|
github.com/filecoin-project/go-data-transfer v0.5.0
|
||||||
github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f
|
github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f
|
||||||
github.com/filecoin-project/go-fil-markets v0.4.1-0.20200715201050-c141144ea312
|
github.com/filecoin-project/go-fil-markets v0.5.1
|
||||||
github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24
|
github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24
|
||||||
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261
|
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261
|
||||||
github.com/filecoin-project/go-statestore v0.1.0
|
github.com/filecoin-project/go-statestore v0.1.0
|
||||||
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b
|
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b
|
||||||
github.com/filecoin-project/sector-storage v0.0.0-20200717213554-a109ef9cbeab
|
github.com/filecoin-project/sector-storage v0.0.0-20200723200950-ed2e57dde6df
|
||||||
github.com/filecoin-project/specs-actors v0.8.1-0.20200720115956-cd051eabf328
|
github.com/filecoin-project/specs-actors v0.8.1-0.20200724015154-3c690d9b7e1d
|
||||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea
|
github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea
|
||||||
github.com/filecoin-project/storage-fsm v0.0.0-20200720190000-2cfe2fe3c334
|
github.com/filecoin-project/storage-fsm v0.0.0-20200720190000-2cfe2fe3c334
|
||||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
||||||
@ -53,8 +52,7 @@ require (
|
|||||||
github.com/ipfs/go-ds-measure v0.1.0
|
github.com/ipfs/go-ds-measure v0.1.0
|
||||||
github.com/ipfs/go-filestore v1.0.0
|
github.com/ipfs/go-filestore v1.0.0
|
||||||
github.com/ipfs/go-fs-lock v0.0.1
|
github.com/ipfs/go-fs-lock v0.0.1
|
||||||
github.com/ipfs/go-graphsync v0.0.6-0.20200715142715-e2f27c4754e6
|
github.com/ipfs/go-graphsync v0.0.6-0.20200715204712-ef06b3d32e83
|
||||||
github.com/ipfs/go-hamt-ipld v0.1.1-0.20200605182717-0310ad2b0b1f
|
|
||||||
github.com/ipfs/go-ipfs-blockstore v1.0.0
|
github.com/ipfs/go-ipfs-blockstore v1.0.0
|
||||||
github.com/ipfs/go-ipfs-chunker v0.0.5
|
github.com/ipfs/go-ipfs-chunker v0.0.5
|
||||||
github.com/ipfs/go-ipfs-ds-help v1.0.0
|
github.com/ipfs/go-ipfs-ds-help v1.0.0
|
||||||
@ -109,7 +107,7 @@ require (
|
|||||||
github.com/syndtr/goleveldb v1.0.0
|
github.com/syndtr/goleveldb v1.0.0
|
||||||
github.com/urfave/cli/v2 v2.2.0
|
github.com/urfave/cli/v2 v2.2.0
|
||||||
github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba
|
github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200715143311-227fab5a2377
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200723182808-cb5de1c427f5
|
||||||
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
|
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
|
||||||
github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d
|
github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d
|
||||||
github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542
|
github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542
|
||||||
|
43
go.sum
43
go.sum
@ -216,8 +216,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
|
|||||||
github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY=
|
github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY=
|
||||||
github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8=
|
github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8=
|
||||||
github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
|
github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
|
||||||
github.com/filecoin-project/chain-validation v0.0.6-0.20200720093255-843129967fdf h1:7SkS/gSZv4ljQaQeDu4SfnF9CcvQuT9QCEf3+Hn1jp8=
|
github.com/filecoin-project/chain-validation v0.0.6-0.20200723211224-ffdcb7a20fe8 h1:WA2KU3u/FELAMVElQgiwEKTQe/QLUUsT52AnW4YjPjs=
|
||||||
github.com/filecoin-project/chain-validation v0.0.6-0.20200720093255-843129967fdf/go.mod h1:9xZvimiD8wsZbTNTUoACMPzXj4/fpIxeZBV2YjQcLhI=
|
github.com/filecoin-project/chain-validation v0.0.6-0.20200723211224-ffdcb7a20fe8/go.mod h1:P4FhsyLtySqsVFbOPpPVFeEShVQ4j/iA5Dzo8D2p978=
|
||||||
github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
|
github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
|
||||||
github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
|
github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
|
||||||
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U=
|
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U=
|
||||||
@ -225,23 +225,27 @@ github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef/go.m
|
|||||||
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg=
|
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg=
|
||||||
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 h1:jamfsxfK0Q9yCMHt8MPWx7Aa/O9k2Lve8eSc6FILYGQ=
|
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2 h1:jamfsxfK0Q9yCMHt8MPWx7Aa/O9k2Lve8eSc6FILYGQ=
|
||||||
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg=
|
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg=
|
||||||
|
github.com/filecoin-project/go-amt-ipld/v2 v2.1.0 h1:t6qDiuGYYngDqaLc2ZUvdtAg4UNxPeOYaXhBWSNsVaM=
|
||||||
|
github.com/filecoin-project/go-amt-ipld/v2 v2.1.0/go.mod h1:nfFPoGyX0CU9SkXX8EoCcSuHN1XcbN0c6KBh7yvP5fs=
|
||||||
github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw=
|
github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw=
|
||||||
github.com/filecoin-project/go-bitfield v0.0.1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY=
|
github.com/filecoin-project/go-bitfield v0.0.1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY=
|
||||||
github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY=
|
github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY=
|
||||||
github.com/filecoin-project/go-bitfield v0.0.3/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY=
|
github.com/filecoin-project/go-bitfield v0.0.3/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY=
|
||||||
github.com/filecoin-project/go-bitfield v0.0.4-0.20200703174658-f4a5758051a1 h1:xuHlrdznafh7ul5t4xEncnA4qgpQvJZEw+mr98eqHXw=
|
github.com/filecoin-project/go-bitfield v0.0.4-0.20200703174658-f4a5758051a1 h1:xuHlrdznafh7ul5t4xEncnA4qgpQvJZEw+mr98eqHXw=
|
||||||
github.com/filecoin-project/go-bitfield v0.0.4-0.20200703174658-f4a5758051a1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY=
|
github.com/filecoin-project/go-bitfield v0.0.4-0.20200703174658-f4a5758051a1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY=
|
||||||
|
github.com/filecoin-project/go-bitfield v0.1.0 h1:ZDAQjvXuLzbrLnwfFruQFJP7IhImmXLuO+8i2qeAczM=
|
||||||
|
github.com/filecoin-project/go-bitfield v0.1.0/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM=
|
||||||
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8=
|
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8=
|
||||||
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg=
|
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg=
|
||||||
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus=
|
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus=
|
||||||
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ=
|
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ=
|
||||||
github.com/filecoin-project/go-data-transfer v0.4.1-0.20200715144713-b3311844e1a5 h1:/OZ+nr0x3uMZCPrreuUbS5EUOFm9DDo4ljgdav8rp/s=
|
github.com/filecoin-project/go-data-transfer v0.5.0 h1:pvWlab69BD5dwheRHjjBjFB6m7CEqEZeI+aChtVqKVk=
|
||||||
github.com/filecoin-project/go-data-transfer v0.4.1-0.20200715144713-b3311844e1a5/go.mod h1:duGDSKvsOxiKl6Dueh8DNA6ZbiM30PWUWlSKjo9ac+o=
|
github.com/filecoin-project/go-data-transfer v0.5.0/go.mod h1:7yckbsPPMGuN3O1+SYNE/lowwheaUn5woGILpjN52UI=
|
||||||
github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA=
|
github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA=
|
||||||
github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f h1:GxJzR3oRIMTPtpZ0b7QF8FKPK6/iPAc7trhlL5k/g+s=
|
github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f h1:GxJzR3oRIMTPtpZ0b7QF8FKPK6/iPAc7trhlL5k/g+s=
|
||||||
github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ=
|
github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ=
|
||||||
github.com/filecoin-project/go-fil-markets v0.4.1-0.20200715201050-c141144ea312 h1:oVZggNjDWZWEjomkxPl8U3jrOLURoS4QSZA6t4YU5BY=
|
github.com/filecoin-project/go-fil-markets v0.5.1 h1:Y69glslNCuXnygfesCmyilTVhEEjcLK7CtAohKP9SL8=
|
||||||
github.com/filecoin-project/go-fil-markets v0.4.1-0.20200715201050-c141144ea312/go.mod h1:MvrpKOiETu39e9H167gdQzdzLNcvHsUp48UkXqPSdtU=
|
github.com/filecoin-project/go-fil-markets v0.5.1/go.mod h1:GKGigsFNMvKmx/+Mcn7093TdZTiCDLc7YGxQ7d6fq2s=
|
||||||
github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 h1:Jc7vkplmZYVuaEcSXGHDwefvZIdoyyaoGDLqSr8Svms=
|
github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 h1:Jc7vkplmZYVuaEcSXGHDwefvZIdoyyaoGDLqSr8Svms=
|
||||||
github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM=
|
github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM=
|
||||||
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs=
|
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs=
|
||||||
@ -260,19 +264,19 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/
|
|||||||
github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM=
|
github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM=
|
||||||
github.com/filecoin-project/sector-storage v0.0.0-20200712023225-1d67dcfa3c15 h1:miw6hiusb/MkV1ryoqUKKWnvHhPW00AYtyeCj0L8pqo=
|
github.com/filecoin-project/sector-storage v0.0.0-20200712023225-1d67dcfa3c15 h1:miw6hiusb/MkV1ryoqUKKWnvHhPW00AYtyeCj0L8pqo=
|
||||||
github.com/filecoin-project/sector-storage v0.0.0-20200712023225-1d67dcfa3c15/go.mod h1:salgVdX7qeXFo/xaiEQE29J4pPkjn71T0kt0n+VDBzo=
|
github.com/filecoin-project/sector-storage v0.0.0-20200712023225-1d67dcfa3c15/go.mod h1:salgVdX7qeXFo/xaiEQE29J4pPkjn71T0kt0n+VDBzo=
|
||||||
github.com/filecoin-project/sector-storage v0.0.0-20200717213554-a109ef9cbeab h1:jEQtbWFyEKnCw3eAVCW3MSX/K7Nv03B3zzS/rfm2k+Q=
|
github.com/filecoin-project/sector-storage v0.0.0-20200723200950-ed2e57dde6df h1:VDdWrCNUNx6qeHnGU9oAy+izuGM02it9V/5+MJyhZQw=
|
||||||
github.com/filecoin-project/sector-storage v0.0.0-20200717213554-a109ef9cbeab/go.mod h1:7EE+f7jM4kCy2MKHoiiwNDQGJSb+QQzZ+y+/17ugq4w=
|
github.com/filecoin-project/sector-storage v0.0.0-20200723200950-ed2e57dde6df/go.mod h1:7EE+f7jM4kCy2MKHoiiwNDQGJSb+QQzZ+y+/17ugq4w=
|
||||||
github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
|
github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
|
||||||
github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y=
|
github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y=
|
||||||
github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
|
github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
|
||||||
github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
|
github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
|
||||||
github.com/filecoin-project/specs-actors v0.7.0/go.mod h1:+z0htZu/wLBDbOLcQTKKUEC2rkUTFzL2KJ/bRAVWkws=
|
|
||||||
github.com/filecoin-project/specs-actors v0.7.3-0.20200716231407-60a2ae96d2e6 h1:F+GcBdKPdW/wTv6bMJxG9Zj1dc0UGkO6uNOQmKP/g1o=
|
github.com/filecoin-project/specs-actors v0.7.3-0.20200716231407-60a2ae96d2e6 h1:F+GcBdKPdW/wTv6bMJxG9Zj1dc0UGkO6uNOQmKP/g1o=
|
||||||
github.com/filecoin-project/specs-actors v0.7.3-0.20200716231407-60a2ae96d2e6/go.mod h1:JOMUa7EijvpOO4ofD1yeHNmqohkmmnhTvz/IpB6so4c=
|
github.com/filecoin-project/specs-actors v0.7.3-0.20200716231407-60a2ae96d2e6/go.mod h1:JOMUa7EijvpOO4ofD1yeHNmqohkmmnhTvz/IpB6so4c=
|
||||||
github.com/filecoin-project/specs-actors v0.8.1-0.20200720061236-f4719fdd7d90 h1:E8M5FyB53tuRXHO5KAAi9DlksOl54ULImW57MrUfyDY=
|
|
||||||
github.com/filecoin-project/specs-actors v0.8.1-0.20200720061236-f4719fdd7d90/go.mod h1:JOMUa7EijvpOO4ofD1yeHNmqohkmmnhTvz/IpB6so4c=
|
|
||||||
github.com/filecoin-project/specs-actors v0.8.1-0.20200720115956-cd051eabf328 h1:jZwz1VxqzNCfINY5FDnsT+ZL03wjzLifi+JwdLkehuU=
|
|
||||||
github.com/filecoin-project/specs-actors v0.8.1-0.20200720115956-cd051eabf328/go.mod h1:0+CxQ5Jeii3522irTvhKRDpr4GG1bj5Erq3p/d38DzY=
|
github.com/filecoin-project/specs-actors v0.8.1-0.20200720115956-cd051eabf328/go.mod h1:0+CxQ5Jeii3522irTvhKRDpr4GG1bj5Erq3p/d38DzY=
|
||||||
|
github.com/filecoin-project/specs-actors v0.8.1-0.20200723200253-a3c01bc62f99 h1:li6OZVhGNrQihzKhUy7x4vwKgUCExnpVSj746VMkq1I=
|
||||||
|
github.com/filecoin-project/specs-actors v0.8.1-0.20200723200253-a3c01bc62f99/go.mod h1:TLvIheTVl0EIuyncuKSTVXPULaj7gzhLup5CLZ/S+uM=
|
||||||
|
github.com/filecoin-project/specs-actors v0.8.1-0.20200724015154-3c690d9b7e1d h1:dti6ssgSFG7Tk851S3RdiDr1TNbOJ26ylc6DJ9Y2Le0=
|
||||||
|
github.com/filecoin-project/specs-actors v0.8.1-0.20200724015154-3c690d9b7e1d/go.mod h1:TLvIheTVl0EIuyncuKSTVXPULaj7gzhLup5CLZ/S+uM=
|
||||||
github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94=
|
github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94=
|
||||||
github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k=
|
github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k=
|
||||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea h1:iixjULRQFPn7Q9KlIqfwLJnlAXO10bbkI+xy5GKGdLY=
|
github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea h1:iixjULRQFPn7Q9KlIqfwLJnlAXO10bbkI+xy5GKGdLY=
|
||||||
@ -418,6 +422,8 @@ github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmv
|
|||||||
github.com/gxed/pubsub v0.0.0-20180201040156-26ebdf44f824/go.mod h1:OiEWyHgK+CWrmOlVquHaIK1vhpUJydC9m0Je6mhaiNE=
|
github.com/gxed/pubsub v0.0.0-20180201040156-26ebdf44f824/go.mod h1:OiEWyHgK+CWrmOlVquHaIK1vhpUJydC9m0Je6mhaiNE=
|
||||||
github.com/hannahhoward/cbor-gen-for v0.0.0-20191218204337-9ab7b1bcc099 h1:vQqOW42RRM5LoM/1K5dK940VipLqpH8lEVGrMz+mNjU=
|
github.com/hannahhoward/cbor-gen-for v0.0.0-20191218204337-9ab7b1bcc099 h1:vQqOW42RRM5LoM/1K5dK940VipLqpH8lEVGrMz+mNjU=
|
||||||
github.com/hannahhoward/cbor-gen-for v0.0.0-20191218204337-9ab7b1bcc099/go.mod h1:WVPCl0HO/0RAL5+vBH2GMxBomlxBF70MAS78+Lu1//k=
|
github.com/hannahhoward/cbor-gen-for v0.0.0-20191218204337-9ab7b1bcc099/go.mod h1:WVPCl0HO/0RAL5+vBH2GMxBomlxBF70MAS78+Lu1//k=
|
||||||
|
github.com/hannahhoward/cbor-gen-for v0.0.0-20200723175505-5892b522820a h1:wfqh5oiHXvn3Rk54xy8Cwqh+HnYihGnjMNzdNb3/ld0=
|
||||||
|
github.com/hannahhoward/cbor-gen-for v0.0.0-20200723175505-5892b522820a/go.mod h1:jvfsLIxk0fY/2BKSQ1xf2406AKA5dwMmKKv0ADcOfN8=
|
||||||
github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY=
|
github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY=
|
||||||
github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY=
|
github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY=
|
||||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||||
@ -520,13 +526,12 @@ github.com/ipfs/go-filestore v1.0.0 h1:QR7ekKH+q2AGiWDc7W2Q0qHuYSRZGUJqUn0GsegEP
|
|||||||
github.com/ipfs/go-filestore v1.0.0/go.mod h1:/XOCuNtIe2f1YPbiXdYvD0BKLA0JR1MgPiFOdcuu9SM=
|
github.com/ipfs/go-filestore v1.0.0/go.mod h1:/XOCuNtIe2f1YPbiXdYvD0BKLA0JR1MgPiFOdcuu9SM=
|
||||||
github.com/ipfs/go-fs-lock v0.0.1 h1:XHX8uW4jQBYWHj59XXcjg7BHlHxV9ZOYs6Y43yb7/l0=
|
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-fs-lock v0.0.1/go.mod h1:DNBekbboPKcxs1aukPSaOtFA3QfSdi5C855v0i9XJ8Y=
|
||||||
github.com/ipfs/go-graphsync v0.0.6-0.20200715142715-e2f27c4754e6 h1:+dQnaRkLV4za46Gfw6b1KNVOCcGDrdnEGZrjz3kF80k=
|
github.com/ipfs/go-graphsync v0.0.6-0.20200715204712-ef06b3d32e83 h1:tkGDAwcZfzDFeBNyBWYOM02Qw0rGpA2UuCvq49T3K5o=
|
||||||
github.com/ipfs/go-graphsync v0.0.6-0.20200715142715-e2f27c4754e6/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE=
|
github.com/ipfs/go-graphsync v0.0.6-0.20200715204712-ef06b3d32e83/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE=
|
||||||
github.com/ipfs/go-hamt-ipld v0.0.15-0.20200131012125-dd88a59d3f2e/go.mod h1:9aQJu/i/TaRDW6jqB5U217dLIDopn50wxLdHXM2CTfE=
|
github.com/ipfs/go-hamt-ipld v0.0.15-0.20200131012125-dd88a59d3f2e/go.mod h1:9aQJu/i/TaRDW6jqB5U217dLIDopn50wxLdHXM2CTfE=
|
||||||
github.com/ipfs/go-hamt-ipld v0.0.15-0.20200204200533-99b8553ef242/go.mod h1:kq3Pi+UP3oHhAdKexE+kHHYRKMoFNuGero0R7q3hWGg=
|
github.com/ipfs/go-hamt-ipld v0.0.15-0.20200204200533-99b8553ef242/go.mod h1:kq3Pi+UP3oHhAdKexE+kHHYRKMoFNuGero0R7q3hWGg=
|
||||||
github.com/ipfs/go-hamt-ipld v0.1.1-0.20200501020327-d53d20a7063e/go.mod h1:giiPqWYCnRBYpNTsJ/EX1ojldX5kTXrXYckSJQ7ko9M=
|
github.com/ipfs/go-hamt-ipld v0.1.1 h1:0IQdvwnAAUKmDE+PMJa5y1QiwOPHpI9+eAbQEEEYthk=
|
||||||
github.com/ipfs/go-hamt-ipld v0.1.1-0.20200605182717-0310ad2b0b1f h1:mchhWiYYUSoCuE3wDfRCo8cho5kqSoxkgnOtGcnNMZw=
|
github.com/ipfs/go-hamt-ipld v0.1.1/go.mod h1:1EZCr2v0jlCnhpa+aZ0JZYp8Tt2w16+JJOAVz17YcDk=
|
||||||
github.com/ipfs/go-hamt-ipld v0.1.1-0.20200605182717-0310ad2b0b1f/go.mod h1:phOFBB7W73N9dg1glcb1fQ9HtQFDUpeyJgatW8ns0bw=
|
|
||||||
github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08=
|
github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08=
|
||||||
github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw=
|
github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw=
|
||||||
github.com/ipfs/go-ipfs-blockstore v0.1.4/go.mod h1:Jxm3XMVjh6R17WvxFEiyKBLUGr86HgIYJW/D/MwqeYQ=
|
github.com/ipfs/go-ipfs-blockstore v0.1.4/go.mod h1:Jxm3XMVjh6R17WvxFEiyKBLUGr86HgIYJW/D/MwqeYQ=
|
||||||
@ -1353,14 +1358,14 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:X
|
|||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200414195334-429a0b5e922e/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200414195334-429a0b5e922e/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200501014322-5f9941ef88e0/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200501232601-351665a6e756/go.mod h1:W5MvapuoHRP8rz4vxjwCK1pDqF1aQcWsV5PZ+AHbqdg=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200501232601-351665a6e756/go.mod h1:W5MvapuoHRP8rz4vxjwCK1pDqF1aQcWsV5PZ+AHbqdg=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200504204219-64967432584d h1:Y25auOnuZb/GuJvqMflRSDWBz8/HBRME8fiD+H8zLfs=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200504204219-64967432584d h1:Y25auOnuZb/GuJvqMflRSDWBz8/HBRME8fiD+H8zLfs=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200504204219-64967432584d/go.mod h1:W5MvapuoHRP8rz4vxjwCK1pDqF1aQcWsV5PZ+AHbqdg=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200504204219-64967432584d/go.mod h1:W5MvapuoHRP8rz4vxjwCK1pDqF1aQcWsV5PZ+AHbqdg=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d h1:wSxKhvbN7kUoP0sfRS+w2tWr45qlU8409i94hHLOT8w=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d h1:wSxKhvbN7kUoP0sfRS+w2tWr45qlU8409i94hHLOT8w=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200715143311-227fab5a2377 h1:LHFlP/ktDvOnCap7PsT87cs7Gwd0p+qv6Qm5g2ZPR+I=
|
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200715143311-227fab5a2377/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200715143311-227fab5a2377/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
||||||
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200723182808-cb5de1c427f5 h1:dJgLhFKggti1Xd7GczL4DetAUyx68RhpCKCfV71ongg=
|
||||||
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200723182808-cb5de1c427f5/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
||||||
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=
|
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/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8=
|
||||||
github.com/whyrusleeping/go-ctrlnet v0.0.0-20180313164037-f564fbbdaa95/go.mod h1:SJqKCCPXRfBFCwXjfNT/skfsceF7+MBFLI2OrvuRA7g=
|
github.com/whyrusleeping/go-ctrlnet v0.0.0-20180313164037-f564fbbdaa95/go.mod h1:SJqKCCPXRfBFCwXjfNT/skfsceF7+MBFLI2OrvuRA7g=
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
package adtutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewStore(ctx context.Context, cst *cbor.BasicIpldStore) adt.Store {
|
|
||||||
return &store{
|
|
||||||
cst: cst,
|
|
||||||
ctx: ctx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type store struct {
|
|
||||||
cst cbor.IpldStore
|
|
||||||
ctx context.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *store) Context() context.Context {
|
|
||||||
return a.ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *store) Get(ctx context.Context, c cid.Cid, out interface{}) error {
|
|
||||||
return a.cst.Get(ctx, c, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *store) Put(ctx context.Context, v interface{}) (cid.Cid, error) {
|
|
||||||
return a.cst.Put(ctx, v)
|
|
||||||
}
|
|
@ -104,7 +104,12 @@ func (bs *BufferedBS) Get(c cid.Cid) (block.Block, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BufferedBS) GetSize(c cid.Cid) (int, error) {
|
func (bs *BufferedBS) GetSize(c cid.Cid) (int, error) {
|
||||||
panic("nyi")
|
s, err := bs.read.GetSize(c)
|
||||||
|
if err == bstore.ErrNotFound || s == 0 {
|
||||||
|
return bs.write.GetSize(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BufferedBS) Put(blk block.Block) error {
|
func (bs *BufferedBS) Put(blk block.Block) error {
|
||||||
|
@ -25,10 +25,14 @@ type IpfsBstore struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewIpfsBstore(ctx context.Context) (*IpfsBstore, error) {
|
func NewIpfsBstore(ctx context.Context) (*IpfsBstore, error) {
|
||||||
api, err := httpapi.NewLocalApi()
|
localApi, err := httpapi.NewLocalApi()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("getting local ipfs api: %w", err)
|
return nil, xerrors.Errorf("getting local ipfs api: %w", err)
|
||||||
}
|
}
|
||||||
|
api, err := localApi.WithOptions(options.Api.Offline(true))
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("setting offline mode: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
return &IpfsBstore{
|
return &IpfsBstore{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
@ -37,9 +41,13 @@ func NewIpfsBstore(ctx context.Context) (*IpfsBstore, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewRemoteIpfsBstore(ctx context.Context, maddr multiaddr.Multiaddr) (*IpfsBstore, error) {
|
func NewRemoteIpfsBstore(ctx context.Context, maddr multiaddr.Multiaddr) (*IpfsBstore, error) {
|
||||||
api, err := httpapi.NewApi(maddr)
|
httpApi, err := httpapi.NewApi(maddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("getting remote ipfs api: %w", err)
|
return nil, xerrors.Errorf("setting remote ipfs api: %w", err)
|
||||||
|
}
|
||||||
|
api, err := httpApi.WithOptions(options.Api.Offline(true))
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("applying offline mode: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &IpfsBstore{
|
return &IpfsBstore{
|
||||||
@ -55,6 +63,13 @@ func (i *IpfsBstore) DeleteBlock(cid cid.Cid) error {
|
|||||||
func (i *IpfsBstore) Has(cid cid.Cid) (bool, error) {
|
func (i *IpfsBstore) Has(cid cid.Cid) (bool, error) {
|
||||||
_, err := i.api.Block().Stat(i.ctx, path.IpldPath(cid))
|
_, err := i.api.Block().Stat(i.ctx, path.IpldPath(cid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// The underlying client is running in Offline mode.
|
||||||
|
// Stat() will fail with an err if the block isn't in the
|
||||||
|
// blockstore. If that's the case, return false without
|
||||||
|
// an error since that's the original intention of this method.
|
||||||
|
if err.Error() == "blockservice: key not found" {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
return false, xerrors.Errorf("getting ipfs block: %w", err)
|
return false, xerrors.Errorf("getting ipfs block: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
"github.com/filecoin-project/go-fil-markets/storagemarket/impl/storedask"
|
"github.com/filecoin-project/go-fil-markets/storagemarket/impl/storedask"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
|
||||||
storage2 "github.com/filecoin-project/specs-storage/storage"
|
storage2 "github.com/filecoin-project/specs-storage/storage"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
@ -57,6 +56,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/node/modules/testing"
|
"github.com/filecoin-project/lotus/node/modules/testing"
|
||||||
"github.com/filecoin-project/lotus/node/repo"
|
"github.com/filecoin-project/lotus/node/repo"
|
||||||
"github.com/filecoin-project/lotus/paychmgr"
|
"github.com/filecoin-project/lotus/paychmgr"
|
||||||
|
"github.com/filecoin-project/lotus/paychmgr/settler"
|
||||||
"github.com/filecoin-project/lotus/storage"
|
"github.com/filecoin-project/lotus/storage"
|
||||||
"github.com/filecoin-project/lotus/storage/sectorblocks"
|
"github.com/filecoin-project/lotus/storage/sectorblocks"
|
||||||
sectorstorage "github.com/filecoin-project/sector-storage"
|
sectorstorage "github.com/filecoin-project/sector-storage"
|
||||||
@ -118,6 +118,7 @@ const (
|
|||||||
// daemon
|
// daemon
|
||||||
ExtractApiKey
|
ExtractApiKey
|
||||||
HeadMetricsKey
|
HeadMetricsKey
|
||||||
|
SettlePaymentChannelsKey
|
||||||
RunPeerTaggerKey
|
RunPeerTaggerKey
|
||||||
JournalKey
|
JournalKey
|
||||||
|
|
||||||
@ -225,7 +226,7 @@ func Online() Option {
|
|||||||
Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages),
|
Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages),
|
||||||
|
|
||||||
Override(new(ffiwrapper.Verifier), ffiwrapper.ProofVerifier),
|
Override(new(ffiwrapper.Verifier), ffiwrapper.ProofVerifier),
|
||||||
Override(new(runtime.Syscalls), vm.Syscalls),
|
Override(new(vm.SyscallBuilder), vm.Syscalls),
|
||||||
Override(new(*store.ChainStore), modules.ChainStore),
|
Override(new(*store.ChainStore), modules.ChainStore),
|
||||||
Override(new(*stmgr.StateManager), stmgr.NewStateManager),
|
Override(new(*stmgr.StateManager), stmgr.NewStateManager),
|
||||||
Override(new(*wallet.Wallet), wallet.NewWallet),
|
Override(new(*wallet.Wallet), wallet.NewWallet),
|
||||||
@ -272,6 +273,7 @@ func Online() Option {
|
|||||||
Override(new(*paychmgr.Store), paychmgr.NewStore),
|
Override(new(*paychmgr.Store), paychmgr.NewStore),
|
||||||
Override(new(*paychmgr.Manager), paychmgr.NewManager),
|
Override(new(*paychmgr.Manager), paychmgr.NewManager),
|
||||||
Override(new(*market.FundMgr), market.NewFundMgr),
|
Override(new(*market.FundMgr), market.NewFundMgr),
|
||||||
|
Override(SettlePaymentChannelsKey, settler.SettlePaymentChannels),
|
||||||
),
|
),
|
||||||
|
|
||||||
// miner
|
// miner
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
xerrors "golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
@ -125,7 +126,7 @@ func (hs *Service) HandleStream(s inet.Stream) {
|
|||||||
func (hs *Service) SayHello(ctx context.Context, pid peer.ID) error {
|
func (hs *Service) SayHello(ctx context.Context, pid peer.ID) error {
|
||||||
s, err := hs.h.NewStream(ctx, pid, ProtocolID)
|
s, err := hs.h.NewStream(ctx, pid, ProtocolID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return xerrors.Errorf("error opening stream: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hts := hs.cs.GetHeaviestTipSet()
|
hts := hs.cs.GetHeaviestTipSet()
|
||||||
@ -149,7 +150,7 @@ func (hs *Service) SayHello(ctx context.Context, pid peer.ID) error {
|
|||||||
|
|
||||||
t0 := build.Clock.Now()
|
t0 := build.Clock.Now()
|
||||||
if err := cborutil.WriteCborRPC(s, hmsg); err != nil {
|
if err := cborutil.WriteCborRPC(s, hmsg); err != nil {
|
||||||
return err
|
return xerrors.Errorf("writing rpc to peer: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-fil-markets/pieceio"
|
"github.com/filecoin-project/go-fil-markets/pieceio"
|
||||||
rm "github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
rm "github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||||
|
"github.com/filecoin-project/go-fil-markets/shared"
|
||||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
@ -261,6 +262,7 @@ func (a *API) makeRetrievalQuery(ctx context.Context, rp rm.RetrievalPeer, paylo
|
|||||||
Piece: piece,
|
Piece: piece,
|
||||||
Size: queryResponse.Size,
|
Size: queryResponse.Size,
|
||||||
MinPrice: queryResponse.PieceRetrievalPrice(),
|
MinPrice: queryResponse.PieceRetrievalPrice(),
|
||||||
|
UnsealPrice: queryResponse.UnsealPrice,
|
||||||
PaymentInterval: queryResponse.MaxPaymentInterval,
|
PaymentInterval: queryResponse.MaxPaymentInterval,
|
||||||
PaymentIntervalIncrease: queryResponse.MaxPaymentIntervalIncrease,
|
PaymentIntervalIncrease: queryResponse.MaxPaymentIntervalIncrease,
|
||||||
Miner: queryResponse.PaymentAddress, // TODO: check
|
Miner: queryResponse.PaymentAddress, // TODO: check
|
||||||
@ -418,10 +420,14 @@ func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref
|
|||||||
|
|
||||||
ppb := types.BigDiv(order.Total, types.NewInt(order.Size))
|
ppb := types.BigDiv(order.Total, types.NewInt(order.Size))
|
||||||
|
|
||||||
_, err := a.Retrieval.Retrieve(
|
params, err := rm.NewParamsV1(ppb, order.PaymentInterval, order.PaymentIntervalIncrease, shared.AllSelector(), order.Piece, order.UnsealPrice)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("Error in retrieval params: %s", err)
|
||||||
|
}
|
||||||
|
_, err = a.Retrieval.Retrieve(
|
||||||
ctx,
|
ctx,
|
||||||
order.Root,
|
order.Root,
|
||||||
rm.NewParamsV0(ppb, order.PaymentInterval, order.PaymentIntervalIncrease),
|
params,
|
||||||
order.Total,
|
order.Total,
|
||||||
order.MinerPeerID,
|
order.MinerPeerID,
|
||||||
order.Client,
|
order.Client,
|
||||||
@ -434,7 +440,7 @@ func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref
|
|||||||
return xerrors.New("Retrieval Timed Out")
|
return xerrors.New("Retrieval Timed Out")
|
||||||
case err := <-retrievalResult:
|
case err := <-retrievalResult:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("RetrieveUnixfs: %w", err)
|
return xerrors.Errorf("Retrieve: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,6 +500,7 @@ func (a *API) ClientCalcCommP(ctx context.Context, inpath string, miner address.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer rdr.Close()
|
||||||
|
|
||||||
stat, err := rdr.Stat()
|
stat, err := rdr.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -554,6 +561,7 @@ func (a *API) clientImport(ctx context.Context, ref api.FileRef, store *importmg
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
stat, err := f.Stat()
|
stat, err := f.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4,19 +4,16 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-amt-ipld/v2"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
"github.com/ipfs/go-blockservice"
|
"github.com/ipfs/go-blockservice"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
|
||||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
@ -26,6 +23,7 @@ import (
|
|||||||
"github.com/ipfs/go-path"
|
"github.com/ipfs/go-path"
|
||||||
"github.com/ipfs/go-path/resolver"
|
"github.com/ipfs/go-path/resolver"
|
||||||
mh "github.com/multiformats/go-multihash"
|
mh "github.com/multiformats/go-multihash"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@ -265,8 +263,17 @@ func (a *ChainAPI) ChainTipSetWeight(ctx context.Context, tsk types.TipSetKey) (
|
|||||||
return a.Chain.Weight(ctx, ts)
|
return a.Chain.Weight(ctx, ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This allows us to lookup string keys in the actor's adt.Map type.
|
||||||
|
type stringKey string
|
||||||
|
|
||||||
|
func (s stringKey) Key() string {
|
||||||
|
return (string)(s)
|
||||||
|
}
|
||||||
|
|
||||||
func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) {
|
func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) {
|
||||||
return func(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) {
|
return func(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) {
|
||||||
|
store := adt.WrapStore(ctx, cbor.NewCborStore(bs))
|
||||||
|
|
||||||
if strings.HasPrefix(names[0], "@Ha:") {
|
if strings.HasPrefix(names[0], "@Ha:") {
|
||||||
addr, err := address.NewFromString(names[0][4:])
|
addr, err := address.NewFromString(names[0][4:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -290,7 +297,7 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod
|
|||||||
if strings.HasPrefix(names[0], "@Hu:") {
|
if strings.HasPrefix(names[0], "@Hu:") {
|
||||||
i, err := strconv.ParseUint(names[0][4:], 10, 64)
|
i, err := strconv.ParseUint(names[0][4:], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, xerrors.Errorf("parsing int64: %w", err)
|
return nil, nil, xerrors.Errorf("parsing uint64: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ik := adt.UIntKey(i)
|
ik := adt.UIntKey(i)
|
||||||
@ -299,16 +306,20 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod
|
|||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(names[0], "@H:") {
|
if strings.HasPrefix(names[0], "@H:") {
|
||||||
cst := cbor.NewCborStore(bs)
|
h, err := adt.AsMap(store, nd.Cid())
|
||||||
|
|
||||||
h, err := hamt.LoadNode(ctx, cst, nd.Cid(), hamt.UseTreeBitWidth(5))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, xerrors.Errorf("resolving hamt link: %w", err)
|
return nil, nil, xerrors.Errorf("resolving hamt link: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var m interface{}
|
var deferred cbg.Deferred
|
||||||
if err := h.Find(ctx, names[0][3:], &m); err != nil {
|
if found, err := h.Get(stringKey(names[0][3:]), &deferred); err != nil {
|
||||||
return nil, nil, xerrors.Errorf("resolve hamt: %w", err)
|
return nil, nil, xerrors.Errorf("resolve hamt: %w", err)
|
||||||
|
} else if !found {
|
||||||
|
return nil, nil, xerrors.Errorf("resolve hamt: not found")
|
||||||
|
}
|
||||||
|
var m interface{}
|
||||||
|
if err := cbor.DecodeInto(deferred.Raw, &m); err != nil {
|
||||||
|
return nil, nil, xerrors.Errorf("failed to decode cbor object: %w", err)
|
||||||
}
|
}
|
||||||
if c, ok := m.(cid.Cid); ok {
|
if c, ok := m.(cid.Cid); ok {
|
||||||
return &ipld.Link{
|
return &ipld.Link{
|
||||||
@ -337,7 +348,7 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod
|
|||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(names[0], "@A:") {
|
if strings.HasPrefix(names[0], "@A:") {
|
||||||
a, err := amt.LoadAMT(ctx, cbor.NewCborStore(bs), nd.Cid())
|
a, err := adt.AsArray(store, nd.Cid())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, xerrors.Errorf("load amt: %w", err)
|
return nil, nil, xerrors.Errorf("load amt: %w", err)
|
||||||
}
|
}
|
||||||
@ -347,11 +358,17 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod
|
|||||||
return nil, nil, xerrors.Errorf("parsing amt index: %w", err)
|
return nil, nil, xerrors.Errorf("parsing amt index: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var m interface{}
|
var deferred cbg.Deferred
|
||||||
if err := a.Get(ctx, idx, &m); err != nil {
|
if found, err := a.Get(idx, &deferred); err != nil {
|
||||||
return nil, nil, xerrors.Errorf("amt get: %w", err)
|
return nil, nil, xerrors.Errorf("resolve amt: %w", err)
|
||||||
|
} else if !found {
|
||||||
|
return nil, nil, xerrors.Errorf("resolve amt: not found")
|
||||||
}
|
}
|
||||||
fmt.Printf("AG %T %v\n", m, m)
|
var m interface{}
|
||||||
|
if err := cbor.DecodeInto(deferred.Raw, &m); err != nil {
|
||||||
|
return nil, nil, xerrors.Errorf("failed to decode cbor object: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if c, ok := m.(cid.Cid); ok {
|
if c, ok := m.(cid.Cid); ok {
|
||||||
return &ipld.Link{
|
return &ipld.Link{
|
||||||
Name: names[0][3:],
|
Name: names[0][3:],
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -17,6 +18,7 @@ type GasAPI struct {
|
|||||||
fx.In
|
fx.In
|
||||||
Stmgr *stmgr.StateManager
|
Stmgr *stmgr.StateManager
|
||||||
Cs *store.ChainStore
|
Cs *store.ChainStore
|
||||||
|
Mpool *messagepool.MessagePool
|
||||||
}
|
}
|
||||||
|
|
||||||
const MinGasPrice = 1
|
const MinGasPrice = 1
|
||||||
@ -35,19 +37,25 @@ func (a *GasAPI) GasEstimateGasPrice(ctx context.Context, nblocksincl uint64,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *GasAPI) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message,
|
func (a *GasAPI) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message, _ types.TipSetKey) (int64, error) {
|
||||||
tsk types.TipSetKey) (int64, error) {
|
|
||||||
|
|
||||||
msg := *msgIn
|
msg := *msgIn
|
||||||
msg.GasLimit = build.BlockGasLimit
|
msg.GasLimit = build.BlockGasLimit
|
||||||
msg.GasPrice = types.NewInt(1)
|
msg.GasPrice = types.NewInt(1)
|
||||||
|
|
||||||
ts, err := a.Cs.GetTipSetFromKey(tsk)
|
currTs := a.Cs.GetHeaviestTipSet()
|
||||||
|
fromA, err := a.Stmgr.ResolveToKeyAddress(ctx, msgIn.From, currTs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, xerrors.Errorf("could not get tipset: %w", err)
|
return -1, xerrors.Errorf("getting key address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := a.Stmgr.CallWithGas(ctx, &msg, ts)
|
pending, ts := a.Mpool.PendingFor(fromA)
|
||||||
|
priorMsgs := make([]types.ChainMsg, 0, len(pending))
|
||||||
|
for _, m := range pending {
|
||||||
|
priorMsgs = append(priorMsgs, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := a.Stmgr.CallWithGas(ctx, &msg, priorMsgs, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, xerrors.Errorf("CallWithGas failed: %w", err)
|
return -1, xerrors.Errorf("CallWithGas failed: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,12 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-amt-ipld/v2"
|
|
||||||
"github.com/filecoin-project/go-bitfield"
|
"github.com/filecoin-project/go-bitfield"
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
@ -522,30 +520,27 @@ func (a *StateAPI) StateMarketParticipants(ctx context.Context, tsk types.TipSet
|
|||||||
if _, err := a.StateManager.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts); err != nil {
|
if _, err := a.StateManager.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cst := cbor.NewCborStore(a.StateManager.ChainStore().Blockstore())
|
store := a.StateManager.ChainStore().Store(ctx)
|
||||||
escrow, err := hamt.LoadNode(ctx, cst, state.EscrowTable, hamt.UseTreeBitWidth(5)) // todo: adt map
|
escrow, err := adt.AsMap(store, state.EscrowTable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
locked, err := hamt.LoadNode(ctx, cst, state.LockedTable, hamt.UseTreeBitWidth(5))
|
locked, err := adt.AsMap(store, state.LockedTable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = escrow.ForEach(ctx, func(k string, val interface{}) error {
|
var es, lk abi.TokenAmount
|
||||||
cv := val.(*cbg.Deferred)
|
err = escrow.ForEach(&es, func(k string) error {
|
||||||
a, err := address.NewFromBytes([]byte(k))
|
a, err := address.NewFromBytes([]byte(k))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var es abi.TokenAmount
|
if found, err := locked.Get(adt.AddrKey(a), &lk); err != nil {
|
||||||
if err := es.UnmarshalCBOR(bytes.NewReader(cv.Raw)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var lk abi.TokenAmount
|
|
||||||
if err := locked.Find(ctx, k, &es); err != nil {
|
|
||||||
return err
|
return err
|
||||||
|
} else if !found {
|
||||||
|
return fmt.Errorf("locked funds not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
out[a.String()] = api.MarketBalance{
|
out[a.String()] = api.MarketBalance{
|
||||||
@ -572,29 +567,23 @@ func (a *StateAPI) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (m
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
blks := cbor.NewCborStore(a.StateManager.ChainStore().Blockstore())
|
store := a.StateManager.ChainStore().Store(ctx)
|
||||||
da, err := amt.LoadAMT(ctx, blks, state.Proposals)
|
da, err := adt.AsArray(store, state.Proposals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sa, err := amt.LoadAMT(ctx, blks, state.States)
|
sa, err := adt.AsArray(store, state.States)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := da.ForEach(ctx, func(i uint64, v *cbg.Deferred) error {
|
|
||||||
var d market.DealProposal
|
var d market.DealProposal
|
||||||
if err := d.UnmarshalCBOR(bytes.NewReader(v.Raw)); err != nil {
|
if err := da.ForEach(&d, func(i int64) error {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var s market.DealState
|
var s market.DealState
|
||||||
if err := sa.Get(ctx, i, &s); err != nil {
|
if found, err := sa.Get(uint64(i), &s); err != nil {
|
||||||
if _, ok := err.(*amt.ErrNotFound); !ok {
|
|
||||||
return xerrors.Errorf("failed to get state for deal in proposals array: %w", err)
|
return xerrors.Errorf("failed to get state for deal in proposals array: %w", err)
|
||||||
}
|
} else if !found {
|
||||||
|
|
||||||
s.SectorStartEpoch = -1
|
s.SectorStartEpoch = -1
|
||||||
}
|
}
|
||||||
out[strconv.FormatInt(int64(i), 10)] = api.MarketDeal{
|
out[strconv.FormatInt(int64(i), 10)] = api.MarketDeal{
|
||||||
@ -617,47 +606,51 @@ func (a *StateAPI) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *StateAPI) StateChangedActors(ctx context.Context, old cid.Cid, new cid.Cid) (map[string]types.Actor, error) {
|
func (a *StateAPI) StateChangedActors(ctx context.Context, old cid.Cid, new cid.Cid) (map[string]types.Actor, error) {
|
||||||
cst := cbor.NewCborStore(a.Chain.Blockstore())
|
store := adt.WrapStore(ctx, cbor.NewCborStore(a.Chain.Blockstore()))
|
||||||
|
|
||||||
nh, err := hamt.LoadNode(ctx, cst, new, hamt.UseTreeBitWidth(5))
|
nh, err := adt.AsMap(store, new)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
oh, err := hamt.LoadNode(ctx, cst, old, hamt.UseTreeBitWidth(5))
|
oh, err := adt.AsMap(store, old)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
out := map[string]types.Actor{}
|
out := map[string]types.Actor{}
|
||||||
|
|
||||||
err = nh.ForEach(ctx, func(k string, nval interface{}) error {
|
var (
|
||||||
ncval := nval.(*cbg.Deferred)
|
ncval, ocval cbg.Deferred
|
||||||
|
buf = bytes.NewReader(nil)
|
||||||
|
)
|
||||||
|
err = nh.ForEach(&ncval, func(k string) error {
|
||||||
var act types.Actor
|
var act types.Actor
|
||||||
|
|
||||||
var ocval cbg.Deferred
|
|
||||||
|
|
||||||
switch err := oh.Find(ctx, k, &ocval); err {
|
|
||||||
case nil:
|
|
||||||
if bytes.Equal(ocval.Raw, ncval.Raw) {
|
|
||||||
return nil // not changed
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
case hamt.ErrNotFound:
|
|
||||||
if err := act.UnmarshalCBOR(bytes.NewReader(ncval.Raw)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
addr, err := address.NewFromBytes([]byte(k))
|
addr, err := address.NewFromBytes([]byte(k))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("address in state tree was not valid: %w", err)
|
return xerrors.Errorf("address in state tree was not valid: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
out[addr.String()] = act
|
found, err := oh.Get(adt.AddrKey(addr), &ocval)
|
||||||
default:
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if found && bytes.Equal(ocval.Raw, ncval.Raw) {
|
||||||
|
return nil // not changed
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Reset(ncval.Raw)
|
||||||
|
err = act.UnmarshalCBOR(buf)
|
||||||
|
buf.Reset(nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out[addr.String()] = act
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1000,7 +993,7 @@ func (a *StateAPI) StateMinerInitialPledgeCollateral(ctx context.Context, maddr
|
|||||||
}
|
}
|
||||||
|
|
||||||
sectorWeight := miner.QAPowerForWeight(ssize, duration, dealWeights.DealWeight, dealWeights.VerifiedDealWeight)
|
sectorWeight := miner.QAPowerForWeight(ssize, duration, dealWeights.DealWeight, dealWeights.VerifiedDealWeight)
|
||||||
initialPledge := miner.InitialPledgeForPower(sectorWeight, powerState.TotalQualityAdjPower, reward.BaselinePowerAt(ts.Height()), powerState.TotalPledgeCollateral, rewardState.ThisEpochReward, circSupply)
|
initialPledge := miner.InitialPledgeForPower(sectorWeight, powerState.TotalQualityAdjPower, reward.SlowConvenientBaselineForEpoch(ts.Height()), powerState.TotalPledgeCollateral, rewardState.ThisEpochReward, circSupply)
|
||||||
|
|
||||||
return types.BigDiv(types.BigMul(initialPledge, initialPledgeNum), initialPledgeDen), nil
|
return types.BigDiv(types.BigMul(initialPledge, initialPledgeNum), initialPledgeDen), nil
|
||||||
}
|
}
|
||||||
@ -1039,24 +1032,23 @@ func (a *StateAPI) StateVerifiedClientStatus(ctx context.Context, addr address.A
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cst := cbor.NewCborStore(a.StateManager.ChainStore().Blockstore())
|
store := a.StateManager.ChainStore().Store(ctx)
|
||||||
|
|
||||||
var st verifreg.State
|
var st verifreg.State
|
||||||
if err := cst.Get(ctx, act.Head, &st); err != nil {
|
if err := store.Get(ctx, act.Head, &st); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
vh, err := hamt.LoadNode(ctx, cst, st.VerifiedClients, hamt.UseTreeBitWidth(5))
|
vh, err := adt.AsMap(store, st.VerifiedClients)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var dcap verifreg.DataCap
|
var dcap verifreg.DataCap
|
||||||
if err := vh.Find(ctx, string(addr.Bytes()), &dcap); err != nil {
|
if found, err := vh.Get(adt.AddrKey(addr), &dcap); err != nil {
|
||||||
if err == hamt.ErrNotFound {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return nil, err
|
return nil, err
|
||||||
|
} else if !found {
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &dcap, nil
|
return &dcap, nil
|
||||||
|
@ -2,6 +2,8 @@ package full
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
|
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/lib/sigs"
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
|
|
||||||
@ -37,10 +39,16 @@ func (a *WalletAPI) WalletList(ctx context.Context) ([]address.Address, error) {
|
|||||||
|
|
||||||
func (a *WalletAPI) WalletBalance(ctx context.Context, addr address.Address) (types.BigInt, error) {
|
func (a *WalletAPI) WalletBalance(ctx context.Context, addr address.Address) (types.BigInt, error) {
|
||||||
var bal types.BigInt
|
var bal types.BigInt
|
||||||
return bal, a.StateManager.WithParentStateTsk(types.EmptyTSK, a.StateManager.WithActor(addr, func(act *types.Actor) error {
|
err := a.StateManager.WithParentStateTsk(types.EmptyTSK, a.StateManager.WithActor(addr, func(act *types.Actor) error {
|
||||||
bal = act.Balance
|
bal = act.Balance
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
if xerrors.Is(err, init_.ErrAddressNotFound) {
|
||||||
|
return big.Zero(), nil
|
||||||
|
} else {
|
||||||
|
return bal, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *WalletAPI) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) {
|
func (a *WalletAPI) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) {
|
||||||
|
@ -107,36 +107,43 @@ func (a *PaychAPI) PaychStatus(ctx context.Context, pch address.Address) (*api.P
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *PaychAPI) PaychClose(ctx context.Context, addr address.Address) (cid.Cid, error) {
|
func (a *PaychAPI) PaychSettle(ctx context.Context, addr address.Address) (cid.Cid, error) {
|
||||||
panic("TODO Settle logic")
|
|
||||||
|
|
||||||
ci, err := a.PaychMgr.GetChannelInfo(addr)
|
ci, err := a.PaychMgr.GetChannelInfo(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce, err := a.MpoolGetNonce(ctx, ci.Control)
|
|
||||||
if err != nil {
|
|
||||||
return cid.Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
To: addr,
|
To: addr,
|
||||||
From: ci.Control,
|
From: ci.Control,
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(0),
|
||||||
Method: builtin.MethodsPaych.Settle,
|
Method: builtin.MethodsPaych.Settle,
|
||||||
Nonce: nonce,
|
|
||||||
|
|
||||||
GasLimit: 0,
|
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
}
|
}
|
||||||
|
smgs, err := a.MpoolPushMessage(ctx, msg)
|
||||||
|
|
||||||
smsg, err := a.WalletSignMessage(ctx, ci.Control, msg)
|
if err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
return smgs.Cid(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *PaychAPI) PaychCollect(ctx context.Context, addr address.Address) (cid.Cid, error) {
|
||||||
|
|
||||||
|
ci, err := a.PaychMgr.GetChannelInfo(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := a.MpoolPush(ctx, smsg); err != nil {
|
msg := &types.Message{
|
||||||
|
To: addr,
|
||||||
|
From: ci.Control,
|
||||||
|
Value: types.NewInt(0),
|
||||||
|
Method: builtin.MethodsPaych.Collect,
|
||||||
|
}
|
||||||
|
|
||||||
|
smsg, err := a.MpoolPushMessage(ctx, msg)
|
||||||
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,11 +226,6 @@ func (a *PaychAPI) PaychVoucherSubmit(ctx context.Context, ch address.Address, s
|
|||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce, err := a.MpoolGetNonce(ctx, ci.Control)
|
|
||||||
if err != nil {
|
|
||||||
return cid.Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if sv.Extra != nil || len(sv.SecretPreimage) > 0 {
|
if sv.Extra != nil || len(sv.SecretPreimage) > 0 {
|
||||||
return cid.Undef, fmt.Errorf("cant handle more advanced payment channel stuff yet")
|
return cid.Undef, fmt.Errorf("cant handle more advanced payment channel stuff yet")
|
||||||
}
|
}
|
||||||
@ -239,22 +241,14 @@ func (a *PaychAPI) PaychVoucherSubmit(ctx context.Context, ch address.Address, s
|
|||||||
From: ci.Control,
|
From: ci.Control,
|
||||||
To: ch,
|
To: ch,
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(0),
|
||||||
Nonce: nonce,
|
|
||||||
Method: builtin.MethodsPaych.UpdateChannelState,
|
Method: builtin.MethodsPaych.UpdateChannelState,
|
||||||
Params: enc,
|
Params: enc,
|
||||||
GasLimit: 0,
|
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
smsg, err := a.WalletSignMessage(ctx, ci.Control, msg)
|
smsg, err := a.MpoolPushMessage(ctx, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := a.MpoolPush(ctx, smsg); err != nil {
|
|
||||||
return cid.Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: should we wait for it...?
|
|
||||||
return smsg.Cid(), nil
|
return smsg.Cid(), nil
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,10 @@ func (sm *StorageMinerAPI) WorkerStats(context.Context) (map[uint64]storiface.Wo
|
|||||||
return sm.StorageMgr.WorkerStats(), nil
|
return sm.StorageMgr.WorkerStats(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sm *StorageMinerAPI) WorkerJobs(ctx context.Context) (map[uint64][]storiface.WorkerJob, error) {
|
||||||
|
return sm.StorageMgr.WorkerJobs(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error) {
|
func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error) {
|
||||||
return sm.Miner.Address(), nil
|
return sm.Miner.Address(), nil
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package modules
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
|
|
||||||
"github.com/ipfs/go-bitswap"
|
"github.com/ipfs/go-bitswap"
|
||||||
"github.com/ipfs/go-bitswap/network"
|
"github.com/ipfs/go-bitswap/network"
|
||||||
@ -17,7 +18,6 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain"
|
"github.com/filecoin-project/lotus/chain"
|
||||||
"github.com/filecoin-project/lotus/chain/beacon"
|
"github.com/filecoin-project/lotus/chain/beacon"
|
||||||
@ -83,7 +83,7 @@ func ChainBlockservice(bs dtypes.ChainBlockstore, rem dtypes.ChainExchange) dtyp
|
|||||||
return blockservice.New(bs, rem)
|
return blockservice.New(bs, rem)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChainStore(lc fx.Lifecycle, bs dtypes.ChainBlockstore, ds dtypes.MetadataDS, syscalls runtime.Syscalls) *store.ChainStore {
|
func ChainStore(lc fx.Lifecycle, bs dtypes.ChainBlockstore, ds dtypes.MetadataDS, syscalls vm.SyscallBuilder) *store.ChainStore {
|
||||||
chain := store.NewChainStore(bs, ds, syscalls)
|
chain := store.NewChainStore(bs, ds, syscalls)
|
||||||
|
|
||||||
if err := chain.Load(); err != nil {
|
if err := chain.Load(); err != nil {
|
||||||
|
@ -92,8 +92,8 @@ func BuiltinBootstrap() (dtypes.BootstrapPeers, error) {
|
|||||||
return build.BuiltinBootstrap()
|
return build.BuiltinBootstrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
func DrandBootstrap() (dtypes.DrandBootstrap, error) {
|
func DrandBootstrap(d dtypes.DrandConfig) (dtypes.DrandBootstrap, error) {
|
||||||
return build.DrandBootstrap()
|
return addrutil.ParseAddresses(context.TODO(), d.Relays)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupJournal(lr repo.LockedRepo) error {
|
func SetupJournal(lr repo.LockedRepo) error {
|
||||||
|
@ -2,5 +2,6 @@ package dtypes
|
|||||||
|
|
||||||
type DrandConfig struct {
|
type DrandConfig struct {
|
||||||
Servers []string
|
Servers []string
|
||||||
|
Relays []string
|
||||||
ChainInfoJSON string
|
ChainInfoJSON string
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,9 @@ func RunHello(mctx helpers.MetricsCtx, lc fx.Lifecycle, h host.Host, svc *hello.
|
|||||||
pic := evt.(event.EvtPeerIdentificationCompleted)
|
pic := evt.(event.EvtPeerIdentificationCompleted)
|
||||||
go func() {
|
go func() {
|
||||||
if err := svc.SayHello(helpers.LifecycleCtx(mctx, lc), pic.Peer); err != nil {
|
if err := svc.SayHello(helpers.LifecycleCtx(mctx, lc), pic.Peer); err != nil {
|
||||||
log.Warnw("failed to say hello", "error", err, "peer", pic.Peer)
|
protos, _ := h.Peerstore().GetProtocols(pic.Peer)
|
||||||
|
agent, _ := h.Peerstore().Get(pic.Peer, "AgentVersion")
|
||||||
|
log.Warnw("failed to say hello", "error", err, "peer", pic.Peer, "supported", protos, "agent", agent)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -114,7 +116,7 @@ type RandomBeaconParams struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BuiltinDrandConfig() dtypes.DrandConfig {
|
func BuiltinDrandConfig() dtypes.DrandConfig {
|
||||||
return build.DrandConfig
|
return build.DrandConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
func RandomBeacon(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.RandomBeacon, error) {
|
func RandomBeacon(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.RandomBeacon, error) {
|
||||||
|
@ -17,12 +17,11 @@ import (
|
|||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/gen"
|
"github.com/filecoin-project/lotus/chain/gen"
|
||||||
genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis"
|
genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
"github.com/filecoin-project/lotus/genesis"
|
"github.com/filecoin-project/lotus/genesis"
|
||||||
"github.com/filecoin-project/lotus/node/modules"
|
"github.com/filecoin-project/lotus/node/modules"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
@ -30,8 +29,8 @@ import (
|
|||||||
|
|
||||||
var glog = logging.Logger("genesis")
|
var glog = logging.Logger("genesis")
|
||||||
|
|
||||||
func MakeGenesisMem(out io.Writer, template genesis.Template) func(bs dtypes.ChainBlockstore, syscalls runtime.Syscalls) modules.Genesis {
|
func MakeGenesisMem(out io.Writer, template genesis.Template) func(bs dtypes.ChainBlockstore, syscalls vm.SyscallBuilder) modules.Genesis {
|
||||||
return func(bs dtypes.ChainBlockstore, syscalls runtime.Syscalls) modules.Genesis {
|
return func(bs dtypes.ChainBlockstore, syscalls vm.SyscallBuilder) modules.Genesis {
|
||||||
return func() (*types.BlockHeader, error) {
|
return func() (*types.BlockHeader, error) {
|
||||||
glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network")
|
glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network")
|
||||||
b, err := genesis2.MakeGenesisBlock(context.TODO(), bs, syscalls, template)
|
b, err := genesis2.MakeGenesisBlock(context.TODO(), bs, syscalls, template)
|
||||||
@ -51,8 +50,8 @@ func MakeGenesisMem(out io.Writer, template genesis.Template) func(bs dtypes.Cha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeGenesis(outFile, genesisTemplate string) func(bs dtypes.ChainBlockstore, syscalls runtime.Syscalls) modules.Genesis {
|
func MakeGenesis(outFile, genesisTemplate string) func(bs dtypes.ChainBlockstore, syscalls vm.SyscallBuilder) modules.Genesis {
|
||||||
return func(bs dtypes.ChainBlockstore, syscalls runtime.Syscalls) modules.Genesis {
|
return func(bs dtypes.ChainBlockstore, syscalls vm.SyscallBuilder) modules.Genesis {
|
||||||
return func() (*types.BlockHeader, error) {
|
return func() (*types.BlockHeader, error) {
|
||||||
glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network")
|
glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network")
|
||||||
genesisTemplate, err := homedir.Expand(genesisTemplate)
|
genesisTemplate, err := homedir.Expand(genesisTemplate)
|
||||||
|
@ -382,8 +382,12 @@ func mockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for i, def := range storage {
|
for i, def := range storage {
|
||||||
// TODO: support non-bootstrap miners
|
// TODO: support non-bootstrap miners
|
||||||
|
|
||||||
|
minerID := abi.ActorID(genesis2.MinerStart + uint64(i))
|
||||||
|
|
||||||
if def.Full != 0 {
|
if def.Full != 0 {
|
||||||
t.Fatal("storage nodes only supported on the first full node")
|
t.Fatal("storage nodes only supported on the first full node")
|
||||||
}
|
}
|
||||||
@ -396,9 +400,17 @@ func mockSbBuilder(t *testing.T, nFull int, storage []test.StorageMiner) ([]test
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sectors := make([]abi.SectorID, len(genms[i].Sectors))
|
||||||
|
for i, sector := range genms[i].Sectors {
|
||||||
|
sectors[i] = abi.SectorID{
|
||||||
|
Miner: minerID,
|
||||||
|
Number: sector.SectorID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
storers[i] = testStorageNode(ctx, t, genms[i].Worker, maddrs[i], pidKeys[i], f, mn, node.Options(
|
storers[i] = testStorageNode(ctx, t, genms[i].Worker, maddrs[i], pidKeys[i], f, mn, node.Options(
|
||||||
node.Override(new(sectorstorage.SectorManager), func() (sectorstorage.SectorManager, error) {
|
node.Override(new(sectorstorage.SectorManager), func() (sectorstorage.SectorManager, error) {
|
||||||
return mock.NewMockSectorMgr(build.DefaultSectorSize()), nil
|
return mock.NewMockSectorMgr(build.DefaultSectorSize(), sectors), nil
|
||||||
}),
|
}),
|
||||||
node.Override(new(ffiwrapper.Verifier), mock.MockVerifier),
|
node.Override(new(ffiwrapper.Verifier), mock.MockVerifier),
|
||||||
node.Unset(new(*sectorstorage.Manager)),
|
node.Unset(new(*sectorstorage.Manager)),
|
||||||
@ -536,7 +548,7 @@ func TestWindowedPost(t *testing.T) {
|
|||||||
logging.SetLogLevel("sub", "ERROR")
|
logging.SetLogLevel("sub", "ERROR")
|
||||||
logging.SetLogLevel("storageminer", "ERROR")
|
logging.SetLogLevel("storageminer", "ERROR")
|
||||||
|
|
||||||
test.TestWindowPost(t, mockSbBuilder, 5*time.Millisecond, 10)
|
test.TestWindowPost(t, mockSbBuilder, 2*time.Millisecond, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCCUpgrade(t *testing.T) {
|
func TestCCUpgrade(t *testing.T) {
|
||||||
@ -548,3 +560,14 @@ func TestCCUpgrade(t *testing.T) {
|
|||||||
|
|
||||||
test.TestCCUpgrade(t, mockSbBuilder, 5*time.Millisecond)
|
test.TestCCUpgrade(t, mockSbBuilder, 5*time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPaymentChannels(t *testing.T) {
|
||||||
|
logging.SetLogLevel("miner", "ERROR")
|
||||||
|
logging.SetLogLevel("chainstore", "ERROR")
|
||||||
|
logging.SetLogLevel("chain", "ERROR")
|
||||||
|
logging.SetLogLevel("sub", "ERROR")
|
||||||
|
logging.SetLogLevel("pubsub", "ERROR")
|
||||||
|
logging.SetLogLevel("storageminer", "ERROR")
|
||||||
|
|
||||||
|
test.TestPaymentChannels(t, mockSbBuilder, 5*time.Millisecond)
|
||||||
|
}
|
||||||
|
@ -390,6 +390,7 @@ func (fsr *fsLockedRepo) List() ([]string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("opening dir to list keystore: %w", err)
|
return nil, xerrors.Errorf("opening dir to list keystore: %w", err)
|
||||||
}
|
}
|
||||||
|
defer dir.Close() //nolint:errcheck
|
||||||
files, err := dir.Readdir(-1)
|
files, err := dir.Readdir(-1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("reading keystore dir: %w", err)
|
return nil, xerrors.Errorf("reading keystore dir: %w", err)
|
||||||
|
@ -185,7 +185,7 @@ func (pm *Manager) checkVoucherValid(ctx context.Context, ch address.Address, sv
|
|||||||
|
|
||||||
// CheckVoucherSpendable checks if the given voucher is currently spendable
|
// CheckVoucherSpendable checks if the given voucher is currently spendable
|
||||||
func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (bool, error) {
|
func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (bool, error) {
|
||||||
owner, err := pm.getPaychOwner(ctx, ch)
|
recipient, err := pm.getPaychRecipient(ctx, ch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -222,7 +222,7 @@ func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret, err := pm.sm.Call(ctx, &types.Message{
|
ret, err := pm.sm.Call(ctx, &types.Message{
|
||||||
From: owner,
|
From: recipient,
|
||||||
To: ch,
|
To: ch,
|
||||||
Method: builtin.MethodsPaych.UpdateChannelState,
|
Method: builtin.MethodsPaych.UpdateChannelState,
|
||||||
Params: enc,
|
Params: enc,
|
||||||
@ -238,13 +238,13 @@ func (pm *Manager) CheckVoucherSpendable(ctx context.Context, ch address.Address
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *Manager) getPaychOwner(ctx context.Context, ch address.Address) (address.Address, error) {
|
func (pm *Manager) getPaychRecipient(ctx context.Context, ch address.Address) (address.Address, error) {
|
||||||
var state paych.State
|
var state paych.State
|
||||||
if _, err := pm.sm.LoadActorState(ctx, ch, &state, nil); err != nil {
|
if _, err := pm.sm.LoadActorState(ctx, ch, &state, nil); err != nil {
|
||||||
return address.Address{}, err
|
return address.Address{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return state.From, nil
|
return state.To, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *Manager) AddVoucher(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) {
|
func (pm *Manager) AddVoucher(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, proof []byte, minDelta types.BigInt) (types.BigInt, error) {
|
||||||
|
141
paychmgr/settler/settler.go
Normal file
141
paychmgr/settler/settler.go
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
package settler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"go.uber.org/fx"
|
||||||
|
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
logging "github.com/ipfs/go-log/v2"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/events"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/node/impl/full"
|
||||||
|
payapi "github.com/filecoin-project/lotus/node/impl/paych"
|
||||||
|
)
|
||||||
|
|
||||||
|
var log = logging.Logger("payment-channel-settler")
|
||||||
|
|
||||||
|
// API are the dependencies need to run the payment channel settler
|
||||||
|
type API struct {
|
||||||
|
fx.In
|
||||||
|
|
||||||
|
full.ChainAPI
|
||||||
|
full.StateAPI
|
||||||
|
payapi.PaychAPI
|
||||||
|
}
|
||||||
|
|
||||||
|
type settlerAPI interface {
|
||||||
|
PaychList(context.Context) ([]address.Address, error)
|
||||||
|
PaychStatus(context.Context, address.Address) (*api.PaychStatus, error)
|
||||||
|
PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error)
|
||||||
|
PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error)
|
||||||
|
PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher) (cid.Cid, error)
|
||||||
|
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type paymentChannelSettler struct {
|
||||||
|
ctx context.Context
|
||||||
|
api settlerAPI
|
||||||
|
}
|
||||||
|
|
||||||
|
// SettlePaymentChannels checks the chain for events related to payment channels settling and
|
||||||
|
// submits any vouchers for inbound channels tracked for this node
|
||||||
|
func SettlePaymentChannels(lc fx.Lifecycle, api API) error {
|
||||||
|
lc.Append(fx.Hook{
|
||||||
|
OnStart: func(ctx context.Context) error {
|
||||||
|
pcs := newPaymentChannelSettler(ctx, &api)
|
||||||
|
ev := events.NewEvents(ctx, &api)
|
||||||
|
return ev.Called(pcs.check, pcs.messageHandler, pcs.revertHandler, int(build.MessageConfidence+1), events.NoTimeout, pcs.matcher)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPaymentChannelSettler(ctx context.Context, api settlerAPI) *paymentChannelSettler {
|
||||||
|
return &paymentChannelSettler{
|
||||||
|
ctx: ctx,
|
||||||
|
api: api,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pcs *paymentChannelSettler) check(ts *types.TipSet) (done bool, more bool, err error) {
|
||||||
|
return false, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pcs *paymentChannelSettler) messageHandler(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error) {
|
||||||
|
vouchers, err := pcs.api.PaychVoucherList(pcs.ctx, msg.To)
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bestByLane := make(map[uint64]*paych.SignedVoucher)
|
||||||
|
for _, voucher := range vouchers {
|
||||||
|
spendable, err := pcs.api.PaychVoucherCheckSpendable(pcs.ctx, msg.To, voucher, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
if spendable {
|
||||||
|
if bestByLane[voucher.Lane] == nil || voucher.Amount.GreaterThan(bestByLane[voucher.Lane].Amount) {
|
||||||
|
bestByLane[voucher.Lane] = voucher
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(len(bestByLane))
|
||||||
|
for _, voucher := range bestByLane {
|
||||||
|
submitMessageCID, err := pcs.api.PaychVoucherSubmit(pcs.ctx, msg.To, voucher)
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
go func(voucher *paych.SignedVoucher, submitMessageCID cid.Cid) {
|
||||||
|
defer wg.Done()
|
||||||
|
msgLookup, err := pcs.api.StateWaitMsg(pcs.ctx, submitMessageCID, build.MessageConfidence)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("submitting voucher: %s", err.Error())
|
||||||
|
}
|
||||||
|
if msgLookup.Receipt.ExitCode != 0 {
|
||||||
|
log.Errorf("failed submitting voucher: %+v", voucher)
|
||||||
|
}
|
||||||
|
}(voucher, submitMessageCID)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pcs *paymentChannelSettler) revertHandler(ctx context.Context, ts *types.TipSet) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pcs *paymentChannelSettler) matcher(msg *types.Message) (matchOnce bool, matched bool, err error) {
|
||||||
|
// Check if this is a settle payment channel message
|
||||||
|
if msg.Method != builtin.MethodsPaych.Settle {
|
||||||
|
return false, false, nil
|
||||||
|
}
|
||||||
|
// Check if this payment channel is of concern to this node (i.e. tracked in payment channel store),
|
||||||
|
// and its inbound (i.e. we're getting vouchers that we may need to redeem)
|
||||||
|
trackedAddresses, err := pcs.api.PaychList(pcs.ctx)
|
||||||
|
if err != nil {
|
||||||
|
return false, false, err
|
||||||
|
}
|
||||||
|
for _, addr := range trackedAddresses {
|
||||||
|
if msg.To == addr {
|
||||||
|
status, err := pcs.api.PaychStatus(pcs.ctx, addr)
|
||||||
|
if err != nil {
|
||||||
|
return false, false, err
|
||||||
|
}
|
||||||
|
if status.Direction == api.PCHInbound {
|
||||||
|
return false, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, false, nil
|
||||||
|
}
|
@ -331,7 +331,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo
|
|||||||
|
|
||||||
params := &miner.SubmitWindowedPoStParams{
|
params := &miner.SubmitWindowedPoStParams{
|
||||||
Deadline: di.Index,
|
Deadline: di.Index,
|
||||||
Partitions: make([]miner.PoStPartition, len(partitions)),
|
Partitions: make([]miner.PoStPartition, 0, len(partitions)),
|
||||||
Proofs: nil,
|
Proofs: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,20 +373,19 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo
|
|||||||
return nil, xerrors.Errorf("getting sorted sector info: %w", err)
|
return nil, xerrors.Errorf("getting sorted sector info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(ssi) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
sinfos = append(sinfos, ssi...)
|
sinfos = append(sinfos, ssi...)
|
||||||
for _, si := range ssi {
|
for _, si := range ssi {
|
||||||
sidToPart[si.SectorNumber] = uint64(partIdx)
|
sidToPart[si.SectorNumber] = uint64(partIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ssi) == 0 {
|
params.Partitions = append(params.Partitions, miner.PoStPartition{
|
||||||
log.Warn("attempted to run windowPost without any sectors...")
|
|
||||||
return nil, xerrors.Errorf("no sectors to run windowPost on")
|
|
||||||
}
|
|
||||||
|
|
||||||
params.Partitions[partIdx] = miner.PoStPartition{
|
|
||||||
Index: uint64(partIdx),
|
Index: uint64(partIdx),
|
||||||
Skipped: skipped,
|
Skipped: skipped,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(sinfos) == 0 {
|
if len(sinfos) == 0 {
|
||||||
@ -463,9 +462,7 @@ func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.Submi
|
|||||||
Method: builtin.MethodsMiner.SubmitWindowedPoSt,
|
Method: builtin.MethodsMiner.SubmitWindowedPoSt,
|
||||||
Params: enc,
|
Params: enc,
|
||||||
Value: types.NewInt(1000), // currently hard-coded late fee in actor, returned if not late
|
Value: types.NewInt(1000), // currently hard-coded late fee in actor, returned if not late
|
||||||
// TODO: Gaslimit needs to be calculated accurately. Before that, use the largest Gaslimit
|
GasPrice: types.NewInt(3),
|
||||||
GasLimit: build.BlockGasLimit,
|
|
||||||
GasPrice: types.NewInt(1),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: consider maybe caring about the output
|
// TODO: consider maybe caring about the output
|
||||||
|
Loading…
Reference in New Issue
Block a user