Compare commits
38
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3686ce88e | ||
|
|
8f4ab925fa | ||
|
|
143dcafdb7 | ||
|
|
d8d2174104 | ||
|
|
1c6ea75f4b | ||
|
|
1ee9fb44e2 | ||
|
|
473afc41e7 | ||
|
|
a055540c25 | ||
|
|
cb0513f4c1 | ||
|
|
be42dd824b | ||
|
|
06c0444d45 | ||
|
|
bae735447d | ||
|
|
1974490ab0 | ||
|
|
d24d3e420d | ||
|
|
0f5aa9ba5c | ||
|
|
4de8f50642 | ||
|
|
4a057d84b8 | ||
|
|
111942b50b | ||
|
|
40e34b334a | ||
|
|
1a049a4f8e | ||
|
|
d0e4150cea | ||
|
|
a71fbee2d1 | ||
|
|
af1a422ddd | ||
|
|
8351420404 | ||
|
|
726eacbe03 | ||
|
|
eae7d62a2b | ||
|
|
5bee85d57a | ||
|
|
0b7dc6971d | ||
|
|
8c7d2efe72 | ||
|
|
a931ff94e9 | ||
|
|
980023e87b | ||
|
|
36a10f4acc | ||
|
|
d1b95b02dd | ||
|
|
b273bfc5c3 | ||
|
|
af14f30e3a | ||
|
|
de1038ecc3 | ||
|
|
d0e432ab16 | ||
|
|
f5132c3b61 |
@@ -1,5 +1,36 @@
|
||||
# Lotus changelog
|
||||
|
||||
# 1.0.0 / 2020-10-19
|
||||
|
||||
It's 1.0.0! This is an optional release of Lotus that introduces some UX improvements to the 0.10 series.
|
||||
|
||||
This very small release is largely cosmetic, and intended to flag the code that the Filecoin mainnet was launched with.
|
||||
|
||||
## API changes
|
||||
|
||||
- `StateMsgGasCost` has been removed. The equivalent information can be gained by calling `StateReplay`.
|
||||
- A `GasCost` field has been added to the `InvocResult` type, meaning detailed gas costs will be returned when calling `StateReplay`, `StateCompute`, and `StateCall`.
|
||||
- The behaviour of `StateReplay` in response to an empty tipset key has been changed. Instead of simply using the heaviest tipset (which is almost guaranteed to be an unsuccessful replay), we search now search the chain for the tipset that included the message, and replay the message in that tipset (we fail if no such tipset is found).
|
||||
|
||||
## Changes
|
||||
|
||||
- Increase code coverage! (https://github.com/filecoin-project/lotus/pull/4410)
|
||||
- Mpool: Don't block node startup loading messages (https://github.com/filecoin-project/lotus/pull/4411)
|
||||
- Improve the UX of multisig approves (https://github.com/filecoin-project/lotus/pull/4398)
|
||||
- Use build.BlockDelaySecs for deal start buffer (https://github.com/filecoin-project/lotus/pull/4415)
|
||||
- Conformance: support multiple protocol versions (https://github.com/filecoin-project/lotus/pull/4393)
|
||||
- Ensure msig inspect cli works with lotus-lite (https://github.com/filecoin-project/lotus/pull/4421)
|
||||
- Add command to (slowly) prune lotus chain datastore (https://github.com/filecoin-project/lotus/pull/3876)
|
||||
- Add WalletVerify to lotus-gateway (https://github.com/filecoin-project/lotus/pull/4373)
|
||||
- Improve StateMsg APIs (https://github.com/filecoin-project/lotus/pull/4429)
|
||||
- Add endpoints needed by spacegap (https://github.com/filecoin-project/lotus/pull/4426)
|
||||
- Make audit balances capable of printing robust addresses (https://github.com/filecoin-project/lotus/pull/4423)
|
||||
- Custom filters for retrieval deals (https://github.com/filecoin-project/lotus/pull/4424)
|
||||
- Fix message list api (https://github.com/filecoin-project/lotus/pull/4422)
|
||||
- Replace bootstrap peers (https://github.com/filecoin-project/lotus/pull/4447)
|
||||
- Don't overwrite previously-configured maxPieceSize for a persisted ask (https://github.com/filecoin-project/lotus/pull/4480)
|
||||
- State: optimize state snapshot address cache (https://github.com/filecoin-project/lotus/pull/4481)
|
||||
|
||||
# 0.10.2 / 2020-10-14
|
||||
|
||||
This is an optional release of Lotus that updates markets to 0.9.1, which fixes an issue affecting deals that were mid-transfer when the node was upgraded to 0.9.0. This release also includes some tweaks to default gas values and minor performance improvements.
|
||||
|
||||
+6
-1
@@ -328,7 +328,7 @@ type FullNode interface {
|
||||
// StateReadState returns the indicated actor's state.
|
||||
StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*ActorState, error)
|
||||
// StateListMessages looks back and returns all messages with a matching to or from address, stopping at the given height.
|
||||
StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error)
|
||||
StateListMessages(ctx context.Context, match *MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error)
|
||||
|
||||
// StateNetworkName returns the name of the network the node is synced to
|
||||
StateNetworkName(context.Context) (dtypes.NetworkName, error)
|
||||
@@ -918,3 +918,8 @@ type MsigVesting struct {
|
||||
StartEpoch abi.ChainEpoch
|
||||
UnlockDuration abi.ChainEpoch
|
||||
}
|
||||
|
||||
type MessageMatch struct {
|
||||
To address.Address
|
||||
From address.Address
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ type FullNodeStruct struct {
|
||||
StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"`
|
||||
StateGetReceipt func(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) `perm:"read"`
|
||||
StateMinerSectorCount func(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error) `perm:"read"`
|
||||
StateListMessages func(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
|
||||
StateListMessages func(ctx context.Context, match *api.MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
|
||||
StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"`
|
||||
StateVerifierStatus func(context.Context, address.Address, types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
||||
StateVerifiedClientStatus func(context.Context, address.Address, types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
||||
@@ -943,7 +943,7 @@ func (c *FullNodeStruct) StateGetReceipt(ctx context.Context, msg cid.Cid, tsk t
|
||||
return c.Internal.StateGetReceipt(ctx, msg, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) {
|
||||
func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *api.MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) {
|
||||
return c.Internal.StateListMessages(ctx, match, tsk, toht)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
/dns4/bootstrap-0.testnet.fildev.network/tcp/1347/p2p/12D3KooWJTUBUjtzWJGWU1XSiY21CwmHaCNLNYn2E7jqHEHyZaP7
|
||||
/dns4/bootstrap-1.testnet.fildev.network/tcp/1347/p2p/12D3KooW9yeKXha4hdrJKq74zEo99T8DhriQdWNoojWnnQbsgB3v
|
||||
/dns4/bootstrap-2.testnet.fildev.network/tcp/1347/p2p/12D3KooWCrx8yVG9U9Kf7w8KLN3Edkj5ZKDhgCaeMqQbcQUoB6CT
|
||||
/dns4/bootstrap-4.testnet.fildev.network/tcp/1347/p2p/12D3KooWPkL9LrKRQgHtq7kn9ecNhGU9QaziG8R5tX8v9v7t3h34
|
||||
/dns4/bootstrap-3.testnet.fildev.network/tcp/1347/p2p/12D3KooWKYSsbpgZ3HAjax5M1BXCwXLa6gVkUARciz7uN3FNtr7T
|
||||
/dns4/bootstrap-5.testnet.fildev.network/tcp/1347/p2p/12D3KooWQYzqnLASJAabyMpPb1GcWZvNSe7JDcRuhdRqonFoiK9W
|
||||
/dns4/lotus-bootstrap.forceup.cn/tcp/41778/p2p/12D3KooWFQsv3nRMUevZNWWsY1Wu6NUzUbawnWU5NcRhgKuJA37C
|
||||
/dns4/bootstrap-0.starpool.in/tcp/12757/p2p/12D3KooWGHpBMeZbestVEWkfdnC9u7p6uFHXL1n7m1ZBqsEmiUzz
|
||||
/dns4/bootstrap-1.starpool.in/tcp/12757/p2p/12D3KooWQZrGH1PxSNZPum99M1zNvjNFM33d1AAu5DcvdHptuU7u
|
||||
/dns4/node.glif.io/tcp/1235/p2p/12D3KooWBF8cpp65hp2u9LK5mh19x67ftAam84z9LsfaquTDSBpt
|
||||
/dns4/bootstrap-0.ipfsmain.cn/tcp/34721/p2p/12D3KooWQnwEGNqcM2nAcPtRR9rAX8Hrg4k9kJLCHoTR5chJfz6d
|
||||
/dns4/bootstrap-1.ipfsmain.cn/tcp/34723/p2p/12D3KooWMKxMkD5DMpSWsW7dBddKxKT7L2GgbNuckz9otxvkvByP
|
||||
/dns4/bootstrap-0.calibration.fildev.network/tcp/1347/p2p/12D3KooWA3bLx1ntQ2nSVXZRQnL4NEtwVdadk9TUrvZQKUGu9qnh
|
||||
/dns4/bootstrap-1.calibration.fildev.network/tcp/1347/p2p/12D3KooWR51XjrKbGFz9y1c8hKw3oguqGvQJNvxPDcPC9UXhkP6K
|
||||
/dns4/bootstrap-2.calibration.fildev.network/tcp/1347/p2p/12D3KooWKKb2C1khuxBBbk21dXe8hdEZ1FETqgB3TEVRNm5ZZxWT
|
||||
/dns4/bootstrap-3.calibration.fildev.network/tcp/1347/p2p/12D3KooWDCQH94idHfDBeoVGCkQVQL7DZp98ZvuRd33F76wJAgfd
|
||||
|
||||
Binary file not shown.
@@ -22,6 +22,8 @@ const UpgradeTapeHeight = -4
|
||||
var UpgradeActorsV2Height = abi.ChainEpoch(10)
|
||||
var UpgradeLiftoffHeight = abi.ChainEpoch(-5)
|
||||
|
||||
const UpgradeKumquatHeight = -6
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
+15
-21
@@ -5,9 +5,6 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"math"
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
@@ -16,43 +13,40 @@ import (
|
||||
)
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandIncentinet,
|
||||
UpgradeSmokeHeight: DrandMainnet,
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
const UpgradeBreezeHeight = 41280
|
||||
const UpgradeBreezeHeight = -1
|
||||
const BreezeGasTampingDuration = 120
|
||||
|
||||
const UpgradeSmokeHeight = 51000
|
||||
const UpgradeSmokeHeight = -2
|
||||
|
||||
const UpgradeIgnitionHeight = 94000
|
||||
const UpgradeRefuelHeight = 130800
|
||||
const UpgradeIgnitionHeight = -3
|
||||
const UpgradeRefuelHeight = -4
|
||||
|
||||
var UpgradeActorsV2Height = abi.ChainEpoch(138720)
|
||||
const UpgradeActorsV2Height = 30
|
||||
|
||||
const UpgradeTapeHeight = 140760
|
||||
const UpgradeTapeHeight = 45
|
||||
|
||||
// This signals our tentative epoch for mainnet launch. Can make it later, but not earlier.
|
||||
// Miners, clients, developers, custodians all need time to prepare.
|
||||
// We still have upgrades and state changes to do, but can happen after signaling timing here.
|
||||
const UpgradeLiftoffHeight = 148888
|
||||
const UpgradeLiftoffHeight = 22400
|
||||
|
||||
// TODO: Confirm epoch
|
||||
const UpgradeKumquatHeight = 22450
|
||||
|
||||
func init() {
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40))
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 30))
|
||||
policy.SetSupportedProofTypes(
|
||||
abi.RegisteredSealProof_StackedDrg512MiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1,
|
||||
)
|
||||
|
||||
if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" {
|
||||
SetAddressNetwork(address.Mainnet)
|
||||
}
|
||||
SetAddressNetwork(address.Testnet)
|
||||
|
||||
if os.Getenv("LOTUS_DISABLE_V2_ACTOR_MIGRATION") == "1" {
|
||||
UpgradeActorsV2Height = math.MaxInt64
|
||||
}
|
||||
|
||||
Devnet = false
|
||||
Devnet = true
|
||||
}
|
||||
|
||||
const BlockDelaySecs = uint64(builtin0.EpochDurationSeconds)
|
||||
|
||||
@@ -25,7 +25,7 @@ const UnixfsLinksPerLevel = 1024
|
||||
// Consensus / Network
|
||||
|
||||
const AllowableClockDriftSecs = uint64(1)
|
||||
const NewestNetworkVersion = network.Version5
|
||||
const NewestNetworkVersion = network.Version6
|
||||
const ActorUpgradeNetworkVersion = network.Version4
|
||||
|
||||
// Epochs
|
||||
|
||||
@@ -86,6 +86,7 @@ var (
|
||||
UpgradeTapeHeight abi.ChainEpoch = -4
|
||||
UpgradeActorsV2Height abi.ChainEpoch = 10
|
||||
UpgradeLiftoffHeight abi.ChainEpoch = -5
|
||||
UpgradeKumquatHeight abi.ChainEpoch = -6
|
||||
|
||||
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ func buildType() string {
|
||||
}
|
||||
|
||||
// BuildVersion is the local build version, set by build system
|
||||
const BuildVersion = "0.10.2"
|
||||
const BuildVersion = "1.0.0"
|
||||
|
||||
func UserVersion() string {
|
||||
return BuildVersion + buildType() + CurrentCommit
|
||||
|
||||
@@ -18,7 +18,7 @@ func VersionForNetwork(version network.Version) Version {
|
||||
switch version {
|
||||
case network.Version0, network.Version1, network.Version2, network.Version3:
|
||||
return Version0
|
||||
case network.Version4, network.Version5:
|
||||
case network.Version4, network.Version5, network.Version6:
|
||||
return Version2
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported network version %d", version))
|
||||
|
||||
@@ -405,7 +405,7 @@ func circSupply(ctx context.Context, vmi *vm.VM, maddr address.Address) abi.Toke
|
||||
rt := unsafeVM.MakeRuntime(ctx, &types.Message{
|
||||
GasLimit: 1_000_000_000,
|
||||
From: maddr,
|
||||
}, maddr, 0, 0, 0)
|
||||
})
|
||||
|
||||
return rt.TotalFilCircSupply()
|
||||
}
|
||||
|
||||
+46
-21
@@ -26,16 +26,18 @@ var log = logging.Logger("statetree")
|
||||
|
||||
// StateTree stores actors state by their ID.
|
||||
type StateTree struct {
|
||||
root adt.Map
|
||||
version types.StateTreeVersion
|
||||
info cid.Cid
|
||||
Store cbor.IpldStore
|
||||
root adt.Map
|
||||
version types.StateTreeVersion
|
||||
info cid.Cid
|
||||
Store cbor.IpldStore
|
||||
lookupIDFun func(address.Address) (address.Address, error)
|
||||
|
||||
snaps *stateSnaps
|
||||
}
|
||||
|
||||
type stateSnaps struct {
|
||||
layers []*stateSnapLayer
|
||||
layers []*stateSnapLayer
|
||||
lastMaybeNonEmptyResolveCache int
|
||||
}
|
||||
|
||||
type stateSnapLayer struct {
|
||||
@@ -67,7 +69,12 @@ func (ss *stateSnaps) addLayer() {
|
||||
|
||||
func (ss *stateSnaps) dropLayer() {
|
||||
ss.layers[len(ss.layers)-1] = nil // allow it to be GCed
|
||||
|
||||
ss.layers = ss.layers[:len(ss.layers)-1]
|
||||
|
||||
if ss.lastMaybeNonEmptyResolveCache == len(ss.layers) {
|
||||
ss.lastMaybeNonEmptyResolveCache = len(ss.layers) - 1
|
||||
}
|
||||
}
|
||||
|
||||
func (ss *stateSnaps) mergeLastLayer() {
|
||||
@@ -86,7 +93,13 @@ func (ss *stateSnaps) mergeLastLayer() {
|
||||
}
|
||||
|
||||
func (ss *stateSnaps) resolveAddress(addr address.Address) (address.Address, bool) {
|
||||
for i := len(ss.layers) - 1; i >= 0; i-- {
|
||||
for i := ss.lastMaybeNonEmptyResolveCache; i >= 0; i-- {
|
||||
if len(ss.layers[i].resolveCache) == 0 {
|
||||
if ss.lastMaybeNonEmptyResolveCache == i {
|
||||
ss.lastMaybeNonEmptyResolveCache = i - 1
|
||||
}
|
||||
continue
|
||||
}
|
||||
resa, ok := ss.layers[i].resolveCache[addr]
|
||||
if ok {
|
||||
return resa, true
|
||||
@@ -97,6 +110,7 @@ func (ss *stateSnaps) resolveAddress(addr address.Address) (address.Address, boo
|
||||
|
||||
func (ss *stateSnaps) cacheResolveAddress(addr, resa address.Address) {
|
||||
ss.layers[len(ss.layers)-1].resolveCache[addr] = resa
|
||||
ss.lastMaybeNonEmptyResolveCache = len(ss.layers) - 1
|
||||
}
|
||||
|
||||
func (ss *stateSnaps) getActor(addr address.Address) (*types.Actor, error) {
|
||||
@@ -160,13 +174,15 @@ func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, e
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &StateTree{
|
||||
s := &StateTree{
|
||||
root: root,
|
||||
info: info,
|
||||
version: ver,
|
||||
Store: cst,
|
||||
snaps: newStateSnaps(),
|
||||
}, nil
|
||||
}
|
||||
s.lookupIDFun = s.lookupIDinternal
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) {
|
||||
@@ -190,13 +206,15 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &StateTree{
|
||||
s := &StateTree{
|
||||
root: nd,
|
||||
info: root.Info,
|
||||
version: root.Version,
|
||||
Store: cst,
|
||||
snaps: newStateSnaps(),
|
||||
}, nil
|
||||
}
|
||||
s.lookupIDFun = s.lookupIDinternal
|
||||
return s, nil
|
||||
default:
|
||||
return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version)
|
||||
}
|
||||
@@ -213,17 +231,7 @@ func (st *StateTree) SetActor(addr address.Address, act *types.Actor) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// LookupID gets the ID address of this actor's `addr` stored in the `InitActor`.
|
||||
func (st *StateTree) LookupID(addr address.Address) (address.Address, error) {
|
||||
if addr.Protocol() == address.ID {
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
resa, ok := st.snaps.resolveAddress(addr)
|
||||
if ok {
|
||||
return resa, nil
|
||||
}
|
||||
|
||||
func (st *StateTree) lookupIDinternal(addr address.Address) (address.Address, error) {
|
||||
act, err := st.GetActor(init_.Address)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("getting init actor: %w", err)
|
||||
@@ -241,6 +249,23 @@ func (st *StateTree) LookupID(addr address.Address) (address.Address, error) {
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("resolve address %s: %w", addr, err)
|
||||
}
|
||||
return a, err
|
||||
}
|
||||
|
||||
// LookupID gets the ID address of this actor's `addr` stored in the `InitActor`.
|
||||
func (st *StateTree) LookupID(addr address.Address) (address.Address, error) {
|
||||
if addr.Protocol() == address.ID {
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
resa, ok := st.snaps.resolveAddress(addr)
|
||||
if ok {
|
||||
return resa, nil
|
||||
}
|
||||
a, err := st.lookupIDFun(addr)
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
|
||||
st.snaps.cacheResolveAddress(addr, a)
|
||||
|
||||
|
||||
@@ -73,6 +73,103 @@ func BenchmarkStateTreeSetFlush(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveCache(t *testing.T) {
|
||||
cst := cbor.NewMemCborStore()
|
||||
st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
nonId := address.NewForTestGetter()()
|
||||
id, _ := address.NewIDAddress(1000)
|
||||
|
||||
st.lookupIDFun = func(a address.Address) (address.Address, error) {
|
||||
if a == nonId {
|
||||
return id, nil
|
||||
}
|
||||
return address.Undef, types.ErrActorNotFound
|
||||
}
|
||||
|
||||
err = st.SetActor(nonId, &types.Actor{Nonce: 1})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
{
|
||||
err = st.Snapshot(context.TODO())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
act, err := st.GetActor(nonId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if act.Nonce != 1 {
|
||||
t.Fatalf("expected nonce 1, got %d", act.Nonce)
|
||||
}
|
||||
err = st.SetActor(nonId, &types.Actor{Nonce: 2})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
act, err = st.GetActor(nonId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if act.Nonce != 2 {
|
||||
t.Fatalf("expected nonce 2, got %d", act.Nonce)
|
||||
}
|
||||
|
||||
if err := st.Revert(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
st.ClearSnapshot()
|
||||
}
|
||||
|
||||
act, err := st.GetActor(nonId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if act.Nonce != 1 {
|
||||
t.Fatalf("expected nonce 1, got %d", act.Nonce)
|
||||
}
|
||||
|
||||
{
|
||||
err = st.Snapshot(context.TODO())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
act, err := st.GetActor(nonId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if act.Nonce != 1 {
|
||||
t.Fatalf("expected nonce 1, got %d", act.Nonce)
|
||||
}
|
||||
err = st.SetActor(nonId, &types.Actor{Nonce: 2})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
act, err = st.GetActor(nonId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if act.Nonce != 2 {
|
||||
t.Fatalf("expected nonce 2, got %d", act.Nonce)
|
||||
}
|
||||
st.ClearSnapshot()
|
||||
}
|
||||
|
||||
act, err = st.GetActor(nonId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if act.Nonce != 2 {
|
||||
t.Fatalf("expected nonce 2, got %d", act.Nonce)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkStateTree10kGetActor(b *testing.B) {
|
||||
cst := cbor.NewMemCborStore()
|
||||
st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion))
|
||||
|
||||
@@ -86,6 +86,10 @@ func DefaultUpgradeSchedule() UpgradeSchedule {
|
||||
Height: build.UpgradeLiftoffHeight,
|
||||
Network: network.Version5,
|
||||
Migration: UpgradeLiftoff,
|
||||
}, {
|
||||
Height: build.UpgradeKumquatHeight,
|
||||
Network: network.Version6,
|
||||
Migration: nil,
|
||||
}}
|
||||
|
||||
if build.UpgradeActorsV2Height == math.MaxInt64 { // disable actors upgrade
|
||||
|
||||
@@ -72,6 +72,7 @@ type Runtime struct {
|
||||
originNonce uint64
|
||||
|
||||
executionTrace types.ExecutionTrace
|
||||
depth uint64
|
||||
numActorsCreated uint64
|
||||
allowInternal bool
|
||||
callerValidated bool
|
||||
|
||||
+23
-19
@@ -38,6 +38,8 @@ import (
|
||||
"github.com/filecoin-project/lotus/lib/bufbstore"
|
||||
)
|
||||
|
||||
const MaxCallDepth = 4096
|
||||
|
||||
var log = logging.Logger("vm")
|
||||
var actorLog = logging.Logger("actors")
|
||||
var gasOnActorExec = newGasCharge("OnActorExec", 0, 0)
|
||||
@@ -97,24 +99,37 @@ func (bs *gasChargingBlocks) Put(blk block.Block) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin address.Address, originNonce uint64, usedGas int64, nac uint64) *Runtime {
|
||||
func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runtime) *Runtime {
|
||||
rt := &Runtime{
|
||||
ctx: ctx,
|
||||
vm: vm,
|
||||
state: vm.cstate,
|
||||
origin: origin,
|
||||
originNonce: originNonce,
|
||||
origin: msg.From,
|
||||
originNonce: msg.Nonce,
|
||||
height: vm.blockHeight,
|
||||
|
||||
gasUsed: usedGas,
|
||||
gasUsed: 0,
|
||||
gasAvailable: msg.GasLimit,
|
||||
numActorsCreated: nac,
|
||||
depth: 0,
|
||||
numActorsCreated: 0,
|
||||
pricelist: PricelistByEpoch(vm.blockHeight),
|
||||
allowInternal: true,
|
||||
callerValidated: false,
|
||||
executionTrace: types.ExecutionTrace{Msg: msg},
|
||||
}
|
||||
|
||||
if parent != nil {
|
||||
rt.gasUsed = parent.gasUsed
|
||||
rt.origin = parent.origin
|
||||
rt.originNonce = parent.originNonce
|
||||
rt.numActorsCreated = parent.numActorsCreated
|
||||
rt.depth = parent.depth + 1
|
||||
}
|
||||
|
||||
if rt.depth > MaxCallDepth && rt.NetworkVersion() >= network.Version6 {
|
||||
rt.Abortf(exitcode.SysErrForbidden, "message execution exceeds call depth")
|
||||
}
|
||||
|
||||
rt.cst = &cbor.BasicIpldStore{
|
||||
Blocks: &gasChargingBlocks{rt.chargeGasFunc(2), rt.pricelist, vm.cst.Blocks},
|
||||
Atlas: vm.cst.Atlas,
|
||||
@@ -148,8 +163,8 @@ type UnsafeVM struct {
|
||||
VM *VM
|
||||
}
|
||||
|
||||
func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message, origin address.Address, originNonce uint64, usedGas int64, nac uint64) *Runtime {
|
||||
return vm.VM.makeRuntime(ctx, msg, origin, originNonce, usedGas, nac)
|
||||
func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message) *Runtime {
|
||||
return vm.VM.makeRuntime(ctx, msg, nil)
|
||||
}
|
||||
|
||||
type CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error)
|
||||
@@ -224,18 +239,7 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
|
||||
|
||||
st := vm.cstate
|
||||
|
||||
origin := msg.From
|
||||
on := msg.Nonce
|
||||
var nac uint64 = 0
|
||||
var gasUsed int64
|
||||
if parent != nil {
|
||||
gasUsed = parent.gasUsed
|
||||
origin = parent.origin
|
||||
on = parent.originNonce
|
||||
nac = parent.numActorsCreated
|
||||
}
|
||||
|
||||
rt := vm.makeRuntime(ctx, msg, origin, on, gasUsed, nac)
|
||||
rt := vm.makeRuntime(ctx, msg, parent)
|
||||
if EnableGasTracing {
|
||||
rt.lastGasChargeTime = start
|
||||
if parent != nil {
|
||||
|
||||
+44
-11
@@ -813,33 +813,66 @@ var stateListMessagesCmd = &cli.Command{
|
||||
froma = a
|
||||
}
|
||||
|
||||
toh := cctx.Uint64("toheight")
|
||||
toh := abi.ChainEpoch(cctx.Uint64("toheight"))
|
||||
|
||||
ts, err := LoadTipSet(ctx, cctx, api)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgs, err := api.StateListMessages(ctx, &types.Message{To: toa, From: froma}, ts.Key(), abi.ChainEpoch(toh))
|
||||
if err != nil {
|
||||
return err
|
||||
if ts == nil {
|
||||
head, err := api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ts = head
|
||||
}
|
||||
|
||||
for _, c := range msgs {
|
||||
if cctx.Bool("cids") {
|
||||
fmt.Println(c.String())
|
||||
continue
|
||||
windowSize := abi.ChainEpoch(100)
|
||||
|
||||
cur := ts
|
||||
for cur.Height() > toh {
|
||||
if ctx.Err() != nil {
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
m, err := api.ChainGetMessage(ctx, c)
|
||||
end := toh
|
||||
if cur.Height()-windowSize > end {
|
||||
end = cur.Height() - windowSize
|
||||
}
|
||||
|
||||
msgs, err := api.StateListMessages(ctx, &lapi.MessageMatch{To: toa, From: froma}, cur.Key(), end)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b, err := json.MarshalIndent(m, "", " ")
|
||||
|
||||
for _, c := range msgs {
|
||||
if cctx.Bool("cids") {
|
||||
fmt.Println(c.String())
|
||||
continue
|
||||
}
|
||||
|
||||
m, err := api.ChainGetMessage(ctx, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b, err := json.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(string(b))
|
||||
}
|
||||
|
||||
if end <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
next, err := api.ChainGetTipSetByHeight(ctx, end-1, cur.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(string(b))
|
||||
|
||||
cur = next
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -6,10 +6,13 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||
@@ -19,7 +22,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
LookbackCap = time.Hour
|
||||
LookbackCap = time.Hour * 12
|
||||
stateWaitLookbackLimit = abi.ChainEpoch(20)
|
||||
)
|
||||
|
||||
@@ -35,6 +38,7 @@ type gatewayDepsAPI interface {
|
||||
ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
|
||||
ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error)
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error)
|
||||
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
||||
MpoolPushUntrusted(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
||||
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
||||
@@ -44,6 +48,15 @@ type gatewayDepsAPI interface {
|
||||
StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||
StateWaitMsgLimited(ctx context.Context, msg cid.Cid, confidence uint64, h abi.ChainEpoch) (*api.MsgLookup, error)
|
||||
StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error)
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error)
|
||||
StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error)
|
||||
StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error)
|
||||
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error)
|
||||
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]api.Deadline, error)
|
||||
StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error)
|
||||
StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, error)
|
||||
StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (api.CirculatingSupply, error)
|
||||
}
|
||||
|
||||
type GatewayAPI struct {
|
||||
@@ -116,9 +129,19 @@ func (a *GatewayAPI) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
ts, err := a.api.ChainGetTipSet(ctx, tsk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var ts *types.TipSet
|
||||
if tsk.IsEmpty() {
|
||||
head, err := a.api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ts = head
|
||||
} else {
|
||||
gts, err := a.api.ChainGetTipSet(ctx, tsk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ts = gts
|
||||
}
|
||||
|
||||
// Check if the tipset key refers to a tipset that's too far in the past
|
||||
@@ -138,6 +161,10 @@ func (a *GatewayAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error
|
||||
return a.api.ChainReadObj(ctx, c)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error) {
|
||||
return a.api.ChainGetNode(ctx, p)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) {
|
||||
if err := a.checkTipsetKey(ctx, tsk); err != nil {
|
||||
return nil, err
|
||||
@@ -198,10 +225,6 @@ func (a *GatewayAPI) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence u
|
||||
return a.api.StateWaitMsgLimited(ctx, msg, confidence, stateWaitLookbackLimit)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) (bool, error) {
|
||||
return sigs.Verify(sig, k, msg) == nil, nil
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) {
|
||||
if err := a.checkTipsetKey(ctx, tsk); err != nil {
|
||||
return nil, err
|
||||
@@ -209,6 +232,73 @@ func (a *GatewayAPI) StateReadState(ctx context.Context, actor address.Address,
|
||||
return a.api.StateReadState(ctx, actor, tsk)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateMinerPower(ctx context.Context, m address.Address, tsk types.TipSetKey) (*api.MinerPower, error) {
|
||||
if err := a.checkTipsetKey(ctx, tsk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a.api.StateMinerPower(ctx, m, tsk)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateMinerFaults(ctx context.Context, m address.Address, tsk types.TipSetKey) (bitfield.BitField, error) {
|
||||
if err := a.checkTipsetKey(ctx, tsk); err != nil {
|
||||
return bitfield.BitField{}, err
|
||||
}
|
||||
return a.api.StateMinerFaults(ctx, m, tsk)
|
||||
}
|
||||
func (a *GatewayAPI) StateMinerRecoveries(ctx context.Context, m address.Address, tsk types.TipSetKey) (bitfield.BitField, error) {
|
||||
if err := a.checkTipsetKey(ctx, tsk); err != nil {
|
||||
return bitfield.BitField{}, err
|
||||
}
|
||||
return a.api.StateMinerRecoveries(ctx, m, tsk)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateMinerInfo(ctx context.Context, m address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) {
|
||||
if err := a.checkTipsetKey(ctx, tsk); err != nil {
|
||||
return miner.MinerInfo{}, err
|
||||
}
|
||||
return a.api.StateMinerInfo(ctx, m, tsk)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateMinerDeadlines(ctx context.Context, m address.Address, tsk types.TipSetKey) ([]api.Deadline, error) {
|
||||
if err := a.checkTipsetKey(ctx, tsk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a.api.StateMinerDeadlines(ctx, m, tsk)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateMinerAvailableBalance(ctx context.Context, m address.Address, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
if err := a.checkTipsetKey(ctx, tsk); err != nil {
|
||||
return types.BigInt{}, err
|
||||
}
|
||||
return a.api.StateMinerAvailableBalance(ctx, m, tsk)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateMinerProvingDeadline(ctx context.Context, m address.Address, tsk types.TipSetKey) (*dline.Info, error) {
|
||||
if err := a.checkTipsetKey(ctx, tsk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a.api.StateMinerProvingDeadline(ctx, m, tsk)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) {
|
||||
if err := a.checkTipsetKey(ctx, tsk); err != nil {
|
||||
return types.BigInt{}, err
|
||||
}
|
||||
return a.api.StateCirculatingSupply(ctx, tsk)
|
||||
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateVMCirculatingSupplyInternal(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) {
|
||||
if err := a.checkTipsetKey(ctx, tsk); err != nil {
|
||||
return api.CirculatingSupply{}, err
|
||||
}
|
||||
return a.api.StateVMCirculatingSupplyInternal(ctx, tsk)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) (bool, error) {
|
||||
return sigs.Verify(sig, k, msg) == nil, nil
|
||||
}
|
||||
|
||||
var _ api.GatewayAPI = (*GatewayAPI)(nil)
|
||||
var _ full.ChainModuleAPI = (*GatewayAPI)(nil)
|
||||
var _ full.GasModuleAPI = (*GatewayAPI)(nil)
|
||||
|
||||
@@ -107,6 +107,9 @@ func TestGatewayAPIChainGetTipSetByHeight(t *testing.T) {
|
||||
type mockGatewayDepsAPI struct {
|
||||
lk sync.RWMutex
|
||||
tipsets []*types.TipSet
|
||||
|
||||
gatewayDepsAPI // satisfies all interface requirements but will panic if
|
||||
// methods are called. easier than filling out with panic stubs IMO
|
||||
}
|
||||
|
||||
func (m *mockGatewayDepsAPI) ChainHasObj(context.Context, cid.Cid) (bool, error) {
|
||||
|
||||
@@ -5,6 +5,10 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/gen/genesis"
|
||||
|
||||
_init "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
|
||||
"github.com/docker/go-units"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
|
||||
@@ -136,6 +140,9 @@ var chainBalanceStateCmd = &cli.Command{
|
||||
&cli.BoolFlag{
|
||||
Name: "miner-info",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "robust-addresses",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
ctx := context.TODO()
|
||||
@@ -187,6 +194,33 @@ var chainBalanceStateCmd = &cli.Command{
|
||||
|
||||
minerInfo := cctx.Bool("miner-info")
|
||||
|
||||
robustMap := make(map[address.Address]address.Address)
|
||||
if cctx.Bool("robust-addresses") {
|
||||
iact, err := tree.GetActor(_init.Address)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to load init actor: %w", err)
|
||||
}
|
||||
|
||||
ist, err := _init.Load(store, iact)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to load init actor state: %w", err)
|
||||
}
|
||||
|
||||
err = ist.ForEachActor(func(id abi.ActorID, addr address.Address) error {
|
||||
idAddr, err := address.NewIDAddress(uint64(id))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to write to addr map: %w", err)
|
||||
}
|
||||
|
||||
robustMap[idAddr] = addr
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to invert init address map: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
var infos []accountInfo
|
||||
err = tree.ForEach(func(addr address.Address, act *types.Actor) error {
|
||||
|
||||
@@ -201,6 +235,23 @@ var chainBalanceStateCmd = &cli.Command{
|
||||
VestingAmount: types.FIL(big.NewInt(0)),
|
||||
}
|
||||
|
||||
if cctx.Bool("robust-addresses") {
|
||||
robust, found := robustMap[addr]
|
||||
if found {
|
||||
ai.Address = robust
|
||||
} else {
|
||||
id, err := address.IDFromAddress(addr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get ID address: %w", err)
|
||||
}
|
||||
|
||||
// TODO: This is not the correctest way to determine whether a robust address should exist
|
||||
if id >= genesis.MinerStart {
|
||||
return xerrors.Errorf("address doesn't have a robust address: %s", addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if minerInfo && builtin.IsStorageMinerActor(act.Code) {
|
||||
pow, _, _, err := stmgr.GetPowerRaw(ctx, sm, sroot, addr)
|
||||
if err != nil {
|
||||
|
||||
@@ -23,6 +23,7 @@ var ProtocolCodenames = []struct {
|
||||
{build.UpgradeActorsV2Height + 1, "actorsv2"},
|
||||
{build.UpgradeTapeHeight + 1, "tape"},
|
||||
{build.UpgradeLiftoffHeight + 1, "liftoff"},
|
||||
{build.UpgradeKumquatHeight + 1, "postliftoff"},
|
||||
}
|
||||
|
||||
// GetProtocolCodename gets the protocol codename associated with a height.
|
||||
|
||||
+186
-197
File diff suppressed because it is too large
Load Diff
@@ -34,12 +34,12 @@ 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-20201003010437-c33112184a2b
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20201013222834-41ea465f274f
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe
|
||||
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.12
|
||||
github.com/filecoin-project/specs-actors/v2 v2.1.0
|
||||
github.com/filecoin-project/specs-actors/v2 v2.2.0
|
||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796
|
||||
github.com/filecoin-project/test-vectors/schema v0.0.5
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
||||
|
||||
@@ -266,8 +266,8 @@ github.com/filecoin-project/go-state-types v0.0.0-20200903145444-247639ffa6ad/go
|
||||
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-20200928172055-2df22083d8ab h1:cEDC5Ei8UuT99hPWhCjA72SM9AuRtnpvdSTIYbnzN8I=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20201003010437-c33112184a2b h1:bMUfG6Sy6YSMbsjQAO1Q2vEZldbSdsbRy/FX3OlTck0=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20201003010437-c33112184a2b/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20201013222834-41ea465f274f h1:TZDTu4MtBKSFLXWGKLy+cvC3nHfMFIrVgWLAz/+GgZQ=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20201013222834-41ea465f274f/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw=
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
||||
github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ=
|
||||
@@ -278,8 +278,8 @@ github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07
|
||||
github.com/filecoin-project/specs-actors v0.9.12 h1:iIvk58tuMtmloFNHhAOQHG+4Gci6Lui0n7DYQGi3cJk=
|
||||
github.com/filecoin-project/specs-actors v0.9.12/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao=
|
||||
github.com/filecoin-project/specs-actors/v2 v2.0.1/go.mod h1:v2NZVYinNIKA9acEMBm5wWXxqv5+frFEbekBFemYghY=
|
||||
github.com/filecoin-project/specs-actors/v2 v2.1.0 h1:ocEuGz8DG2cUWw32c/tvF8D6xT+dGVWJTr5yDevU00g=
|
||||
github.com/filecoin-project/specs-actors/v2 v2.1.0/go.mod h1:E7fAX4CZkDVQvDNRCxfq+hc3nx56KcCKyuZf0hlQJ20=
|
||||
github.com/filecoin-project/specs-actors/v2 v2.2.0 h1:IyCICb0NHYeD0sdSqjVGwWydn/7r7xXuxdpvGAcRCGY=
|
||||
github.com/filecoin-project/specs-actors/v2 v2.2.0/go.mod h1:rlv5Mx9wUhV8Qsz+vUezZNm+zL4tK08O0HreKKPB2Wc=
|
||||
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/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg=
|
||||
|
||||
+41
-19
@@ -6,35 +6,57 @@ import (
|
||||
"encoding/json"
|
||||
"os/exec"
|
||||
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
func CliDealFilter(cmd string) dtypes.DealFilter {
|
||||
// TODO: run some checks on the cmd string
|
||||
|
||||
func CliStorageDealFilter(cmd string) dtypes.StorageDealFilter {
|
||||
return func(ctx context.Context, deal storagemarket.MinerDeal) (bool, string, error) {
|
||||
j, err := json.MarshalIndent(deal, "", " ")
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
d := struct {
|
||||
storagemarket.MinerDeal
|
||||
DealType string
|
||||
}{
|
||||
MinerDeal: deal,
|
||||
DealType: "storage",
|
||||
}
|
||||
return runDealFilter(ctx, cmd, d)
|
||||
}
|
||||
}
|
||||
|
||||
var out bytes.Buffer
|
||||
func CliRetrievalDealFilter(cmd string) dtypes.RetrievalDealFilter {
|
||||
return func(ctx context.Context, deal retrievalmarket.ProviderDealState) (bool, string, error) {
|
||||
d := struct {
|
||||
retrievalmarket.ProviderDealState
|
||||
DealType string
|
||||
}{
|
||||
ProviderDealState: deal,
|
||||
DealType: "retrieval",
|
||||
}
|
||||
return runDealFilter(ctx, cmd, d)
|
||||
}
|
||||
}
|
||||
|
||||
func runDealFilter(ctx context.Context, cmd string, deal interface{}) (bool, string, error) {
|
||||
j, err := json.MarshalIndent(deal, "", " ")
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
|
||||
c := exec.Command("sh", "-c", cmd)
|
||||
c.Stdin = bytes.NewReader(j)
|
||||
c.Stdout = &out
|
||||
c.Stderr = &out
|
||||
var out bytes.Buffer
|
||||
|
||||
switch err := c.Run().(type) {
|
||||
case nil:
|
||||
return true, "", nil
|
||||
case *exec.ExitError:
|
||||
return false, out.String(), nil
|
||||
default:
|
||||
return false, "filter cmd run error", err
|
||||
}
|
||||
c := exec.Command("sh", "-c", cmd)
|
||||
c.Stdin = bytes.NewReader(j)
|
||||
c.Stdout = &out
|
||||
c.Stderr = &out
|
||||
|
||||
switch err := c.Run().(type) {
|
||||
case nil:
|
||||
return true, "", nil
|
||||
case *exec.ExitError:
|
||||
return false, out.String(), nil
|
||||
default:
|
||||
return false, "filter cmd run error", err
|
||||
}
|
||||
}
|
||||
|
||||
+7
-2
@@ -354,7 +354,8 @@ func Online() Option {
|
||||
Override(new(dtypes.ProviderDataTransfer), modules.NewProviderDAGServiceDataTransfer),
|
||||
Override(new(dtypes.ProviderPieceStore), modules.NewProviderPieceStore),
|
||||
Override(new(*storedask.StoredAsk), modules.NewStorageAsk),
|
||||
Override(new(dtypes.DealFilter), modules.BasicDealFilter(nil)),
|
||||
Override(new(dtypes.StorageDealFilter), modules.BasicDealFilter(nil)),
|
||||
Override(new(dtypes.RetrievalDealFilter), modules.RetrievalDealFilter(nil)),
|
||||
Override(new(modules.ProviderDealFunds), modules.NewProviderDealFunds),
|
||||
Override(new(storagemarket.StorageProvider), modules.StorageProvider),
|
||||
Override(new(storagemarket.StorageProviderNode), storageadapter.NewProviderNodeAdapter(nil)),
|
||||
@@ -484,7 +485,11 @@ func ConfigStorageMiner(c interface{}) Option {
|
||||
ConfigCommon(&cfg.Common),
|
||||
|
||||
If(cfg.Dealmaking.Filter != "",
|
||||
Override(new(dtypes.DealFilter), modules.BasicDealFilter(dealfilter.CliDealFilter(cfg.Dealmaking.Filter))),
|
||||
Override(new(dtypes.StorageDealFilter), modules.BasicDealFilter(dealfilter.CliStorageDealFilter(cfg.Dealmaking.Filter))),
|
||||
),
|
||||
|
||||
If(cfg.Dealmaking.RetrievalFilter != "",
|
||||
Override(new(dtypes.RetrievalDealFilter), modules.RetrievalDealFilter(dealfilter.CliRetrievalDealFilter(cfg.Dealmaking.RetrievalFilter))),
|
||||
),
|
||||
|
||||
Override(new(storagemarket.StorageProviderNode), storageadapter.NewProviderNodeAdapter(&cfg.Fees)),
|
||||
|
||||
+2
-1
@@ -45,7 +45,8 @@ type DealmakingConfig struct {
|
||||
PieceCidBlocklist []cid.Cid
|
||||
ExpectedSealDuration Duration
|
||||
|
||||
Filter string
|
||||
Filter string
|
||||
RetrievalFilter string
|
||||
}
|
||||
|
||||
type SealingConfig struct {
|
||||
|
||||
@@ -349,6 +349,7 @@ func (a *StateAPI) StateCall(ctx context.Context, msg *types.Message, tsk types.
|
||||
func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid.Cid) (*api.InvocResult, error) {
|
||||
msgToReplay := mc
|
||||
var ts *types.TipSet
|
||||
var err error
|
||||
if tsk == types.EmptyTSK {
|
||||
mlkp, err := a.StateSearchMsg(ctx, mc)
|
||||
if err != nil {
|
||||
@@ -370,7 +371,10 @@ func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid.
|
||||
return nil, xerrors.Errorf("loading parent tipset %s: %w", mlkp.TipSet, err)
|
||||
}
|
||||
} else {
|
||||
ts = a.Chain.GetHeaviestTipSet()
|
||||
ts, err = a.Chain.LoadTipSet(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading specified tipset %s: %w", tsk, err)
|
||||
}
|
||||
}
|
||||
|
||||
m, r, err := a.StateManager.Replay(ctx, ts, msgToReplay)
|
||||
@@ -783,7 +787,7 @@ func (a *StateAPI) StateSectorPartition(ctx context.Context, maddr address.Addre
|
||||
return mas.FindSector(sectorNumber)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toheight abi.ChainEpoch) ([]cid.Cid, error) {
|
||||
func (a *StateAPI) StateListMessages(ctx context.Context, match *api.MessageMatch, tsk types.TipSetKey, toheight abi.ChainEpoch) ([]cid.Cid, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
@@ -71,4 +72,5 @@ type SetExpectedSealDurationFunc func(time.Duration) error
|
||||
// too determine how long sealing is expected to take
|
||||
type GetExpectedSealDurationFunc func() (time.Duration, error)
|
||||
|
||||
type DealFilter func(ctx context.Context, deal storagemarket.MinerDeal) (bool, string, error)
|
||||
type StorageDealFilter func(ctx context.Context, deal storagemarket.MinerDeal) (bool, string, error)
|
||||
type RetrievalDealFilter func(ctx context.Context, deal retrievalmarket.ProviderDealState) (bool, string, error)
|
||||
|
||||
@@ -398,8 +398,6 @@ func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.Metadat
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a := storedAsk.GetAsk().Ask
|
||||
err = storedAsk.SetAsk(a.Price, a.VerifiedPrice, a.Expiry-a.Timestamp)
|
||||
if err != nil {
|
||||
return storedAsk, err
|
||||
}
|
||||
@@ -412,16 +410,16 @@ func NewProviderDealFunds(ds dtypes.MetadataDS) (ProviderDealFunds, error) {
|
||||
return funds.NewDealFunds(ds, datastore.NewKey("/marketfunds/provider"))
|
||||
}
|
||||
|
||||
func BasicDealFilter(user dtypes.DealFilter) func(onlineOk dtypes.ConsiderOnlineStorageDealsConfigFunc,
|
||||
func BasicDealFilter(user dtypes.StorageDealFilter) func(onlineOk dtypes.ConsiderOnlineStorageDealsConfigFunc,
|
||||
offlineOk dtypes.ConsiderOfflineStorageDealsConfigFunc,
|
||||
blocklistFunc dtypes.StorageDealPieceCidBlocklistConfigFunc,
|
||||
expectedSealTimeFunc dtypes.GetExpectedSealDurationFunc,
|
||||
spn storagemarket.StorageProviderNode) dtypes.DealFilter {
|
||||
spn storagemarket.StorageProviderNode) dtypes.StorageDealFilter {
|
||||
return func(onlineOk dtypes.ConsiderOnlineStorageDealsConfigFunc,
|
||||
offlineOk dtypes.ConsiderOfflineStorageDealsConfigFunc,
|
||||
blocklistFunc dtypes.StorageDealPieceCidBlocklistConfigFunc,
|
||||
expectedSealTimeFunc dtypes.GetExpectedSealDurationFunc,
|
||||
spn storagemarket.StorageProviderNode) dtypes.DealFilter {
|
||||
spn storagemarket.StorageProviderNode) dtypes.StorageDealFilter {
|
||||
|
||||
return func(ctx context.Context, deal storagemarket.MinerDeal) (bool, string, error) {
|
||||
b, err := onlineOk()
|
||||
@@ -497,7 +495,7 @@ func StorageProvider(minerAddress dtypes.MinerAddress,
|
||||
pieceStore dtypes.ProviderPieceStore,
|
||||
dataTransfer dtypes.ProviderDataTransfer,
|
||||
spn storagemarket.StorageProviderNode,
|
||||
df dtypes.DealFilter,
|
||||
df dtypes.StorageDealFilter,
|
||||
funds ProviderDealFunds,
|
||||
) (storagemarket.StorageProvider, error) {
|
||||
net := smnet.NewFromLibp2pHost(h)
|
||||
@@ -511,8 +509,52 @@ func StorageProvider(minerAddress dtypes.MinerAddress,
|
||||
return storageimpl.NewProvider(net, namespace.Wrap(ds, datastore.NewKey("/deals/provider")), store, mds, pieceStore, dataTransfer, spn, address.Address(minerAddress), ffiConfig.SealProofType, storedAsk, funds, opt)
|
||||
}
|
||||
|
||||
func RetrievalDealFilter(userFilter dtypes.RetrievalDealFilter) func(onlineOk dtypes.ConsiderOnlineRetrievalDealsConfigFunc,
|
||||
offlineOk dtypes.ConsiderOfflineRetrievalDealsConfigFunc) dtypes.RetrievalDealFilter {
|
||||
return func(onlineOk dtypes.ConsiderOnlineRetrievalDealsConfigFunc,
|
||||
offlineOk dtypes.ConsiderOfflineRetrievalDealsConfigFunc) dtypes.RetrievalDealFilter {
|
||||
return func(ctx context.Context, state retrievalmarket.ProviderDealState) (bool, string, error) {
|
||||
b, err := onlineOk()
|
||||
if err != nil {
|
||||
return false, "miner error", err
|
||||
}
|
||||
|
||||
if !b {
|
||||
log.Warn("online retrieval deal consideration disabled; rejecting retrieval deal proposal from client")
|
||||
return false, "miner is not accepting online retrieval deals", nil
|
||||
}
|
||||
|
||||
b, err = offlineOk()
|
||||
if err != nil {
|
||||
return false, "miner error", err
|
||||
}
|
||||
|
||||
if !b {
|
||||
log.Info("offline retrieval has not been implemented yet")
|
||||
}
|
||||
|
||||
if userFilter != nil {
|
||||
return userFilter(ctx, state)
|
||||
}
|
||||
|
||||
return true, "", nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RetrievalProvider creates a new retrieval provider attached to the provider blockstore
|
||||
func RetrievalProvider(h host.Host, miner *storage.Miner, sealer sectorstorage.SectorManager, full lapi.FullNode, ds dtypes.MetadataDS, pieceStore dtypes.ProviderPieceStore, mds dtypes.StagingMultiDstore, dt dtypes.ProviderDataTransfer, onlineOk dtypes.ConsiderOnlineRetrievalDealsConfigFunc, offlineOk dtypes.ConsiderOfflineRetrievalDealsConfigFunc) (retrievalmarket.RetrievalProvider, error) {
|
||||
func RetrievalProvider(h host.Host,
|
||||
miner *storage.Miner,
|
||||
sealer sectorstorage.SectorManager,
|
||||
full lapi.FullNode,
|
||||
ds dtypes.MetadataDS,
|
||||
pieceStore dtypes.ProviderPieceStore,
|
||||
mds dtypes.StagingMultiDstore,
|
||||
dt dtypes.ProviderDataTransfer,
|
||||
onlineOk dtypes.ConsiderOnlineRetrievalDealsConfigFunc,
|
||||
offlineOk dtypes.ConsiderOfflineRetrievalDealsConfigFunc,
|
||||
userFilter dtypes.RetrievalDealFilter,
|
||||
) (retrievalmarket.RetrievalProvider, error) {
|
||||
adapter := retrievaladapter.NewRetrievalProviderNode(miner, sealer, full)
|
||||
|
||||
maddr, err := minerAddrFromDS(ds)
|
||||
@@ -521,29 +563,7 @@ func RetrievalProvider(h host.Host, miner *storage.Miner, sealer sectorstorage.S
|
||||
}
|
||||
|
||||
netwk := rmnet.NewFromLibp2pHost(h)
|
||||
|
||||
opt := retrievalimpl.DealDeciderOpt(func(ctx context.Context, state retrievalmarket.ProviderDealState) (bool, string, error) {
|
||||
b, err := onlineOk()
|
||||
if err != nil {
|
||||
return false, "miner error", err
|
||||
}
|
||||
|
||||
if !b {
|
||||
log.Warn("online retrieval deal consideration disabled; rejecting retrieval deal proposal from client")
|
||||
return false, "miner is not accepting online retrieval deals", nil
|
||||
}
|
||||
|
||||
b, err = offlineOk()
|
||||
if err != nil {
|
||||
return false, "miner error", err
|
||||
}
|
||||
|
||||
if !b {
|
||||
log.Info("offline retrieval has not been implemented yet")
|
||||
}
|
||||
|
||||
return true, "", nil
|
||||
})
|
||||
opt := retrievalimpl.DealDeciderOpt(retrievalimpl.DealDecider(userFilter))
|
||||
|
||||
return retrievalimpl.NewProvider(maddr, adapter, netwk, pieceStore, mds, dt, namespace.Wrap(ds, datastore.NewKey("/retrievals/provider")), opt)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user