Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
232cc320bd | ||
|
|
e7edc46daf | ||
|
|
6813ab4e65 | ||
|
|
fd714cbceb | ||
|
|
db6bd890d9 | ||
|
|
7a46c5ff31 | ||
|
|
98a9042c07 | ||
|
|
4170e18dea | ||
|
|
230ef2484d | ||
|
|
beba92aed4 | ||
|
|
cbb693e99e | ||
|
|
774e068436 | ||
|
|
86ba21029d | ||
|
|
316ac61875 | ||
|
|
d5d264d13b | ||
|
|
c71e1adc93 | ||
|
|
564d0ae974 | ||
|
|
9a48ec194e | ||
|
|
bb0a7f91cc | ||
|
|
73e54352cd | ||
|
|
64fa6fd9e5 | ||
|
|
2d3f92aeed | ||
|
|
9e9856bb45 | ||
|
|
890e6280df | ||
|
|
da7e4b3a09 | ||
|
|
747a7de168 | ||
|
|
bfa47b3663 | ||
|
|
0e7f14159a | ||
|
|
b755ce9528 | ||
|
|
f3cae55bd4 | ||
|
|
f64bd55bc6 | ||
|
|
4c8bb846ea | ||
|
|
bd14fb90fc | ||
|
|
9e5bce90f4 | ||
|
|
72c7d4c886 | ||
|
|
558b637b07 | ||
|
|
767341b279 | ||
|
|
c73916b4e7 | ||
|
|
0361ca1c39 | ||
|
|
cd4cd22928 | ||
|
|
e1a0cf6ca5 | ||
|
|
73bb9d5afb | ||
|
|
183df4c135 | ||
|
|
f2b238f50a | ||
|
|
09194aa613 | ||
|
|
e58327d4ed | ||
|
|
8414aa6e4b | ||
|
|
7d1d690eb7 | ||
|
|
47ad7ccb5f | ||
|
|
679c4183e7 | ||
|
|
8807c75c51 | ||
|
|
be9d8f7ce3 | ||
|
|
a7a43a1124 | ||
|
|
8b2862a1b8 | ||
|
|
1d4b5c201e | ||
|
|
f983145897 | ||
|
|
d369f542c5 | ||
|
|
6c8a44b056 | ||
|
|
ef18f93609 | ||
|
|
540afb1573 | ||
|
|
2d7a924275 | ||
|
|
702799290f | ||
|
|
f7d3d371f7 | ||
|
|
311d20eeb2 | ||
|
|
afa913f2ed | ||
|
|
f0554676dd | ||
|
|
3337b9a98f | ||
|
|
22fdb9594d | ||
|
|
93a0052219 | ||
|
|
5c852e26c2 | ||
|
|
7d2118cd97 | ||
|
|
5e3c178b9e | ||
|
|
35aa78dad9 | ||
|
|
7747f5a3fa | ||
|
|
a2f1e76fea | ||
|
|
cf515bc5ca | ||
|
|
97cbfa11b7 | ||
|
|
f2b76d8b3b | ||
|
|
e2a6d02570 | ||
|
|
1d78ffc04d | ||
|
|
42b9d42a8f | ||
|
|
7dbbe84086 | ||
|
|
e9b85f5acb | ||
|
|
cb3b0ab2bb | ||
|
|
de772bf1f9 | ||
|
|
91a9bae308 | ||
|
|
fe7c152c97 | ||
|
|
333c7ce1c9 | ||
|
|
ef2303bc5d | ||
|
|
6d2b4ab775 | ||
|
|
b3dedfedc0 | ||
|
|
2a3743ff84 | ||
|
|
a5afd83c7b | ||
|
|
e8d1bab914 | ||
|
|
de654de911 | ||
|
|
37c0f75499 | ||
|
|
5c5c1c80cf | ||
|
|
e91ee9f62a | ||
|
|
213b4eace8 | ||
|
|
f695c0c164 | ||
|
|
194b6eb9d8 | ||
|
|
2aba16e2c9 | ||
|
|
0b09082450 | ||
|
|
29aa972f18 | ||
|
|
06b814b627 | ||
|
|
8c0994e290 | ||
|
|
b1d251e950 | ||
|
|
63cdbef219 | ||
|
|
8a8f0ab3ec | ||
|
|
1ef0359731 | ||
|
|
38863d3025 | ||
|
|
44f4372ca3 | ||
|
|
46d3769a44 | ||
|
|
65b7d71bdf | ||
|
|
1d67e38f78 | ||
|
|
3697a1af4d | ||
|
|
26ff596983 | ||
|
|
b33db9c1ab | ||
|
|
867469e9b3 | ||
|
|
a4fc5c6975 | ||
|
|
e87ccbfa22 | ||
|
|
17c15a74a2 | ||
|
|
8bbdf2e7cb | ||
|
|
b66058e417 | ||
|
|
4fce0181ab | ||
|
|
ba9678bd61 | ||
|
|
74e577610a | ||
|
|
37ec1a978e | ||
|
|
27fa9969f3 | ||
|
|
4045ffea3c | ||
|
|
e9e067eebf | ||
|
|
93176c91f4 | ||
|
|
7ee5973400 | ||
|
|
043e62ab63 | ||
|
|
f91f665f3f | ||
|
|
f985f42e93 | ||
|
|
c77f5f6252 | ||
|
|
878ffafb51 | ||
|
|
453e826a0f | ||
|
|
55b1456d45 | ||
|
|
88c04ce959 | ||
|
|
5ead23a8d4 | ||
|
|
d0ccb54aba | ||
|
|
aaad01105e | ||
|
|
eb3ca82fa0 |
@@ -225,12 +225,17 @@ jobs:
|
||||
cd extern/test-vectors
|
||||
git fetch
|
||||
git checkout origin/<< parameters.vectors-branch >>
|
||||
- run:
|
||||
name: go get vectors branch
|
||||
command: go get github.com/filecoin-project/test-vectors@<< parameters.vectors-branch >>
|
||||
- go/install-gotestsum:
|
||||
gobin: $HOME/.local/bin
|
||||
version: 0.5.2
|
||||
- run:
|
||||
name: install statediff globally
|
||||
command: |
|
||||
## statediff is optional; we succeed even if compilation fails.
|
||||
mkdir -p /tmp/statediff
|
||||
git clone https://github.com/filecoin-project/statediff.git /tmp/statediff
|
||||
cd /tmp/statediff
|
||||
go install ./cmd/statediff || exit 0
|
||||
- run:
|
||||
name: go test
|
||||
environment:
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
## filecoin-project/lotus CODEOWNERS
|
||||
## Refer to https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners.
|
||||
##
|
||||
## These users or groups will be automatically assigned as reviewers every time
|
||||
## a PR is submitted that modifies code in the specified locations.
|
||||
##
|
||||
## The Lotus repo configuration requires that at least ONE codeowner approves
|
||||
## the PR before merging.
|
||||
|
||||
### Global owners.
|
||||
* @magik6k @whyrusleeping @Kubuxu
|
||||
|
||||
### Conformance testing.
|
||||
conformance/ @raulk
|
||||
extern/test-vectors @raulk
|
||||
+102
@@ -1,5 +1,107 @@
|
||||
# Lotus changelog
|
||||
|
||||
# 0.7.0 / 2020-09-10
|
||||
|
||||
This consensus-breaking release of Lotus is designed to test a network upgrade on the space race testnet. The changes that break consensus are:
|
||||
|
||||
- Upgrading the Drand network used from the test Drand network to the League of Entropy main drand network. This is the same Drand network that will be used in the Filecoin mainnet.
|
||||
- Upgrading to specs-actors v0.9.8, which adds a new method to the Multisig actor.
|
||||
|
||||
## Changes
|
||||
|
||||
#### Core Lotus
|
||||
|
||||
- Fix IsAncestorOf (https://github.com/filecoin-project/lotus/pull/3717)
|
||||
- Update to specs-actors v0.9.8 (https://github.com/filecoin-project/lotus/pull/3725)
|
||||
- Increase chain throughput by 20% (https://github.com/filecoin-project/lotus/pull/3732)
|
||||
- Updare to go-libp2p-pubsub `master` (https://github.com/filecoin-project/lotus/pull/3735)
|
||||
- Drand upgrade (https://github.com/filecoin-project/lotus/pull/3670)
|
||||
- Multisig API additions (https://github.com/filecoin-project/lotus/pull/3590)
|
||||
|
||||
#### Storage Miner
|
||||
|
||||
- Increase the number of times precommit2 is attempted before moving back to precommit1 (https://github.com/filecoin-project/lotus/pull/3720)
|
||||
|
||||
#### Message pool
|
||||
|
||||
- Relax mpool add strictness checks for local pushes (https://github.com/filecoin-project/lotus/pull/3724)
|
||||
|
||||
|
||||
#### Maintenance
|
||||
|
||||
- Fix devnets (https://github.com/filecoin-project/lotus/pull/3712)
|
||||
- Fix(chainwatch): compare prev miner with cur miner (https://github.com/filecoin-project/lotus/pull/3715)
|
||||
- CI: fix statediff build; make optional (https://github.com/filecoin-project/lotus/pull/3729)
|
||||
- Feat: Chaos abort (https://github.com/filecoin-project/lotus/pull/3733)
|
||||
|
||||
## Contributors
|
||||
|
||||
The following contributors had commits go into this release.
|
||||
We are grateful for every contribution!
|
||||
|
||||
| Contributor | Commits | Lines ± |
|
||||
|--------------------|---------|---------------|
|
||||
| arajasek | 28 | +1144/-239 |
|
||||
| Kubuxu | 19 | +452/-261 |
|
||||
| whyrusleeping | 13 | +456/-87 |
|
||||
| vyzo | 11 | +318/-20 |
|
||||
| raulk | 10 | +1289/-350 |
|
||||
| magik6k | 6 | +188/-55 |
|
||||
| dirkmc | 3 | +31/-8 |
|
||||
| alanshaw | 3 | +176/-37 |
|
||||
| Stebalien | 2 | +9/-12 |
|
||||
| lanzafame | 1 | +1/-1 |
|
||||
| frrist | 1 | +1/-1 |
|
||||
| mishmosh | 1 | +1/-1 |
|
||||
| nonsense | 1 | +1/-0 |
|
||||
|
||||
# 0.6.2 / 2020-09-09
|
||||
|
||||
This release introduces some critical fixes to message selection and gas estimation logic. It also adds the ability for nodes to mark a certain tipset as checkpointed, as well as various minor improvements and bugfixes.
|
||||
|
||||
## Changes
|
||||
|
||||
#### Messagepool
|
||||
|
||||
- Warn when optimal selection fails to pack a block and we fall back to random selection (https://github.com/filecoin-project/lotus/pull/3708)
|
||||
- Add basic command for printing gas performance of messages in the mpool (https://github.com/filecoin-project/lotus/pull/3701)
|
||||
- Adjust optimal selection to always try to fill blocks (https://github.com/filecoin-project/lotus/pull/3685)
|
||||
- Fix very minor bug in repub baseFeeLowerBound (https://github.com/filecoin-project/lotus/pull/3663)
|
||||
- Add an auto flag to mpool replace (https://github.com/filecoin-project/lotus/pull/3676)
|
||||
- Fix mpool optimal selection packing failure (https://github.com/filecoin-project/lotus/pull/3698)
|
||||
|
||||
#### Core Lotus
|
||||
|
||||
- Don't use latency as initital estimate for blocksync (https://github.com/filecoin-project/lotus/pull/3648)
|
||||
- Add niceSleep 1 second when drand errors (https://github.com/filecoin-project/lotus/pull/3664)
|
||||
- Fix isChainNearSync check in block validator (https://github.com/filecoin-project/lotus/pull/3650)
|
||||
- Add peer to peer manager before fetching the tipset (https://github.com/filecoin-project/lotus/pull/3667)
|
||||
- Add StageFetchingMessages to sync status (https://github.com/filecoin-project/lotus/pull/3668)
|
||||
- Pass tipset through upgrade logic (https://github.com/filecoin-project/lotus/pull/3673)
|
||||
- Allow nodes to mark tipsets as checkpointed (https://github.com/filecoin-project/lotus/pull/3680)
|
||||
- Remove hard-coded late-fee in window PoSt (https://github.com/filecoin-project/lotus/pull/3702)
|
||||
- Gas: Fix median calc (https://github.com/filecoin-project/lotus/pull/3686)
|
||||
|
||||
#### Storage
|
||||
|
||||
- Storage manager: bail out with an error if unsealed cid is undefined (https://github.com/filecoin-project/lotus/pull/3655)
|
||||
- Storage: return true from Sealer.ReadPiece() on success (https://github.com/filecoin-project/lotus/pull/3657)
|
||||
|
||||
#### Maintenance
|
||||
|
||||
- Resolve lotus, test-vectors, statediff dependency cycle (https://github.com/filecoin-project/lotus/pull/3688)
|
||||
- Paych: add docs on how to use paych status (https://github.com/filecoin-project/lotus/pull/3690)
|
||||
- Initial CODEOWNERS (https://github.com/filecoin-project/lotus/pull/3691)
|
||||
|
||||
# 0.6.1 / 2020-09-08
|
||||
|
||||
This optional release introduces a minor improvement to the sync process, ensuring nodes don't fall behind and then resync.
|
||||
|
||||
## Changes
|
||||
|
||||
- Update `test-vectors` (https://github.com/filecoin-project/lotus/pull/3645)
|
||||
- Revert "only subscribe to pubsub topics once we are synced" (https://github.com/filecoin-project/lotus/pull/3643)
|
||||
|
||||
# 0.6.0 / 2020-09-07
|
||||
|
||||
This consensus-breaking release of Lotus is designed to test a network upgrade on the space race testnet. The changes that break consensus are:
|
||||
|
||||
+48
-4
@@ -2,8 +2,11 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -156,10 +159,16 @@ type FullNode interface {
|
||||
// yet synced block headers.
|
||||
SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error)
|
||||
|
||||
// SyncCheckpoint marks a blocks as checkpointed, meaning that it won't ever fork away from it.
|
||||
SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) error
|
||||
|
||||
// SyncMarkBad marks a blocks as bad, meaning that it won't ever by synced.
|
||||
// Use with extreme caution.
|
||||
SyncMarkBad(ctx context.Context, bcid cid.Cid) error
|
||||
|
||||
// SyncUnmarkBad unmarks a blocks as bad, making it possible to be validated and synced again.
|
||||
SyncUnmarkBad(ctx context.Context, bcid cid.Cid) error
|
||||
|
||||
// SyncCheckBad checks if a block was marked as bad, and if it was, returns
|
||||
// the reason.
|
||||
SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error)
|
||||
@@ -311,7 +320,7 @@ type FullNode interface {
|
||||
StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error)
|
||||
// StateMinerProvingDeadline calculates the deadline at some epoch for a proving period
|
||||
// and returns the deadline-related calculations.
|
||||
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error)
|
||||
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error)
|
||||
// StateMinerPower returns the power of the indicated miner
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
||||
// StateMinerInfo returns info about the indicated miner
|
||||
@@ -390,6 +399,9 @@ type FullNode interface {
|
||||
|
||||
// MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent
|
||||
MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||
// MsigGetVested returns the amount of FIL that vested in a multisig in a certain period.
|
||||
// It takes the following params: <multisig address>, <start epoch>, <end epoch>
|
||||
MsigGetVested(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error)
|
||||
// MsigCreate creates a multisig wallet
|
||||
// It takes the following params: <required number of senders>, <approving addresses>, <unlock duration>
|
||||
//<initial balance>, <sender address of the create msg>, <gas price>
|
||||
@@ -406,17 +418,29 @@ type FullNode interface {
|
||||
// It takes the following params: <multisig address>, <proposed message ID>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the cancel msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
||||
// MsigAddPropose proposes adding a signer in the multisig
|
||||
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||
// <new signer>, <whether the number of required signers should be increased>
|
||||
MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error)
|
||||
// MsigAddApprove approves a previously proposed AddSigner message
|
||||
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||
// <proposer address>, <new signer>, <whether the number of required signers should be increased>
|
||||
MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error)
|
||||
// MsigAddCancel cancels a previously proposed AddSigner message
|
||||
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||
// <new signer>, <whether the number of required signers should be increased>
|
||||
MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (cid.Cid, error)
|
||||
// MsigSwapPropose proposes swapping 2 signers in the multisig
|
||||
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||
// <old signer> <new signer>
|
||||
// <old signer>, <new signer>
|
||||
MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error)
|
||||
// MsigSwapApprove approves a previously proposed SwapSigner
|
||||
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||
// <proposer address>, <old signer> <new signer>
|
||||
// <proposer address>, <old signer>, <new signer>
|
||||
MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error)
|
||||
// MsigSwapCancel cancels a previously proposed SwapSigner message
|
||||
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||
// <old signer> <new signer>
|
||||
// <old signer>, <new signer>
|
||||
MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error)
|
||||
|
||||
MarketEnsureAvailable(context.Context, address.Address, address.Address, types.BigInt) (cid.Cid, error)
|
||||
@@ -709,8 +733,28 @@ const (
|
||||
StageMessages
|
||||
StageSyncComplete
|
||||
StageSyncErrored
|
||||
StageFetchingMessages
|
||||
)
|
||||
|
||||
func (v SyncStateStage) String() string {
|
||||
switch v {
|
||||
case StageHeaders:
|
||||
return "header sync"
|
||||
case StagePersistHeaders:
|
||||
return "persisting headers"
|
||||
case StageMessages:
|
||||
return "message sync"
|
||||
case StageSyncComplete:
|
||||
return "complete"
|
||||
case StageSyncErrored:
|
||||
return "error"
|
||||
case StageFetchingMessages:
|
||||
return "fetching messages"
|
||||
default:
|
||||
return fmt.Sprintf("<unknown: %d>", v)
|
||||
}
|
||||
}
|
||||
|
||||
type MpoolChange int
|
||||
|
||||
const (
|
||||
|
||||
+34
-2
@@ -5,6 +5,8 @@ import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
@@ -105,7 +107,9 @@ type FullNodeStruct struct {
|
||||
SyncState func(context.Context) (*api.SyncState, error) `perm:"read"`
|
||||
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
|
||||
SyncIncomingBlocks func(ctx context.Context) (<-chan *types.BlockHeader, error) `perm:"read"`
|
||||
SyncCheckpoint func(ctx context.Context, key types.TipSetKey) error `perm:"admin"`
|
||||
SyncMarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"`
|
||||
SyncUnmarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"`
|
||||
SyncCheckBad func(ctx context.Context, bcid cid.Cid) (string, error) `perm:"read"`
|
||||
|
||||
MpoolGetConfig func(context.Context) (*types.MpoolConfig, error) `perm:"read"`
|
||||
@@ -160,7 +164,7 @@ type FullNodeStruct struct {
|
||||
StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"`
|
||||
StateMinerSectors func(context.Context, address.Address, *bitfield.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
|
||||
StateMinerActiveSectors func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
|
||||
StateMinerProvingDeadline func(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) `perm:"read"`
|
||||
StateMinerProvingDeadline func(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) `perm:"read"`
|
||||
StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) `perm:"read"`
|
||||
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) `perm:"read"`
|
||||
StateMinerDeadlines func(context.Context, address.Address, types.TipSetKey) ([]*miner.Deadline, error) `perm:"read"`
|
||||
@@ -199,10 +203,14 @@ type FullNodeStruct struct {
|
||||
StateCirculatingSupply func(context.Context, types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
|
||||
|
||||
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
MsigGetVested func(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
MsigCreate func(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
MsigPropose func(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigApprove func(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigCancel func(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddPropose func(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddApprove func(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddCancel func(context.Context, address.Address, address.Address, uint64, address.Address, bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigSwapPropose func(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigSwapApprove func(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigSwapCancel func(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
@@ -704,10 +712,18 @@ func (c *FullNodeStruct) SyncIncomingBlocks(ctx context.Context) (<-chan *types.
|
||||
return c.Internal.SyncIncomingBlocks(ctx)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) error {
|
||||
return c.Internal.SyncCheckpoint(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) SyncMarkBad(ctx context.Context, bcid cid.Cid) error {
|
||||
return c.Internal.SyncMarkBad(ctx, bcid)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) SyncUnmarkBad(ctx context.Context, bcid cid.Cid) error {
|
||||
return c.Internal.SyncUnmarkBad(ctx, bcid)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error) {
|
||||
return c.Internal.SyncCheckBad(ctx, bcid)
|
||||
}
|
||||
@@ -724,7 +740,7 @@ func (c *FullNodeStruct) StateMinerActiveSectors(ctx context.Context, addr addre
|
||||
return c.Internal.StateMinerActiveSectors(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*miner.DeadlineInfo, error) {
|
||||
func (c *FullNodeStruct) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) {
|
||||
return c.Internal.StateMinerProvingDeadline(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
@@ -872,6 +888,10 @@ func (c *FullNodeStruct) MsigGetAvailableBalance(ctx context.Context, a address.
|
||||
return c.Internal.MsigGetAvailableBalance(ctx, a, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigGetVested(ctx context.Context, a address.Address, sTsk types.TipSetKey, eTsk types.TipSetKey) (types.BigInt, error) {
|
||||
return c.Internal.MsigGetVested(ctx, a, sTsk, eTsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigCreate(ctx context.Context, req uint64, addrs []address.Address, duration abi.ChainEpoch, val types.BigInt, src address.Address, gp types.BigInt) (cid.Cid, error) {
|
||||
return c.Internal.MsigCreate(ctx, req, addrs, duration, val, src, gp)
|
||||
}
|
||||
@@ -888,6 +908,18 @@ func (c *FullNodeStruct) MsigCancel(ctx context.Context, msig address.Address, t
|
||||
return c.Internal.MsigCancel(ctx, msig, txID, to, amt, src, method, params)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigAddPropose(ctx context.Context, msig address.Address, src address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
return c.Internal.MsigAddPropose(ctx, msig, src, newAdd, inc)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
return c.Internal.MsigAddApprove(ctx, msig, src, txID, proposer, newAdd, inc)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
return c.Internal.MsigAddCancel(ctx, msig, src, txID, newAdd, inc)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||
return c.Internal.MsigSwapPropose(ctx, msig, src, oldAdd, newAdd)
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ func init() {
|
||||
addExample(network.Connected)
|
||||
addExample(dtypes.NetworkName("lotus"))
|
||||
addExample(api.SyncStateStage(1))
|
||||
addExample(build.APIVersion)
|
||||
addExample(build.FullAPIVersion)
|
||||
addExample(api.PCHInbound)
|
||||
addExample(time.Minute)
|
||||
addExample(datatransfer.TransferID(3))
|
||||
|
||||
@@ -65,6 +65,8 @@ func TestApis(t *testing.T, b APIBuilder) {
|
||||
var OneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}}
|
||||
|
||||
func (ts *testSuite) testVersion(t *testing.T) {
|
||||
build.RunningNodeType = build.NodeFull
|
||||
|
||||
ctx := context.Background()
|
||||
apis, _ := ts.makeNodes(t, 1, OneMiner)
|
||||
api := apis[0]
|
||||
|
||||
+17
-6
@@ -1,15 +1,26 @@
|
||||
package build
|
||||
|
||||
import "github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
import (
|
||||
"sort"
|
||||
|
||||
var DrandNetwork = DrandIncentinet
|
||||
|
||||
func DrandConfig() dtypes.DrandConfig {
|
||||
return DrandConfigs[DrandNetwork]
|
||||
}
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
type DrandEnum int
|
||||
|
||||
func DrandConfigSchedule() dtypes.DrandSchedule {
|
||||
out := dtypes.DrandSchedule{}
|
||||
for start, config := range DrandSchedule {
|
||||
out = append(out, dtypes.DrandPoint{Start: start, Config: DrandConfigs[config]})
|
||||
}
|
||||
|
||||
sort.Slice(out, func(i, j int) bool {
|
||||
return out[i].Start < out[j].Start
|
||||
})
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
const (
|
||||
DrandMainnet DrandEnum = iota + 1
|
||||
DrandTestnet
|
||||
|
||||
+8
-2
@@ -10,9 +10,15 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
)
|
||||
|
||||
const UpgradeBreezeHeight = 0
|
||||
const UpgradeBreezeHeight = -1
|
||||
const BreezeGasTampingDuration = 0
|
||||
|
||||
const UpgradeSmokeHeight = -1
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
func init() {
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
@@ -23,7 +29,7 @@ func init() {
|
||||
BuildType |= Build2k
|
||||
}
|
||||
|
||||
const BlockDelaySecs = uint64(4)
|
||||
const BlockDelaySecs = uint64(30)
|
||||
|
||||
const PropagationDelaySecs = uint64(1)
|
||||
|
||||
|
||||
@@ -36,3 +36,11 @@ func MessagesTopic(netName dtypes.NetworkName) string { return "/fil/msgs/" + st
|
||||
func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
|
||||
return protocol.ID("/fil/kad/" + string(netName))
|
||||
}
|
||||
|
||||
func UseNewestNetwork() bool {
|
||||
// TODO: Put these in a container we can iterate over
|
||||
if UpgradeBreezeHeight <= 0 && UpgradeSmokeHeight <= 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ package build
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
@@ -20,6 +22,7 @@ const UnixfsLinksPerLevel = 1024
|
||||
// Consensus / Network
|
||||
|
||||
const AllowableClockDriftSecs = uint64(1)
|
||||
const NewestNetworkVersion = network.Version2
|
||||
|
||||
// Epochs
|
||||
const ForkLengthThreshold = Finality
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"math/big"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
)
|
||||
@@ -70,6 +71,14 @@ var (
|
||||
PackingEfficiencyNum int64 = 4
|
||||
PackingEfficiencyDenom int64 = 5
|
||||
|
||||
UpgradeBreezeHeight abi.ChainEpoch = 0
|
||||
UpgradeBreezeHeight abi.ChainEpoch = -1
|
||||
BreezeGasTampingDuration abi.ChainEpoch = 0
|
||||
|
||||
UpgradeSmokeHeight abi.ChainEpoch = -1
|
||||
|
||||
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
NewestNetworkVersion = network.Version2
|
||||
)
|
||||
|
||||
@@ -12,9 +12,16 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
)
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandIncentinet,
|
||||
UpgradeSmokeHeight: DrandMainnet,
|
||||
}
|
||||
|
||||
const UpgradeBreezeHeight = 41280
|
||||
const BreezeGasTampingDuration = 120
|
||||
|
||||
const UpgradeSmokeHeight = 51000
|
||||
|
||||
func init() {
|
||||
power.ConsensusMinerMinPower = big.NewInt(10 << 40)
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
|
||||
+37
-4
@@ -1,6 +1,10 @@
|
||||
package build
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var CurrentCommit string
|
||||
var BuildType int
|
||||
@@ -25,7 +29,7 @@ func buildType() string {
|
||||
}
|
||||
|
||||
// BuildVersion is the local build version, set by build system
|
||||
const BuildVersion = "0.6.0"
|
||||
const BuildVersion = "0.7.0"
|
||||
|
||||
func UserVersion() string {
|
||||
return BuildVersion + buildType() + CurrentCommit
|
||||
@@ -52,8 +56,37 @@ func (ve Version) EqMajorMinor(v2 Version) bool {
|
||||
return ve&minorMask == v2&minorMask
|
||||
}
|
||||
|
||||
// APIVersion is a semver version of the rpc api exposed
|
||||
var APIVersion Version = newVer(0, 14, 0)
|
||||
type NodeType int
|
||||
|
||||
const (
|
||||
NodeUnknown NodeType = iota
|
||||
|
||||
NodeFull
|
||||
NodeMiner
|
||||
NodeWorker
|
||||
)
|
||||
|
||||
var RunningNodeType NodeType
|
||||
|
||||
func VersionForType(nodeType NodeType) (Version, error) {
|
||||
switch nodeType {
|
||||
case NodeFull:
|
||||
return FullAPIVersion, nil
|
||||
case NodeMiner:
|
||||
return MinerAPIVersion, nil
|
||||
case NodeWorker:
|
||||
return WorkerAPIVersion, nil
|
||||
default:
|
||||
return Version(0), xerrors.Errorf("unknown node type %d", nodeType)
|
||||
}
|
||||
}
|
||||
|
||||
// semver versions of the rpc api exposed
|
||||
var (
|
||||
FullAPIVersion = newVer(0, 14, 0)
|
||||
MinerAPIVersion = newVer(0, 14, 0)
|
||||
WorkerAPIVersion = newVer(0, 14, 0)
|
||||
)
|
||||
|
||||
//nolint:varcheck,deadcode
|
||||
const (
|
||||
|
||||
@@ -56,6 +56,10 @@ func (bts *BadBlockCache) Add(c cid.Cid, bbr BadBlockReason) {
|
||||
bts.badBlocks.Add(c, bbr)
|
||||
}
|
||||
|
||||
func (bts *BadBlockCache) Remove(c cid.Cid) {
|
||||
bts.badBlocks.Remove(c)
|
||||
}
|
||||
|
||||
func (bts *BadBlockCache) Has(c cid.Cid) (BadBlockReason, bool) {
|
||||
rval, ok := bts.badBlocks.Get(c)
|
||||
if !ok {
|
||||
|
||||
+67
-6
@@ -18,6 +18,23 @@ type Response struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
type Schedule []BeaconPoint
|
||||
|
||||
func (bs Schedule) BeaconForEpoch(e abi.ChainEpoch) RandomBeacon {
|
||||
for i := len(bs) - 1; i >= 0; i-- {
|
||||
bp := bs[i]
|
||||
if e >= bp.Start {
|
||||
return bp.Beacon
|
||||
}
|
||||
}
|
||||
return bs[0].Beacon
|
||||
}
|
||||
|
||||
type BeaconPoint struct {
|
||||
Start abi.ChainEpoch
|
||||
Beacon RandomBeacon
|
||||
}
|
||||
|
||||
// RandomBeacon represents a system that provides randomness to Lotus.
|
||||
// Other components interrogate the RandomBeacon to acquire randomness that's
|
||||
// valid for a specific chain epoch. Also to verify beacon entries that have
|
||||
@@ -25,11 +42,30 @@ type Response struct {
|
||||
type RandomBeacon interface {
|
||||
Entry(context.Context, uint64) <-chan Response
|
||||
VerifyEntry(types.BeaconEntry, types.BeaconEntry) error
|
||||
MaxBeaconRoundForEpoch(abi.ChainEpoch, types.BeaconEntry) uint64
|
||||
MaxBeaconRoundForEpoch(abi.ChainEpoch) uint64
|
||||
}
|
||||
|
||||
func ValidateBlockValues(b RandomBeacon, h *types.BlockHeader, prevEntry types.BeaconEntry) error {
|
||||
maxRound := b.MaxBeaconRoundForEpoch(h.Height, prevEntry)
|
||||
func ValidateBlockValues(bSchedule Schedule, h *types.BlockHeader, parentEpoch abi.ChainEpoch,
|
||||
prevEntry types.BeaconEntry) error {
|
||||
{
|
||||
parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
|
||||
currBeacon := bSchedule.BeaconForEpoch(h.Height)
|
||||
if parentBeacon != currBeacon {
|
||||
if len(h.BeaconEntries) != 2 {
|
||||
return xerrors.Errorf("expected two beacon entries at beacon fork, got %d", len(h.BeaconEntries))
|
||||
}
|
||||
err := currBeacon.VerifyEntry(h.BeaconEntries[1], h.BeaconEntries[0])
|
||||
if err != nil {
|
||||
return xerrors.Errorf("beacon at fork point invalid: (%v, %v): %w",
|
||||
h.BeaconEntries[1], h.BeaconEntries[0], err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: fork logic
|
||||
b := bSchedule.BeaconForEpoch(h.Height)
|
||||
maxRound := b.MaxBeaconRoundForEpoch(h.Height)
|
||||
if maxRound == prevEntry.Round {
|
||||
if len(h.BeaconEntries) != 0 {
|
||||
return xerrors.Errorf("expected not to have any beacon entries in this block, got %d", len(h.BeaconEntries))
|
||||
@@ -56,10 +92,35 @@ func ValidateBlockValues(b RandomBeacon, h *types.BlockHeader, prevEntry types.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func BeaconEntriesForBlock(ctx context.Context, beacon RandomBeacon, round abi.ChainEpoch, prev types.BeaconEntry) ([]types.BeaconEntry, error) {
|
||||
func BeaconEntriesForBlock(ctx context.Context, bSchedule Schedule, epoch abi.ChainEpoch, parentEpoch abi.ChainEpoch, prev types.BeaconEntry) ([]types.BeaconEntry, error) {
|
||||
{
|
||||
parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
|
||||
currBeacon := bSchedule.BeaconForEpoch(epoch)
|
||||
if parentBeacon != currBeacon {
|
||||
// Fork logic
|
||||
round := currBeacon.MaxBeaconRoundForEpoch(epoch)
|
||||
out := make([]types.BeaconEntry, 2)
|
||||
rch := currBeacon.Entry(ctx, round-1)
|
||||
res := <-rch
|
||||
if res.Err != nil {
|
||||
return nil, xerrors.Errorf("getting entry %d returned error: %w", round-1, res.Err)
|
||||
}
|
||||
out[0] = res.Entry
|
||||
rch = currBeacon.Entry(ctx, round)
|
||||
res = <-rch
|
||||
if res.Err != nil {
|
||||
return nil, xerrors.Errorf("getting entry %d returned error: %w", round, res.Err)
|
||||
}
|
||||
out[1] = res.Entry
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
|
||||
beacon := bSchedule.BeaconForEpoch(epoch)
|
||||
|
||||
start := build.Clock.Now()
|
||||
|
||||
maxRound := beacon.MaxBeaconRoundForEpoch(round, prev)
|
||||
maxRound := beacon.MaxBeaconRoundForEpoch(epoch)
|
||||
if maxRound == prev.Round {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -82,7 +143,7 @@ func BeaconEntriesForBlock(ctx context.Context, beacon RandomBeacon, round abi.C
|
||||
out = append(out, resp.Entry)
|
||||
cur = resp.Entry.Round - 1
|
||||
case <-ctx.Done():
|
||||
return nil, xerrors.Errorf("context timed out waiting on beacon entry to come back for round %d: %w", round, ctx.Err())
|
||||
return nil, xerrors.Errorf("context timed out waiting on beacon entry to come back for epoch %d: %w", epoch, ctx.Err())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntr
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DrandBeacon) MaxBeaconRoundForEpoch(filEpoch abi.ChainEpoch, prevEntry types.BeaconEntry) uint64 {
|
||||
func (db *DrandBeacon) MaxBeaconRoundForEpoch(filEpoch abi.ChainEpoch) uint64 {
|
||||
// TODO: sometimes the genesis time for filecoin is zero and this goes negative
|
||||
latestTs := ((uint64(filEpoch) * db.filRoundTime) + db.filGenTime) - db.filRoundTime
|
||||
dround := (latestTs - db.drandGenTime) / uint64(db.interval.Seconds())
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func TestPrintGroupInfo(t *testing.T) {
|
||||
server := build.DrandConfig().Servers[0]
|
||||
server := build.DrandConfigs[build.DrandIncentinet].Servers[0]
|
||||
c, err := hclient.New(server, nil, nil)
|
||||
assert.NoError(t, err)
|
||||
cg := c.(interface {
|
||||
|
||||
@@ -53,11 +53,7 @@ func (mb *mockBeacon) VerifyEntry(from types.BeaconEntry, to types.BeaconEntry)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mb *mockBeacon) IsEntryForEpoch(e types.BeaconEntry, epoch abi.ChainEpoch, nulls int) (bool, error) {
|
||||
return int64(e.Round) <= int64(epoch) && int64(epoch)-int64(nulls) >= int64(e.Round), nil
|
||||
}
|
||||
|
||||
func (mb *mockBeacon) MaxBeaconRoundForEpoch(epoch abi.ChainEpoch, prevEntry types.BeaconEntry) uint64 {
|
||||
func (mb *mockBeacon) MaxBeaconRoundForEpoch(epoch abi.ChainEpoch) uint64 {
|
||||
return uint64(epoch)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"github.com/ipfs/go-datastore"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var CheckpointKey = datastore.NewKey("/chain/checks")
|
||||
|
||||
func loadCheckpoint(ds dtypes.MetadataDS) (types.TipSetKey, error) {
|
||||
haveChks, err := ds.Has(CheckpointKey)
|
||||
if err != nil {
|
||||
return types.EmptyTSK, err
|
||||
}
|
||||
|
||||
if !haveChks {
|
||||
return types.EmptyTSK, nil
|
||||
}
|
||||
|
||||
tskBytes, err := ds.Get(CheckpointKey)
|
||||
if err != nil {
|
||||
return types.EmptyTSK, err
|
||||
}
|
||||
|
||||
var tsk types.TipSetKey
|
||||
err = json.Unmarshal(tskBytes, &tsk)
|
||||
if err != nil {
|
||||
return types.EmptyTSK, err
|
||||
}
|
||||
|
||||
return tsk, err
|
||||
}
|
||||
|
||||
func (syncer *Syncer) SetCheckpoint(tsk types.TipSetKey) error {
|
||||
if tsk == types.EmptyTSK {
|
||||
return xerrors.Errorf("called with empty tsk")
|
||||
}
|
||||
|
||||
syncer.checkptLk.Lock()
|
||||
defer syncer.checkptLk.Unlock()
|
||||
|
||||
ts, err := syncer.ChainStore().LoadTipSet(tsk)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("cannot find tipset: %w", err)
|
||||
}
|
||||
|
||||
hts := syncer.ChainStore().GetHeaviestTipSet()
|
||||
anc, err := syncer.ChainStore().IsAncestorOf(ts, hts)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("cannot determine whether checkpoint tipset is in main-chain: %w", err)
|
||||
}
|
||||
|
||||
if !hts.Equals(ts) && !anc {
|
||||
return xerrors.Errorf("cannot mark tipset as checkpoint, since it isn't in the main-chain: %w", err)
|
||||
}
|
||||
|
||||
tskBytes, err := json.Marshal(tsk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = syncer.ds.Put(CheckpointKey, tskBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
syncer.checkpt = tsk
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (syncer *Syncer) GetCheckpoint() types.TipSetKey {
|
||||
syncer.checkptLk.Lock()
|
||||
defer syncer.checkptLk.Unlock()
|
||||
return syncer.checkpt
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT.
|
||||
|
||||
package blocksync
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,4 +1,4 @@
|
||||
package blocksync
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
@@ -7,13 +7,16 @@ import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
host "github.com/libp2p/go-libp2p-core/host"
|
||||
inet "github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
||||
"go.opencensus.io/trace"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
cborutil "github.com/filecoin-project/go-cbor-util"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -21,11 +24,9 @@ import (
|
||||
"github.com/filecoin-project/lotus/lib/peermgr"
|
||||
)
|
||||
|
||||
// Protocol client.
|
||||
// FIXME: Rename to just `Client`. Not done at the moment to avoid
|
||||
// disrupting too much of the consumer code, should be done along
|
||||
// https://github.com/filecoin-project/lotus/issues/2612.
|
||||
type BlockSync struct {
|
||||
// client implements exchange.Client, using the libp2p ChainExchange protocol
|
||||
// as the fetching mechanism.
|
||||
type client struct {
|
||||
// Connection manager used to contact the server.
|
||||
// FIXME: We should have a reduced interface here, initialized
|
||||
// just with our protocol ID, we shouldn't be able to open *any*
|
||||
@@ -35,13 +36,14 @@ type BlockSync struct {
|
||||
peerTracker *bsPeerTracker
|
||||
}
|
||||
|
||||
func NewClient(
|
||||
host host.Host,
|
||||
pmgr peermgr.MaybePeerMgr,
|
||||
) *BlockSync {
|
||||
return &BlockSync{
|
||||
var _ Client = (*client)(nil)
|
||||
|
||||
// NewClient creates a new libp2p-based exchange.Client that uses the libp2p
|
||||
// ChainExhange protocol as the fetching mechanism.
|
||||
func NewClient(lc fx.Lifecycle, host host.Host, pmgr peermgr.MaybePeerMgr) Client {
|
||||
return &client{
|
||||
host: host,
|
||||
peerTracker: newPeerTracker(pmgr.Mgr),
|
||||
peerTracker: newPeerTracker(lc, host, pmgr.Mgr),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,11 +64,7 @@ func NewClient(
|
||||
// request options without disrupting external calls. In the future the
|
||||
// consumers should be forced to use a more standardized service and
|
||||
// adhere to a single API derived from this function.
|
||||
func (client *BlockSync) doRequest(
|
||||
ctx context.Context,
|
||||
req *Request,
|
||||
singlePeer *peer.ID,
|
||||
) (*validatedResponse, error) {
|
||||
func (c *client) doRequest(ctx context.Context, req *Request, singlePeer *peer.ID) (*validatedResponse, error) {
|
||||
// Validate request.
|
||||
if req.Length == 0 {
|
||||
return nil, xerrors.Errorf("invalid request of length 0")
|
||||
@@ -86,7 +84,7 @@ func (client *BlockSync) doRequest(
|
||||
if singlePeer != nil {
|
||||
peers = []peer.ID{*singlePeer}
|
||||
} else {
|
||||
peers = client.getShuffledPeers()
|
||||
peers = c.getShuffledPeers()
|
||||
if len(peers) == 0 {
|
||||
return nil, xerrors.Errorf("no peers available")
|
||||
}
|
||||
@@ -107,9 +105,9 @@ func (client *BlockSync) doRequest(
|
||||
}
|
||||
|
||||
// Send request, read response.
|
||||
res, err := client.sendRequestToPeer(ctx, peer, req)
|
||||
res, err := c.sendRequestToPeer(ctx, peer, req)
|
||||
if err != nil {
|
||||
if !xerrors.Is(err, inet.ErrNoConn) {
|
||||
if !xerrors.Is(err, network.ErrNoConn) {
|
||||
log.Warnf("could not connect to peer %s: %s",
|
||||
peer.String(), err)
|
||||
}
|
||||
@@ -117,15 +115,15 @@ func (client *BlockSync) doRequest(
|
||||
}
|
||||
|
||||
// Process and validate response.
|
||||
validRes, err := client.processResponse(req, res)
|
||||
validRes, err := c.processResponse(req, res)
|
||||
if err != nil {
|
||||
log.Warnf("processing peer %s response failed: %s",
|
||||
peer.String(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
client.peerTracker.logGlobalSuccess(build.Clock.Since(globalTime))
|
||||
client.host.ConnManager().TagPeer(peer, "bsync", SUCCESS_PEER_TAG_VALUE)
|
||||
c.peerTracker.logGlobalSuccess(build.Clock.Since(globalTime))
|
||||
c.host.ConnManager().TagPeer(peer, "bsync", SuccessPeerTagValue)
|
||||
return validRes, nil
|
||||
}
|
||||
|
||||
@@ -144,11 +142,8 @@ func (client *BlockSync) doRequest(
|
||||
// We are conflating in the single error returned both status and validation
|
||||
// errors. Peer penalization should happen here then, before returning, so
|
||||
// we can apply the correct penalties depending on the cause of the error.
|
||||
func (client *BlockSync) processResponse(
|
||||
req *Request,
|
||||
res *Response,
|
||||
// FIXME: Add the `peer` as argument once we implement penalties.
|
||||
) (*validatedResponse, error) {
|
||||
// FIXME: Add the `peer` as argument once we implement penalties.
|
||||
func (c *client) processResponse(req *Request, res *Response) (*validatedResponse, error) {
|
||||
err := res.statusToError()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("status error: %s", err)
|
||||
@@ -246,16 +241,8 @@ func (client *BlockSync) processResponse(
|
||||
return validRes, nil
|
||||
}
|
||||
|
||||
// GetBlocks fetches count blocks from the network, from the provided tipset
|
||||
// *backwards*, returning as many tipsets as count.
|
||||
//
|
||||
// {hint/usage}: This is used by the Syncer during normal chain syncing and when
|
||||
// resolving forks.
|
||||
func (client *BlockSync) GetBlocks(
|
||||
ctx context.Context,
|
||||
tsk types.TipSetKey,
|
||||
count int,
|
||||
) ([]*types.TipSet, error) {
|
||||
// GetBlocks implements Client.GetBlocks(). Refer to the godocs there.
|
||||
func (c *client) GetBlocks(ctx context.Context, tsk types.TipSetKey, count int) ([]*types.TipSet, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "bsync.GetBlocks")
|
||||
defer span.End()
|
||||
if span.IsRecordingEvents() {
|
||||
@@ -271,7 +258,7 @@ func (client *BlockSync) GetBlocks(
|
||||
Options: Headers,
|
||||
}
|
||||
|
||||
validRes, err := client.doRequest(ctx, req, nil)
|
||||
validRes, err := c.doRequest(ctx, req, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -279,11 +266,8 @@ func (client *BlockSync) GetBlocks(
|
||||
return validRes.tipsets, nil
|
||||
}
|
||||
|
||||
func (client *BlockSync) GetFullTipSet(
|
||||
ctx context.Context,
|
||||
peer peer.ID,
|
||||
tsk types.TipSetKey,
|
||||
) (*store.FullTipSet, error) {
|
||||
// GetFullTipSet implements Client.GetFullTipSet(). Refer to the godocs there.
|
||||
func (c *client) GetFullTipSet(ctx context.Context, peer peer.ID, tsk types.TipSetKey) (*store.FullTipSet, error) {
|
||||
// TODO: round robin through these peers on error
|
||||
|
||||
req := &Request{
|
||||
@@ -292,7 +276,7 @@ func (client *BlockSync) GetFullTipSet(
|
||||
Options: Headers | Messages,
|
||||
}
|
||||
|
||||
validRes, err := client.doRequest(ctx, req, &peer)
|
||||
validRes, err := c.doRequest(ctx, req, &peer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -302,11 +286,8 @@ func (client *BlockSync) GetFullTipSet(
|
||||
// *one* tipset here, so it's safe to index directly.
|
||||
}
|
||||
|
||||
func (client *BlockSync) GetChainMessages(
|
||||
ctx context.Context,
|
||||
head *types.TipSet,
|
||||
length uint64,
|
||||
) ([]*CompactedMessages, error) {
|
||||
// GetChainMessages implements Client.GetChainMessages(). Refer to the godocs there.
|
||||
func (c *client) GetChainMessages(ctx context.Context, head *types.TipSet, length uint64) ([]*CompactedMessages, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "GetChainMessages")
|
||||
if span.IsRecordingEvents() {
|
||||
span.AddAttributes(
|
||||
@@ -322,7 +303,7 @@ func (client *BlockSync) GetChainMessages(
|
||||
Options: Messages,
|
||||
}
|
||||
|
||||
validRes, err := client.doRequest(ctx, req, nil)
|
||||
validRes, err := c.doRequest(ctx, req, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -333,11 +314,7 @@ func (client *BlockSync) GetChainMessages(
|
||||
// Send a request to a peer. Write request in the stream and read the
|
||||
// response back. We do not do any processing of the request/response
|
||||
// here.
|
||||
func (client *BlockSync) sendRequestToPeer(
|
||||
ctx context.Context,
|
||||
peer peer.ID,
|
||||
req *Request,
|
||||
) (_ *Response, err error) {
|
||||
func (c *client) sendRequestToPeer(ctx context.Context, peer peer.ID, req *Request) (_ *Response, err error) {
|
||||
// Trace code.
|
||||
ctx, span := trace.StartSpan(ctx, "sendRequestToPeer")
|
||||
defer span.End()
|
||||
@@ -358,34 +335,33 @@ func (client *BlockSync) sendRequestToPeer(
|
||||
}()
|
||||
// -- TRACE --
|
||||
|
||||
supported, err := client.host.Peerstore().SupportsProtocols(peer, BlockSyncProtocolID)
|
||||
supported, err := c.host.Peerstore().SupportsProtocols(peer, BlockSyncProtocolID, ChainExchangeProtocolID)
|
||||
if err != nil {
|
||||
c.RemovePeer(peer)
|
||||
return nil, xerrors.Errorf("failed to get protocols for peer: %w", err)
|
||||
}
|
||||
if len(supported) == 0 || supported[0] != BlockSyncProtocolID {
|
||||
return nil, xerrors.Errorf("peer %s does not support protocol %s",
|
||||
peer, BlockSyncProtocolID)
|
||||
// FIXME: `ProtoBook` should support a *single* protocol check that returns
|
||||
// a bool instead of a list.
|
||||
if len(supported) == 0 || (supported[0] != BlockSyncProtocolID && supported[0] != ChainExchangeProtocolID) {
|
||||
return nil, xerrors.Errorf("peer %s does not support protocols %s",
|
||||
peer, []string{BlockSyncProtocolID, ChainExchangeProtocolID})
|
||||
}
|
||||
|
||||
connectionStart := build.Clock.Now()
|
||||
|
||||
// Open stream to peer.
|
||||
stream, err := client.host.NewStream(
|
||||
inet.WithNoDial(ctx, "should already have connection"),
|
||||
stream, err := c.host.NewStream(
|
||||
network.WithNoDial(ctx, "should already have connection"),
|
||||
peer,
|
||||
BlockSyncProtocolID)
|
||||
ChainExchangeProtocolID, BlockSyncProtocolID)
|
||||
if err != nil {
|
||||
client.RemovePeer(peer)
|
||||
c.RemovePeer(peer)
|
||||
return nil, xerrors.Errorf("failed to open stream to peer: %w", err)
|
||||
}
|
||||
|
||||
// Write request.
|
||||
_ = stream.SetWriteDeadline(time.Now().Add(WRITE_REQ_DEADLINE))
|
||||
_ = stream.SetWriteDeadline(time.Now().Add(WriteReqDeadline))
|
||||
if err := cborutil.WriteCborRPC(stream, req); err != nil {
|
||||
_ = stream.SetWriteDeadline(time.Time{})
|
||||
client.peerTracker.logFailure(peer, build.Clock.Since(connectionStart))
|
||||
c.peerTracker.logFailure(peer, build.Clock.Since(connectionStart), req.Length)
|
||||
// FIXME: Should we also remove peer here?
|
||||
return nil, err
|
||||
}
|
||||
@@ -395,11 +371,11 @@ func (client *BlockSync) sendRequestToPeer(
|
||||
// Read response.
|
||||
var res Response
|
||||
err = cborutil.ReadCborRPC(
|
||||
bufio.NewReader(incrt.New(stream, READ_RES_MIN_SPEED, READ_RES_DEADLINE)),
|
||||
bufio.NewReader(incrt.New(stream, ReadResMinSpeed, ReadResDeadline)),
|
||||
&res)
|
||||
if err != nil {
|
||||
client.peerTracker.logFailure(peer, build.Clock.Since(connectionStart))
|
||||
return nil, xerrors.Errorf("failed to read blocksync response: %w", err)
|
||||
c.peerTracker.logFailure(peer, build.Clock.Since(connectionStart), req.Length)
|
||||
return nil, xerrors.Errorf("failed to read chainxchg response: %w", err)
|
||||
}
|
||||
|
||||
// FIXME: Move all this together at the top using a defer as done elsewhere.
|
||||
@@ -412,32 +388,34 @@ func (client *BlockSync) sendRequestToPeer(
|
||||
)
|
||||
}
|
||||
|
||||
client.peerTracker.logSuccess(peer, build.Clock.Since(connectionStart))
|
||||
c.peerTracker.logSuccess(peer, build.Clock.Since(connectionStart), uint64(len(res.Chain)))
|
||||
// FIXME: We should really log a success only after we validate the response.
|
||||
// It might be a bit hard to do.
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (client *BlockSync) AddPeer(p peer.ID) {
|
||||
client.peerTracker.addPeer(p)
|
||||
// AddPeer implements Client.AddPeer(). Refer to the godocs there.
|
||||
func (c *client) AddPeer(p peer.ID) {
|
||||
c.peerTracker.addPeer(p)
|
||||
}
|
||||
|
||||
func (client *BlockSync) RemovePeer(p peer.ID) {
|
||||
client.peerTracker.removePeer(p)
|
||||
// RemovePeer implements Client.RemovePeer(). Refer to the godocs there.
|
||||
func (c *client) RemovePeer(p peer.ID) {
|
||||
c.peerTracker.removePeer(p)
|
||||
}
|
||||
|
||||
// getShuffledPeers returns a preference-sorted set of peers (by latency
|
||||
// and failure counting), shuffling the first few peers so we don't always
|
||||
// pick the same peer.
|
||||
// FIXME: Consider merging with `shufflePrefix()s`.
|
||||
func (client *BlockSync) getShuffledPeers() []peer.ID {
|
||||
peers := client.peerTracker.prefSortedPeers()
|
||||
func (c *client) getShuffledPeers() []peer.ID {
|
||||
peers := c.peerTracker.prefSortedPeers()
|
||||
shufflePrefix(peers)
|
||||
return peers
|
||||
}
|
||||
|
||||
func shufflePrefix(peers []peer.ID) {
|
||||
prefix := SHUFFLE_PEERS_PREFIX
|
||||
prefix := ShufflePeersPrefix
|
||||
if len(peers) < prefix {
|
||||
prefix = len(peers)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Package exchange contains the ChainExchange server and client components.
|
||||
//
|
||||
// ChainExchange is the basic chain synchronization protocol of Filecoin.
|
||||
// ChainExchange is an RPC-oriented protocol, with a single operation to
|
||||
// request blocks for now.
|
||||
//
|
||||
// A request contains a start anchor block (referred to with a CID), and a
|
||||
// amount of blocks requested beyond the anchor (including the anchor itself).
|
||||
//
|
||||
// A client can also pass options, encoded as a 64-bit bitfield. Lotus supports
|
||||
// two options at the moment:
|
||||
//
|
||||
// - include block contents
|
||||
// - include block messages
|
||||
//
|
||||
// The response will include a status code, an optional message, and the
|
||||
// response payload in case of success. The payload is a slice of serialized
|
||||
// tipsets.
|
||||
package exchange
|
||||
@@ -0,0 +1,51 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
// Server is the responder side of the ChainExchange protocol. It accepts
|
||||
// requests from clients and services them by returning the requested
|
||||
// chain data.
|
||||
type Server interface {
|
||||
// HandleStream is the protocol handler to be registered on a libp2p
|
||||
// protocol router.
|
||||
//
|
||||
// In the current version of the protocol, streams are single-use. The
|
||||
// server will read a single Request, and will respond with a single
|
||||
// Response. It will dispose of the stream straight after.
|
||||
HandleStream(stream network.Stream)
|
||||
}
|
||||
|
||||
// Client is the requesting side of the ChainExchange protocol. It acts as
|
||||
// a proxy for other components to request chain data from peers. It is chiefly
|
||||
// used by the Syncer.
|
||||
type Client interface {
|
||||
// GetBlocks fetches block headers from the network, from the provided
|
||||
// tipset *backwards*, returning as many tipsets as the count parameter,
|
||||
// or less.
|
||||
GetBlocks(ctx context.Context, tsk types.TipSetKey, count int) ([]*types.TipSet, error)
|
||||
|
||||
// GetChainMessages fetches messages from the network, from the provided
|
||||
// tipset *backwards*, returning the messages from as many tipsets as the
|
||||
// count parameter, or less.
|
||||
GetChainMessages(ctx context.Context, head *types.TipSet, length uint64) ([]*CompactedMessages, error)
|
||||
|
||||
// GetFullTipSet fetches a full tipset from a given peer. If successful,
|
||||
// the fetched object contains block headers and all messages in full form.
|
||||
GetFullTipSet(ctx context.Context, peer peer.ID, tsk types.TipSetKey) (*store.FullTipSet, error)
|
||||
|
||||
// AddPeer adds a peer to the pool of peers that the Client requests
|
||||
// data from.
|
||||
AddPeer(peer peer.ID)
|
||||
|
||||
// RemovePeer removes a peer from the pool of peers that the Client
|
||||
// requests data from.
|
||||
RemovePeer(peer peer.ID)
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
package blocksync
|
||||
package exchange
|
||||
|
||||
// FIXME: This needs to be reviewed.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
host "github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"go.uber.org/fx"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/lib/peermgr"
|
||||
@@ -29,11 +32,30 @@ type bsPeerTracker struct {
|
||||
pmgr *peermgr.PeerMgr
|
||||
}
|
||||
|
||||
func newPeerTracker(pmgr *peermgr.PeerMgr) *bsPeerTracker {
|
||||
return &bsPeerTracker{
|
||||
func newPeerTracker(lc fx.Lifecycle, h host.Host, pmgr *peermgr.PeerMgr) *bsPeerTracker {
|
||||
bsPt := &bsPeerTracker{
|
||||
peers: make(map[peer.ID]*peerStats),
|
||||
pmgr: pmgr,
|
||||
}
|
||||
|
||||
sub, err := h.EventBus().Subscribe(new(peermgr.NewFilPeer))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
for newPeer := range sub.Out() {
|
||||
bsPt.addPeer(newPeer.(peermgr.NewFilPeer).Id)
|
||||
}
|
||||
}()
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return sub.Close()
|
||||
},
|
||||
})
|
||||
|
||||
return bsPt
|
||||
}
|
||||
|
||||
func (bpt *bsPeerTracker) addPeer(p peer.ID) {
|
||||
@@ -72,16 +94,7 @@ func (bpt *bsPeerTracker) prefSortedPeers() []peer.ID {
|
||||
var costI, costJ float64
|
||||
|
||||
getPeerInitLat := func(p peer.ID) float64 {
|
||||
var res float64
|
||||
if bpt.pmgr != nil {
|
||||
if lat, ok := bpt.pmgr.GetPeerLatency(p); ok {
|
||||
res = float64(lat)
|
||||
}
|
||||
}
|
||||
if res == 0 {
|
||||
res = float64(bpt.avgGlobalTime)
|
||||
}
|
||||
return res * newPeerMul
|
||||
return float64(bpt.avgGlobalTime) * newPeerMul
|
||||
}
|
||||
|
||||
if pi.successes+pi.failures > 0 {
|
||||
@@ -107,8 +120,8 @@ func (bpt *bsPeerTracker) prefSortedPeers() []peer.ID {
|
||||
const (
|
||||
// xInvAlpha = (N+1)/2
|
||||
|
||||
localInvAlpha = 5 // 86% of the value is the last 9
|
||||
globalInvAlpha = 20 // 86% of the value is the last 39
|
||||
localInvAlpha = 10 // 86% of the value is the last 19
|
||||
globalInvAlpha = 25 // 86% of the value is the last 49
|
||||
)
|
||||
|
||||
func (bpt *bsPeerTracker) logGlobalSuccess(dur time.Duration) {
|
||||
@@ -133,7 +146,7 @@ func logTime(pi *peerStats, dur time.Duration) {
|
||||
|
||||
}
|
||||
|
||||
func (bpt *bsPeerTracker) logSuccess(p peer.ID, dur time.Duration) {
|
||||
func (bpt *bsPeerTracker) logSuccess(p peer.ID, dur time.Duration, reqSize uint64) {
|
||||
bpt.lk.Lock()
|
||||
defer bpt.lk.Unlock()
|
||||
|
||||
@@ -145,10 +158,13 @@ func (bpt *bsPeerTracker) logSuccess(p peer.ID, dur time.Duration) {
|
||||
}
|
||||
|
||||
pi.successes++
|
||||
logTime(pi, dur)
|
||||
if reqSize == 0 {
|
||||
reqSize = 1
|
||||
}
|
||||
logTime(pi, dur/time.Duration(reqSize))
|
||||
}
|
||||
|
||||
func (bpt *bsPeerTracker) logFailure(p peer.ID, dur time.Duration) {
|
||||
func (bpt *bsPeerTracker) logFailure(p peer.ID, dur time.Duration, reqSize uint64) {
|
||||
bpt.lk.Lock()
|
||||
defer bpt.lk.Unlock()
|
||||
|
||||
@@ -160,7 +176,10 @@ func (bpt *bsPeerTracker) logFailure(p peer.ID, dur time.Duration) {
|
||||
}
|
||||
|
||||
pi.failures++
|
||||
logTime(pi, dur)
|
||||
if reqSize == 0 {
|
||||
reqSize = 1
|
||||
}
|
||||
logTime(pi, dur/time.Duration(reqSize))
|
||||
}
|
||||
|
||||
func (bpt *bsPeerTracker) removePeer(p peer.ID) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package blocksync
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"time"
|
||||
@@ -13,9 +13,17 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var log = logging.Logger("blocksync")
|
||||
var log = logging.Logger("chainxchg")
|
||||
|
||||
const BlockSyncProtocolID = "/fil/sync/blk/0.0.1"
|
||||
const (
|
||||
// BlockSyncProtocolID is the protocol ID of the former blocksync protocol.
|
||||
// Deprecated.
|
||||
BlockSyncProtocolID = "/fil/sync/blk/0.0.1"
|
||||
|
||||
// ChainExchangeProtocolID is the protocol ID of the chain exchange
|
||||
// protocol.
|
||||
ChainExchangeProtocolID = "/fil/chain/xchg/0.0.1"
|
||||
)
|
||||
|
||||
// FIXME: Bumped from original 800 to this to accommodate `syncFork()`
|
||||
// use of `GetBlocks()`. It seems the expectation of that API is to
|
||||
@@ -25,14 +33,16 @@ const BlockSyncProtocolID = "/fil/sync/blk/0.0.1"
|
||||
// qualifier to avoid "const initializer [...] is not a constant" error.)
|
||||
var MaxRequestLength = uint64(build.ForkLengthThreshold)
|
||||
|
||||
// Extracted constants from the code.
|
||||
// FIXME: Should be reviewed and confirmed.
|
||||
const SUCCESS_PEER_TAG_VALUE = 25
|
||||
const WRITE_REQ_DEADLINE = 5 * time.Second
|
||||
const READ_RES_DEADLINE = WRITE_REQ_DEADLINE
|
||||
const READ_RES_MIN_SPEED = 50 << 10
|
||||
const SHUFFLE_PEERS_PREFIX = 5
|
||||
const WRITE_RES_DEADLINE = 60 * time.Second
|
||||
const (
|
||||
// Extracted constants from the code.
|
||||
// FIXME: Should be reviewed and confirmed.
|
||||
SuccessPeerTagValue = 25
|
||||
WriteReqDeadline = 5 * time.Second
|
||||
ReadResDeadline = WriteReqDeadline
|
||||
ReadResMinSpeed = 50 << 10
|
||||
ShufflePeersPrefix = 5
|
||||
WriteResDeadline = 60 * time.Second
|
||||
)
|
||||
|
||||
// FIXME: Rename. Make private.
|
||||
type Request struct {
|
||||
@@ -117,7 +127,7 @@ func (res *Response) statusToError() error {
|
||||
case NotFound:
|
||||
return xerrors.Errorf("not found")
|
||||
case GoAway:
|
||||
return xerrors.Errorf("not handling 'go away' blocksync responses yet")
|
||||
return xerrors.Errorf("not handling 'go away' chainxchg responses yet")
|
||||
case InternalError:
|
||||
return xerrors.Errorf("block sync peer errored: %s", res.ErrorMessage)
|
||||
case BadRequest:
|
||||
@@ -1,4 +1,4 @@
|
||||
package blocksync
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
@@ -18,38 +18,25 @@ import (
|
||||
inet "github.com/libp2p/go-libp2p-core/network"
|
||||
)
|
||||
|
||||
// BlockSyncService is the component that services BlockSync requests from
|
||||
// peers.
|
||||
//
|
||||
// BlockSync is the basic chain synchronization protocol of Filecoin. BlockSync
|
||||
// is an RPC-oriented protocol, with a single operation to request blocks.
|
||||
//
|
||||
// A request contains a start anchor block (referred to with a CID), and a
|
||||
// amount of blocks requested beyond the anchor (including the anchor itself).
|
||||
//
|
||||
// A client can also pass options, encoded as a 64-bit bitfield. Lotus supports
|
||||
// two options at the moment:
|
||||
//
|
||||
// - include block contents
|
||||
// - include block messages
|
||||
//
|
||||
// The response will include a status code, an optional message, and the
|
||||
// response payload in case of success. The payload is a slice of serialized
|
||||
// tipsets.
|
||||
// FIXME: Rename to just `Server` (will be done later, see note on `BlockSync`).
|
||||
type BlockSyncService struct {
|
||||
// server implements exchange.Server. It services requests for the
|
||||
// libp2p ChainExchange protocol.
|
||||
type server struct {
|
||||
cs *store.ChainStore
|
||||
}
|
||||
|
||||
func NewBlockSyncService(cs *store.ChainStore) *BlockSyncService {
|
||||
return &BlockSyncService{
|
||||
var _ Server = (*server)(nil)
|
||||
|
||||
// NewServer creates a new libp2p-based exchange.Server. It services requests
|
||||
// for the libp2p ChainExchange protocol.
|
||||
func NewServer(cs *store.ChainStore) Server {
|
||||
return &server{
|
||||
cs: cs,
|
||||
}
|
||||
}
|
||||
|
||||
// Entry point of the service, handles `Request`s.
|
||||
func (server *BlockSyncService) HandleStream(stream inet.Stream) {
|
||||
ctx, span := trace.StartSpan(context.Background(), "blocksync.HandleStream")
|
||||
// HandleStream implements Server.HandleStream. Refer to the godocs there.
|
||||
func (s *server) HandleStream(stream inet.Stream) {
|
||||
ctx, span := trace.StartSpan(context.Background(), "chainxchg.HandleStream")
|
||||
defer span.End()
|
||||
|
||||
defer stream.Close() //nolint:errcheck
|
||||
@@ -62,13 +49,13 @@ func (server *BlockSyncService) HandleStream(stream inet.Stream) {
|
||||
log.Infow("block sync request",
|
||||
"start", req.Head, "len", req.Length)
|
||||
|
||||
resp, err := server.processRequest(ctx, &req)
|
||||
resp, err := s.processRequest(ctx, &req)
|
||||
if err != nil {
|
||||
log.Warn("failed to process request: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
_ = stream.SetDeadline(time.Now().Add(WRITE_RES_DEADLINE))
|
||||
_ = stream.SetDeadline(time.Now().Add(WriteResDeadline))
|
||||
if err := cborutil.WriteCborRPC(stream, resp); err != nil {
|
||||
_ = stream.SetDeadline(time.Time{})
|
||||
log.Warnw("failed to write back response for handle stream",
|
||||
@@ -80,10 +67,7 @@ func (server *BlockSyncService) HandleStream(stream inet.Stream) {
|
||||
|
||||
// Validate and service the request. We return either a protocol
|
||||
// response or an internal error.
|
||||
func (server *BlockSyncService) processRequest(
|
||||
ctx context.Context,
|
||||
req *Request,
|
||||
) (*Response, error) {
|
||||
func (s *server) processRequest(ctx context.Context, req *Request) (*Response, error) {
|
||||
validReq, errResponse := validateRequest(ctx, req)
|
||||
if errResponse != nil {
|
||||
// The request did not pass validation, return the response
|
||||
@@ -91,17 +75,14 @@ func (server *BlockSyncService) processRequest(
|
||||
return errResponse, nil
|
||||
}
|
||||
|
||||
return server.serviceRequest(ctx, validReq)
|
||||
return s.serviceRequest(ctx, validReq)
|
||||
}
|
||||
|
||||
// Validate request. We either return a `validatedRequest`, or an error
|
||||
// `Response` indicating why we can't process it. We do not return any
|
||||
// internal errors here, we just signal protocol ones.
|
||||
func validateRequest(
|
||||
ctx context.Context,
|
||||
req *Request,
|
||||
) (*validatedRequest, *Response) {
|
||||
_, span := trace.StartSpan(ctx, "blocksync.ValidateRequest")
|
||||
func validateRequest(ctx context.Context, req *Request) (*validatedRequest, *Response) {
|
||||
_, span := trace.StartSpan(ctx, "chainxchg.ValidateRequest")
|
||||
defer span.End()
|
||||
|
||||
validReq := validatedRequest{}
|
||||
@@ -147,14 +128,11 @@ func validateRequest(
|
||||
return &validReq, nil
|
||||
}
|
||||
|
||||
func (server *BlockSyncService) serviceRequest(
|
||||
ctx context.Context,
|
||||
req *validatedRequest,
|
||||
) (*Response, error) {
|
||||
_, span := trace.StartSpan(ctx, "blocksync.ServiceRequest")
|
||||
func (s *server) serviceRequest(ctx context.Context, req *validatedRequest) (*Response, error) {
|
||||
_, span := trace.StartSpan(ctx, "chainxchg.ServiceRequest")
|
||||
defer span.End()
|
||||
|
||||
chain, err := collectChainSegment(server.cs, req)
|
||||
chain, err := collectChainSegment(s.cs, req)
|
||||
if err != nil {
|
||||
log.Warn("block sync request: collectChainSegment failed: ", err)
|
||||
return &Response{
|
||||
@@ -174,10 +152,7 @@ func (server *BlockSyncService) serviceRequest(
|
||||
}, nil
|
||||
}
|
||||
|
||||
func collectChainSegment(
|
||||
cs *store.ChainStore,
|
||||
req *validatedRequest,
|
||||
) ([]*BSTipSet, error) {
|
||||
func collectChainSegment(cs *store.ChainStore, req *validatedRequest) ([]*BSTipSet, error) {
|
||||
var bstips []*BSTipSet
|
||||
|
||||
cur := req.head
|
||||
+5
-5
@@ -59,7 +59,7 @@ type ChainGen struct {
|
||||
|
||||
cs *store.ChainStore
|
||||
|
||||
beacon beacon.RandomBeacon
|
||||
beacon beacon.Schedule
|
||||
|
||||
sm *stmgr.StateManager
|
||||
|
||||
@@ -252,7 +252,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
|
||||
miners := []address.Address{maddr1, maddr2}
|
||||
|
||||
beac := beacon.NewMockBeacon(time.Second)
|
||||
beac := beacon.Schedule{{Start: 0, Beacon: beacon.NewMockBeacon(time.Second)}}
|
||||
//beac, err := drand.NewDrandBeacon(tpl.Timestamp, build.BlockDelaySecs)
|
||||
//if err != nil {
|
||||
//return nil, xerrors.Errorf("creating drand beacon: %w", err)
|
||||
@@ -338,7 +338,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
|
||||
|
||||
prev := mbi.PrevBeaconEntry
|
||||
|
||||
entries, err := beacon.BeaconEntriesForBlock(ctx, cg.beacon, round, prev)
|
||||
entries, err := beacon.BeaconEntriesForBlock(ctx, cg.beacon, round, pts.Height(), prev)
|
||||
if err != nil {
|
||||
return nil, nil, nil, xerrors.Errorf("get beacon entries for block: %w", err)
|
||||
}
|
||||
@@ -358,7 +358,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
|
||||
return nil, nil, nil, xerrors.Errorf("failed to cbor marshal address: %w", err)
|
||||
}
|
||||
|
||||
if len(entries) == 0 {
|
||||
if round > build.UpgradeSmokeHeight {
|
||||
buf.Write(pts.MinTicket().VRFProof)
|
||||
}
|
||||
|
||||
@@ -559,7 +559,7 @@ type mca struct {
|
||||
w *wallet.Wallet
|
||||
sm *stmgr.StateManager
|
||||
pv ffiwrapper.Verifier
|
||||
bcn beacon.RandomBeacon
|
||||
bcn beacon.Schedule
|
||||
}
|
||||
|
||||
func (mca mca) ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-datastore"
|
||||
@@ -406,8 +406,8 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
||||
verifNeeds := make(map[address.Address]abi.PaddedPieceSize)
|
||||
var sum abi.PaddedPieceSize
|
||||
|
||||
nwv := func(context.Context, abi.ChainEpoch) runtime.NetworkVersion {
|
||||
return runtime.NetworkVersion1
|
||||
nwv := func(context.Context, abi.ChainEpoch) network.Version {
|
||||
return build.NewestNetworkVersion
|
||||
}
|
||||
|
||||
vmopt := vm.VMOpts{
|
||||
|
||||
@@ -6,6 +6,10 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -61,8 +65,8 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
return big.Zero(), nil
|
||||
}
|
||||
|
||||
nwv := func(context.Context, abi.ChainEpoch) runtime.NetworkVersion {
|
||||
return runtime.NetworkVersion1
|
||||
nwv := func(context.Context, abi.ChainEpoch) network.Version {
|
||||
return build.NewestNetworkVersion
|
||||
}
|
||||
|
||||
vmopt := &vm.VMOpts{
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
@@ -154,6 +155,11 @@ func newMsgSet(nonce uint64) *msgSet {
|
||||
}
|
||||
}
|
||||
|
||||
func ComputeMinRBF(curPrem abi.TokenAmount) abi.TokenAmount {
|
||||
minPrice := types.BigAdd(curPrem, types.BigDiv(types.BigMul(curPrem, rbfNumBig), rbfDenomBig))
|
||||
return types.BigAdd(minPrice, types.NewInt(1))
|
||||
}
|
||||
|
||||
func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict bool) (bool, error) {
|
||||
nextNonce := ms.nextNonce
|
||||
nonceGap := false
|
||||
@@ -181,9 +187,7 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict bool) (boo
|
||||
|
||||
if m.Cid() != exms.Cid() {
|
||||
// check if RBF passes
|
||||
minPrice := exms.Message.GasPremium
|
||||
minPrice = types.BigAdd(minPrice, types.BigDiv(types.BigMul(minPrice, rbfNumBig), rbfDenomBig))
|
||||
minPrice = types.BigAdd(minPrice, types.NewInt(1))
|
||||
minPrice := ComputeMinRBF(exms.Message.GasPremium)
|
||||
if types.BigCmp(m.Message.GasPremium, minPrice) >= 0 {
|
||||
log.Infow("add with RBF", "oldpremium", exms.Message.GasPremium,
|
||||
"newpremium", m.Message.GasPremium, "addr", m.Message.From, "nonce", m.Message.Nonce)
|
||||
@@ -586,7 +590,7 @@ func (mp *MessagePool) addTs(m *types.SignedMessage, curTs *types.TipSet, local
|
||||
return false, err
|
||||
}
|
||||
|
||||
return publish, mp.addLocked(m, true)
|
||||
return publish, mp.addLocked(m, !local)
|
||||
}
|
||||
|
||||
func (mp *MessagePool) addLoaded(m *types.SignedMessage) error {
|
||||
@@ -808,7 +812,7 @@ func (mp *MessagePool) PushWithNonce(ctx context.Context, addr address.Address,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := mp.addLocked(msg, true); err != nil {
|
||||
if err := mp.addLocked(msg, false); err != nil {
|
||||
return nil, xerrors.Errorf("add locked failed: %w", err)
|
||||
}
|
||||
if err := mp.addLocal(msg, msgb); err != nil {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -56,6 +57,13 @@ func (tma *testMpoolAPI) nextBlock() *types.BlockHeader {
|
||||
return newBlk
|
||||
}
|
||||
|
||||
func (tma *testMpoolAPI) nextBlockWithHeight(height uint64) *types.BlockHeader {
|
||||
newBlk := mock.MkBlock(tma.tipsets[len(tma.tipsets)-1], 1, 1)
|
||||
newBlk.Height = abi.ChainEpoch(height)
|
||||
tma.tipsets = append(tma.tipsets, mock.TipSet(newBlk))
|
||||
return newBlk
|
||||
}
|
||||
|
||||
func (tma *testMpoolAPI) applyBlock(t *testing.T, b *types.BlockHeader) {
|
||||
t.Helper()
|
||||
if err := tma.cb(nil, []*types.TipSet{mock.TipSet(b)}); err != nil {
|
||||
|
||||
@@ -27,7 +27,11 @@ func (mp *MessagePool) republishPendingMessages() error {
|
||||
mp.curTsLk.Unlock()
|
||||
return xerrors.Errorf("computing basefee: %w", err)
|
||||
}
|
||||
|
||||
baseFeeLowerBound := types.BigDiv(baseFee, baseFeeLowerBoundFactor)
|
||||
if baseFeeLowerBoundFactor.LessThan(minimumBaseFee) {
|
||||
baseFeeLowerBound = minimumBaseFee
|
||||
}
|
||||
|
||||
pending := make(map[address.Address]map[uint64]*types.SignedMessage)
|
||||
mp.lk.Lock()
|
||||
|
||||
@@ -3,6 +3,7 @@ package messagepool
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
@@ -198,9 +199,11 @@ func (mp *MessagePool) selectMessagesOptimal(curTs, ts *types.TipSet, tq float64
|
||||
gasLimit -= chainGasLimit
|
||||
|
||||
// resort to account for already merged chains and effective performance adjustments
|
||||
sort.Slice(chains[i+1:], func(i, j int) bool {
|
||||
// the sort *must* be stable or we end up getting negative gasPerfs pushed up.
|
||||
sort.SliceStable(chains[i+1:], func(i, j int) bool {
|
||||
return chains[i].BeforeEffective(chains[j])
|
||||
})
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -304,6 +307,79 @@ tailLoop:
|
||||
log.Infow("pack tail chains done", "took", dt)
|
||||
}
|
||||
|
||||
// if we have gasLimit to spare, pick some random (non-negative) chains to fill the block
|
||||
// we pick randomly so that we minimize the probability of duplication among all miners
|
||||
if gasLimit >= minGas {
|
||||
randomCount := 0
|
||||
|
||||
startRandom := time.Now()
|
||||
shuffleChains(chains)
|
||||
|
||||
for _, chain := range chains {
|
||||
// have we filled the block
|
||||
if gasLimit < minGas {
|
||||
break
|
||||
}
|
||||
|
||||
// has it been merged or invalidated?
|
||||
if chain.merged || !chain.valid {
|
||||
continue
|
||||
}
|
||||
|
||||
// is it negative?
|
||||
if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// compute the dependencies that must be merged and the gas limit including deps
|
||||
chainGasLimit := chain.gasLimit
|
||||
depGasLimit := int64(0)
|
||||
var chainDeps []*msgChain
|
||||
for curChain := chain.prev; curChain != nil && !curChain.merged; curChain = curChain.prev {
|
||||
chainDeps = append(chainDeps, curChain)
|
||||
chainGasLimit += curChain.gasLimit
|
||||
depGasLimit += curChain.gasLimit
|
||||
}
|
||||
|
||||
// do the deps fit? if the deps won't fit, invalidate the chain
|
||||
if depGasLimit > gasLimit {
|
||||
chain.Invalidate()
|
||||
continue
|
||||
}
|
||||
|
||||
// do they fit as is? if it doesn't, trim to make it fit if possible
|
||||
if chainGasLimit > gasLimit {
|
||||
chain.Trim(gasLimit-depGasLimit, mp, baseFee, allowNegativeChains(curTs.Height()))
|
||||
|
||||
if !chain.valid {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// include it together with all dependencies
|
||||
for i := len(chainDeps) - 1; i >= 0; i-- {
|
||||
curChain := chainDeps[i]
|
||||
curChain.merged = true
|
||||
result = append(result, curChain.msgs...)
|
||||
randomCount += len(curChain.msgs)
|
||||
}
|
||||
|
||||
chain.merged = true
|
||||
result = append(result, chain.msgs...)
|
||||
randomCount += len(chain.msgs)
|
||||
gasLimit -= chainGasLimit
|
||||
}
|
||||
|
||||
if dt := time.Since(startRandom); dt > time.Millisecond {
|
||||
log.Infow("pack random tail chains done", "took", dt)
|
||||
}
|
||||
|
||||
if randomCount > 0 {
|
||||
log.Warnf("optimal selection failed to pack a block; picked %d messages with random selection",
|
||||
randomCount)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -848,7 +924,16 @@ func (mc *msgChain) SetNullEffectivePerf() {
|
||||
|
||||
func (mc *msgChain) BeforeEffective(other *msgChain) bool {
|
||||
// move merged chains to the front so we can discard them earlier
|
||||
return (mc.merged && !other.merged) || mc.effPerf > other.effPerf ||
|
||||
return (mc.merged && !other.merged) ||
|
||||
(mc.gasPerf >= 0 && other.gasPerf < 0) ||
|
||||
mc.effPerf > other.effPerf ||
|
||||
(mc.effPerf == other.effPerf && mc.gasPerf > other.gasPerf) ||
|
||||
(mc.effPerf == other.effPerf && mc.gasPerf == other.gasPerf && mc.gasReward.Cmp(other.gasReward) > 0)
|
||||
}
|
||||
|
||||
func shuffleChains(lst []*msgChain) {
|
||||
for i := range lst {
|
||||
j := rand.Intn(i + 1)
|
||||
lst[i], lst[j] = lst[j], lst[i]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package messagepool
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"os"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@@ -1281,3 +1286,177 @@ func TestGasReward(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRealWorldSelection(t *testing.T) {
|
||||
// load test-messages.json.gz and rewrite the messages so that
|
||||
// 1) we map each real actor to a test actor so that we can sign the messages
|
||||
// 2) adjust the nonces so that they start from 0
|
||||
file, err := os.Open("test-messages.json.gz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
gzr, err := gzip.NewReader(file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dec := json.NewDecoder(gzr)
|
||||
|
||||
var msgs []*types.SignedMessage
|
||||
baseNonces := make(map[address.Address]uint64)
|
||||
|
||||
readLoop:
|
||||
for {
|
||||
m := new(types.SignedMessage)
|
||||
err := dec.Decode(m)
|
||||
switch err {
|
||||
case nil:
|
||||
msgs = append(msgs, m)
|
||||
nonce, ok := baseNonces[m.Message.From]
|
||||
if !ok || m.Message.Nonce < nonce {
|
||||
baseNonces[m.Message.From] = m.Message.Nonce
|
||||
}
|
||||
|
||||
case io.EOF:
|
||||
break readLoop
|
||||
|
||||
default:
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
actorMap := make(map[address.Address]address.Address)
|
||||
actorWallets := make(map[address.Address]*wallet.Wallet)
|
||||
|
||||
for _, m := range msgs {
|
||||
baseNonce := baseNonces[m.Message.From]
|
||||
|
||||
localActor, ok := actorMap[m.Message.From]
|
||||
if !ok {
|
||||
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a, err := w.GenerateKey(crypto.SigTypeSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
actorMap[m.Message.From] = a
|
||||
actorWallets[a] = w
|
||||
localActor = a
|
||||
}
|
||||
|
||||
w, ok := actorWallets[localActor]
|
||||
if !ok {
|
||||
t.Fatalf("failed to lookup wallet for actor %s", localActor)
|
||||
}
|
||||
|
||||
m.Message.From = localActor
|
||||
m.Message.Nonce -= baseNonce
|
||||
|
||||
sig, err := w.Sign(context.TODO(), localActor, m.Message.Cid().Bytes())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m.Signature = *sig
|
||||
}
|
||||
|
||||
mp, tma := makeTestMpool()
|
||||
|
||||
block := tma.nextBlockWithHeight(build.UpgradeBreezeHeight + 10)
|
||||
ts := mock.TipSet(block)
|
||||
tma.applyBlock(t, block)
|
||||
|
||||
for _, a := range actorMap {
|
||||
tma.setBalance(a, 1000000)
|
||||
}
|
||||
|
||||
tma.baseFee = types.NewInt(800_000_000)
|
||||
|
||||
sort.Slice(msgs, func(i, j int) bool {
|
||||
return msgs[i].Message.Nonce < msgs[j].Message.Nonce
|
||||
})
|
||||
|
||||
// add the messages
|
||||
for _, m := range msgs {
|
||||
mustAdd(t, mp, m)
|
||||
}
|
||||
|
||||
// do message selection and check block packing
|
||||
minGasLimit := int64(0.9 * float64(build.BlockGasLimit))
|
||||
|
||||
// greedy first
|
||||
selected, err := mp.SelectMessages(ts, 1.0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
gasLimit := int64(0)
|
||||
for _, m := range selected {
|
||||
gasLimit += m.Message.GasLimit
|
||||
}
|
||||
if gasLimit < minGasLimit {
|
||||
t.Fatalf("failed to pack with tq=1.0; packed %d, minimum packing: %d", gasLimit, minGasLimit)
|
||||
}
|
||||
|
||||
// high quality ticket
|
||||
selected, err = mp.SelectMessages(ts, .8)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
gasLimit = int64(0)
|
||||
for _, m := range selected {
|
||||
gasLimit += m.Message.GasLimit
|
||||
}
|
||||
if gasLimit < minGasLimit {
|
||||
t.Fatalf("failed to pack with tq=0.8; packed %d, minimum packing: %d", gasLimit, minGasLimit)
|
||||
}
|
||||
|
||||
// mid quality ticket
|
||||
selected, err = mp.SelectMessages(ts, .4)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
gasLimit = int64(0)
|
||||
for _, m := range selected {
|
||||
gasLimit += m.Message.GasLimit
|
||||
}
|
||||
if gasLimit < minGasLimit {
|
||||
t.Fatalf("failed to pack with tq=0.4; packed %d, minimum packing: %d", gasLimit, minGasLimit)
|
||||
}
|
||||
|
||||
// low quality ticket
|
||||
selected, err = mp.SelectMessages(ts, .1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
gasLimit = int64(0)
|
||||
for _, m := range selected {
|
||||
gasLimit += m.Message.GasLimit
|
||||
}
|
||||
if gasLimit < minGasLimit {
|
||||
t.Fatalf("failed to pack with tq=0.1; packed %d, minimum packing: %d", gasLimit, minGasLimit)
|
||||
}
|
||||
|
||||
// very low quality ticket
|
||||
selected, err = mp.SelectMessages(ts, .01)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
gasLimit = int64(0)
|
||||
for _, m := range selected {
|
||||
gasLimit += m.Message.GasLimit
|
||||
}
|
||||
if gasLimit < minGasLimit {
|
||||
t.Fatalf("failed to pack with tq=0.01; packed %d, minimum packing: %d", gasLimit, minGasLimit)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -17,14 +17,14 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, types.StateTree) error{
|
||||
var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, types.StateTree, *types.TipSet) error{
|
||||
build.UpgradeBreezeHeight: UpgradeFaucetBurnRecovery,
|
||||
}
|
||||
|
||||
func (sm *StateManager) handleStateForks(ctx context.Context, st types.StateTree, height abi.ChainEpoch) (err error) {
|
||||
func (sm *StateManager) handleStateForks(ctx context.Context, st types.StateTree, height abi.ChainEpoch, ts *types.TipSet) (err error) {
|
||||
f, ok := ForksAtHeight[height]
|
||||
if ok {
|
||||
err := f(ctx, sm, st)
|
||||
err := f(ctx, sm, st, ts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -66,7 +66,7 @@ func doTransfer(tree types.StateTree, from, to address.Address, amt abi.TokenAmo
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types.StateTree) error {
|
||||
func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types.StateTree, ts *types.TipSet) error {
|
||||
// Some initial parameters
|
||||
FundsForMiners := types.FromFil(1_000_000)
|
||||
LookbackEpoch := abi.ChainEpoch(32000)
|
||||
@@ -91,7 +91,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
|
||||
}
|
||||
|
||||
// Grab lookback state for account checks
|
||||
lbts, err := sm.ChainStore().GetTipsetByHeight(ctx, LookbackEpoch, nil, false)
|
||||
lbts, err := sm.ChainStore().GetTipsetByHeight(ctx, LookbackEpoch, ts, false)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get tipset at lookback height: %w", err)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"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"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
@@ -73,15 +72,15 @@ func (ta *testActor) Exports() []interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
func (ta *testActor) Constructor(rt runtime.Runtime, params *adt.EmptyValue) *adt.EmptyValue {
|
||||
func (ta *testActor) Constructor(rt runtime.Runtime, params *abi.EmptyValue) *abi.EmptyValue {
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
rt.State().Create(&testActorState{11})
|
||||
fmt.Println("NEW ACTOR ADDRESS IS: ", rt.Message().Receiver())
|
||||
|
||||
return adt.Empty
|
||||
return abi.Empty
|
||||
}
|
||||
|
||||
func (ta *testActor) TestMethod(rt runtime.Runtime, params *adt.EmptyValue) *adt.EmptyValue {
|
||||
func (ta *testActor) TestMethod(rt runtime.Runtime, params *abi.EmptyValue) *abi.EmptyValue {
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
var st testActorState
|
||||
rt.State().Readonly(&st)
|
||||
@@ -96,7 +95,7 @@ func (ta *testActor) TestMethod(rt runtime.Runtime, params *adt.EmptyValue) *adt
|
||||
}
|
||||
}
|
||||
|
||||
return adt.Empty
|
||||
return abi.Empty
|
||||
}
|
||||
|
||||
func TestForkHeightTriggers(t *testing.T) {
|
||||
@@ -119,7 +118,7 @@ func TestForkHeightTriggers(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
stmgr.ForksAtHeight[testForkHeight] = func(ctx context.Context, sm *StateManager, st types.StateTree) error {
|
||||
stmgr.ForksAtHeight[testForkHeight] = func(ctx context.Context, sm *StateManager, st types.StateTree, ts *types.TipSet) error {
|
||||
cst := cbor.NewCborStore(sm.ChainStore().Blockstore())
|
||||
|
||||
act, err := st.GetActor(taddr)
|
||||
|
||||
+13
-9
@@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
|
||||
@@ -147,7 +147,7 @@ func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (c
|
||||
|
||||
type ExecCallback func(cid.Cid, *types.Message, *vm.ApplyRet) error
|
||||
|
||||
func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEpoch, pstate cid.Cid, bms []store.BlockMessages, epoch abi.ChainEpoch, r vm.Rand, cb ExecCallback, baseFee abi.TokenAmount) (cid.Cid, cid.Cid, error) {
|
||||
func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEpoch, pstate cid.Cid, bms []store.BlockMessages, epoch abi.ChainEpoch, r vm.Rand, cb ExecCallback, baseFee abi.TokenAmount, ts *types.TipSet) (cid.Cid, cid.Cid, error) {
|
||||
|
||||
vmopt := &vm.VMOpts{
|
||||
StateBase: pstate,
|
||||
@@ -201,7 +201,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
||||
|
||||
for i := parentEpoch; i < epoch; i++ {
|
||||
// handle state forks
|
||||
err = sm.handleStateForks(ctx, vmi.StateTree(), i)
|
||||
err = sm.handleStateForks(ctx, vmi.StateTree(), i, ts)
|
||||
if err != nil {
|
||||
return cid.Undef, cid.Undef, xerrors.Errorf("error handling state forks: %w", err)
|
||||
}
|
||||
@@ -350,7 +350,7 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, ts *types.TipSet
|
||||
|
||||
baseFee := blks[0].ParentBaseFee
|
||||
|
||||
return sm.ApplyBlocks(ctx, parentEpoch, pstate, blkmsgs, blks[0].Height, r, cb, baseFee)
|
||||
return sm.ApplyBlocks(ctx, parentEpoch, pstate, blkmsgs, blks[0].Height, r, cb, baseFee, ts)
|
||||
}
|
||||
|
||||
func (sm *StateManager) parentState(ts *types.TipSet) cid.Cid {
|
||||
@@ -1124,14 +1124,18 @@ func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.Cha
|
||||
return csi.FilCirculating, nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) runtime.NetworkVersion {
|
||||
if build.UpgradeBreezeHeight == 0 {
|
||||
return runtime.NetworkVersion1
|
||||
func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version {
|
||||
if build.UseNewestNetwork() {
|
||||
return build.NewestNetworkVersion
|
||||
}
|
||||
|
||||
if height <= build.UpgradeBreezeHeight {
|
||||
return runtime.NetworkVersion0
|
||||
return network.Version0
|
||||
}
|
||||
|
||||
return runtime.NetworkVersion1
|
||||
if height <= build.UpgradeSmokeHeight {
|
||||
return network.Version1
|
||||
}
|
||||
|
||||
return build.NewestNetworkVersion
|
||||
}
|
||||
|
||||
@@ -456,7 +456,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
|
||||
|
||||
for i := ts.Height(); i < height; i++ {
|
||||
// handle state forks
|
||||
err = sm.handleStateForks(ctx, vmi.StateTree(), i)
|
||||
err = sm.handleStateForks(ctx, vmi.StateTree(), i, ts)
|
||||
if err != nil {
|
||||
return cid.Undef, nil, xerrors.Errorf("error handling state forks: %w", err)
|
||||
}
|
||||
@@ -502,7 +502,7 @@ func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.
|
||||
return lbts, nil
|
||||
}
|
||||
|
||||
func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcn beacon.RandomBeacon, tsk types.TipSetKey, round abi.ChainEpoch, maddr address.Address, pv ffiwrapper.Verifier) (*api.MiningBaseInfo, error) {
|
||||
func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule, tsk types.TipSetKey, round abi.ChainEpoch, maddr address.Address, pv ffiwrapper.Verifier) (*api.MiningBaseInfo, error) {
|
||||
ts, err := sm.ChainStore().LoadTipSet(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load tipset for mining base: %w", err)
|
||||
@@ -517,7 +517,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcn beacon.RandomBe
|
||||
prev = &types.BeaconEntry{}
|
||||
}
|
||||
|
||||
entries, err := beacon.BeaconEntriesForBlock(ctx, bcn, round, *prev)
|
||||
entries, err := beacon.BeaconEntriesForBlock(ctx, bcs, round, ts.Height(), *prev)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -624,8 +624,8 @@ func init() {
|
||||
// Explicitly add send, it's special.
|
||||
methods[builtin.MethodSend] = MethodMeta{
|
||||
Name: "Send",
|
||||
Params: reflect.TypeOf(new(adt.EmptyValue)),
|
||||
Ret: reflect.TypeOf(new(adt.EmptyValue)),
|
||||
Params: reflect.TypeOf(new(abi.EmptyValue)),
|
||||
Ret: reflect.TypeOf(new(abi.EmptyValue)),
|
||||
}
|
||||
|
||||
// Learn method names from the builtin.Methods* structs.
|
||||
|
||||
+12
-6
@@ -11,14 +11,20 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func computeNextBaseFee(baseFee types.BigInt, gasLimitUsed int64, noOfBlocks int) types.BigInt {
|
||||
// deta := 1/PackingEfficiency * gasLimitUsed/noOfBlocks - build.BlockGasTarget
|
||||
// change := baseFee * deta / BlockGasTarget / BaseFeeMaxChangeDenom
|
||||
func ComputeNextBaseFee(baseFee types.BigInt, gasLimitUsed int64, noOfBlocks int, epoch abi.ChainEpoch) types.BigInt {
|
||||
// deta := gasLimitUsed/noOfBlocks - build.BlockGasTarget
|
||||
// change := baseFee * deta / BlockGasTarget
|
||||
// nextBaseFee = baseFee + change
|
||||
// nextBaseFee = max(nextBaseFee, build.MinimumBaseFee)
|
||||
|
||||
delta := build.PackingEfficiencyDenom * gasLimitUsed / (int64(noOfBlocks) * build.PackingEfficiencyNum)
|
||||
delta -= build.BlockGasTarget
|
||||
var delta int64
|
||||
if epoch > build.UpgradeSmokeHeight {
|
||||
delta = gasLimitUsed / int64(noOfBlocks)
|
||||
delta -= build.BlockGasTarget
|
||||
} else {
|
||||
delta = build.PackingEfficiencyDenom * gasLimitUsed / (int64(noOfBlocks) * build.PackingEfficiencyNum)
|
||||
delta -= build.BlockGasTarget
|
||||
}
|
||||
|
||||
// cap change at 12.5% (BaseFeeMaxChangeDenom) by capping delta
|
||||
if delta > build.BlockGasTarget {
|
||||
@@ -73,5 +79,5 @@ func (cs *ChainStore) ComputeBaseFee(ctx context.Context, ts *types.TipSet) (abi
|
||||
}
|
||||
parentBaseFee := ts.Blocks()[0].ParentBaseFee
|
||||
|
||||
return computeNextBaseFee(parentBaseFee, totalLimit, len(ts.Blocks())), nil
|
||||
return ComputeNextBaseFee(parentBaseFee, totalLimit, len(ts.Blocks()), ts.Height()), nil
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ func TestBaseFee(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(fmt.Sprintf("%v", test), func(t *testing.T) {
|
||||
output := computeNextBaseFee(types.NewInt(test.basefee), test.limitUsed, test.noOfBlocks)
|
||||
output := ComputeNextBaseFee(types.NewInt(test.basefee), test.limitUsed, test.noOfBlocks, 0)
|
||||
assert.Equal(t, fmt.Sprintf("%d", test.output), output.String())
|
||||
})
|
||||
}
|
||||
|
||||
+4
-29
@@ -5,7 +5,6 @@ import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
@@ -52,8 +51,6 @@ var blockValidationCacheKeyPrefix = dstore.NewKey("blockValidation")
|
||||
var DefaultTipSetCacheSize = 8192
|
||||
var DefaultMsgMetaCacheSize = 2048
|
||||
|
||||
var ErrNotifieeDone = errors.New("notifee is done and should be removed")
|
||||
|
||||
func init() {
|
||||
if s := os.Getenv("LOTUS_CHAIN_TIPSET_CACHE"); s != "" {
|
||||
tscs, err := strconv.Atoi(s)
|
||||
@@ -361,33 +358,11 @@ func (cs *ChainStore) reorgWorker(ctx context.Context, initialNotifees []ReorgNo
|
||||
apply[i], apply[opp] = apply[opp], apply[i]
|
||||
}
|
||||
|
||||
var toremove map[int]struct{}
|
||||
for i, hcf := range notifees {
|
||||
err := hcf(revert, apply)
|
||||
if err != nil {
|
||||
if err == ErrNotifieeDone {
|
||||
if toremove == nil {
|
||||
toremove = make(map[int]struct{})
|
||||
}
|
||||
toremove[i] = struct{}{}
|
||||
} else {
|
||||
log.Error("head change func errored (BAD): ", err)
|
||||
}
|
||||
for _, hcf := range notifees {
|
||||
if err := hcf(revert, apply); err != nil {
|
||||
log.Error("head change func errored (BAD): ", err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(toremove) > 0 {
|
||||
newNotifees := make([]ReorgNotifee, 0, len(notifees)-len(toremove))
|
||||
for i, hcf := range notifees {
|
||||
_, remove := toremove[i]
|
||||
if remove {
|
||||
continue
|
||||
}
|
||||
newNotifees = append(newNotifees, hcf)
|
||||
}
|
||||
notifees = newNotifees
|
||||
}
|
||||
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
@@ -496,7 +471,7 @@ func (cs *ChainStore) IsAncestorOf(a, b *types.TipSet) (bool, error) {
|
||||
|
||||
cur := b
|
||||
for !a.Equals(cur) && cur.Height() > a.Height() {
|
||||
next, err := cs.LoadTipSet(b.Parents())
|
||||
next, err := cs.LoadTipSet(cur.Parents())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
@@ -369,9 +369,8 @@ func (bv *BlockValidator) decodeAndCheckBlock(msg *pubsub.Message) (*types.Block
|
||||
func (bv *BlockValidator) isChainNearSynced() bool {
|
||||
ts := bv.chain.GetHeaviestTipSet()
|
||||
timestamp := ts.MinTimestamp()
|
||||
now := build.Clock.Now().UnixNano()
|
||||
cutoff := uint64(now) - uint64(6*time.Hour)
|
||||
return timestamp > cutoff
|
||||
timestampTime := time.Unix(int64(timestamp), 0)
|
||||
return build.Clock.Since(timestampTime) < 6*time.Hour
|
||||
}
|
||||
|
||||
func (bv *BlockValidator) validateMsgMeta(ctx context.Context, msg *types.BlockMsg) error {
|
||||
|
||||
+67
-26
@@ -9,8 +9,11 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
|
||||
"github.com/Gurpartap/async"
|
||||
@@ -38,7 +41,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/beacon"
|
||||
"github.com/filecoin-project/lotus/chain/blocksync"
|
||||
"github.com/filecoin-project/lotus/chain/exchange"
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
@@ -52,7 +55,7 @@ import (
|
||||
)
|
||||
|
||||
// Blocks that are more than MaxHeightDrift epochs above
|
||||
//the theoretical max height based on systime are quickly rejected
|
||||
// the theoretical max height based on systime are quickly rejected
|
||||
const MaxHeightDrift = 5
|
||||
|
||||
var defaultMessageFetchWindowSize = 200
|
||||
@@ -89,7 +92,7 @@ var LocalIncoming = "incoming"
|
||||
// The Syncer does not run workers itself. It's mainly concerned with
|
||||
// ensuring a consistent state of chain consensus. The reactive and network-
|
||||
// interfacing processes are part of other components, such as the SyncManager
|
||||
// (which owns the sync scheduler and sync workers), BlockSync, the HELLO
|
||||
// (which owns the sync scheduler and sync workers), ChainExchange, the HELLO
|
||||
// protocol, and the gossipsub block propagation layer.
|
||||
//
|
||||
// {hint/concept} The fork-choice rule as it currently stands is: "pick the
|
||||
@@ -100,7 +103,7 @@ type Syncer struct {
|
||||
store *store.ChainStore
|
||||
|
||||
// handle to the random beacon for verification
|
||||
beacon beacon.RandomBeacon
|
||||
beacon beacon.Schedule
|
||||
|
||||
// the state manager handles making state queries
|
||||
sm *stmgr.StateManager
|
||||
@@ -112,7 +115,7 @@ type Syncer struct {
|
||||
bad *BadBlockCache
|
||||
|
||||
// handle to the block sync service
|
||||
Bsync *blocksync.BlockSync
|
||||
Exchange exchange.Client
|
||||
|
||||
self peer.ID
|
||||
|
||||
@@ -129,10 +132,16 @@ type Syncer struct {
|
||||
windowSize int
|
||||
|
||||
tickerCtxCancel context.CancelFunc
|
||||
|
||||
checkptLk sync.Mutex
|
||||
|
||||
checkpt types.TipSetKey
|
||||
|
||||
ds dtypes.MetadataDS
|
||||
}
|
||||
|
||||
// NewSyncer creates a new Syncer object.
|
||||
func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, connmgr connmgr.ConnManager, self peer.ID, beacon beacon.RandomBeacon, verifier ffiwrapper.Verifier) (*Syncer, error) {
|
||||
func NewSyncer(ds dtypes.MetadataDS, sm *stmgr.StateManager, exchange exchange.Client, connmgr connmgr.ConnManager, self peer.ID, beacon beacon.Schedule, verifier ffiwrapper.Verifier) (*Syncer, error) {
|
||||
gen, err := sm.ChainStore().GetGenesis()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting genesis block: %w", err)
|
||||
@@ -143,11 +152,18 @@ func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, connmgr connm
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cp, err := loadCheckpoint(ds)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("error loading mpool config: %w", err)
|
||||
}
|
||||
|
||||
s := &Syncer{
|
||||
ds: ds,
|
||||
checkpt: cp,
|
||||
beacon: beacon,
|
||||
bad: NewBadBlockCache(),
|
||||
Genesis: gent,
|
||||
Bsync: bsync,
|
||||
Exchange: exchange,
|
||||
store: sm.ChainStore(),
|
||||
sm: sm,
|
||||
self: self,
|
||||
@@ -248,7 +264,7 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
syncer.Bsync.AddPeer(from)
|
||||
syncer.Exchange.AddPeer(from)
|
||||
|
||||
bestPweight := syncer.store.GetHeaviestTipSet().ParentWeight()
|
||||
targetWeight := fts.TipSet().ParentWeight()
|
||||
@@ -479,7 +495,7 @@ func computeMsgMeta(bs cbor.IpldStore, bmsgCids, smsgCids []cid.Cid) (cid.Cid, e
|
||||
}
|
||||
|
||||
// FetchTipSet tries to load the provided tipset from the store, and falls back
|
||||
// to the network (BlockSync) by querying the supplied peer if not found
|
||||
// to the network (client) by querying the supplied peer if not found
|
||||
// locally.
|
||||
//
|
||||
// {hint/usage} This is used from the HELLO protocol, to fetch the greeting
|
||||
@@ -490,7 +506,7 @@ func (syncer *Syncer) FetchTipSet(ctx context.Context, p peer.ID, tsk types.TipS
|
||||
}
|
||||
|
||||
// fall back to the network.
|
||||
return syncer.Bsync.GetFullTipSet(ctx, p, tsk)
|
||||
return syncer.Exchange.GetFullTipSet(ctx, p, tsk)
|
||||
}
|
||||
|
||||
// tryLoadFullTipSet queries the tipset in the ChainStore, and returns a full
|
||||
@@ -863,7 +879,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := beacon.ValidateBlockValues(syncer.beacon, h, *prevBeacon); err != nil {
|
||||
if err := beacon.ValidateBlockValues(syncer.beacon, h, baseTs.Height(), *prevBeacon); err != nil {
|
||||
return xerrors.Errorf("failed to validate blocks random beacon values: %w", err)
|
||||
}
|
||||
return nil
|
||||
@@ -875,10 +891,12 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
|
||||
return xerrors.Errorf("failed to marshal miner address to cbor: %w", err)
|
||||
}
|
||||
|
||||
beaconBase := *prevBeacon
|
||||
if len(h.BeaconEntries) == 0 {
|
||||
if h.Height > build.UpgradeSmokeHeight {
|
||||
buf.Write(baseTs.MinTicket().VRFProof)
|
||||
} else {
|
||||
}
|
||||
|
||||
beaconBase := *prevBeacon
|
||||
if len(h.BeaconEntries) != 0 {
|
||||
beaconBase = h.BeaconEntries[len(h.BeaconEntries)-1]
|
||||
}
|
||||
|
||||
@@ -1192,7 +1210,7 @@ func extractSyncState(ctx context.Context) *SyncerState {
|
||||
// total equality of the BeaconEntries in each block.
|
||||
// 3. Traverse the chain backwards, for each tipset:
|
||||
// 3a. Load it from the chainstore; if found, it move on to its parent.
|
||||
// 3b. Query our peers via BlockSync in batches, requesting up to a
|
||||
// 3b. Query our peers via client in batches, requesting up to a
|
||||
// maximum of 500 tipsets every time.
|
||||
//
|
||||
// Once we've concluded, if we find a mismatching tipset at the height where the
|
||||
@@ -1293,7 +1311,7 @@ loop:
|
||||
if gap := int(blockSet[len(blockSet)-1].Height() - untilHeight); gap < window {
|
||||
window = gap
|
||||
}
|
||||
blks, err := syncer.Bsync.GetBlocks(ctx, at, window)
|
||||
blks, err := syncer.Exchange.GetBlocks(ctx, at, window)
|
||||
if err != nil {
|
||||
// Most likely our peers aren't fully synced yet, but forwarded
|
||||
// new block message (ideally we'd find better peers)
|
||||
@@ -1311,7 +1329,7 @@ loop:
|
||||
// have. Since we fetch from the head backwards our reassembled chain
|
||||
// is sorted in reverse here: we have a child -> parent order, our last
|
||||
// tipset then should be child of the first tipset retrieved.
|
||||
// FIXME: The reassembly logic should be part of the `BlockSync`
|
||||
// FIXME: The reassembly logic should be part of the `client`
|
||||
// service, the consumer should not be concerned with the
|
||||
// `MaxRequestLength` limitation, it should just be able to request
|
||||
// an segment of arbitrary length. The same burden is put on
|
||||
@@ -1361,7 +1379,7 @@ loop:
|
||||
log.Warnf("(fork detected) synced header chain (%s - %d) does not link to our best block (%s - %d)", incoming.Cids(), incoming.Height(), known.Cids(), known.Height())
|
||||
fork, err := syncer.syncFork(ctx, base, known)
|
||||
if err != nil {
|
||||
if xerrors.Is(err, ErrForkTooLong) {
|
||||
if xerrors.Is(err, ErrForkTooLong) || xerrors.Is(err, ErrForkCheckpoint) {
|
||||
// TODO: we're marking this block bad in the same way that we mark invalid blocks bad. Maybe distinguish?
|
||||
log.Warn("adding forked chain to our bad tipset cache")
|
||||
for _, b := range incoming.Blocks() {
|
||||
@@ -1377,15 +1395,24 @@ loop:
|
||||
}
|
||||
|
||||
var ErrForkTooLong = fmt.Errorf("fork longer than threshold")
|
||||
var ErrForkCheckpoint = fmt.Errorf("fork would require us to diverge from checkpointed block")
|
||||
|
||||
// syncFork tries to obtain the chain fragment that links a fork into a common
|
||||
// ancestor in our view of the chain.
|
||||
//
|
||||
// If the fork is too long (build.ForkLengthThreshold), we add the entire subchain to the
|
||||
// denylist. Else, we find the common ancestor, and add the missing chain
|
||||
// If the fork is too long (build.ForkLengthThreshold), or would cause us to diverge from the checkpoint (ErrForkCheckpoint),
|
||||
// we add the entire subchain to the denylist. Else, we find the common ancestor, and add the missing chain
|
||||
// fragment until the fork point to the returned []TipSet.
|
||||
func (syncer *Syncer) syncFork(ctx context.Context, incoming *types.TipSet, known *types.TipSet) ([]*types.TipSet, error) {
|
||||
tips, err := syncer.Bsync.GetBlocks(ctx, incoming.Parents(), int(build.ForkLengthThreshold))
|
||||
|
||||
chkpt := syncer.GetCheckpoint()
|
||||
if known.Key() == chkpt {
|
||||
return nil, ErrForkCheckpoint
|
||||
}
|
||||
|
||||
// TODO: Does this mean we always ask for ForkLengthThreshold blocks from the network, even if we just need, like, 2?
|
||||
// Would it not be better to ask in smaller chunks, given that an ~ForkLengthThreshold is very rare?
|
||||
tips, err := syncer.Exchange.GetBlocks(ctx, incoming.Parents(), int(build.ForkLengthThreshold))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1410,12 +1437,18 @@ func (syncer *Syncer) syncFork(ctx context.Context, incoming *types.TipSet, know
|
||||
if nts.Height() < tips[cur].Height() {
|
||||
cur++
|
||||
} else {
|
||||
// We will be forking away from nts, check that it isn't checkpointed
|
||||
if nts.Key() == chkpt {
|
||||
return nil, ErrForkCheckpoint
|
||||
}
|
||||
|
||||
nts, err = syncer.store.LoadTipSet(nts.Parents())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading next local tipset: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, ErrForkTooLong
|
||||
}
|
||||
|
||||
@@ -1439,6 +1472,7 @@ func (syncer *Syncer) syncMessagesAndCheckState(ctx context.Context, headers []*
|
||||
|
||||
// fills out each of the given tipsets with messages and calls the callback with it
|
||||
func (syncer *Syncer) iterFullTipsets(ctx context.Context, headers []*types.TipSet, cb func(context.Context, *store.FullTipSet) error) error {
|
||||
ss := extractSyncState(ctx)
|
||||
ctx, span := trace.StartSpan(ctx, "iterFullTipsets")
|
||||
defer span.End()
|
||||
|
||||
@@ -1466,12 +1500,13 @@ mainLoop:
|
||||
|
||||
nextI := (i + 1) - batchSize // want to fetch batchSize values, 'i' points to last one we want to fetch, so its 'inclusive' of our request, thus we need to add one to our request start index
|
||||
|
||||
var bstout []*blocksync.CompactedMessages
|
||||
ss.SetStage(api.StageFetchingMessages)
|
||||
var bstout []*exchange.CompactedMessages
|
||||
for len(bstout) < batchSize {
|
||||
next := headers[nextI]
|
||||
|
||||
nreq := batchSize - len(bstout)
|
||||
bstips, err := syncer.Bsync.GetChainMessages(ctx, next, uint64(nreq))
|
||||
bstips, err := syncer.Exchange.GetChainMessages(ctx, next, uint64(nreq))
|
||||
if err != nil {
|
||||
// TODO check errors for temporary nature
|
||||
if windowSize > 1 {
|
||||
@@ -1485,6 +1520,7 @@ mainLoop:
|
||||
bstout = append(bstout, bstips...)
|
||||
nextI += len(bstips)
|
||||
}
|
||||
ss.SetStage(api.StageMessages)
|
||||
|
||||
for bsi := 0; bsi < len(bstout); bsi++ {
|
||||
// temp storage so we don't persist data we dont want to
|
||||
@@ -1516,8 +1552,8 @@ mainLoop:
|
||||
|
||||
if i >= windowSize {
|
||||
newWindowSize := windowSize + 10
|
||||
if newWindowSize > int(blocksync.MaxRequestLength) {
|
||||
newWindowSize = int(blocksync.MaxRequestLength)
|
||||
if newWindowSize > int(exchange.MaxRequestLength) {
|
||||
newWindowSize = int(exchange.MaxRequestLength)
|
||||
}
|
||||
if newWindowSize > windowSize {
|
||||
windowSize = newWindowSize
|
||||
@@ -1534,7 +1570,7 @@ mainLoop:
|
||||
return nil
|
||||
}
|
||||
|
||||
func persistMessages(bs bstore.Blockstore, bst *blocksync.CompactedMessages) error {
|
||||
func persistMessages(bs bstore.Blockstore, bst *exchange.CompactedMessages) error {
|
||||
for _, m := range bst.Bls {
|
||||
//log.Infof("putting BLS message: %s", m.Cid())
|
||||
if _, err := store.PutMessage(bs, m); err != nil {
|
||||
@@ -1641,6 +1677,11 @@ func (syncer *Syncer) MarkBad(blk cid.Cid) {
|
||||
syncer.bad.Add(blk, NewBadBlockReason([]cid.Cid{blk}, "manually marked bad"))
|
||||
}
|
||||
|
||||
// UnmarkBad manually adds a block to the "bad blocks" cache.
|
||||
func (syncer *Syncer) UnmarkBad(blk cid.Cid) {
|
||||
syncer.bad.Remove(blk)
|
||||
}
|
||||
|
||||
func (syncer *Syncer) CheckBadBlockCache(blk cid.Cid) (string, bool) {
|
||||
bbr, ok := syncer.bad.Has(blk)
|
||||
return bbr.String(), ok
|
||||
|
||||
+114
-3
@@ -34,7 +34,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
"github.com/filecoin-project/lotus/node/impl"
|
||||
"github.com/filecoin-project/lotus/node/modules"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
)
|
||||
|
||||
@@ -234,7 +233,6 @@ func (tu *syncTestUtil) addSourceNode(gen int) {
|
||||
node.Repo(sourceRepo),
|
||||
node.MockHost(tu.mn),
|
||||
node.Test(),
|
||||
node.Override(new(dtypes.Bootstrapper), dtypes.Bootstrapper(true)),
|
||||
|
||||
node.Override(new(modules.Genesis), modules.LoadGenesis(genesis)),
|
||||
)
|
||||
@@ -267,7 +265,6 @@ func (tu *syncTestUtil) addClientNode() int {
|
||||
node.Repo(repo.NewMemory(nil)),
|
||||
node.MockHost(tu.mn),
|
||||
node.Test(),
|
||||
node.Override(new(dtypes.Bootstrapper), dtypes.Bootstrapper(true)),
|
||||
|
||||
node.Override(new(modules.Genesis), modules.LoadGenesis(tu.genesis)),
|
||||
)
|
||||
@@ -336,6 +333,36 @@ func (tu *syncTestUtil) compareSourceState(with int) {
|
||||
}
|
||||
}
|
||||
|
||||
func (tu *syncTestUtil) assertBad(node int, ts *types.TipSet) {
|
||||
for _, blk := range ts.Cids() {
|
||||
rsn, err := tu.nds[node].SyncCheckBad(context.TODO(), blk)
|
||||
require.NoError(tu.t, err)
|
||||
require.True(tu.t, len(rsn) != 0)
|
||||
}
|
||||
}
|
||||
|
||||
func (tu *syncTestUtil) getHead(node int) *types.TipSet {
|
||||
ts, err := tu.nds[node].ChainHead(context.TODO())
|
||||
require.NoError(tu.t, err)
|
||||
return ts
|
||||
}
|
||||
|
||||
func (tu *syncTestUtil) checkpointTs(node int, tsk types.TipSetKey) {
|
||||
require.NoError(tu.t, tu.nds[node].SyncCheckpoint(context.TODO(), tsk))
|
||||
}
|
||||
|
||||
func (tu *syncTestUtil) waitUntilNodeHasTs(node int, tsk types.TipSetKey) {
|
||||
for {
|
||||
_, err := tu.nds[node].ChainGetTipSet(context.TODO(), tsk)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Time to allow for syncing and validation
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
|
||||
func (tu *syncTestUtil) waitUntilSync(from, to int) {
|
||||
target, err := tu.nds[from].ChainHead(tu.ctx)
|
||||
if err != nil {
|
||||
@@ -681,3 +708,87 @@ func TestSyncInputs(t *testing.T) {
|
||||
t.Fatal("should error on block with nil election proof")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncCheckpointHead(t *testing.T) {
|
||||
H := 10
|
||||
tu := prepSyncTest(t, H)
|
||||
|
||||
p1 := tu.addClientNode()
|
||||
p2 := tu.addClientNode()
|
||||
|
||||
fmt.Println("GENESIS: ", tu.g.Genesis().Cid())
|
||||
tu.loadChainToNode(p1)
|
||||
tu.loadChainToNode(p2)
|
||||
|
||||
base := tu.g.CurTipset
|
||||
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
|
||||
|
||||
// The two nodes fork at this point into 'a' and 'b'
|
||||
a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil)
|
||||
a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil)
|
||||
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil)
|
||||
|
||||
tu.waitUntilSyncTarget(p1, a.TipSet())
|
||||
tu.checkpointTs(p1, a.TipSet().Key())
|
||||
|
||||
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
|
||||
// chain B will now be heaviest
|
||||
b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil)
|
||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
|
||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
|
||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
|
||||
|
||||
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
|
||||
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
|
||||
|
||||
// Now for the fun part!! p1 should mark p2's head as BAD.
|
||||
|
||||
require.NoError(t, tu.mn.LinkAll())
|
||||
tu.connect(p1, p2)
|
||||
tu.waitUntilNodeHasTs(p1, b.TipSet().Key())
|
||||
p1Head := tu.getHead(p1)
|
||||
require.Equal(tu.t, p1Head, a.TipSet())
|
||||
tu.assertBad(p1, b.TipSet())
|
||||
}
|
||||
|
||||
func TestSyncCheckpointEarlierThanHead(t *testing.T) {
|
||||
H := 10
|
||||
tu := prepSyncTest(t, H)
|
||||
|
||||
p1 := tu.addClientNode()
|
||||
p2 := tu.addClientNode()
|
||||
|
||||
fmt.Println("GENESIS: ", tu.g.Genesis().Cid())
|
||||
tu.loadChainToNode(p1)
|
||||
tu.loadChainToNode(p2)
|
||||
|
||||
base := tu.g.CurTipset
|
||||
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
|
||||
|
||||
// The two nodes fork at this point into 'a' and 'b'
|
||||
a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil)
|
||||
a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil)
|
||||
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil)
|
||||
|
||||
tu.waitUntilSyncTarget(p1, a.TipSet())
|
||||
tu.checkpointTs(p1, a1.TipSet().Key())
|
||||
|
||||
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
|
||||
// chain B will now be heaviest
|
||||
b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil)
|
||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
|
||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
|
||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
|
||||
|
||||
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
|
||||
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
|
||||
|
||||
// Now for the fun part!! p1 should mark p2's head as BAD.
|
||||
|
||||
require.NoError(t, tu.mn.LinkAll())
|
||||
tu.connect(p1, p2)
|
||||
tu.waitUntilNodeHasTs(p1, b.TipSet().Key())
|
||||
p1Head := tu.getHead(p1)
|
||||
require.Equal(tu.t, p1Head, a.TipSet())
|
||||
tu.assertBad(p1, b.TipSet())
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -12,23 +11,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func SyncStageString(v api.SyncStateStage) string {
|
||||
switch v {
|
||||
case api.StageHeaders:
|
||||
return "header sync"
|
||||
case api.StagePersistHeaders:
|
||||
return "persisting headers"
|
||||
case api.StageMessages:
|
||||
return "message sync"
|
||||
case api.StageSyncComplete:
|
||||
return "complete"
|
||||
case api.StageSyncErrored:
|
||||
return "error"
|
||||
default:
|
||||
return fmt.Sprintf("<unknown: %d>", v)
|
||||
}
|
||||
}
|
||||
|
||||
type SyncerState struct {
|
||||
lk sync.Mutex
|
||||
Target *types.TipSet
|
||||
|
||||
+2
-4
@@ -15,6 +15,7 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/cron"
|
||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
@@ -27,9 +28,6 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/system"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
)
|
||||
|
||||
type Invoker struct {
|
||||
@@ -47,7 +45,7 @@ func NewInvoker() *Invoker {
|
||||
}
|
||||
|
||||
// add builtInCode using: register(cid, singleton)
|
||||
inv.Register(builtin.SystemActorCodeID, system.Actor{}, adt.EmptyValue{})
|
||||
inv.Register(builtin.SystemActorCodeID, system.Actor{}, abi.EmptyValue{})
|
||||
inv.Register(builtin.InitActorCodeID, init_.Actor{}, init_.State{})
|
||||
inv.Register(builtin.RewardActorCodeID, reward.Actor{}, reward.State{})
|
||||
inv.Register(builtin.CronActorCodeID, cron.Actor{}, cron.State{})
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/stretchr/testify/assert"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@@ -13,7 +15,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
type basicContract struct{}
|
||||
@@ -60,17 +61,17 @@ func (b basicContract) Exports() []interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
func (basicContract) InvokeSomething0(rt runtime.Runtime, params *basicParams) *adt.EmptyValue {
|
||||
func (basicContract) InvokeSomething0(rt runtime.Runtime, params *basicParams) *abi.EmptyValue {
|
||||
rt.Abortf(exitcode.ExitCode(params.B), "params.B")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (basicContract) BadParam(rt runtime.Runtime, params *basicParams) *adt.EmptyValue {
|
||||
func (basicContract) BadParam(rt runtime.Runtime, params *basicParams) *abi.EmptyValue {
|
||||
rt.Abortf(255, "bad params")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (basicContract) InvokeSomething10(rt runtime.Runtime, params *basicParams) *adt.EmptyValue {
|
||||
func (basicContract) InvokeSomething10(rt runtime.Runtime, params *basicParams) *abi.EmptyValue {
|
||||
rt.Abortf(exitcode.ExitCode(params.B+10), "params.B")
|
||||
return nil
|
||||
}
|
||||
|
||||
+4
-3
@@ -8,6 +8,8 @@ import (
|
||||
gruntime "runtime"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
@@ -16,7 +18,6 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@@ -56,7 +57,7 @@ type Runtime struct {
|
||||
lastGasCharge *types.GasTrace
|
||||
}
|
||||
|
||||
func (rt *Runtime) NetworkVersion() vmr.NetworkVersion {
|
||||
func (rt *Runtime) NetworkVersion() network.Version {
|
||||
return rt.vm.GetNtwkVersion(rt.ctx, rt.CurrEpoch())
|
||||
}
|
||||
|
||||
@@ -136,7 +137,7 @@ func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act
|
||||
switch ret := ret.(type) {
|
||||
case []byte:
|
||||
return ret, nil
|
||||
case *adt.EmptyValue:
|
||||
case *abi.EmptyValue:
|
||||
return nil, nil
|
||||
case cbg.CBORMarshaler:
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
+3
-3
@@ -7,7 +7,7 @@ import (
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||
|
||||
@@ -142,7 +142,7 @@ func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message, origin
|
||||
}
|
||||
|
||||
type CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error)
|
||||
type NtwkVersionGetter func(context.Context, abi.ChainEpoch) runtime.NetworkVersion
|
||||
type NtwkVersionGetter func(context.Context, abi.ChainEpoch) network.Version
|
||||
|
||||
type VM struct {
|
||||
cstate *state.StateTree
|
||||
@@ -722,7 +722,7 @@ func (vm *VM) SetInvoker(i *Invoker) {
|
||||
vm.inv = i
|
||||
}
|
||||
|
||||
func (vm *VM) GetNtwkVersion(ctx context.Context, ce abi.ChainEpoch) runtime.NetworkVersion {
|
||||
func (vm *VM) GetNtwkVersion(ctx context.Context, ce abi.ChainEpoch) network.Version {
|
||||
return vm.ntwkVersion(ctx, ce)
|
||||
}
|
||||
|
||||
|
||||
@@ -337,25 +337,6 @@ var chainSetHeadCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
func parseTipSet(ctx context.Context, api api.FullNode, vals []string) (*types.TipSet, error) {
|
||||
var headers []*types.BlockHeader
|
||||
for _, c := range vals {
|
||||
blkc, err := cid.Decode(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bh, err := api.ChainGetBlock(ctx, blkc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
headers = append(headers, bh)
|
||||
}
|
||||
|
||||
return types.NewTipSet(headers)
|
||||
}
|
||||
|
||||
var chainListCmd = &cli.Command{
|
||||
Name: "list",
|
||||
Usage: "View a segment of the chain",
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ var logSetLevel = &cli.Command{
|
||||
|
||||
The system flag can be specified multiple times.
|
||||
|
||||
eg) log set-level --system chain --system blocksync debug
|
||||
eg) log set-level --system chain --system chainxchg debug
|
||||
|
||||
Available Levels:
|
||||
debug
|
||||
|
||||
+116
-9
@@ -3,6 +3,7 @@ package cli
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
stdbig "math/big"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
@@ -11,7 +12,11 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
lapi "github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
@@ -26,6 +31,7 @@ var mpoolCmd = &cli.Command{
|
||||
mpoolReplaceCmd,
|
||||
mpoolFindCmd,
|
||||
mpoolConfig,
|
||||
mpoolGasPerfCmd,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -293,6 +299,10 @@ var mpoolReplaceCmd = &cli.Command{
|
||||
Name: "gas-limit",
|
||||
Usage: "gas price for new message",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "auto",
|
||||
Usage: "automatically reprice the specified message",
|
||||
},
|
||||
},
|
||||
ArgsUsage: "[from] [nonce]",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
@@ -342,15 +352,29 @@ var mpoolReplaceCmd = &cli.Command{
|
||||
|
||||
msg := found.Message
|
||||
|
||||
msg.GasLimit = cctx.Int64("gas-limit")
|
||||
msg.GasPremium, err = types.BigFromString(cctx.String("gas-premium"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing gas-premium: %w", err)
|
||||
}
|
||||
// TODO: estimate fee cap here
|
||||
msg.GasFeeCap, err = types.BigFromString(cctx.String("gas-feecap"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing gas-feecap: %w", err)
|
||||
if cctx.Bool("auto") {
|
||||
// msg.GasLimit = 0 // TODO: need to fix the way we estimate gas limits to account for the messages already being in the mempool
|
||||
msg.GasFeeCap = abi.NewTokenAmount(0)
|
||||
msg.GasPremium = abi.NewTokenAmount(0)
|
||||
retm, err := api.GasEstimateMessageGas(ctx, &msg, &lapi.MessageSendSpec{}, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to estimate gas values: %w", err)
|
||||
}
|
||||
msg.GasFeeCap = retm.GasFeeCap
|
||||
|
||||
minRBF := messagepool.ComputeMinRBF(msg.GasPremium)
|
||||
msg.GasPremium = big.Max(retm.GasPremium, minRBF)
|
||||
} else {
|
||||
msg.GasLimit = cctx.Int64("gas-limit")
|
||||
msg.GasPremium, err = types.BigFromString(cctx.String("gas-premium"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing gas-premium: %w", err)
|
||||
}
|
||||
// TODO: estimate fee cap here
|
||||
msg.GasFeeCap, err = types.BigFromString(cctx.String("gas-feecap"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing gas-feecap: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
smsg, err := api.WalletSignMessage(ctx, msg.From, &msg)
|
||||
@@ -495,3 +519,86 @@ var mpoolConfig = &cli.Command{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var mpoolGasPerfCmd = &cli.Command{
|
||||
Name: "gas-perf",
|
||||
Usage: "Check gas performance of messages in mempool",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "all",
|
||||
Usage: "print gas performance for all mempool messages (default only prints for local)",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msgs, err := api.MpoolPending(ctx, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var filter map[address.Address]struct{}
|
||||
if !cctx.Bool("all") {
|
||||
filter = map[address.Address]struct{}{}
|
||||
|
||||
addrss, err := api.WalletList(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting local addresses: %w", err)
|
||||
}
|
||||
|
||||
for _, a := range addrss {
|
||||
filter[a] = struct{}{}
|
||||
}
|
||||
|
||||
var filtered []*types.SignedMessage
|
||||
for _, msg := range msgs {
|
||||
if _, has := filter[msg.Message.From]; !has {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, msg)
|
||||
}
|
||||
msgs = filtered
|
||||
}
|
||||
|
||||
ts, err := api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get chain head: %w", err)
|
||||
}
|
||||
|
||||
baseFee := ts.Blocks()[0].ParentBaseFee
|
||||
|
||||
bigBlockGasLimit := big.NewInt(build.BlockGasLimit)
|
||||
|
||||
getGasReward := func(msg *types.SignedMessage) big.Int {
|
||||
maxPremium := types.BigSub(msg.Message.GasFeeCap, baseFee)
|
||||
if types.BigCmp(maxPremium, msg.Message.GasPremium) < 0 {
|
||||
maxPremium = msg.Message.GasPremium
|
||||
}
|
||||
return types.BigMul(maxPremium, types.NewInt(uint64(msg.Message.GasLimit)))
|
||||
}
|
||||
|
||||
getGasPerf := func(gasReward big.Int, gasLimit int64) float64 {
|
||||
// gasPerf = gasReward * build.BlockGasLimit / gasLimit
|
||||
a := new(stdbig.Rat).SetInt(new(stdbig.Int).Mul(gasReward.Int, bigBlockGasLimit.Int))
|
||||
b := stdbig.NewRat(1, gasLimit)
|
||||
c := new(stdbig.Rat).Mul(a, b)
|
||||
r, _ := c.Float64()
|
||||
return r
|
||||
}
|
||||
|
||||
for _, m := range msgs {
|
||||
gasReward := getGasReward(m)
|
||||
gasPerf := getGasPerf(gasReward, m.Message.GasLimit)
|
||||
|
||||
fmt.Printf("%s\t%d\t%s\t%f\n", m.Message.From, m.Message.Nonce, gasReward, gasPerf)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
+298
-2
@@ -37,9 +37,13 @@ var multisigCmd = &cli.Command{
|
||||
msigInspectCmd,
|
||||
msigProposeCmd,
|
||||
msigApproveCmd,
|
||||
msigAddProposeCmd,
|
||||
msigAddApproveCmd,
|
||||
msigAddCancelCmd,
|
||||
msigSwapProposeCmd,
|
||||
msigSwapApproveCmd,
|
||||
msigSwapCancelCmd,
|
||||
msigVestedCmd,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -506,6 +510,236 @@ var msigApproveCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var msigAddProposeCmd = &cli.Command{
|
||||
Name: "add-propose",
|
||||
Usage: "Propose to add a signer",
|
||||
ArgsUsage: "[multisigAddress signer]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "increase-threshold",
|
||||
Usage: "whether the number of required signers should be increased",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "from",
|
||||
Usage: "account to send the propose message from",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.Args().Len() != 2 {
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address and signer address"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr, err := address.NewFromString(cctx.Args().Get(1))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var from address.Address
|
||||
if cctx.IsSet("from") {
|
||||
f, err := address.NewFromString(cctx.String("from"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
from = f
|
||||
} else {
|
||||
defaddr, err := api.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
from = defaddr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigAddPropose(ctx, msig, from, addr, cctx.Bool("increase-threshold"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("sent add proposal in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if wait.Receipt.ExitCode != 0 {
|
||||
return fmt.Errorf("add proposal returned exit %d", wait.Receipt.ExitCode)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var msigAddApproveCmd = &cli.Command{
|
||||
Name: "add-approve",
|
||||
Usage: "Approve a message to add a signer",
|
||||
ArgsUsage: "[multisigAddress proposerAddress txId newAddress increaseThreshold]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "from",
|
||||
Usage: "account to send the approve message from",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.Args().Len() != 5 {
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, proposer address, transaction id, new signer address, whether to increase threshold"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
prop, err := address.NewFromString(cctx.Args().Get(1))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txid, err := strconv.ParseUint(cctx.Args().Get(2), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newAdd, err := address.NewFromString(cctx.Args().Get(3))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
inc, err := strconv.ParseBool(cctx.Args().Get(4))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var from address.Address
|
||||
if cctx.IsSet("from") {
|
||||
f, err := address.NewFromString(cctx.String("from"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
from = f
|
||||
} else {
|
||||
defaddr, err := api.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
from = defaddr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigAddApprove(ctx, msig, from, txid, prop, newAdd, inc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("sent add approval in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if wait.Receipt.ExitCode != 0 {
|
||||
return fmt.Errorf("add approval returned exit %d", wait.Receipt.ExitCode)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var msigAddCancelCmd = &cli.Command{
|
||||
Name: "add-cancel",
|
||||
Usage: "Cancel a message to add a signer",
|
||||
ArgsUsage: "[multisigAddress txId newAddress increaseThreshold]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "from",
|
||||
Usage: "account to send the approve message from",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.Args().Len() != 4 {
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, transaction id, new signer address, whether to increase threshold"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txid, err := strconv.ParseUint(cctx.Args().Get(1), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newAdd, err := address.NewFromString(cctx.Args().Get(2))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
inc, err := strconv.ParseBool(cctx.Args().Get(3))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var from address.Address
|
||||
if cctx.IsSet("from") {
|
||||
f, err := address.NewFromString(cctx.String("from"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
from = f
|
||||
} else {
|
||||
defaddr, err := api.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
from = defaddr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigAddCancel(ctx, msig, from, txid, newAdd, inc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("sent add cancellation in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if wait.Receipt.ExitCode != 0 {
|
||||
return fmt.Errorf("add cancellation returned exit %d", wait.Receipt.ExitCode)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var msigSwapProposeCmd = &cli.Command{
|
||||
Name: "swap-propose",
|
||||
Usage: "Propose to swap signers",
|
||||
@@ -722,7 +956,7 @@ var msigSwapCancelCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("sent swap approval in message: ", msgCid)
|
||||
fmt.Println("sent swap cancellation in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
|
||||
if err != nil {
|
||||
@@ -730,9 +964,71 @@ var msigSwapCancelCmd = &cli.Command{
|
||||
}
|
||||
|
||||
if wait.Receipt.ExitCode != 0 {
|
||||
return fmt.Errorf("swap approval returned exit %d", wait.Receipt.ExitCode)
|
||||
return fmt.Errorf("swap cancellation returned exit %d", wait.Receipt.ExitCode)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var msigVestedCmd = &cli.Command{
|
||||
Name: "vested",
|
||||
Usage: "Gets the amount vested in an msig between two epochs",
|
||||
ArgsUsage: "[multisigAddress]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.Int64Flag{
|
||||
Name: "start-epoch",
|
||||
Usage: "start epoch to measure vesting from",
|
||||
Value: 0,
|
||||
},
|
||||
&cli.Int64Flag{
|
||||
Name: "end-epoch",
|
||||
Usage: "end epoch to stop measure vesting at",
|
||||
Value: -1,
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.Args().Len() != 1 {
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
start, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Int64("start-epoch")), types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var end *types.TipSet
|
||||
if cctx.Int64("end-epoch") < 0 {
|
||||
end, err = LoadTipSet(ctx, cctx, api)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
end, err = api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Int64("end-epoch")), types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
ret, err := api.MsigGetVested(ctx, msig, start.Key(), end.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Vested: %s between %d and %d\n", types.FIL(ret), start.Height(), end.Height())
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
+46
-5
@@ -8,12 +8,17 @@ import (
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/addrutil"
|
||||
)
|
||||
|
||||
@@ -141,7 +146,7 @@ var NetListen = &cli.Command{
|
||||
var netConnect = &cli.Command{
|
||||
Name: "connect",
|
||||
Usage: "Connect to a peer",
|
||||
ArgsUsage: "[peerMultiaddr]",
|
||||
ArgsUsage: "[peerMultiaddr|minerActorAddress]",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetAPI(cctx)
|
||||
if err != nil {
|
||||
@@ -152,7 +157,43 @@ var netConnect = &cli.Command{
|
||||
|
||||
pis, err := addrutil.ParseAddresses(ctx, cctx.Args().Slice())
|
||||
if err != nil {
|
||||
return err
|
||||
a, perr := address.NewFromString(cctx.Args().First())
|
||||
if perr != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
na, fc, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fc()
|
||||
|
||||
mi, err := na.StateMinerInfo(ctx, a, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting miner info: %w", err)
|
||||
}
|
||||
|
||||
if mi.PeerId == nil {
|
||||
return xerrors.Errorf("no PeerID for miner")
|
||||
}
|
||||
multiaddrs := make([]multiaddr.Multiaddr, 0, len(mi.Multiaddrs))
|
||||
for i, a := range mi.Multiaddrs {
|
||||
maddr, err := multiaddr.NewMultiaddrBytes(a)
|
||||
if err != nil {
|
||||
log.Warnf("parsing multiaddr %d (%x): %s", i, a, err)
|
||||
continue
|
||||
}
|
||||
multiaddrs = append(multiaddrs, maddr)
|
||||
}
|
||||
|
||||
pi := peer.AddrInfo{
|
||||
ID: *mi.PeerId,
|
||||
Addrs: multiaddrs,
|
||||
}
|
||||
|
||||
fmt.Printf("%s -> %s\n", a, pi)
|
||||
|
||||
pis = append(pis, pi)
|
||||
}
|
||||
|
||||
for _, pi := range pis {
|
||||
|
||||
+73
-3
@@ -5,13 +5,14 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain"
|
||||
)
|
||||
|
||||
var syncCmd = &cli.Command{
|
||||
@@ -21,7 +22,9 @@ var syncCmd = &cli.Command{
|
||||
syncStatusCmd,
|
||||
syncWaitCmd,
|
||||
syncMarkBadCmd,
|
||||
syncUnmarkBadCmd,
|
||||
syncCheckBadCmd,
|
||||
syncCheckpointCmd,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -61,7 +64,7 @@ var syncStatusCmd = &cli.Command{
|
||||
fmt.Printf("\tBase:\t%s\n", base)
|
||||
fmt.Printf("\tTarget:\t%s (%d)\n", target, theight)
|
||||
fmt.Printf("\tHeight diff:\t%d\n", heightDiff)
|
||||
fmt.Printf("\tStage: %s\n", chain.SyncStageString(ss.Stage))
|
||||
fmt.Printf("\tStage: %s\n", ss.Stage)
|
||||
fmt.Printf("\tHeight: %d\n", ss.Height)
|
||||
if ss.End.IsZero() {
|
||||
if !ss.Start.IsZero() {
|
||||
@@ -118,6 +121,31 @@ var syncMarkBadCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var syncUnmarkBadCmd = &cli.Command{
|
||||
Name: "unmark-bad",
|
||||
Usage: "Unmark the given block as bad, makes it possible to sync to a chain containing it",
|
||||
ArgsUsage: "[blockCid]",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
napi, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("must specify block cid to unmark")
|
||||
}
|
||||
|
||||
bcid, err := cid.Decode(cctx.Args().First())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to decode input as a cid: %s", err)
|
||||
}
|
||||
|
||||
return napi.SyncUnmarkBad(ctx, bcid)
|
||||
},
|
||||
}
|
||||
|
||||
var syncCheckBadCmd = &cli.Command{
|
||||
Name: "check-bad",
|
||||
Usage: "check if the given block was marked bad, and for what reason",
|
||||
@@ -154,6 +182,48 @@ var syncCheckBadCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var syncCheckpointCmd = &cli.Command{
|
||||
Name: "checkpoint",
|
||||
Usage: "mark a certain tipset as checkpointed; the node will never fork away from this tipset",
|
||||
ArgsUsage: "[tipsetKey]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.Uint64Flag{
|
||||
Name: "epoch",
|
||||
Usage: "checkpoint the tipset at the given epoch",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
napi, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
var ts *types.TipSet
|
||||
|
||||
if cctx.IsSet("epoch") {
|
||||
ts, err = napi.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Uint64("epoch")), types.EmptyTSK)
|
||||
}
|
||||
if ts == nil {
|
||||
ts, err = parseTipSet(ctx, napi, cctx.Args().Slice())
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ts == nil {
|
||||
return fmt.Errorf("must pass cids for tipset to set as head, or specify epoch flag")
|
||||
}
|
||||
|
||||
if err := napi.SyncCheckpoint(ctx, ts.Key()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func SyncWait(ctx context.Context, napi api.FullNode) error {
|
||||
for {
|
||||
state, err := napi.SyncState(ctx)
|
||||
@@ -186,7 +256,7 @@ func SyncWait(ctx context.Context, napi api.FullNode) error {
|
||||
theight = ss.Target.Height()
|
||||
}
|
||||
|
||||
fmt.Printf("\r\x1b[2KWorker %d: Target Height: %d\tTarget: %s\tState: %s\tHeight: %d", working, theight, target, chain.SyncStageString(ss.Stage), ss.Height)
|
||||
fmt.Printf("\r\x1b[2KWorker %d: Target Height: %d\tTarget: %s\tState: %s\tHeight: %d", working, theight, target, ss.Stage, ss.Height)
|
||||
|
||||
if time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelaySecs) {
|
||||
fmt.Println("\nDone!")
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
func parseTipSet(ctx context.Context, api api.FullNode, vals []string) (*types.TipSet, error) {
|
||||
var headers []*types.BlockHeader
|
||||
for _, c := range vals {
|
||||
blkc, err := cid.Decode(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bh, err := api.ChainGetBlock(ctx, blkc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
headers = append(headers, bh)
|
||||
}
|
||||
|
||||
return types.NewTipSet(headers)
|
||||
}
|
||||
@@ -694,7 +694,7 @@ func (p *Processor) getMinerSectorChanges(ctx context.Context, m minerActorInfo)
|
||||
}
|
||||
|
||||
func (p *Processor) diffMinerPartitions(ctx context.Context, m minerActorInfo, events chan<- *MinerSectorsEvent) error {
|
||||
prevMiner, err := p.getMinerStateAt(ctx, m.common.addr, m.common.tsKey)
|
||||
prevMiner, err := p.getMinerStateAt(ctx, m.common.addr, m.common.parentTsKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ const FlagWorkerRepo = "worker-repo"
|
||||
const FlagWorkerRepoDeprecation = "workerrepo"
|
||||
|
||||
func main() {
|
||||
build.RunningNodeType = build.NodeWorker
|
||||
|
||||
lotuslog.SetupLogLevels()
|
||||
|
||||
local := []*cli.Command{
|
||||
@@ -187,8 +189,8 @@ var runCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if v.APIVersion != build.APIVersion {
|
||||
return xerrors.Errorf("lotus-miner API version doesn't match: local: %s", api.Version{APIVersion: build.APIVersion})
|
||||
if v.APIVersion != build.MinerAPIVersion {
|
||||
return xerrors.Errorf("lotus-miner API version doesn't match: expected: %s", api.Version{APIVersion: build.MinerAPIVersion})
|
||||
}
|
||||
log.Infof("Remote version %s", v)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ type worker struct {
|
||||
}
|
||||
|
||||
func (w *worker) Version(context.Context) (build.Version, error) {
|
||||
return build.APIVersion, nil
|
||||
return build.WorkerAPIVersion, nil
|
||||
}
|
||||
|
||||
func (w *worker) StorageAddLocal(ctx context.Context, path string) error {
|
||||
|
||||
@@ -33,6 +33,7 @@ func main() {
|
||||
mpoolCmd,
|
||||
genesisVerifyCmd,
|
||||
mathCmd,
|
||||
mpoolStatsCmd,
|
||||
}
|
||||
|
||||
app := &cli.App{
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"contrib.go.opencensus.io/exporter/prometheus"
|
||||
"github.com/ipfs/go-cid"
|
||||
logging "github.com/ipfs/go-log"
|
||||
"github.com/urfave/cli/v2"
|
||||
"go.opencensus.io/stats"
|
||||
"go.opencensus.io/stats/view"
|
||||
"go.opencensus.io/tag"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
lapi "github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
)
|
||||
|
||||
var (
|
||||
MpoolAge = stats.Float64("mpoolage", "Age of messages in the mempool", stats.UnitSeconds)
|
||||
MpoolSize = stats.Int64("mpoolsize", "Number of messages in mempool", stats.UnitDimensionless)
|
||||
MpoolInboundRate = stats.Int64("inbound", "Counter for inbound messages", stats.UnitDimensionless)
|
||||
BlockInclusionRate = stats.Int64("inclusion", "Counter for message included in blocks", stats.UnitDimensionless)
|
||||
MsgWaitTime = stats.Float64("msg-wait-time", "Wait time of messages to make it into a block", stats.UnitSeconds)
|
||||
)
|
||||
|
||||
var (
|
||||
LeTag, _ = tag.NewKey("quantile")
|
||||
MTTag, _ = tag.NewKey("msg_type")
|
||||
)
|
||||
|
||||
var (
|
||||
AgeView = &view.View{
|
||||
Name: "mpool-age",
|
||||
Measure: MpoolAge,
|
||||
TagKeys: []tag.Key{LeTag, MTTag},
|
||||
Aggregation: view.LastValue(),
|
||||
}
|
||||
SizeView = &view.View{
|
||||
Name: "mpool-size",
|
||||
Measure: MpoolSize,
|
||||
TagKeys: []tag.Key{MTTag},
|
||||
Aggregation: view.LastValue(),
|
||||
}
|
||||
InboundRate = &view.View{
|
||||
Name: "msg-inbound",
|
||||
Measure: MpoolInboundRate,
|
||||
TagKeys: []tag.Key{MTTag},
|
||||
Aggregation: view.Count(),
|
||||
}
|
||||
InclusionRate = &view.View{
|
||||
Name: "msg-inclusion",
|
||||
Measure: BlockInclusionRate,
|
||||
TagKeys: []tag.Key{MTTag},
|
||||
Aggregation: view.Count(),
|
||||
}
|
||||
MsgWait = &view.View{
|
||||
Name: "msg-wait",
|
||||
Measure: MsgWaitTime,
|
||||
TagKeys: []tag.Key{MTTag},
|
||||
Aggregation: view.Distribution(10, 30, 60, 120, 240, 600, 1800, 3600),
|
||||
}
|
||||
)
|
||||
|
||||
type msgInfo struct {
|
||||
msg *types.SignedMessage
|
||||
seen time.Time
|
||||
}
|
||||
|
||||
var mpoolStatsCmd = &cli.Command{
|
||||
Name: "mpool-stats",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
logging.SetLogLevel("rpc", "ERROR")
|
||||
|
||||
if err := view.Register(AgeView, SizeView, InboundRate, InclusionRate, MsgWait); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
expo, err := prometheus.NewExporter(prometheus.Options{
|
||||
Namespace: "lotusmpool",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
http.Handle("/debug/metrics", expo)
|
||||
|
||||
go func() {
|
||||
if err := http.ListenAndServe(":10555", nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer closer()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
updates, err := api.MpoolSub(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mcache := make(map[address.Address]bool)
|
||||
isMiner := func(addr address.Address) (bool, error) {
|
||||
cache, ok := mcache[addr]
|
||||
if ok {
|
||||
return cache, nil
|
||||
}
|
||||
|
||||
act, err := api.StateGetActor(ctx, addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
ism := act.Code == builtin.StorageMinerActorCodeID
|
||||
mcache[addr] = ism
|
||||
return ism, nil
|
||||
}
|
||||
|
||||
wpostTracker := make(map[cid.Cid]*msgInfo)
|
||||
tracker := make(map[cid.Cid]*msgInfo)
|
||||
tick := time.Tick(time.Second)
|
||||
for {
|
||||
select {
|
||||
case u, ok := <-updates:
|
||||
if !ok {
|
||||
return fmt.Errorf("connection with lotus node broke")
|
||||
}
|
||||
switch u.Type {
|
||||
case lapi.MpoolAdd:
|
||||
stats.Record(ctx, MpoolInboundRate.M(1))
|
||||
tracker[u.Message.Cid()] = &msgInfo{
|
||||
msg: u.Message,
|
||||
seen: time.Now(),
|
||||
}
|
||||
|
||||
if u.Message.Message.Method == builtin.MethodsMiner.SubmitWindowedPoSt {
|
||||
|
||||
miner, err := isMiner(u.Message.Message.To)
|
||||
if err != nil {
|
||||
log.Warnf("failed to determine if message target was to a miner: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if miner {
|
||||
wpostTracker[u.Message.Cid()] = &msgInfo{
|
||||
msg: u.Message,
|
||||
seen: time.Now(),
|
||||
}
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(MTTag, "wpost")}, MpoolInboundRate.M(1))
|
||||
}
|
||||
}
|
||||
|
||||
case lapi.MpoolRemove:
|
||||
mi, ok := tracker[u.Message.Cid()]
|
||||
if ok {
|
||||
fmt.Printf("%s was in the mempool for %s (feecap=%s, prem=%s)\n", u.Message.Cid(), time.Since(mi.seen), u.Message.Message.GasFeeCap, u.Message.Message.GasPremium)
|
||||
stats.Record(ctx, BlockInclusionRate.M(1))
|
||||
stats.Record(ctx, MsgWaitTime.M(time.Since(mi.seen).Seconds()))
|
||||
delete(tracker, u.Message.Cid())
|
||||
}
|
||||
|
||||
wm, ok := wpostTracker[u.Message.Cid()]
|
||||
if ok {
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(MTTag, "wpost")}, BlockInclusionRate.M(1))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(MTTag, "wpost")}, MsgWaitTime.M(time.Since(wm.seen).Seconds()))
|
||||
delete(wpostTracker, u.Message.Cid())
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unrecognized mpool update state: %d", u.Type)
|
||||
}
|
||||
case <-tick:
|
||||
var ages []time.Duration
|
||||
if len(tracker) > 0 {
|
||||
for _, v := range tracker {
|
||||
age := time.Since(v.seen)
|
||||
ages = append(ages, age)
|
||||
}
|
||||
|
||||
st := ageStats(ages)
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "40")}, MpoolAge.M(st.Perc40.Seconds()))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "50")}, MpoolAge.M(st.Perc50.Seconds()))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "60")}, MpoolAge.M(st.Perc60.Seconds()))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "70")}, MpoolAge.M(st.Perc70.Seconds()))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "80")}, MpoolAge.M(st.Perc80.Seconds()))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "90")}, MpoolAge.M(st.Perc90.Seconds()))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "95")}, MpoolAge.M(st.Perc95.Seconds()))
|
||||
|
||||
stats.Record(ctx, MpoolSize.M(int64(len(tracker))))
|
||||
fmt.Printf("%d messages in mempool for average of %s, (%s / %s / %s)\n", st.Count, st.Average, st.Perc50, st.Perc80, st.Perc95)
|
||||
}
|
||||
|
||||
var wpages []time.Duration
|
||||
if len(wpostTracker) > 0 {
|
||||
for _, v := range wpostTracker {
|
||||
age := time.Since(v.seen)
|
||||
wpages = append(wpages, age)
|
||||
}
|
||||
|
||||
st := ageStats(wpages)
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "40"), tag.Upsert(MTTag, "wpost")}, MpoolAge.M(st.Perc40.Seconds()))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "50"), tag.Upsert(MTTag, "wpost")}, MpoolAge.M(st.Perc50.Seconds()))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "60"), tag.Upsert(MTTag, "wpost")}, MpoolAge.M(st.Perc60.Seconds()))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "70"), tag.Upsert(MTTag, "wpost")}, MpoolAge.M(st.Perc70.Seconds()))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "80"), tag.Upsert(MTTag, "wpost")}, MpoolAge.M(st.Perc80.Seconds()))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "90"), tag.Upsert(MTTag, "wpost")}, MpoolAge.M(st.Perc90.Seconds()))
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(LeTag, "95"), tag.Upsert(MTTag, "wpost")}, MpoolAge.M(st.Perc95.Seconds()))
|
||||
|
||||
_ = stats.RecordWithTags(ctx, []tag.Mutator{tag.Upsert(MTTag, "wpost")}, MpoolSize.M(int64(len(wpostTracker))))
|
||||
fmt.Printf("%d wpost messages in mempool for average of %s, (%s / %s / %s)\n", st.Count, st.Average, st.Perc50, st.Perc80, st.Perc95)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
type ageStat struct {
|
||||
Average time.Duration
|
||||
Max time.Duration
|
||||
Perc40 time.Duration
|
||||
Perc50 time.Duration
|
||||
Perc60 time.Duration
|
||||
Perc70 time.Duration
|
||||
Perc80 time.Duration
|
||||
Perc90 time.Duration
|
||||
Perc95 time.Duration
|
||||
Count int
|
||||
}
|
||||
|
||||
func ageStats(ages []time.Duration) *ageStat {
|
||||
sort.Slice(ages, func(i, j int) bool {
|
||||
return ages[i] < ages[j]
|
||||
})
|
||||
|
||||
st := ageStat{
|
||||
Count: len(ages),
|
||||
}
|
||||
var sum time.Duration
|
||||
for _, a := range ages {
|
||||
sum += a
|
||||
if a > st.Max {
|
||||
st.Max = a
|
||||
}
|
||||
}
|
||||
st.Average = sum / time.Duration(len(ages))
|
||||
|
||||
p40 := (4 * len(ages)) / 10
|
||||
p50 := len(ages) / 2
|
||||
p60 := (6 * len(ages)) / 10
|
||||
p70 := (7 * len(ages)) / 10
|
||||
p80 := (4 * len(ages)) / 5
|
||||
p90 := (9 * len(ages)) / 10
|
||||
p95 := (19 * len(ages)) / 20
|
||||
|
||||
st.Perc40 = ages[p40]
|
||||
st.Perc50 = ages[p50]
|
||||
st.Perc60 = ages[p60]
|
||||
st.Perc70 = ages[p70]
|
||||
st.Perc80 = ages[p80]
|
||||
st.Perc90 = ages[p90]
|
||||
st.Perc95 = ages[p95]
|
||||
|
||||
return &st
|
||||
}
|
||||
@@ -179,8 +179,8 @@ var initCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if !v.APIVersion.EqMajorMinor(build.APIVersion) {
|
||||
return xerrors.Errorf("Remote API version didn't match (local %s, remote %s)", build.APIVersion, v.APIVersion)
|
||||
if !v.APIVersion.EqMajorMinor(build.FullAPIVersion) {
|
||||
return xerrors.Errorf("Remote API version didn't match (expected %s, remote %s)", build.FullAPIVersion, v.APIVersion)
|
||||
}
|
||||
|
||||
log.Info("Initializing repo")
|
||||
|
||||
@@ -26,6 +26,8 @@ const FlagMinerRepo = "miner-repo"
|
||||
const FlagMinerRepoDeprecation = "storagerepo"
|
||||
|
||||
func main() {
|
||||
build.RunningNodeType = build.NodeMiner
|
||||
|
||||
lotuslog.SetupLogLevels()
|
||||
|
||||
local := []*cli.Command{
|
||||
|
||||
@@ -77,8 +77,8 @@ var runCmd = &cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
if v.APIVersion != build.APIVersion {
|
||||
return xerrors.Errorf("lotus-daemon API version doesn't match: local: %s", api.Version{APIVersion: build.APIVersion})
|
||||
if v.APIVersion != build.FullAPIVersion {
|
||||
return xerrors.Errorf("lotus-daemon API version doesn't match: expected: %s", api.Version{APIVersion: build.FullAPIVersion})
|
||||
}
|
||||
|
||||
log.Info("Checking full node sync status")
|
||||
|
||||
@@ -46,6 +46,7 @@ func init() {
|
||||
return xerrors.Errorf("StateMinerWorker: %w", err)
|
||||
}
|
||||
|
||||
// XXX: This can't be right
|
||||
rand, err := api.ChainGetRandomnessFromTickets(ctx, head.Key(), crypto.DomainSeparationTag_TicketProduction, head.Height(), addr.Bytes())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get randomness: %w", err)
|
||||
|
||||
@@ -16,6 +16,8 @@ import (
|
||||
var AdvanceBlockCmd *cli.Command
|
||||
|
||||
func main() {
|
||||
build.RunningNodeType = build.NodeFull
|
||||
|
||||
lotuslog.SetupLogLevels()
|
||||
|
||||
local := []*cli.Command{
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
package chaos
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
typegen "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
|
||||
//go:generate go run ./gen
|
||||
|
||||
// Actor is a chaos actor. It implements a variety of illegal behaviours that
|
||||
// trigger violations of VM invariants. These behaviours are not found in
|
||||
// production code, but are important to test that the VM constraints are
|
||||
// properly enforced.
|
||||
//
|
||||
// The chaos actor is being incubated and its behaviour and ABI be standardised
|
||||
// shortly. Its CID is ChaosActorCodeCID, and its singleton address is 98 (Address).
|
||||
// It cannot be instantiated via the init actor, and its constructor panics.
|
||||
//
|
||||
// Test vectors relying on the chaos actor being deployed will carry selector
|
||||
// "chaos_actor:true".
|
||||
type Actor struct{}
|
||||
|
||||
// CallerValidationBranch is an enum used to select a branch in the
|
||||
// CallerValidation method.
|
||||
type CallerValidationBranch int64
|
||||
|
||||
const (
|
||||
CallerValidationBranchNone CallerValidationBranch = iota
|
||||
CallerValidationBranchTwice
|
||||
CallerValidationBranchAddrNilSet
|
||||
CallerValidationBranchTypeNilSet
|
||||
)
|
||||
|
||||
// MutateStateBranch is an enum used to select the type of state mutation to attempt.
|
||||
type MutateStateBranch int64
|
||||
|
||||
const (
|
||||
// MutateInTransaction legally mutates state within a transaction.
|
||||
MutateInTransaction MutateStateBranch = iota
|
||||
// MutateReadonly ILLEGALLY mutates readonly state.
|
||||
MutateReadonly
|
||||
// MutateAfterTransaction ILLEGALLY mutates state after a transaction.
|
||||
MutateAfterTransaction
|
||||
)
|
||||
|
||||
const (
|
||||
_ = 0 // skip zero iota value; first usage of iota gets 1.
|
||||
MethodCallerValidation = builtin.MethodConstructor + iota
|
||||
MethodCreateActor
|
||||
MethodResolveAddress
|
||||
// MethodDeleteActor is the identifier for the method that deletes this actor.
|
||||
MethodDeleteActor
|
||||
// MethodSend is the identifier for the method that sends a message to another actor.
|
||||
MethodSend
|
||||
// MethodMutateState is the identifier for the method that attempts to mutate
|
||||
// a state value in the actor.
|
||||
MethodMutateState
|
||||
// MethodAbortWith is the identifier for the method that panics optionally with
|
||||
// a passed exit code.
|
||||
MethodAbortWith
|
||||
)
|
||||
|
||||
// Exports defines the methods this actor exposes publicly.
|
||||
func (a Actor) Exports() []interface{} {
|
||||
return []interface{}{
|
||||
builtin.MethodConstructor: a.Constructor,
|
||||
MethodCallerValidation: a.CallerValidation,
|
||||
MethodCreateActor: a.CreateActor,
|
||||
MethodResolveAddress: a.ResolveAddress,
|
||||
MethodDeleteActor: a.DeleteActor,
|
||||
MethodSend: a.Send,
|
||||
MethodMutateState: a.MutateState,
|
||||
MethodAbortWith: a.AbortWith,
|
||||
}
|
||||
}
|
||||
|
||||
var _ runtime.Invokee = Actor{}
|
||||
|
||||
// SendArgs are the arguments for the Send method.
|
||||
type SendArgs struct {
|
||||
To address.Address
|
||||
Value abi.TokenAmount
|
||||
Method abi.MethodNum
|
||||
Params []byte
|
||||
}
|
||||
|
||||
// SendReturn is the return values for the Send method.
|
||||
type SendReturn struct {
|
||||
Return runtime.CBORBytes
|
||||
Code exitcode.ExitCode
|
||||
}
|
||||
|
||||
// Send requests for this actor to send a message to an actor with the
|
||||
// passed parameters.
|
||||
func (a Actor) Send(rt runtime.Runtime, args *SendArgs) *SendReturn {
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
ret, code := rt.Send(
|
||||
args.To,
|
||||
args.Method,
|
||||
runtime.CBORBytes(args.Params),
|
||||
args.Value,
|
||||
)
|
||||
var out runtime.CBORBytes
|
||||
if ret != nil {
|
||||
if err := ret.Into(&out); err != nil {
|
||||
rt.Abortf(exitcode.ErrIllegalState, "failed to unmarshal send return: %v", err)
|
||||
}
|
||||
}
|
||||
return &SendReturn{
|
||||
Return: out,
|
||||
Code: code,
|
||||
}
|
||||
}
|
||||
|
||||
// Constructor will panic because the Chaos actor is a singleton.
|
||||
func (a Actor) Constructor(_ runtime.Runtime, _ *abi.EmptyValue) *abi.EmptyValue {
|
||||
panic("constructor should not be called; the Chaos actor is a singleton actor")
|
||||
}
|
||||
|
||||
// CallerValidation violates VM call validation constraints.
|
||||
//
|
||||
// CallerValidationBranchNone performs no validation.
|
||||
// CallerValidationBranchTwice validates twice.
|
||||
// CallerValidationBranchAddrNilSet validates against an empty caller
|
||||
// address set.
|
||||
// CallerValidationBranchTypeNilSet validates against an empty caller type set.
|
||||
func (a Actor) CallerValidation(rt runtime.Runtime, branch *typegen.CborInt) *abi.EmptyValue {
|
||||
switch CallerValidationBranch(*branch) {
|
||||
case CallerValidationBranchNone:
|
||||
case CallerValidationBranchTwice:
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
case CallerValidationBranchAddrNilSet:
|
||||
rt.ValidateImmediateCallerIs()
|
||||
case CallerValidationBranchTypeNilSet:
|
||||
rt.ValidateImmediateCallerType()
|
||||
default:
|
||||
panic("invalid branch passed to CallerValidation")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateActorArgs are the arguments to CreateActor.
|
||||
type CreateActorArgs struct {
|
||||
// UndefActorCID instructs us to use cid.Undef; we can't pass cid.Undef
|
||||
// in ActorCID because it doesn't serialize.
|
||||
UndefActorCID bool
|
||||
ActorCID cid.Cid
|
||||
|
||||
// UndefAddress is the same as UndefActorCID but for Address.
|
||||
UndefAddress bool
|
||||
Address address.Address
|
||||
}
|
||||
|
||||
// CreateActor creates an actor with the supplied CID and Address.
|
||||
func (a Actor) CreateActor(rt runtime.Runtime, args *CreateActorArgs) *abi.EmptyValue {
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
|
||||
var (
|
||||
acid = args.ActorCID
|
||||
addr = args.Address
|
||||
)
|
||||
|
||||
if args.UndefActorCID {
|
||||
acid = cid.Undef
|
||||
}
|
||||
if args.UndefAddress {
|
||||
addr = address.Undef
|
||||
}
|
||||
|
||||
rt.CreateActor(acid, addr)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResolveAddressResponse holds the response of a call to runtime.ResolveAddress
|
||||
type ResolveAddressResponse struct {
|
||||
Address address.Address
|
||||
Success bool
|
||||
}
|
||||
|
||||
func (a Actor) ResolveAddress(rt runtime.Runtime, args *address.Address) *ResolveAddressResponse {
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
|
||||
resolvedAddr, ok := rt.ResolveAddress(*args)
|
||||
if !ok {
|
||||
invalidAddr, _ := address.NewIDAddress(0)
|
||||
resolvedAddr = invalidAddr
|
||||
}
|
||||
return &ResolveAddressResponse{resolvedAddr, ok}
|
||||
}
|
||||
|
||||
// DeleteActor deletes the executing actor from the state tree, transferring any
|
||||
// balance to beneficiary.
|
||||
func (a Actor) DeleteActor(rt runtime.Runtime, beneficiary *address.Address) *abi.EmptyValue {
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
rt.DeleteActor(*beneficiary)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MutateStateArgs specify the value to set on the state and the way in which
|
||||
// it should be attempted to be set.
|
||||
type MutateStateArgs struct {
|
||||
Value string
|
||||
Branch MutateStateBranch
|
||||
}
|
||||
|
||||
// MutateState attempts to mutate a state value in the actor.
|
||||
func (a Actor) MutateState(rt runtime.Runtime, args *MutateStateArgs) *abi.EmptyValue {
|
||||
rt.ValidateImmediateCallerAcceptAny()
|
||||
var st State
|
||||
switch args.Branch {
|
||||
case MutateInTransaction:
|
||||
rt.State().Transaction(&st, func() {
|
||||
st.Value = args.Value
|
||||
})
|
||||
case MutateReadonly:
|
||||
rt.State().Readonly(&st)
|
||||
st.Value = args.Value
|
||||
case MutateAfterTransaction:
|
||||
rt.State().Transaction(&st, func() {
|
||||
st.Value = args.Value + "-in"
|
||||
})
|
||||
st.Value = args.Value
|
||||
default:
|
||||
panic("unknown mutation type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AbortWithArgs are the arguments to the Actor.AbortWith method, specifying the
|
||||
// exit code to (optionally) abort with and the message.
|
||||
type AbortWithArgs struct {
|
||||
Code exitcode.ExitCode
|
||||
Message string
|
||||
Uncontrolled bool
|
||||
}
|
||||
|
||||
// AbortWith simply causes a panic with the passed exit code.
|
||||
func (a Actor) AbortWith(rt runtime.Runtime, args *AbortWithArgs) *abi.EmptyValue {
|
||||
if args.Uncontrolled { // uncontrolled abort: directly panic
|
||||
panic(args.Message)
|
||||
} else {
|
||||
rt.Abortf(args.Code, args.Message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,732 @@
|
||||
// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT.
|
||||
|
||||
package chaos
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
abi "github.com/filecoin-project/go-state-types/abi"
|
||||
exitcode "github.com/filecoin-project/go-state-types/exitcode"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var _ = xerrors.Errorf
|
||||
|
||||
var lengthBufState = []byte{130}
|
||||
|
||||
func (t *State) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufState); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.Value (string) (string)
|
||||
if len(t.Value) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field t.Value was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len(t.Value))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string(t.Value)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Unmarshallable ([]*chaos.UnmarshallableCBOR) (slice)
|
||||
if len(t.Unmarshallable) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Slice value in field t.Unmarshallable was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajArray, uint64(len(t.Unmarshallable))); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range t.Unmarshallable {
|
||||
if err := v.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *State) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = State{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 2 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Value (string) (string)
|
||||
|
||||
{
|
||||
sval, err := cbg.ReadStringBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Value = string(sval)
|
||||
}
|
||||
// t.Unmarshallable ([]*chaos.UnmarshallableCBOR) (slice)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > cbg.MaxLength {
|
||||
return fmt.Errorf("t.Unmarshallable: array too large (%d)", extra)
|
||||
}
|
||||
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("expected cbor array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.Unmarshallable = make([]*UnmarshallableCBOR, extra)
|
||||
}
|
||||
|
||||
for i := 0; i < int(extra); i++ {
|
||||
|
||||
var v UnmarshallableCBOR
|
||||
if err := v.UnmarshalCBOR(br); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Unmarshallable[i] = &v
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufCreateActorArgs = []byte{132}
|
||||
|
||||
func (t *CreateActorArgs) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufCreateActorArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.UndefActorCID (bool) (bool)
|
||||
if err := cbg.WriteBool(w, t.UndefActorCID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.ActorCID (cid.Cid) (struct)
|
||||
|
||||
if err := cbg.WriteCidBuf(scratch, w, t.ActorCID); err != nil {
|
||||
return xerrors.Errorf("failed to write cid field t.ActorCID: %w", err)
|
||||
}
|
||||
|
||||
// t.UndefAddress (bool) (bool)
|
||||
if err := cbg.WriteBool(w, t.UndefAddress); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Address (address.Address) (struct)
|
||||
if err := t.Address.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CreateActorArgs) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = CreateActorArgs{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 4 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.UndefActorCID (bool) (bool)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajOther {
|
||||
return fmt.Errorf("booleans must be major type 7")
|
||||
}
|
||||
switch extra {
|
||||
case 20:
|
||||
t.UndefActorCID = false
|
||||
case 21:
|
||||
t.UndefActorCID = true
|
||||
default:
|
||||
return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra)
|
||||
}
|
||||
// t.ActorCID (cid.Cid) (struct)
|
||||
|
||||
{
|
||||
|
||||
c, err := cbg.ReadCid(br)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to read cid field t.ActorCID: %w", err)
|
||||
}
|
||||
|
||||
t.ActorCID = c
|
||||
|
||||
}
|
||||
// t.UndefAddress (bool) (bool)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajOther {
|
||||
return fmt.Errorf("booleans must be major type 7")
|
||||
}
|
||||
switch extra {
|
||||
case 20:
|
||||
t.UndefAddress = false
|
||||
case 21:
|
||||
t.UndefAddress = true
|
||||
default:
|
||||
return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra)
|
||||
}
|
||||
// t.Address (address.Address) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.Address.UnmarshalCBOR(br); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.Address: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufResolveAddressResponse = []byte{130}
|
||||
|
||||
func (t *ResolveAddressResponse) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufResolveAddressResponse); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Address (address.Address) (struct)
|
||||
if err := t.Address.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Success (bool) (bool)
|
||||
if err := cbg.WriteBool(w, t.Success); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *ResolveAddressResponse) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = ResolveAddressResponse{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 2 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Address (address.Address) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.Address.UnmarshalCBOR(br); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.Address: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.Success (bool) (bool)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajOther {
|
||||
return fmt.Errorf("booleans must be major type 7")
|
||||
}
|
||||
switch extra {
|
||||
case 20:
|
||||
t.Success = false
|
||||
case 21:
|
||||
t.Success = true
|
||||
default:
|
||||
return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufSendArgs = []byte{132}
|
||||
|
||||
func (t *SendArgs) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufSendArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.To (address.Address) (struct)
|
||||
if err := t.To.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Value (big.Int) (struct)
|
||||
if err := t.Value.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Method (abi.MethodNum) (uint64)
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Method)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Params ([]uint8) (slice)
|
||||
if len(t.Params) > cbg.ByteArrayMaxLen {
|
||||
return xerrors.Errorf("Byte array in field t.Params was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajByteString, uint64(len(t.Params))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := w.Write(t.Params[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *SendArgs) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = SendArgs{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 4 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.To (address.Address) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.To.UnmarshalCBOR(br); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.To: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.Value (big.Int) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.Value.UnmarshalCBOR(br); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.Value: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.Method (abi.MethodNum) (uint64)
|
||||
|
||||
{
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajUnsignedInt {
|
||||
return fmt.Errorf("wrong type for uint64 field")
|
||||
}
|
||||
t.Method = abi.MethodNum(extra)
|
||||
|
||||
}
|
||||
// t.Params ([]uint8) (slice)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > cbg.ByteArrayMaxLen {
|
||||
return fmt.Errorf("t.Params: byte array too large (%d)", extra)
|
||||
}
|
||||
if maj != cbg.MajByteString {
|
||||
return fmt.Errorf("expected byte array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.Params = make([]uint8, extra)
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(br, t.Params[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufSendReturn = []byte{130}
|
||||
|
||||
func (t *SendReturn) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufSendReturn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.Return (runtime.CBORBytes) (slice)
|
||||
if len(t.Return) > cbg.ByteArrayMaxLen {
|
||||
return xerrors.Errorf("Byte array in field t.Return was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajByteString, uint64(len(t.Return))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := w.Write(t.Return[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Code (exitcode.ExitCode) (int64)
|
||||
if t.Code >= 0 {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Code)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.Code-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *SendReturn) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = SendReturn{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 2 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Return (runtime.CBORBytes) (slice)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > cbg.ByteArrayMaxLen {
|
||||
return fmt.Errorf("t.Return: byte array too large (%d)", extra)
|
||||
}
|
||||
if maj != cbg.MajByteString {
|
||||
return fmt.Errorf("expected byte array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.Return = make([]uint8, extra)
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(br, t.Return[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
// t.Code (exitcode.ExitCode) (int64)
|
||||
{
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.Code = exitcode.ExitCode(extraI)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufMutateStateArgs = []byte{130}
|
||||
|
||||
func (t *MutateStateArgs) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufMutateStateArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.Value (string) (string)
|
||||
if len(t.Value) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field t.Value was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len(t.Value))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string(t.Value)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Branch (chaos.MutateStateBranch) (int64)
|
||||
if t.Branch >= 0 {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Branch)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.Branch-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *MutateStateArgs) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = MutateStateArgs{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 2 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Value (string) (string)
|
||||
|
||||
{
|
||||
sval, err := cbg.ReadStringBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Value = string(sval)
|
||||
}
|
||||
// t.Branch (chaos.MutateStateBranch) (int64)
|
||||
{
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.Branch = MutateStateBranch(extraI)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufAbortWithArgs = []byte{131}
|
||||
|
||||
func (t *AbortWithArgs) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufAbortWithArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.Code (exitcode.ExitCode) (int64)
|
||||
if t.Code >= 0 {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Code)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.Code-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.Message (string) (string)
|
||||
if len(t.Message) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field t.Message was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len(t.Message))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string(t.Message)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Uncontrolled (bool) (bool)
|
||||
if err := cbg.WriteBool(w, t.Uncontrolled); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *AbortWithArgs) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = AbortWithArgs{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 3 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Code (exitcode.ExitCode) (int64)
|
||||
{
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.Code = exitcode.ExitCode(extraI)
|
||||
}
|
||||
// t.Message (string) (string)
|
||||
|
||||
{
|
||||
sval, err := cbg.ReadStringBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Message = string(sval)
|
||||
}
|
||||
// t.Uncontrolled (bool) (bool)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajOther {
|
||||
return fmt.Errorf("booleans must be major type 7")
|
||||
}
|
||||
switch extra {
|
||||
case 20:
|
||||
t.Uncontrolled = false
|
||||
case 21:
|
||||
t.Uncontrolled = true
|
||||
default:
|
||||
return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/lotus/conformance/chaos"
|
||||
|
||||
gen "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := gen.WriteTupleEncodersToFile("../cbor_gen.go", "chaos",
|
||||
chaos.State{},
|
||||
chaos.CreateActorArgs{},
|
||||
chaos.ResolveAddressResponse{},
|
||||
chaos.SendArgs{},
|
||||
chaos.SendReturn{},
|
||||
chaos.MutateStateArgs{},
|
||||
chaos.AbortWithArgs{},
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package chaos
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/multiformats/go-multihash"
|
||||
)
|
||||
|
||||
// ChaosActorCodeCID is the CID by which this kind of actor will be identified.
|
||||
var ChaosActorCodeCID = func() cid.Cid {
|
||||
builder := cid.V1Builder{Codec: cid.Raw, MhType: multihash.IDENTITY}
|
||||
c, err := builder.Sum([]byte("fil/1/chaos"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return c
|
||||
}()
|
||||
|
||||
// Address is the singleton address of this actor. Its value is 98
|
||||
// (builtin.FirstNonSingletonActorId - 2), as 99 is reserved for the burnt funds
|
||||
// singleton.
|
||||
var Address = func() address.Address {
|
||||
// the address before the burnt funds address (99)
|
||||
addr, err := address.NewIDAddress(98)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return addr
|
||||
}()
|
||||
@@ -0,0 +1,32 @@
|
||||
package chaos
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// State is the state for the chaos actor used by some methods to invoke
|
||||
// behaviours in the vm or runtime.
|
||||
type State struct {
|
||||
// Value can be updated by chaos actor methods to test illegal state
|
||||
// mutations when the state is in readonly mode for example.
|
||||
Value string
|
||||
// Unmarshallable is a sentinel value. If the slice contains no values, the
|
||||
// State struct will encode as CBOR without issue. If the slice is non-nil,
|
||||
// CBOR encoding will fail.
|
||||
Unmarshallable []*UnmarshallableCBOR
|
||||
}
|
||||
|
||||
// UnmarshallableCBOR is a type that cannot be marshalled or unmarshalled to
|
||||
// CBOR despite implementing the CBORMarshaler and CBORUnmarshaler interface.
|
||||
type UnmarshallableCBOR struct{}
|
||||
|
||||
// UnmarshalCBOR will fail to unmarshal the value from CBOR.
|
||||
func (t *UnmarshallableCBOR) UnmarshalCBOR(io.Reader) error {
|
||||
return fmt.Errorf("failed to unmarshal cbor")
|
||||
}
|
||||
|
||||
// MarshalCBOR will fail to marshal the value to CBOR.
|
||||
func (t *UnmarshallableCBOR) MarshalCBOR(io.Writer) error {
|
||||
return fmt.Errorf("failed to marshal cbor")
|
||||
}
|
||||
@@ -9,12 +9,12 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/conformance/chaos"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/filecoin-project/test-vectors/chaos"
|
||||
"github.com/filecoin-project/test-vectors/schema"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@@ -96,13 +96,16 @@ func (d *Driver) ExecuteTipset(bs blockstore.Blockstore, ds ds.Batching, preroot
|
||||
var (
|
||||
messages []*types.Message
|
||||
results []*vm.ApplyRet
|
||||
|
||||
epoch = abi.ChainEpoch(tipset.Epoch)
|
||||
basefee = abi.NewTokenAmount(tipset.BaseFee.Int64())
|
||||
)
|
||||
|
||||
postcid, receiptsroot, err := sm.ApplyBlocks(context.Background(), parentEpoch, preroot, blocks, tipset.Epoch, vmRand, func(_ cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
|
||||
postcid, receiptsroot, err := sm.ApplyBlocks(context.Background(), parentEpoch, preroot, blocks, epoch, vmRand, func(_ cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
|
||||
messages = append(messages, msg)
|
||||
results = append(results, ret)
|
||||
return nil
|
||||
}, tipset.BaseFee)
|
||||
}, basefee, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -9,19 +9,25 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
"github.com/ipfs/go-blockservice"
|
||||
"github.com/ipfs/go-cid"
|
||||
ds "github.com/ipfs/go-datastore"
|
||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||
format "github.com/ipfs/go-ipld-format"
|
||||
"github.com/ipfs/go-merkledag"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
||||
|
||||
"github.com/filecoin-project/statediff"
|
||||
"github.com/filecoin-project/test-vectors/schema"
|
||||
|
||||
"github.com/fatih/color"
|
||||
@@ -177,7 +183,7 @@ func executeMessageVector(t *testing.T, vector *schema.TestVector) {
|
||||
|
||||
// Execute the message.
|
||||
var ret *vm.ApplyRet
|
||||
ret, root, err = driver.ExecuteMessage(bs, root, epoch, msg)
|
||||
ret, root, err = driver.ExecuteMessage(bs, root, abi.ChainEpoch(epoch), msg)
|
||||
if err != nil {
|
||||
t.Fatalf("fatal failure when executing message: %s", err)
|
||||
}
|
||||
@@ -188,8 +194,10 @@ func executeMessageVector(t *testing.T, vector *schema.TestVector) {
|
||||
|
||||
// Once all messages are applied, assert that the final state root matches
|
||||
// the expected postcondition root.
|
||||
if root != vector.Post.StateTree.RootCID {
|
||||
if expected, actual := vector.Post.StateTree.RootCID, root; expected != actual {
|
||||
t.Logf("actual state root CID doesn't match expected one; expected: %s, actual: %s", expected, actual)
|
||||
dumpThreeWayStateDiff(t, vector, bs, root)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +220,7 @@ func executeTipsetVector(t *testing.T, vector *schema.TestVector) {
|
||||
var receiptsIdx int
|
||||
for i, ts := range vector.ApplyTipsets {
|
||||
ts := ts // capture
|
||||
ret, err := driver.ExecuteTipset(bs, tmpds, root, prevEpoch, &ts)
|
||||
ret, err := driver.ExecuteTipset(bs, tmpds, root, abi.ChainEpoch(prevEpoch), &ts)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to apply tipset %d message: %s", i, err)
|
||||
}
|
||||
@@ -233,8 +241,10 @@ func executeTipsetVector(t *testing.T, vector *schema.TestVector) {
|
||||
|
||||
// Once all messages are applied, assert that the final state root matches
|
||||
// the expected postcondition root.
|
||||
if root != vector.Post.StateTree.RootCID {
|
||||
if expected, actual := vector.Post.StateTree.RootCID, root; expected != actual {
|
||||
t.Logf("actual state root CID doesn't match expected one; expected: %s, actual: %s", expected, actual)
|
||||
dumpThreeWayStateDiff(t, vector, bs, root)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +254,7 @@ func executeTipsetVector(t *testing.T, vector *schema.TestVector) {
|
||||
func assertMsgResult(t *testing.T, expected *schema.Receipt, actual *vm.ApplyRet, label string) {
|
||||
t.Helper()
|
||||
|
||||
if expected, actual := expected.ExitCode, actual.ExitCode; expected != actual {
|
||||
if expected, actual := exitcode.ExitCode(expected.ExitCode), actual.ExitCode; expected != actual {
|
||||
t.Errorf("exit code of msg %s did not match; expected: %s, got: %s", label, expected, actual)
|
||||
}
|
||||
if expected, actual := expected.GasUsed, actual.GasUsed; expected != actual {
|
||||
@@ -256,6 +266,23 @@ func assertMsgResult(t *testing.T, expected *schema.Receipt, actual *vm.ApplyRet
|
||||
}
|
||||
|
||||
func dumpThreeWayStateDiff(t *testing.T, vector *schema.TestVector, bs blockstore.Blockstore, actual cid.Cid) {
|
||||
// check if statediff exists; if not, skip.
|
||||
if err := exec.Command("statediff", "--help").Run(); err != nil {
|
||||
t.Log("could not dump 3-way state tree diff upon test failure: statediff command not found")
|
||||
t.Log("install statediff with:")
|
||||
t.Log("$ git clone https://github.com/filecoin-project/statediff.git")
|
||||
t.Log("$ cd statediff")
|
||||
t.Log("$ go generate ./...")
|
||||
t.Log("$ go install ./cmd/statediff")
|
||||
return
|
||||
}
|
||||
|
||||
tmpCar := writeStateToTempCAR(t, bs,
|
||||
vector.Pre.StateTree.RootCID,
|
||||
vector.Post.StateTree.RootCID,
|
||||
actual,
|
||||
)
|
||||
|
||||
color.NoColor = false // enable colouring.
|
||||
|
||||
t.Errorf("wrong post root cid; expected %v, but got %v", vector.Post.StateTree.RootCID, actual)
|
||||
@@ -269,19 +296,64 @@ func dumpThreeWayStateDiff(t *testing.T, vector *schema.TestVector, bs blockstor
|
||||
d3 = color.New(color.FgGreen, color.Bold).Sprint("[Δ3]")
|
||||
)
|
||||
|
||||
printDiff := func(left, right cid.Cid) {
|
||||
cmd := exec.Command("statediff", "car", "--file", tmpCar, left.String(), right.String())
|
||||
b, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("statediff failed: %s", err)
|
||||
}
|
||||
t.Log(string(b))
|
||||
}
|
||||
|
||||
bold := color.New(color.Bold).SprintfFunc()
|
||||
|
||||
// run state diffs.
|
||||
t.Log(bold("=== dumping 3-way diffs between %s, %s, %s ===", a, b, c))
|
||||
|
||||
t.Log(bold("--- %s left: %s; right: %s ---", d1, a, b))
|
||||
t.Log(statediff.Diff(context.Background(), bs, vector.Post.StateTree.RootCID, actual))
|
||||
printDiff(vector.Post.StateTree.RootCID, actual)
|
||||
|
||||
t.Log(bold("--- %s left: %s; right: %s ---", d2, c, b))
|
||||
t.Log(statediff.Diff(context.Background(), bs, vector.Pre.StateTree.RootCID, actual))
|
||||
printDiff(vector.Pre.StateTree.RootCID, actual)
|
||||
|
||||
t.Log(bold("--- %s left: %s; right: %s ---", d3, c, a))
|
||||
t.Log(statediff.Diff(context.Background(), bs, vector.Pre.StateTree.RootCID, vector.Post.StateTree.RootCID))
|
||||
printDiff(vector.Pre.StateTree.RootCID, vector.Post.StateTree.RootCID)
|
||||
}
|
||||
|
||||
// writeStateToTempCAR writes the provided roots to a temporary CAR that'll be
|
||||
// cleaned up via t.Cleanup(). It returns the full path of the temp file.
|
||||
func writeStateToTempCAR(t *testing.T, bs blockstore.Blockstore, roots ...cid.Cid) string {
|
||||
tmp, err := ioutil.TempFile("", "lotus-tests-*.car")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create temp file to dump CAR for diffing: %s", err)
|
||||
}
|
||||
// register a cleanup function to delete the CAR.
|
||||
t.Cleanup(func() {
|
||||
_ = os.Remove(tmp.Name())
|
||||
})
|
||||
|
||||
carWalkFn := func(nd format.Node) (out []*format.Link, err error) {
|
||||
for _, link := range nd.Links() {
|
||||
if link.Cid.Prefix().Codec == cid.FilCommitmentSealed || link.Cid.Prefix().Codec == cid.FilCommitmentUnsealed {
|
||||
continue
|
||||
}
|
||||
out = append(out, link)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
var (
|
||||
offl = offline.Exchange(bs)
|
||||
blkserv = blockservice.New(bs, offl)
|
||||
dserv = merkledag.NewDAGService(blkserv)
|
||||
)
|
||||
|
||||
err = car.WriteCarWithWalker(context.Background(), dserv, roots, tmp, carWalkFn)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to dump CAR for diffing: %s", err)
|
||||
}
|
||||
_ = tmp.Close()
|
||||
return tmp.Name()
|
||||
}
|
||||
|
||||
func loadCAR(t *testing.T, vectorCAR schema.Base64EncodedBytes) blockstore.Blockstore {
|
||||
|
||||
@@ -75,10 +75,14 @@
|
||||
* [MpoolSetConfig](#MpoolSetConfig)
|
||||
* [MpoolSub](#MpoolSub)
|
||||
* [Msig](#Msig)
|
||||
* [MsigAddApprove](#MsigAddApprove)
|
||||
* [MsigAddCancel](#MsigAddCancel)
|
||||
* [MsigAddPropose](#MsigAddPropose)
|
||||
* [MsigApprove](#MsigApprove)
|
||||
* [MsigCancel](#MsigCancel)
|
||||
* [MsigCreate](#MsigCreate)
|
||||
* [MsigGetAvailableBalance](#MsigGetAvailableBalance)
|
||||
* [MsigGetVested](#MsigGetVested)
|
||||
* [MsigPropose](#MsigPropose)
|
||||
* [MsigSwapApprove](#MsigSwapApprove)
|
||||
* [MsigSwapCancel](#MsigSwapCancel)
|
||||
@@ -156,10 +160,12 @@
|
||||
* [StateWaitMsg](#StateWaitMsg)
|
||||
* [Sync](#Sync)
|
||||
* [SyncCheckBad](#SyncCheckBad)
|
||||
* [SyncCheckpoint](#SyncCheckpoint)
|
||||
* [SyncIncomingBlocks](#SyncIncomingBlocks)
|
||||
* [SyncMarkBad](#SyncMarkBad)
|
||||
* [SyncState](#SyncState)
|
||||
* [SyncSubmitBlock](#SyncSubmitBlock)
|
||||
* [SyncUnmarkBad](#SyncUnmarkBad)
|
||||
* [Wallet](#Wallet)
|
||||
* [WalletBalance](#WalletBalance)
|
||||
* [WalletDefaultAddress](#WalletDefaultAddress)
|
||||
@@ -1837,6 +1843,84 @@ The Msig methods are used to interact with multisig wallets on the
|
||||
filecoin network
|
||||
|
||||
|
||||
### MsigAddApprove
|
||||
MsigAddApprove approves a previously proposed AddSigner message
|
||||
It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||
<proposer address>, <new signer>, <whether the number of required signers should be increased>
|
||||
|
||||
|
||||
Perms: sign
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
"t01234",
|
||||
"t01234",
|
||||
42,
|
||||
"t01234",
|
||||
"t01234",
|
||||
true
|
||||
]
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
```
|
||||
|
||||
### MsigAddCancel
|
||||
MsigAddCancel cancels a previously proposed AddSigner message
|
||||
It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||
<new signer>, <whether the number of required signers should be increased>
|
||||
|
||||
|
||||
Perms: sign
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
"t01234",
|
||||
"t01234",
|
||||
42,
|
||||
"t01234",
|
||||
true
|
||||
]
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
```
|
||||
|
||||
### MsigAddPropose
|
||||
MsigAddPropose proposes adding a signer in the multisig
|
||||
It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||
<new signer>, <whether the number of required signers should be increased>
|
||||
|
||||
|
||||
Perms: sign
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
"t01234",
|
||||
"t01234",
|
||||
"t01234",
|
||||
true
|
||||
]
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
```
|
||||
|
||||
### MsigApprove
|
||||
MsigApprove approves a previously-proposed multisig message
|
||||
It takes the following params: <multisig address>, <proposed message ID>, <proposer address>, <recipient address>, <value to transfer>,
|
||||
@@ -1944,6 +2028,38 @@ Inputs:
|
||||
|
||||
Response: `"0"`
|
||||
|
||||
### MsigGetVested
|
||||
MsigGetVested returns the amount of FIL that vested in a multisig in a certain period.
|
||||
It takes the following params: <multisig address>, <start epoch>, <end epoch>
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
"t01234",
|
||||
[
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
},
|
||||
{
|
||||
"/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
},
|
||||
{
|
||||
"/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
|
||||
}
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
Response: `"0"`
|
||||
|
||||
### MsigPropose
|
||||
MsigPropose proposes a multisig message
|
||||
It takes the following params: <multisig address>, <recipient address>, <value to transfer>,
|
||||
@@ -1974,7 +2090,7 @@ Response:
|
||||
### MsigSwapApprove
|
||||
MsigSwapApprove approves a previously proposed SwapSigner
|
||||
It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||
<proposer address>, <old signer> <new signer>
|
||||
<proposer address>, <old signer>, <new signer>
|
||||
|
||||
|
||||
Perms: sign
|
||||
@@ -2001,7 +2117,7 @@ Response:
|
||||
### MsigSwapCancel
|
||||
MsigSwapCancel cancels a previously proposed SwapSigner message
|
||||
It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||
<old signer> <new signer>
|
||||
<old signer>, <new signer>
|
||||
|
||||
|
||||
Perms: sign
|
||||
@@ -2027,7 +2143,7 @@ Response:
|
||||
### MsigSwapPropose
|
||||
MsigSwapPropose proposes swapping 2 signers in the multisig
|
||||
It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||
<old signer> <new signer>
|
||||
<old signer>, <new signer>
|
||||
|
||||
|
||||
Perms: sign
|
||||
@@ -3517,7 +3633,12 @@ Response:
|
||||
"Open": 10101,
|
||||
"Close": 10101,
|
||||
"Challenge": 10101,
|
||||
"FaultCutoff": 10101
|
||||
"FaultCutoff": 10101,
|
||||
"WPoStPeriodDeadlines": 42,
|
||||
"WPoStProvingPeriod": 10101,
|
||||
"WPoStChallengeWindow": 10101,
|
||||
"WPoStChallengeLookback": 10101,
|
||||
"FaultDeclarationCutoff": 10101
|
||||
}
|
||||
```
|
||||
|
||||
@@ -3995,6 +4116,28 @@ Inputs:
|
||||
|
||||
Response: `"string value"`
|
||||
|
||||
### SyncCheckpoint
|
||||
SyncCheckpoint marks a blocks as checkpointed, meaning that it won't ever fork away from it.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
[
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
},
|
||||
{
|
||||
"/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
|
||||
}
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
Response: `{}`
|
||||
|
||||
### SyncIncomingBlocks
|
||||
SyncIncomingBlocks returns a channel streaming incoming, potentially not
|
||||
yet synced block headers.
|
||||
@@ -4130,6 +4273,23 @@ Inputs:
|
||||
|
||||
Response: `{}`
|
||||
|
||||
### SyncUnmarkBad
|
||||
SyncUnmarkBad unmarks a blocks as bad, making it possible to be validated and synced again.
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Response: `{}`
|
||||
|
||||
## Wallet
|
||||
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@ When we launch a Lotus node with the command `./lotus daemon`
|
||||
(see [here](https://github.com/filecoin-project/lotus/blob/master/cmd/lotus/daemon.go) for more),
|
||||
the node is created through [dependency injection](https://godoc.org/go.uber.org/fx).
|
||||
This relies on reflection, which makes some of the references hard to follow.
|
||||
The node sets up all of the subsystems it needs to run, such as the repository, the network connections, thechain sync
|
||||
The node sets up all of the subsystems it needs to run, such as the repository, the network connections, the chain sync
|
||||
service, etc.
|
||||
This setup is orchestrated through calls to the `node.Override` function.
|
||||
The structure of each call indicates the type of component it will set up
|
||||
|
||||
@@ -84,3 +84,28 @@ Once the settlement period is over, either the client or provider can call colle
|
||||
```sh
|
||||
$ lotus paych collect <channel addr>
|
||||
```
|
||||
|
||||
Check the status of a channel that is still being created using `lotus paych status-by-from-to`.
|
||||
|
||||
```sh
|
||||
$ lotus paych status-by-from-to <from addr> <to addr>
|
||||
Creating channel
|
||||
From: t3sb6xzvs6rhlziatagevxpp3dwapdolurtkpn4kyh3kgoo4tn5o7lutjqlsnvpceztlhxu3lzzfe34rvpsjgq
|
||||
To: t1zip4sblhyrn4oxygzsm6nafbsynp2avmk3xafea
|
||||
Pending Amt: 10000
|
||||
Wait Sentinel: bafy2bzacedk2jidsyxcynusted35t5ipkhu2kpiodtwyjr3pimrhke6f5pqbm
|
||||
```
|
||||
|
||||
Check the status of a channel that has been created using `lotus paych status`.
|
||||
|
||||
```sh
|
||||
$ lotus paych status <channel addr>
|
||||
Channel exists
|
||||
Channel: t2nydpzhmeqkmid5smtqnowlr2mr5az6rexpmyv6i
|
||||
From: t3sb6xzvs6rhlziatagevxpp3dwapdolurtkpn4kyh3kgoo4tn5o7lutjqlsnvpceztlhxu3lzzfe34rvpsjgq
|
||||
To: t1zip4sblhyrn4oxygzsm6nafbsynp2avmk3xafea
|
||||
Confirmed Amt: 10000
|
||||
Pending Amt: 6000
|
||||
Queued Amt: 3000
|
||||
Voucher Redeemed Amt: 2000
|
||||
```
|
||||
|
||||
+1
-1
@@ -410,7 +410,7 @@ func (sb *Sealer) ReadPiece(ctx context.Context, writer io.Writer, sector abi.Se
|
||||
return false, xerrors.Errorf("closing partial file: %w", err)
|
||||
}
|
||||
|
||||
return false, nil
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (sb *Sealer) SealPreCommit1(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (out storage.PreCommit1Out, err error) {
|
||||
|
||||
Vendored
+5
-7
@@ -217,16 +217,11 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector abi.Sect
|
||||
return xerrors.Errorf("read piece: checking for already existing unsealed sector: %w", err)
|
||||
}
|
||||
|
||||
var readOk bool
|
||||
var selector WorkerSelector
|
||||
if len(best) == 0 { // new
|
||||
selector = newAllocSelector(m.index, stores.FTUnsealed, stores.PathSealing)
|
||||
} else { // append to existing
|
||||
selector = newExistingSelector(m.index, sector, stores.FTUnsealed, false)
|
||||
}
|
||||
|
||||
var readOk bool
|
||||
|
||||
if len(best) > 0 {
|
||||
// There is unsealed sector, see if we can read from it
|
||||
|
||||
selector = newExistingSelector(m.index, sector, stores.FTUnsealed, false)
|
||||
@@ -257,6 +252,9 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector abi.Sect
|
||||
return nil
|
||||
}
|
||||
|
||||
if unsealed == cid.Undef {
|
||||
return xerrors.Errorf("cannot unseal piece (sector: %d, offset: %d size: %d) - unsealed cid is undefined", sector, offset, size)
|
||||
}
|
||||
err = m.sched.Schedule(ctx, sector, sealtasks.TTUnseal, selector, unsealFetch, func(ctx context.Context, w Worker) error {
|
||||
return w.UnsealPiece(ctx, sector, offset, size, ticket, unsealed)
|
||||
})
|
||||
@@ -274,7 +272,7 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector abi.Sect
|
||||
return xerrors.Errorf("reading piece from sealed sector: %w", err)
|
||||
}
|
||||
|
||||
if readOk {
|
||||
if !readOk {
|
||||
return xerrors.Errorf("failed to read unsealed piece")
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ func (m *Sealing) handleSealPrecommit2Failed(ctx statemachine.Context, sector Se
|
||||
return err
|
||||
}
|
||||
|
||||
if sector.PreCommit2Fails > 1 {
|
||||
if sector.PreCommit2Fails > 3 {
|
||||
return ctx.Send(SectorRetrySealPreCommit1{})
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
Submodule extern/test-vectors updated: ef5dba45b8...7d3becbeb5
+6
-6
@@ -7,7 +7,7 @@ import (
|
||||
gen "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/blocksync"
|
||||
"github.com/filecoin-project/lotus/chain/exchange"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/node/hello"
|
||||
"github.com/filecoin-project/lotus/paychmgr"
|
||||
@@ -63,11 +63,11 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = gen.WriteTupleEncodersToFile("./chain/blocksync/cbor_gen.go", "blocksync",
|
||||
blocksync.Request{},
|
||||
blocksync.Response{},
|
||||
blocksync.CompactedMessages{},
|
||||
blocksync.BSTipSet{},
|
||||
err = gen.WriteTupleEncodersToFile("./chain/exchange/cbor_gen.go", "exchange",
|
||||
exchange.Request{},
|
||||
exchange.Response{},
|
||||
exchange.CompactedMessages{},
|
||||
exchange.BSTipSet{},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
|
||||
@@ -7,19 +7,18 @@ replace github.com/supranational/blst => github.com/supranational/blst v0.1.2-al
|
||||
require (
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.1.0
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.1.0
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/GeertJohan/go.rice v1.0.0
|
||||
github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
|
||||
github.com/buger/goterm v0.0.0-20200322175922-2f3e71b85129
|
||||
github.com/coreos/go-systemd/v22 v22.0.0
|
||||
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
||||
github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e
|
||||
github.com/dgraph-io/badger/v2 v2.0.3
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/drand/drand v1.0.3-0.20200714175734-29705eaf09d4
|
||||
github.com/drand/kyber v1.1.1
|
||||
github.com/drand/drand v1.1.2-0.20200905144319-79c957281b32
|
||||
github.com/drand/kyber v1.1.2
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/elastic/go-sysinfo v1.3.0
|
||||
github.com/fatih/color v1.8.0
|
||||
@@ -35,16 +34,16 @@ require (
|
||||
github.com/filecoin-project/go-multistore v0.0.3
|
||||
github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20
|
||||
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200909080127-001afaca718c
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370
|
||||
github.com/filecoin-project/go-statestore v0.1.0
|
||||
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b
|
||||
github.com/filecoin-project/specs-actors v0.9.7
|
||||
github.com/filecoin-project/specs-actors v0.9.8
|
||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796
|
||||
github.com/filecoin-project/statediff v0.0.1
|
||||
github.com/filecoin-project/test-vectors v0.0.0-20200907193218-2c0739eccce6
|
||||
github.com/filecoin-project/test-vectors/schema v0.0.1
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
||||
github.com/go-kit/kit v0.10.0
|
||||
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gorilla/mux v1.7.4
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
@@ -93,7 +92,7 @@ require (
|
||||
github.com/libp2p/go-libp2p-mplex v0.2.4
|
||||
github.com/libp2p/go-libp2p-noise v0.1.1
|
||||
github.com/libp2p/go-libp2p-peerstore v0.2.6
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.6-0.20200907103802-a3445b756fdb
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.6-0.20200910093904-f7f33e10cc18
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.8.0
|
||||
github.com/libp2p/go-libp2p-record v0.1.3
|
||||
github.com/libp2p/go-libp2p-routing-helpers v0.2.3
|
||||
@@ -129,6 +128,7 @@ require (
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
|
||||
gotest.tools v2.2.0+incompatible
|
||||
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect
|
||||
)
|
||||
|
||||
replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0
|
||||
|
||||
@@ -8,20 +8,14 @@ cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxK
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.1.0 h1:WNc9HbA38xEQmsI40Tjd/MNU/g8byN2Of7lwIjv0Jdc=
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.1.0/go.mod h1:VYianECmuFPwU37O699Vc1GOcy+y8kOsfaxHRImmjbA=
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.1.0 h1:SByaIoWwNgMdPSgl5sMqM2KDE5H/ukPWBRo314xiDvg=
|
||||
@@ -35,8 +29,6 @@ git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGy
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4=
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M=
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
@@ -99,6 +91,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/briandowns/spinner v1.11.1 h1:OixPqDEcX3juo5AjQZAnFPbeUA0jvkp2qzB5gOZJ/L0=
|
||||
github.com/briandowns/spinner v1.11.1/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ=
|
||||
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
|
||||
github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
||||
@@ -160,7 +153,6 @@ github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0=
|
||||
github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis=
|
||||
github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY=
|
||||
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
|
||||
github.com/dave/jennifer v1.4.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
@@ -168,8 +160,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4=
|
||||
github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f h1:BOaYiTvg8p9vBUXpklC22XSK/mifLF7lG9jtmYYi3Tc=
|
||||
github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4=
|
||||
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU=
|
||||
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U=
|
||||
github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e h1:lj77EKYUpYXTd8CD/+QMIf8b6OIOTsfEBSXiAzuEHTU=
|
||||
github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e/go.mod h1:3ZQK6DMPSz/QZ73jlWxBtUhNA8xZx7LzUFSq/OfP8vk=
|
||||
github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ=
|
||||
@@ -190,12 +180,12 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/drand/bls12-381 v0.3.2 h1:RImU8Wckmx8XQx1tp1q04OV73J9Tj6mmpQLYDP7V1XE=
|
||||
github.com/drand/bls12-381 v0.3.2/go.mod h1:dtcLgPtYT38L3NO6mPDYH0nbpc5tjPassDqiniuAt4Y=
|
||||
github.com/drand/drand v1.0.3-0.20200714175734-29705eaf09d4 h1:+Rov3bfUriGWFR/lUVXnpimx+HMr9BXRC4by0BxuQ8k=
|
||||
github.com/drand/drand v1.0.3-0.20200714175734-29705eaf09d4/go.mod h1:SnqWL9jksIMK63UKkfmWI6f9PDN8ROoCgg+Z4zWk7hg=
|
||||
github.com/drand/drand v1.1.2-0.20200905144319-79c957281b32 h1:sU+51aQRaDxg0KnjQg19KuYRIxDBEUHffBAICSnBys8=
|
||||
github.com/drand/drand v1.1.2-0.20200905144319-79c957281b32/go.mod h1:0sQEVg+ngs1jaDPVIiEgY0lbENWJPaUlWxGHEaSmKVM=
|
||||
github.com/drand/kyber v1.0.1-0.20200110225416-8de27ed8c0e2/go.mod h1:UpXoA0Upd1N9l4TvRPHr1qAUBBERj6JQ/mnKI3BPEmw=
|
||||
github.com/drand/kyber v1.0.2/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw=
|
||||
github.com/drand/kyber v1.1.1 h1:mwCY2XGRB+Qc1MPfrnRuVuXELkPhcq/r9yMoJIcDhHI=
|
||||
github.com/drand/kyber v1.1.1/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw=
|
||||
github.com/drand/kyber v1.1.2 h1:faemqlaFyLrbBSjZGRzzu5SG/do+uTYpHlnrJIHbAhQ=
|
||||
github.com/drand/kyber v1.1.2/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw=
|
||||
github.com/drand/kyber-bls12381 v0.1.0 h1:/P4C65VnyEwxzR5ZYYVMNzY1If+aYBrdUU5ukwh7LQw=
|
||||
github.com/drand/kyber-bls12381 v0.1.0/go.mod h1:N1emiHpm+jj7kMlxEbu3MUyOiooTgNySln564cgD9mk=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
@@ -221,55 +211,38 @@ 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/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8=
|
||||
github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
|
||||
github.com/filecoin-project/chain-validation v0.0.6-0.20200813000554-40c22fe26eef h1:MtQRSnJLsQOOlmsd/Ua5KWXimpxcaa715h6FUh/eJPY=
|
||||
github.com/filecoin-project/chain-validation v0.0.6-0.20200813000554-40c22fe26eef/go.mod h1:SMj5VK1pYgqC8FXVEtOBRTc+9AIrYu+C+K3tAXi2Rk8=
|
||||
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.3 h1:eVfbdjEbpbzIrbiSa+PiGUY+oDK9HnUn+M1R/ggoHf8=
|
||||
github.com/filecoin-project/go-address v0.0.3/go.mod h1:jr8JxKsYx+lQlQZmF5i2U0Z+cGQ59wMIps/8YW/lDj8=
|
||||
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/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-amt-ipld/v2 v2.1.1-0.20200731171407-e559a0579161 h1:K6t4Hrs+rwUxBz2xg88Bdqeh4k5/rycQFdPseZhRyfE=
|
||||
github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20200731171407-e559a0579161/go.mod h1:vgmwKBkx+ca5OIeEvstiQgzAZnb7R6QaqE1oEDSqa6g=
|
||||
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.3/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.2/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM=
|
||||
github.com/filecoin-project/go-bitfield v0.2.0 h1:gCtLcjskIPtdg4NfN7gQZSQF9yrBQ7mkT0qCJxzGI2Q=
|
||||
github.com/filecoin-project/go-bitfield v0.2.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/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/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ=
|
||||
github.com/filecoin-project/go-data-transfer v0.6.1/go.mod h1:uRYBRKVBVM12CSusBtVrzDHkVw/3DKZpkxKJVP1Ydas=
|
||||
github.com/filecoin-project/go-data-transfer v0.6.3 h1:7TLwm8nuodHYD/uiwJjKc/PGRR+LwqM8jmlZqgWuUfY=
|
||||
github.com/filecoin-project/go-data-transfer v0.6.3/go.mod h1:PmBKVXkhh67/tnEdJXQwDHl5mT+7Tbcwe1NPninqhnM=
|
||||
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/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ=
|
||||
github.com/filecoin-project/go-fil-markets v0.5.6-0.20200814234959-80b1788108ac/go.mod h1:umicPCaN99ysHTiYOmwhuLxTFbOwcsI+mdw/t96vvM4=
|
||||
github.com/filecoin-project/go-fil-markets v0.5.8/go.mod h1:6ZX1vbZbnukbVQ8tCB/MmEizuW/bmRX7SpGAltU3KVg=
|
||||
github.com/filecoin-project/go-fil-markets v0.6.0 h1:gfxMweUHo4u+2BZh2Q7/7+cV0/ttikuJfhkkxLRsE2Q=
|
||||
github.com/filecoin-project/go-fil-markets v0.6.0/go.mod h1:LhSFYLkjaoe0vFRKABGYyw1Jz+9jCpF1sPA7yOftLTw=
|
||||
github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200817153016-2ea5cbaf5ec0/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4=
|
||||
github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM=
|
||||
github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24=
|
||||
github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52 h1:FXtCp0ybqdQL9knb3OGDpkNTaBbPxgkqPeWKotUwkH0=
|
||||
github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4=
|
||||
github.com/filecoin-project/go-multistore v0.0.3 h1:vaRBY4YiA2UZFPK57RNuewypB8u0DzzQwqsL0XarpnI=
|
||||
github.com/filecoin-project/go-multistore v0.0.3/go.mod h1:kaNqCC4IhU4B1uyr7YWFHd23TL4KM32aChS0jNkyUvQ=
|
||||
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6/go.mod h1:0HgYnrkeSU4lu1p+LEOeDpFsNBssa0OGGriWdA4hvaE=
|
||||
github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 h1:+/4aUeUoKr6AKfPE3mBhXA5spIV6UcKdTYDPNU2Tdmg=
|
||||
github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20/go.mod h1:mPn+LRRd5gEKNAtc+r3ScpW2JRU/pj4NBKdADYWHiak=
|
||||
github.com/filecoin-project/go-paramfetch v0.0.1/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc=
|
||||
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc=
|
||||
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261 h1:A256QonvzRaknIIAuWhe/M2dpV2otzs3NBhi5TWa/UA=
|
||||
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200903145444-247639ffa6ad/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df h1:m2esXSuGBkuXlRyCsl1a/7/FkFam63o1OzIgzaHtOfI=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I=
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200909080127-001afaca718c h1:HHRMFpU8OrODDUja5NmGWNBAVGoSy4MRjxgZa+a0qIw=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200909080127-001afaca718c/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I=
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200714194326-a77c3ae20989/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370 h1:Jbburj7Ih2iaJ/o5Q9A+EAeTabME6YII7FLi9SKUf5c=
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
||||
@@ -277,31 +250,15 @@ github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIi
|
||||
github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI=
|
||||
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg=
|
||||
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8=
|
||||
github.com/filecoin-project/lotus v0.4.3-0.20200820203717-d1718369a182/go.mod h1:biFZPQ/YyQGfkHUmHMiaNf2hnD6zm1+OAXPQYQ61Zkg=
|
||||
github.com/filecoin-project/lotus v0.5.8-0.20200903221953-ada5e6ae68cf/go.mod h1:wxuzS4ozpCFThia18G+J5P0Jp/DSiq9ezzJF1yvZuP4=
|
||||
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-20200730050024-3ee28c3b6d9a/go.mod h1:oOawOl9Yk+qeytLzzIryjI8iRbqo+qzS6EEeElP4PWA=
|
||||
github.com/filecoin-project/sector-storage v0.0.0-20200810171746-eac70842d8e0/go.mod h1:oOawOl9Yk+qeytLzzIryjI8iRbqo+qzS6EEeElP4PWA=
|
||||
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.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
|
||||
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.2/go.mod h1:Q3ACV5kBLvqPaYbthc/J1lGMJ5OwogmD9pzdtPRMdCw=
|
||||
github.com/filecoin-project/specs-actors v0.8.7-0.20200811203034-272d022c1923/go.mod h1:hukRu6vKQrrS7Nt+fC/ql4PqWLSfmAWNshD/VDtARZU=
|
||||
github.com/filecoin-project/specs-actors v0.9.2/go.mod h1:YasnVUOUha0DN5wB+twl+V8LlDKVNknRG00kTJpsfFA=
|
||||
github.com/filecoin-project/specs-actors v0.9.3/go.mod h1:YasnVUOUha0DN5wB+twl+V8LlDKVNknRG00kTJpsfFA=
|
||||
github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4=
|
||||
github.com/filecoin-project/specs-actors v0.9.6 h1:U3PU4jrHcmXxfEP0CC1fGETx4RrXlm5RYJeuT5eWjhI=
|
||||
github.com/filecoin-project/specs-actors v0.9.6/go.mod h1:wM2z+kwqYgXn5Z7scV1YHLyd1Q1cy0R8HfTIWQ0BFGU=
|
||||
github.com/filecoin-project/specs-actors v0.9.7 h1:7PAZ8kdqwBdmgf/23FCkQZLCXcVu02XJrkpkhBikiA8=
|
||||
github.com/filecoin-project/specs-actors v0.9.7/go.mod h1:wM2z+kwqYgXn5Z7scV1YHLyd1Q1cy0R8HfTIWQ0BFGU=
|
||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k=
|
||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200730063404-f7db367e9401/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k=
|
||||
github.com/filecoin-project/specs-actors v0.9.8 h1:45fnx/BsseFL3CtvSoR6CszFY26TFtsh9AHwCW2vkg8=
|
||||
github.com/filecoin-project/specs-actors v0.9.8/go.mod h1:xFObDoWPySBNTNBrGXVVrutmgSZH/mMo46Q1bec/0hw=
|
||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk=
|
||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g=
|
||||
github.com/filecoin-project/statediff v0.0.1 h1:lym6d5wNnzr+5Uc/6RRWx1hgwb+tCKn2mFIK0Eb1Q18=
|
||||
github.com/filecoin-project/statediff v0.0.1/go.mod h1:qNWauolLFEzOiA4LNWermBRVNbaZHfPcPevumZeh+hE=
|
||||
github.com/filecoin-project/storage-fsm v0.0.0-20200805013058-9d9ea4e6331f/go.mod h1:1CGbd11KkHuyWPT+xwwCol1zl/jnlpiKD2L4fzKxaiI=
|
||||
github.com/filecoin-project/test-vectors/schema v0.0.1 h1:5fNF76nl4qolEvcIsjc0kUADlTMVHO73tW4kXXPnsus=
|
||||
github.com/filecoin-project/test-vectors/schema v0.0.1/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as=
|
||||
github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ=
|
||||
@@ -320,7 +277,6 @@ github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclK
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo=
|
||||
@@ -364,7 +320,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -372,7 +327,6 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
@@ -400,9 +354,7 @@ github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8v
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
@@ -421,7 +373,6 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/rpc v1.2.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36jkTQ=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
@@ -494,7 +445,6 @@ github.com/ipfs/go-bitswap v0.0.9/go.mod h1:kAPf5qgn2W2DrgAcscZ3HrM9qh4pH+X8Fkk3
|
||||
github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0=
|
||||
github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs=
|
||||
github.com/ipfs/go-bitswap v0.1.8/go.mod h1:TOWoxllhccevbWFUR2N7B1MTSVVge1s6XSMiCSA4MzM=
|
||||
github.com/ipfs/go-bitswap v0.2.8/go.mod h1:2Yjog0GMdH8+AsxkE0DI9D2mANaUTxbVVav0pPoZoug=
|
||||
github.com/ipfs/go-bitswap v0.2.20 h1:Zfi5jDUoqxDThORUznqdeL77DdGniAzlccNJ4vr+Itc=
|
||||
github.com/ipfs/go-bitswap v0.2.20/go.mod h1:C7TwBgHnu89Q8sHsTJP7IhUqF9XYLe71P4tT5adgmYo=
|
||||
github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc=
|
||||
@@ -549,15 +499,11 @@ github.com/ipfs/go-ds-measure v0.1.0 h1:vE4TyY4aeLeVgnnPBC5QzKIjKrqzha0NCujTfgvV
|
||||
github.com/ipfs/go-ds-measure v0.1.0/go.mod h1:1nDiFrhLlwArTME1Ees2XaBOl49OoCgd2A3f8EchMSY=
|
||||
github.com/ipfs/go-filestore v1.0.0 h1:QR7ekKH+q2AGiWDc7W2Q0qHuYSRZGUJqUn0GsegEPb0=
|
||||
github.com/ipfs/go-filestore v1.0.0/go.mod h1:/XOCuNtIe2f1YPbiXdYvD0BKLA0JR1MgPiFOdcuu9SM=
|
||||
github.com/ipfs/go-fs-lock v0.0.1/go.mod h1:DNBekbboPKcxs1aukPSaOtFA3QfSdi5C855v0i9XJ8Y=
|
||||
github.com/ipfs/go-fs-lock v0.0.6 h1:sn3TWwNVQqSeNjlWy6zQ1uUGAZrV3hPOyEA6y1/N2a0=
|
||||
github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28L7zESmM=
|
||||
github.com/ipfs/go-graphsync v0.1.0/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE=
|
||||
github.com/ipfs/go-graphsync v0.1.1/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE=
|
||||
github.com/ipfs/go-graphsync v0.1.2 h1:25Ll9kIXCE+DY0dicvfS3KMw+U5sd01b/FJbA7KAbhg=
|
||||
github.com/ipfs/go-graphsync v0.1.2/go.mod h1:sLXVXm1OxtE2XYPw62MuXCdAuNwkAdsbnfrmos5odbA=
|
||||
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.1.1 h1:0IQdvwnAAUKmDE+PMJa5y1QiwOPHpI9+eAbQEEEYthk=
|
||||
github.com/ipfs/go-hamt-ipld v0.1.1/go.mod h1:1EZCr2v0jlCnhpa+aZ0JZYp8Tt2w16+JJOAVz17YcDk=
|
||||
github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08=
|
||||
@@ -589,7 +535,6 @@ github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAz
|
||||
github.com/ipfs/go-ipfs-files v0.0.2/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4=
|
||||
github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4=
|
||||
github.com/ipfs/go-ipfs-files v0.0.4/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4=
|
||||
github.com/ipfs/go-ipfs-files v0.0.7/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs=
|
||||
github.com/ipfs/go-ipfs-files v0.0.8 h1:8o0oFJkJ8UkO/ABl8T6ac6tKF3+NIpj67aAB6ZpusRg=
|
||||
github.com/ipfs/go-ipfs-files v0.0.8/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs=
|
||||
github.com/ipfs/go-ipfs-flags v0.0.1/go.mod h1:RnXBb9WV53GSfTrSDVK61NLTFKvWc60n+K9EgCDh+rA=
|
||||
@@ -778,7 +723,6 @@ github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qD
|
||||
github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El8cTaefiM=
|
||||
github.com/libp2p/go-libp2p v0.9.2/go.mod h1:cunHNLDVus66Ct9iXXcjKRLdmHdFdHVe1TAnbubJQqQ=
|
||||
github.com/libp2p/go-libp2p v0.10.0/go.mod h1:yBJNpb+mGJdgrwbKAKrhPU0u3ogyNFTfjJ6bdM+Q/G8=
|
||||
github.com/libp2p/go-libp2p v0.10.3/go.mod h1:0ER6iPSaPeQjryNgOnm9bLNpMJCYmuw54xJXsVR17eE=
|
||||
github.com/libp2p/go-libp2p v0.11.0 h1:jb5mqdqYEBAybTEhD8io43Cz5LzVKuWxOK7znSN69jE=
|
||||
github.com/libp2p/go-libp2p v0.11.0/go.mod h1:3/ogJDXsbbepEfqtZKBR/DedzxJXCeK17t2Z9RE9bEE=
|
||||
github.com/libp2p/go-libp2p-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4=
|
||||
@@ -906,13 +850,10 @@ github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1
|
||||
github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.1.1/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.2-0.20200527132641-c0712c6e92cf/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.5-0.20200820194335-bfc96c2cd081/go.mod h1:DTMSVmZZfXodB/pvdTGrY2eHPZ9W2ev7hzTH83OKHrI=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.6-0.20200901174250-06a12f17b7de/go.mod h1:DTMSVmZZfXodB/pvdTGrY2eHPZ9W2ev7hzTH83OKHrI=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.6-0.20200907103802-a3445b756fdb h1:0jm9ZSDkteX9XRjZqZwG5X0wuR+e0zAJ6ZEnqo2vcb0=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.6-0.20200907103802-a3445b756fdb/go.mod h1:DTMSVmZZfXodB/pvdTGrY2eHPZ9W2ev7hzTH83OKHrI=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.6-0.20200910093904-f7f33e10cc18 h1:+ae7vHSv/PJ4xGXwLV6LKGj32zjyB8ttJHtyV4TXal0=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.6-0.20200910093904-f7f33e10cc18/go.mod h1:DTMSVmZZfXodB/pvdTGrY2eHPZ9W2ev7hzTH83OKHrI=
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU=
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.5.0/go.mod h1:IEcuC5MLxvZ5KuHKjRu+dr3LjCT1Be3rcD/4d8JrX8M=
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.7.1/go.mod h1:TD31to4E5exogR/GWHClXCfkktigjAl5rXSt7HoxNvY=
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.8.0 h1:mHA94K2+TD0e9XtjWx/P5jGGZn0GdQ4OFYwNllagv4E=
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.8.0/go.mod h1:F2FG/6Bzz0U6essUVxDzE0s9CrY4XGLbl7QEmDNvU7A=
|
||||
github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q=
|
||||
@@ -1047,7 +988,6 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw=
|
||||
github.com/lucas-clemente/quic-go v0.16.0/go.mod h1:I0+fcNTdb9eS1ZcjQZbDVPGchJ86chcIxPALn9lEJqE=
|
||||
github.com/lucas-clemente/quic-go v0.17.3/go.mod h1:I0+fcNTdb9eS1ZcjQZbDVPGchJ86chcIxPALn9lEJqE=
|
||||
github.com/lucas-clemente/quic-go v0.18.0 h1:JhQDdqxdwdmGdKsKgXi1+coHRoGhvU6z0rNzOJqZ/4o=
|
||||
github.com/lucas-clemente/quic-go v0.18.0/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg=
|
||||
github.com/lufia/iostat v1.1.0/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg=
|
||||
@@ -1072,10 +1012,8 @@ github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
@@ -1094,7 +1032,6 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N
|
||||
github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
|
||||
@@ -1377,9 +1314,8 @@ github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
@@ -1430,13 +1366,11 @@ github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba/go.mod h1:CH
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20191212224538-d370462a7e8a/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20191216205031-b047b6acb3c0/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/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-20200414195334-429a0b5e922e/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
||||
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/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-20200723185710-6a3894a6352b/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200810223238-211df3b9e24c/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200812213548-958ddffe352c/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200814224545-656e08ce49ee h1:U7zWWvvAjT76EiuWPSOiZlQDnaQYPxPoxugTtTAcJK0=
|
||||
@@ -1463,12 +1397,7 @@ github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d/go.mod h1:g7c
|
||||
github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow=
|
||||
github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg=
|
||||
github.com/whyrusleeping/yamux v1.1.5/go.mod h1:E8LnQQ8HKx5KD29HZFUwM1PxCOdPRzGwur1mcYhXcD8=
|
||||
github.com/willscott/go-cmp v0.5.2-0.20200812183318-8affb9542345 h1:IJVAwIctqDFOrO0C2qzksXmANviyHJzrklU27e1ltzE=
|
||||
github.com/willscott/go-cmp v0.5.2-0.20200812183318-8affb9542345/go.mod h1:D7hA8H5pyQx7Y5Em7IWx1R4vNJzfon3gpG9nxjkITjQ=
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xlab/c-for-go v0.0.0-20200718154222-87b0065af829 h1:wb7xrDzfkLgPHsSEBm+VSx6aDdi64VtV0xvP0E6j8bk=
|
||||
github.com/xlab/c-for-go v0.0.0-20200718154222-87b0065af829/go.mod h1:h/1PEBwj7Ym/8kOuMWvO2ujZ6Lt+TMbySEXNhjjR87I=
|
||||
@@ -1478,7 +1407,6 @@ github.com/xorcare/golden v0.6.0/go.mod h1:7T39/ZMvaSEZlBPoYfVFmsBLmUl3uz9IuzWj/
|
||||
github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542 h1:oWgZJmC1DorFZDpfMfWg7xk29yEOZiXmo/wZl+utTI8=
|
||||
github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542/go.mod h1:7T39/ZMvaSEZlBPoYfVFmsBLmUl3uz9IuzWj/U6FtvQ=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs=
|
||||
go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw=
|
||||
@@ -1509,7 +1437,6 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/dig v1.8.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw=
|
||||
go.uber.org/dig v1.10.0 h1:yLmDDj9/zuDjv3gz8GQGviXMs9TfysIUMUilCpgzUJY=
|
||||
go.uber.org/dig v1.10.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw=
|
||||
go.uber.org/fx v1.9.0 h1:7OAz8ucp35AU8eydejpYG7QrbE8rLKzGhHbZlJi5LYY=
|
||||
@@ -1529,8 +1456,6 @@ go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
|
||||
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
go4.org v0.0.0-20190218023631-ce4c26f7be8e/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
go4.org v0.0.0-20190313082347-94abd6928b1d/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU=
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg=
|
||||
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||
@@ -1555,15 +1480,11 @@ golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
@@ -1574,10 +1495,8 @@ golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm0
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd h1:zkO/Lhoka23X63N9OSzpSeROEUQ5ODw47tM3YWjygbs=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -1589,15 +1508,13 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -1635,11 +1552,8 @@ golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
@@ -1697,13 +1611,11 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1713,20 +1625,14 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200427175716-29b57079015a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y=
|
||||
@@ -1770,22 +1676,14 @@ golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200108195415-316d2f248479/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200216192241-b320d3a0f5a2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200711155855-7342f9734a7d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3 h1:r3P/5xOq/dK1991B65Oy6E1fRF/2d/fSYZJ/fXGVfJc=
|
||||
golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
@@ -1806,11 +1704,8 @@ google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEn
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0 h1:0q95w+VuFtv4PAx4PZVQdBMmYbaCHbnfKaEiDIcVyag=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.25.0 h1:LodzhlzZEUfhXzNUMIfVlf9Gr6Ua5MMtoFWh7+f47qA=
|
||||
google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -1836,12 +1731,7 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482 h1:i+Aiej6cta/Frzp13/swvwz5O00kYcSe0A/C5Wd7zX8=
|
||||
@@ -1862,10 +1752,8 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v0.0.0-20200617041141-9a465503579e/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -1914,9 +1802,8 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M=
|
||||
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
|
||||
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||
|
||||
+21
-4
@@ -10,7 +10,10 @@ import (
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"go.opencensus.io/stats"
|
||||
"go.uber.org/fx"
|
||||
"go.uber.org/multierr"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/event"
|
||||
host "github.com/libp2p/go-libp2p-core/host"
|
||||
net "github.com/libp2p/go-libp2p-core/network"
|
||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||
@@ -50,12 +53,17 @@ type PeerMgr struct {
|
||||
h host.Host
|
||||
dht *dht.IpfsDHT
|
||||
|
||||
notifee *net.NotifyBundle
|
||||
notifee *net.NotifyBundle
|
||||
filPeerEmitter event.Emitter
|
||||
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func NewPeerMgr(lc fx.Lifecycle, h host.Host, dht *dht.IpfsDHT, bootstrap dtypes.BootstrapPeers) *PeerMgr {
|
||||
type NewFilPeer struct {
|
||||
Id peer.ID
|
||||
}
|
||||
|
||||
func NewPeerMgr(lc fx.Lifecycle, h host.Host, dht *dht.IpfsDHT, bootstrap dtypes.BootstrapPeers) (*PeerMgr, error) {
|
||||
pm := &PeerMgr{
|
||||
h: h,
|
||||
dht: dht,
|
||||
@@ -69,10 +77,18 @@ func NewPeerMgr(lc fx.Lifecycle, h host.Host, dht *dht.IpfsDHT, bootstrap dtypes
|
||||
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
emitter, err := h.EventBus().Emitter(new(NewFilPeer))
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("creating NewFilPeer emitter: %w", err)
|
||||
}
|
||||
pm.filPeerEmitter = emitter
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return pm.Stop(ctx)
|
||||
return multierr.Combine(
|
||||
pm.filPeerEmitter.Close(),
|
||||
pm.Stop(ctx),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
@@ -84,10 +100,11 @@ func NewPeerMgr(lc fx.Lifecycle, h host.Host, dht *dht.IpfsDHT, bootstrap dtypes
|
||||
|
||||
h.Network().Notify(pm.notifee)
|
||||
|
||||
return pm
|
||||
return pm, nil
|
||||
}
|
||||
|
||||
func (pmgr *PeerMgr) AddFilecoinPeer(p peer.ID) {
|
||||
_ = pmgr.filPeerEmitter.Emit(NewFilPeer{Id: p}) //nolint:errcheck
|
||||
pmgr.peersLk.Lock()
|
||||
defer pmgr.peersLk.Unlock()
|
||||
pmgr.peers[p] = time.Duration(0)
|
||||
|
||||
@@ -161,7 +161,7 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor
|
||||
|
||||
pubmsg, err := c.cs.GetMessage(*deal.PublishMessage)
|
||||
if err != nil {
|
||||
return 0, xerrors.Errorf("getting deal pubsish message: %w", err)
|
||||
return 0, xerrors.Errorf("getting deal publish message: %w", err)
|
||||
}
|
||||
|
||||
mi, err := stmgr.StateMinerInfo(ctx, c.sm, c.cs.GetHeaviestTipSet(), deal.Proposal.Provider)
|
||||
|
||||
+6
-4
@@ -189,6 +189,7 @@ func (m *Miner) mine(ctx context.Context) {
|
||||
_, err = m.api.BeaconGetEntry(ctx, prebase.TipSet.Height()+prebase.NullRounds+1)
|
||||
if err != nil {
|
||||
log.Errorf("failed getting beacon entry: %s", err)
|
||||
m.niceSleep(time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -361,7 +362,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg,
|
||||
rbase = bvals[len(bvals)-1]
|
||||
}
|
||||
|
||||
ticket, err := m.computeTicket(ctx, &rbase, base, len(bvals) > 0)
|
||||
ticket, err := m.computeTicket(ctx, &rbase, base)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("scratching ticket failed: %w", err)
|
||||
}
|
||||
@@ -431,7 +432,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg,
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, base *MiningBase, haveNewEntries bool) (*types.Ticket, error) {
|
||||
func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, base *MiningBase) (*types.Ticket, error) {
|
||||
mi, err := m.api.StateMinerInfo(ctx, m.address, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -446,11 +447,12 @@ func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, bas
|
||||
return nil, xerrors.Errorf("failed to marshal address to cbor: %w", err)
|
||||
}
|
||||
|
||||
if !haveNewEntries {
|
||||
round := base.TipSet.Height() + base.NullRounds + 1
|
||||
if round > build.UpgradeSmokeHeight {
|
||||
buf.Write(base.TipSet.MinTicket().VRFProof)
|
||||
}
|
||||
|
||||
input, err := store.DrawRandomness(brand.Data, crypto.DomainSeparationTag_TicketProduction, base.TipSet.Height()+base.NullRounds+1-build.TicketRandomnessLookback, buf.Bytes())
|
||||
input, err := store.DrawRandomness(brand.Data, crypto.DomainSeparationTag_TicketProduction, round-build.TicketRandomnessLookback, buf.Bytes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+10
-10
@@ -29,7 +29,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain"
|
||||
"github.com/filecoin-project/lotus/chain/beacon"
|
||||
"github.com/filecoin-project/lotus/chain/blocksync"
|
||||
"github.com/filecoin-project/lotus/chain/exchange"
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
|
||||
"github.com/filecoin-project/lotus/chain/market"
|
||||
@@ -103,7 +103,7 @@ const (
|
||||
SetGenesisKey
|
||||
|
||||
RunHelloKey
|
||||
RunBlockSyncKey
|
||||
RunChainExchangeKey
|
||||
RunChainGraphsync
|
||||
RunPeerMgrKey
|
||||
|
||||
@@ -226,7 +226,7 @@ func Online() Option {
|
||||
|
||||
Override(new(dtypes.BootstrapPeers), modules.BuiltinBootstrap),
|
||||
Override(new(dtypes.DrandBootstrap), modules.DrandBootstrap),
|
||||
Override(new(dtypes.DrandConfig), modules.BuiltinDrandConfig),
|
||||
Override(new(dtypes.DrandSchedule), modules.BuiltinDrandConfig),
|
||||
|
||||
Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages),
|
||||
|
||||
@@ -238,12 +238,12 @@ func Online() Option {
|
||||
|
||||
Override(new(dtypes.ChainGCLocker), blockstore.NewGCLocker),
|
||||
Override(new(dtypes.ChainGCBlockstore), modules.ChainGCBlockstore),
|
||||
Override(new(dtypes.ChainExchange), modules.ChainExchange),
|
||||
Override(new(dtypes.ChainBlockService), modules.ChainBlockservice),
|
||||
Override(new(dtypes.ChainBitswap), modules.ChainBitswap),
|
||||
Override(new(dtypes.ChainBlockService), modules.ChainBlockService),
|
||||
|
||||
// Filecoin services
|
||||
Override(new(*chain.Syncer), modules.NewSyncer),
|
||||
Override(new(*blocksync.BlockSync), blocksync.NewClient),
|
||||
Override(new(exchange.Client), exchange.NewClient),
|
||||
Override(new(*messagepool.MessagePool), modules.MessagePool),
|
||||
|
||||
Override(new(modules.Genesis), modules.ErrorGenesis),
|
||||
@@ -252,14 +252,14 @@ func Online() Option {
|
||||
|
||||
Override(new(dtypes.NetworkName), modules.NetworkName),
|
||||
Override(new(*hello.Service), hello.NewHelloService),
|
||||
Override(new(*blocksync.BlockSyncService), blocksync.NewBlockSyncService),
|
||||
Override(new(exchange.Server), exchange.NewServer),
|
||||
Override(new(*peermgr.PeerMgr), peermgr.NewPeerMgr),
|
||||
|
||||
Override(new(dtypes.Graphsync), modules.Graphsync),
|
||||
Override(new(*dtypes.MpoolLocker), new(dtypes.MpoolLocker)),
|
||||
|
||||
Override(RunHelloKey, modules.RunHello),
|
||||
Override(RunBlockSyncKey, modules.RunBlockSync),
|
||||
Override(RunChainExchangeKey, modules.RunChainExchange),
|
||||
Override(RunPeerMgrKey, modules.RunPeerMgr),
|
||||
Override(HandleIncomingBlocksKey, modules.HandleIncomingBlocks),
|
||||
|
||||
@@ -272,7 +272,7 @@ func Online() Option {
|
||||
Override(new(modules.ClientDealFunds), modules.NewClientDealFunds),
|
||||
Override(new(storagemarket.StorageClient), modules.StorageClient),
|
||||
Override(new(storagemarket.StorageClientNode), storageadapter.NewClientNodeAdapter),
|
||||
Override(new(beacon.RandomBeacon), modules.RandomBeacon),
|
||||
Override(new(beacon.Schedule), modules.RandomSchedule),
|
||||
|
||||
Override(new(*paychmgr.Store), paychmgr.NewStore),
|
||||
Override(new(*paychmgr.Manager), paychmgr.NewManager),
|
||||
@@ -535,6 +535,6 @@ func Test() Option {
|
||||
return Options(
|
||||
Unset(RunPeerMgrKey),
|
||||
Unset(new(*peermgr.PeerMgr)),
|
||||
Override(new(beacon.RandomBeacon), testing.RandomBeacon),
|
||||
Override(new(beacon.Schedule), testing.RandomBeacon),
|
||||
)
|
||||
}
|
||||
|
||||
+4
-3
@@ -104,6 +104,10 @@ func (hs *Service) HandleStream(s inet.Stream) {
|
||||
build.Clock.Sleep(time.Millisecond * 300)
|
||||
}
|
||||
|
||||
if hs.pmgr != nil {
|
||||
hs.pmgr.AddFilecoinPeer(s.Conn().RemotePeer())
|
||||
}
|
||||
|
||||
ts, err := hs.syncer.FetchTipSet(context.Background(), s.Conn().RemotePeer(), types.NewTipSetKey(hmsg.HeaviestTipSet...))
|
||||
if err != nil {
|
||||
log.Errorf("failed to fetch tipset from peer during hello: %+v", err)
|
||||
@@ -117,9 +121,6 @@ func (hs *Service) HandleStream(s inet.Stream) {
|
||||
log.Infof("Got new tipset through Hello: %s from %s", ts.Cids(), s.Conn().RemotePeer())
|
||||
hs.syncer.InformNewHead(s.Conn().RemotePeer(), ts)
|
||||
}
|
||||
if hs.pmgr != nil {
|
||||
hs.pmgr.AddFilecoinPeer(s.Conn().RemotePeer())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"golang.org/x/xerrors"
|
||||
@@ -80,7 +82,7 @@ type API struct {
|
||||
Host host.Host
|
||||
}
|
||||
|
||||
func calcDealExpiration(minDuration uint64, md *miner.DeadlineInfo, startEpoch abi.ChainEpoch) abi.ChainEpoch {
|
||||
func calcDealExpiration(minDuration uint64, md *dline.Info, startEpoch abi.ChainEpoch) abi.ChainEpoch {
|
||||
// Make sure we give some time for the miner to seal
|
||||
minExp := startEpoch + abi.ChainEpoch(minDuration)
|
||||
|
||||
|
||||
@@ -170,9 +170,14 @@ func (a *CommonAPI) ID(context.Context) (peer.ID, error) {
|
||||
}
|
||||
|
||||
func (a *CommonAPI) Version(context.Context) (api.Version, error) {
|
||||
v, err := build.VersionForType(build.RunningNodeType)
|
||||
if err != nil {
|
||||
return api.Version{}, err
|
||||
}
|
||||
|
||||
return api.Version{
|
||||
Version: build.UserVersion(),
|
||||
APIVersion: build.APIVersion,
|
||||
APIVersion: v,
|
||||
|
||||
BlockDelay: build.BlockDelaySecs,
|
||||
}, nil
|
||||
|
||||
@@ -13,12 +13,13 @@ import (
|
||||
type BeaconAPI struct {
|
||||
fx.In
|
||||
|
||||
Beacon beacon.RandomBeacon
|
||||
Beacon beacon.Schedule
|
||||
}
|
||||
|
||||
func (a *BeaconAPI) BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) {
|
||||
rr := a.Beacon.MaxBeaconRoundForEpoch(epoch, types.BeaconEntry{})
|
||||
e := a.Beacon.Entry(ctx, rr)
|
||||
b := a.Beacon.BeaconForEpoch(epoch)
|
||||
rr := b.MaxBeaconRoundForEpoch(epoch)
|
||||
e := b.Entry(ctx, rr)
|
||||
|
||||
select {
|
||||
case be, ok := <-e:
|
||||
|
||||
+38
-32
@@ -6,12 +6,8 @@ import (
|
||||
"math/rand"
|
||||
"sort"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"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/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
@@ -19,8 +15,12 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"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/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
type GasAPI struct {
|
||||
@@ -50,6 +50,35 @@ func (a *GasAPI) GasEstimateFeeCap(ctx context.Context, msg *types.Message, maxq
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type gasMeta struct {
|
||||
price big.Int
|
||||
limit int64
|
||||
}
|
||||
|
||||
func medianGasPremium(prices []gasMeta, blocks int) abi.TokenAmount {
|
||||
sort.Slice(prices, func(i, j int) bool {
|
||||
// sort desc by price
|
||||
return prices[i].price.GreaterThan(prices[j].price)
|
||||
})
|
||||
|
||||
at := build.BlockGasTarget * int64(blocks) / 2
|
||||
prev1, prev2 := big.Zero(), big.Zero()
|
||||
for _, price := range prices {
|
||||
prev1, prev2 = price.price, prev1
|
||||
at -= price.limit
|
||||
if at < 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
premium := prev1
|
||||
if prev2.Sign() != 0 {
|
||||
premium = big.Div(types.BigAdd(prev1, prev2), types.NewInt(2))
|
||||
}
|
||||
|
||||
return premium
|
||||
}
|
||||
|
||||
func (a *GasAPI) GasEstimateGasPremium(ctx context.Context, nblocksincl uint64,
|
||||
sender address.Address, gaslimit int64, _ types.TipSetKey) (types.BigInt, error) {
|
||||
|
||||
@@ -57,11 +86,6 @@ func (a *GasAPI) GasEstimateGasPremium(ctx context.Context, nblocksincl uint64,
|
||||
nblocksincl = 1
|
||||
}
|
||||
|
||||
type gasMeta struct {
|
||||
price big.Int
|
||||
limit int64
|
||||
}
|
||||
|
||||
var prices []gasMeta
|
||||
var blocks int
|
||||
|
||||
@@ -92,25 +116,7 @@ func (a *GasAPI) GasEstimateGasPremium(ctx context.Context, nblocksincl uint64,
|
||||
ts = pts
|
||||
}
|
||||
|
||||
sort.Slice(prices, func(i, j int) bool {
|
||||
// sort desc by price
|
||||
return prices[i].price.GreaterThan(prices[j].price)
|
||||
})
|
||||
|
||||
at := build.BlockGasTarget * int64(blocks) / 2
|
||||
prev1, prev2 := big.Zero(), big.Zero()
|
||||
for _, price := range prices {
|
||||
prev1, prev2 = price.price, prev1
|
||||
at -= price.limit
|
||||
if at > 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
premium := prev1
|
||||
if prev2.Sign() != 0 {
|
||||
premium = big.Div(types.BigAdd(prev1, prev2), types.NewInt(2))
|
||||
}
|
||||
premium := medianGasPremium(prices, blocks)
|
||||
|
||||
if types.BigCmp(premium, types.NewInt(MinGasPremium)) < 0 {
|
||||
switch nblocksincl {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package full
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func TestMedian(t *testing.T) {
|
||||
require.Equal(t, types.NewInt(5), medianGasPremium([]gasMeta{
|
||||
{big.NewInt(5), build.BlockGasTarget},
|
||||
}, 1))
|
||||
|
||||
require.Equal(t, types.NewInt(10), medianGasPremium([]gasMeta{
|
||||
{big.NewInt(5), build.BlockGasTarget},
|
||||
{big.NewInt(10), build.BlockGasTarget},
|
||||
}, 1))
|
||||
|
||||
require.Equal(t, types.NewInt(15), medianGasPremium([]gasMeta{
|
||||
{big.NewInt(10), build.BlockGasTarget / 2},
|
||||
{big.NewInt(20), build.BlockGasTarget / 2},
|
||||
}, 1))
|
||||
|
||||
require.Equal(t, types.NewInt(25), medianGasPremium([]gasMeta{
|
||||
{big.NewInt(10), build.BlockGasTarget / 2},
|
||||
{big.NewInt(20), build.BlockGasTarget / 2},
|
||||
{big.NewInt(30), build.BlockGasTarget / 2},
|
||||
}, 1))
|
||||
|
||||
require.Equal(t, types.NewInt(15), medianGasPremium([]gasMeta{
|
||||
{big.NewInt(10), build.BlockGasTarget / 2},
|
||||
{big.NewInt(20), build.BlockGasTarget / 2},
|
||||
{big.NewInt(30), build.BlockGasTarget / 2},
|
||||
}, 2))
|
||||
}
|
||||
@@ -130,6 +130,33 @@ func (a *MsigAPI) MsigPropose(ctx context.Context, msig address.Address, to addr
|
||||
return smsg.Cid(), nil
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigAddPropose(ctx context.Context, msig address.Address, src address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
enc, actErr := serializeAddParams(newAdd, inc)
|
||||
if actErr != nil {
|
||||
return cid.Undef, actErr
|
||||
}
|
||||
|
||||
return a.MsigPropose(ctx, msig, msig, big.Zero(), src, uint64(builtin.MethodsMultisig.AddSigner), enc)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
enc, actErr := serializeAddParams(newAdd, inc)
|
||||
if actErr != nil {
|
||||
return cid.Undef, actErr
|
||||
}
|
||||
|
||||
return a.MsigApprove(ctx, msig, txID, proposer, msig, big.Zero(), src, uint64(builtin.MethodsMultisig.AddSigner), enc)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
enc, actErr := serializeAddParams(newAdd, inc)
|
||||
if actErr != nil {
|
||||
return cid.Undef, actErr
|
||||
}
|
||||
|
||||
return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(builtin.MethodsMultisig.AddSigner), enc)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||
enc, actErr := serializeSwapParams(oldAdd, newAdd)
|
||||
if actErr != nil {
|
||||
@@ -244,6 +271,18 @@ func (a *MsigAPI) msigApproveOrCancel(ctx context.Context, operation api.MsigPro
|
||||
return smsg.Cid(), nil
|
||||
}
|
||||
|
||||
func serializeAddParams(new address.Address, inc bool) ([]byte, error) {
|
||||
enc, actErr := actors.SerializeParams(&samsig.AddSignerParams{
|
||||
Signer: new,
|
||||
Increase: inc,
|
||||
})
|
||||
if actErr != nil {
|
||||
return nil, actErr
|
||||
}
|
||||
|
||||
return enc, nil
|
||||
}
|
||||
|
||||
func serializeSwapParams(old address.Address, new address.Address) ([]byte, error) {
|
||||
enc, actErr := actors.SerializeParams(&samsig.SwapSignerParams{
|
||||
From: old,
|
||||
|
||||
+46
-2
@@ -7,6 +7,8 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@@ -53,7 +55,7 @@ type StateAPI struct {
|
||||
ProofVerifier ffiwrapper.Verifier
|
||||
StateManager *stmgr.StateManager
|
||||
Chain *store.ChainStore
|
||||
Beacon beacon.RandomBeacon
|
||||
Beacon beacon.Schedule
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateNetworkName(ctx context.Context) (dtypes.NetworkName, error) {
|
||||
@@ -145,7 +147,7 @@ func (a *StateAPI) StateMinerPartitions(ctx context.Context, m address.Address,
|
||||
}))))))
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*miner.DeadlineInfo, error) {
|
||||
func (a *StateAPI) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
@@ -886,6 +888,48 @@ func (a *StateAPI) MsigGetAvailableBalance(ctx context.Context, addr address.Add
|
||||
return types.BigSub(act.Balance, minBalance), nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) {
|
||||
startTs, err := a.Chain.GetTipSetFromKey(start)
|
||||
if err != nil {
|
||||
return types.EmptyInt, xerrors.Errorf("loading start tipset %s: %w", start, err)
|
||||
}
|
||||
|
||||
endTs, err := a.Chain.GetTipSetFromKey(end)
|
||||
if err != nil {
|
||||
return types.EmptyInt, xerrors.Errorf("loading end tipset %s: %w", end, err)
|
||||
}
|
||||
|
||||
if startTs.Height() > endTs.Height() {
|
||||
return types.EmptyInt, xerrors.Errorf("start tipset %d is after end tipset %d", startTs.Height(), endTs.Height())
|
||||
} else if startTs.Height() == endTs.Height() {
|
||||
return big.Zero(), nil
|
||||
}
|
||||
|
||||
var mst samsig.State
|
||||
act, err := a.StateManager.LoadActorState(ctx, addr, &mst, endTs)
|
||||
if err != nil {
|
||||
return types.EmptyInt, xerrors.Errorf("failed to load multisig actor state at end epoch: %w", err)
|
||||
}
|
||||
|
||||
if act.Code != builtin.MultisigActorCodeID {
|
||||
return types.EmptyInt, fmt.Errorf("given actor was not a multisig")
|
||||
}
|
||||
|
||||
if mst.UnlockDuration == 0 ||
|
||||
mst.InitialBalance.IsZero() ||
|
||||
mst.StartEpoch+mst.UnlockDuration <= startTs.Height() ||
|
||||
mst.StartEpoch >= endTs.Height() {
|
||||
return big.Zero(), nil
|
||||
}
|
||||
|
||||
startLk := mst.InitialBalance
|
||||
if startTs.Height() > mst.StartEpoch {
|
||||
startLk = mst.AmountLocked(startTs.Height() - mst.StartEpoch)
|
||||
}
|
||||
|
||||
return big.Sub(startLk, mst.AmountLocked(endTs.Height()-mst.StartEpoch)), nil
|
||||
}
|
||||
|
||||
var initialPledgeNum = types.NewInt(110)
|
||||
var initialPledgeDen = types.NewInt(100)
|
||||
|
||||
|
||||
@@ -97,12 +97,23 @@ func (a *SyncAPI) SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHe
|
||||
return a.Syncer.IncomingBlocks(ctx)
|
||||
}
|
||||
|
||||
func (a *SyncAPI) SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) error {
|
||||
log.Warnf("Marking tipset %s as checkpoint", tsk)
|
||||
return a.Syncer.SetCheckpoint(tsk)
|
||||
}
|
||||
|
||||
func (a *SyncAPI) SyncMarkBad(ctx context.Context, bcid cid.Cid) error {
|
||||
log.Warnf("Marking block %s as bad", bcid)
|
||||
a.Syncer.MarkBad(bcid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *SyncAPI) SyncUnmarkBad(ctx context.Context, bcid cid.Cid) error {
|
||||
log.Warnf("Unmarking block %s as bad", bcid)
|
||||
a.Syncer.UnmarkBad(bcid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *SyncAPI) SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error) {
|
||||
reason, ok := a.Syncer.CheckBadBlockCache(bcid)
|
||||
if !ok {
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/chain"
|
||||
"github.com/filecoin-project/lotus/chain/beacon"
|
||||
"github.com/filecoin-project/lotus/chain/blocksync"
|
||||
"github.com/filecoin-project/lotus/chain/exchange"
|
||||
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
)
|
||||
|
||||
func ChainExchange(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, rt routing.Routing, bs dtypes.ChainGCBlockstore) dtypes.ChainExchange {
|
||||
func ChainBitswap(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, rt routing.Routing, bs dtypes.ChainGCBlockstore) dtypes.ChainBitswap {
|
||||
// prefix protocol for chain bitswap
|
||||
// (so bitswap uses /chain/ipfs/bitswap/1.0.0 internally for chain sync stuff)
|
||||
bitswapNetwork := network.NewFromIpfsHost(host, rt, network.Prefix("/chain"))
|
||||
@@ -83,7 +83,7 @@ func ChainGCBlockstore(bs dtypes.ChainBlockstore, gcl dtypes.ChainGCLocker) dtyp
|
||||
return blockstore.NewGCBlockstore(bs, gcl)
|
||||
}
|
||||
|
||||
func ChainBlockservice(bs dtypes.ChainBlockstore, rem dtypes.ChainExchange) dtypes.ChainBlockService {
|
||||
func ChainBlockService(bs dtypes.ChainBlockstore, rem dtypes.ChainBitswap) dtypes.ChainBlockService {
|
||||
return blockservice.New(bs, rem)
|
||||
}
|
||||
|
||||
@@ -163,8 +163,8 @@ func NetworkName(mctx helpers.MetricsCtx, lc fx.Lifecycle, cs *store.ChainStore,
|
||||
return netName, err
|
||||
}
|
||||
|
||||
func NewSyncer(lc fx.Lifecycle, sm *stmgr.StateManager, bsync *blocksync.BlockSync, h host.Host, beacon beacon.RandomBeacon, verifier ffiwrapper.Verifier) (*chain.Syncer, error) {
|
||||
syncer, err := chain.NewSyncer(sm, bsync, h.ConnManager(), h.ID(), beacon, verifier)
|
||||
func NewSyncer(lc fx.Lifecycle, ds dtypes.MetadataDS, sm *stmgr.StateManager, exchange exchange.Client, h host.Host, beacon beacon.Schedule, verifier ffiwrapper.Verifier) (*chain.Syncer, error) {
|
||||
syncer, err := chain.NewSyncer(ds, sm, exchange, h.ConnManager(), h.ID(), beacon, verifier)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+11
-6
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/gbrlsnchs/jwt/v3"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/libp2p/go-libp2p-core/peerstore"
|
||||
record "github.com/libp2p/go-libp2p-record"
|
||||
"golang.org/x/xerrors"
|
||||
@@ -93,14 +94,18 @@ func BuiltinBootstrap() (dtypes.BootstrapPeers, error) {
|
||||
return build.BuiltinBootstrap()
|
||||
}
|
||||
|
||||
func DrandBootstrap(d dtypes.DrandConfig) (dtypes.DrandBootstrap, error) {
|
||||
func DrandBootstrap(ds dtypes.DrandSchedule) (dtypes.DrandBootstrap, error) {
|
||||
// TODO: retry resolving, don't fail if at least one resolve succeeds
|
||||
addrs, err := addrutil.ParseAddresses(context.TODO(), d.Relays)
|
||||
if err != nil {
|
||||
log.Errorf("reoslving drand relays addresses: %+v", err)
|
||||
return nil, nil
|
||||
res := []peer.AddrInfo{}
|
||||
for _, d := range ds {
|
||||
addrs, err := addrutil.ParseAddresses(context.TODO(), d.Config.Relays)
|
||||
if err != nil {
|
||||
log.Errorf("reoslving drand relays addresses: %+v", err)
|
||||
return res, nil
|
||||
}
|
||||
res = append(res, addrs...)
|
||||
}
|
||||
return addrs, nil
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func SetupJournal(lr repo.LockedRepo) error {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user