Merge branch 'master' into asr/spec-v1
This commit is contained in:
		
						commit
						947d1e2902
					
				
							
								
								
									
										57
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @ -1,5 +1,62 @@ | ||||
| # Lotus changelog | ||||
| 
 | ||||
| # 0.8.0 / 2020-09-26 | ||||
| 
 | ||||
| This consensus-breaking release of Lotus introduces an upgrade to the network. The changes that break consensus are: | ||||
| 
 | ||||
| - Upgrading to specs-actors v0.9.11, which reduces WindowPoSt faults per [FIP 0002](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0002.md) to reduce cost for honest miners with occasional faults (see https://github.com/filecoin-project/specs-actors/pull/1181) | ||||
| - Revisions to some cryptoeconomics and network params | ||||
| 
 | ||||
| This release also updates go-fil-markets to fix an incompatibility issue between v0.7.2 and earlier versions. | ||||
| 
 | ||||
| ## Changes  | ||||
| 
 | ||||
| #### Dependencies | ||||
| 
 | ||||
| - Update spec actors to 0.9.11 (https://github.com/filecoin-project/lotus/pull/4039) | ||||
| - Update markets to 0.6.3 (https://github.com/filecoin-project/lotus/pull/4013) | ||||
| 
 | ||||
| #### Core Lotus | ||||
| 
 | ||||
| - Network upgrade (https://github.com/filecoin-project/lotus/pull/4039) | ||||
| - Fix AddSupportedProofTypes (https://github.com/filecoin-project/lotus/pull/4033) | ||||
| - Return an error when we fail to find a sector when checking sector expiration (https://github.com/filecoin-project/lotus/pull/4026) | ||||
| - Batch blockstore copies after block validation (https://github.com/filecoin-project/lotus/pull/3980) | ||||
| - Remove a misleading miner actor abstraction (https://github.com/filecoin-project/lotus/pull/3977) | ||||
| - Fix out-of-bounds when loading all sector infos (https://github.com/filecoin-project/lotus/pull/3976) | ||||
| - Fix break condition in the miner (https://github.com/filecoin-project/lotus/pull/3953) | ||||
| 
 | ||||
| #### UX | ||||
| 
 | ||||
| - Correct helptext around miners setting ask (https://github.com/filecoin-project/lotus/pull/4009) | ||||
| - Make sync wait nicer (https://github.com/filecoin-project/lotus/pull/3991) | ||||
| 
 | ||||
| #### Tooling and validation | ||||
| 
 | ||||
| - Small adjustments following network upgradability changes (https://github.com/filecoin-project/lotus/pull/3996) | ||||
| - Add some more big pictures stats to stateroot stat (https://github.com/filecoin-project/lotus/pull/3995) | ||||
| - Add some actors policy setters for testing (https://github.com/filecoin-project/lotus/pull/3975) | ||||
| 
 | ||||
| ## Contributors | ||||
| 
 | ||||
| The following contributors had 5 or more commits go into this release. | ||||
| We are grateful for every contribution! | ||||
| 
 | ||||
| | Contributor        | Commits | Lines ±       | | ||||
| |--------------------|---------|---------------| | ||||
| | arajasek           | 66       | +3140/-1261  | | ||||
| | Stebalien          | 64       | +3797/-3434  | | ||||
| | magik6k            | 48       | +1892/-976   | | ||||
| | raulk              | 40       | +2412/-1549  | | ||||
| | vyzo               | 22       | +287/-196    | | ||||
| | alanshaw           | 15       | +761/-146    | | ||||
| | whyrusleeping      | 15       | +736/-52     | | ||||
| | hannahhoward       | 14       | +1237/837-   |  | ||||
| | anton              | 6        | +32/-8       | | ||||
| | travisperson       | 5        | +502/-6      | | ||||
| | Frank              | 5        | +78/-39      | | ||||
| | Jennifer           | 5        | +148/-41     | | ||||
| 
 | ||||
| # 0.7.2 / 2020-09-23 | ||||
| 
 | ||||
| This optional release of Lotus introduces a major refactor around how a Lotus node interacts with code from the specs-actors repo. We now use interfaces to read the state of actors, which is required to be able to reason about different versions of actors code at the same time. | ||||
|  | ||||
| @ -94,6 +94,22 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) { | ||||
| 		require.Less(t, 50000, int(exp.OnTime)) | ||||
| 	} | ||||
| 
 | ||||
| 	dlInfo, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) | ||||
| 	require.NoError(t, err) | ||||
| 
 | ||||
| 	// Sector should expire.
 | ||||
| 	for { | ||||
| 		// Wait for the sector to expire.
 | ||||
| 		status, err := miner.SectorsStatus(ctx, CC, true) | ||||
| 		require.NoError(t, err) | ||||
| 		if status.OnTime == 0 && status.Early == 0 { | ||||
| 			break | ||||
| 		} | ||||
| 		t.Log("waiting for sector to expire") | ||||
| 		// wait one deadline per loop.
 | ||||
| 		time.Sleep(time.Duration(dlInfo.WPoStChallengeWindow) * blocktime) | ||||
| 	} | ||||
| 
 | ||||
| 	fmt.Println("shutting down mining") | ||||
| 	atomic.AddInt64(&mine, -1) | ||||
| 	<-done | ||||
|  | ||||
| @ -4,3 +4,9 @@ | ||||
| /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 | ||||
|  | ||||
| @ -12,6 +12,8 @@ const UpgradeBreezeHeight = -1 | ||||
| const BreezeGasTampingDuration = 0 | ||||
| 
 | ||||
| const UpgradeSmokeHeight = -1 | ||||
| const UpgradeIgnitionHeight = -2 | ||||
| const UpgradeLiftoffHeight = -3 | ||||
| 
 | ||||
| var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ | ||||
| 	0: DrandMainnet, | ||||
|  | ||||
| @ -3,6 +3,8 @@ package build | ||||
| import ( | ||||
| 	"sort" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/go-address" | ||||
| 
 | ||||
| 	"github.com/libp2p/go-libp2p-core/protocol" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/go-state-types/abi" | ||||
| @ -44,3 +46,7 @@ func UseNewestNetwork() bool { | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func SetAddressNetwork(n address.Network) { | ||||
| 	address.CurrentNetwork = n | ||||
| } | ||||
|  | ||||
| @ -4,6 +4,9 @@ package build | ||||
| 
 | ||||
| import ( | ||||
| 	"math/big" | ||||
| 	"os" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/go-address" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/go-state-types/network" | ||||
| 
 | ||||
| @ -22,8 +25,8 @@ const UnixfsLinksPerLevel = 1024 | ||||
| // Consensus / Network
 | ||||
| 
 | ||||
| const AllowableClockDriftSecs = uint64(1) | ||||
| const NewestNetworkVersion = network.Version2 | ||||
| const ActorUpgradeNetworkVersion = network.Version3 | ||||
| const NewestNetworkVersion = network.Version3 | ||||
| const ActorUpgradeNetworkVersion = network.Version4 | ||||
| 
 | ||||
| // Epochs
 | ||||
| const ForkLengthThreshold = Finality | ||||
| @ -60,9 +63,16 @@ const TicketRandomnessLookback = abi.ChainEpoch(1) | ||||
| 
 | ||||
| const WinningPoStSectorSetLookback = abi.ChainEpoch(10) | ||||
| 
 | ||||
| // /////
 | ||||
| // Address
 | ||||
| 
 | ||||
| const AddressMainnetEnvVar = "_mainnet_" | ||||
| 
 | ||||
| // /////
 | ||||
| // Devnet settings
 | ||||
| 
 | ||||
| var Devnet = true | ||||
| 
 | ||||
| const FilBase = uint64(2_000_000_000) | ||||
| const FilAllocStorageMining = uint64(1_100_000_000) | ||||
| 
 | ||||
| @ -75,6 +85,10 @@ var InitialRewardBalance *big.Int | ||||
| func init() { | ||||
| 	InitialRewardBalance = big.NewInt(int64(FilAllocStorageMining)) | ||||
| 	InitialRewardBalance = InitialRewardBalance.Mul(InitialRewardBalance, big.NewInt(int64(FilecoinPrecision))) | ||||
| 
 | ||||
| 	if os.Getenv("LOTUS_ADDRESS_TYPE") == AddressMainnetEnvVar { | ||||
| 		SetAddressNetwork(address.Mainnet) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Sync
 | ||||
|  | ||||
| @ -74,7 +74,9 @@ var ( | ||||
| 	UpgradeBreezeHeight      abi.ChainEpoch = -1 | ||||
| 	BreezeGasTampingDuration abi.ChainEpoch = 0 | ||||
| 
 | ||||
| 	UpgradeSmokeHeight abi.ChainEpoch = -1 | ||||
| 	UpgradeSmokeHeight    abi.ChainEpoch = -1 | ||||
| 	UpgradeIgnitionHeight abi.ChainEpoch = -2 | ||||
| 	UpgradeLiftoffHeight  abi.ChainEpoch = -3 | ||||
| 
 | ||||
| 	DrandSchedule = map[abi.ChainEpoch]DrandEnum{ | ||||
| 		0: DrandMainnet, | ||||
| @ -82,4 +84,6 @@ var ( | ||||
| 
 | ||||
| 	NewestNetworkVersion       = network.Version2 | ||||
| 	ActorUpgradeNetworkVersion = network.Version3 | ||||
| 
 | ||||
| 	Devnet = true | ||||
| ) | ||||
|  | ||||
| @ -21,12 +21,20 @@ const BreezeGasTampingDuration = 120 | ||||
| 
 | ||||
| const UpgradeSmokeHeight = 51000 | ||||
| 
 | ||||
| const UpgradeIgnitionHeight = 94000 | ||||
| 
 | ||||
| // 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 | ||||
| 
 | ||||
| func init() { | ||||
| 	policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40)) | ||||
| 	policy.SetSupportedProofTypes( | ||||
| 		abi.RegisteredSealProof_StackedDrg32GiBV1, | ||||
| 		abi.RegisteredSealProof_StackedDrg64GiBV1, | ||||
| 	) | ||||
| 	Devnet = false | ||||
| } | ||||
| 
 | ||||
| const BlockDelaySecs = uint64(builtin0.EpochDurationSeconds) | ||||
|  | ||||
| @ -29,7 +29,7 @@ func buildType() string { | ||||
| } | ||||
| 
 | ||||
| // BuildVersion is the local build version, set by build system
 | ||||
| const BuildVersion = "0.7.2" | ||||
| const BuildVersion = "0.8.0" | ||||
| 
 | ||||
| func UserVersion() string { | ||||
| 	return BuildVersion + buildType() + CurrentCommit | ||||
|  | ||||
| @ -11,6 +11,7 @@ import ( | ||||
| 	"github.com/ipfs/go-cid" | ||||
| 	"github.com/libp2p/go-libp2p-core/peer" | ||||
| 	cbg "github.com/whyrusleeping/cbor-gen" | ||||
| 	"golang.org/x/xerrors" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/lotus/chain/actors/adt" | ||||
| 
 | ||||
| @ -106,9 +107,7 @@ func (s *state0) NumLiveSectors() (uint64, error) { | ||||
| 
 | ||||
| // GetSectorExpiration returns the effective expiration of the given sector.
 | ||||
| //
 | ||||
| // If the sector isn't found or has already been terminated, this method returns
 | ||||
| // nil and no error. If the sector does not expire early, the Early expiration
 | ||||
| // field is 0.
 | ||||
| // If the sector does not expire early, the Early expiration field is 0.
 | ||||
| func (s *state0) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) { | ||||
| 	dls, err := s.State.LoadDeadlines(s.store) | ||||
| 	if err != nil { | ||||
| @ -171,7 +170,7 @@ func (s *state0) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, e | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if out.Early == 0 && out.OnTime == 0 { | ||||
| 		return nil, nil | ||||
| 		return nil, xerrors.Errorf("failed to find sector %d", num) | ||||
| 	} | ||||
| 	return &out, nil | ||||
| } | ||||
|  | ||||
| @ -22,12 +22,10 @@ func SetSupportedProofTypes(types ...abi.RegisteredSealProof) { | ||||
| // AddSupportedProofTypes sets supported proof types, across all actor versions.
 | ||||
| // This should only be used for testing.
 | ||||
| func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { | ||||
| 	newTypes := make(map[abi.RegisteredSealProof]struct{}, len(types)) | ||||
| 	for _, t := range types { | ||||
| 		newTypes[t] = struct{}{} | ||||
| 		// Set for all miner versions.
 | ||||
| 		miner0.SupportedProofTypes[t] = struct{}{} | ||||
| 	} | ||||
| 	// Set for all miner versions.
 | ||||
| 	miner0.SupportedProofTypes = newTypes | ||||
| } | ||||
| 
 | ||||
| // SetPreCommitChallengeDelay sets the pre-commit challenge delay across all
 | ||||
|  | ||||
							
								
								
									
										36
									
								
								chain/actors/policy/policy_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								chain/actors/policy/policy_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| package policy | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/go-state-types/abi" | ||||
| 	miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" | ||||
| ) | ||||
| 
 | ||||
| func TestSupportedProofTypes(t *testing.T) { | ||||
| 	var oldTypes []abi.RegisteredSealProof | ||||
| 	for t := range miner0.SupportedProofTypes { | ||||
| 		oldTypes = append(oldTypes, t) | ||||
| 	} | ||||
| 	t.Cleanup(func() { | ||||
| 		SetSupportedProofTypes(oldTypes...) | ||||
| 	}) | ||||
| 
 | ||||
| 	SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1) | ||||
| 	require.EqualValues(t, | ||||
| 		miner0.SupportedProofTypes, | ||||
| 		map[abi.RegisteredSealProof]struct{}{ | ||||
| 			abi.RegisteredSealProof_StackedDrg2KiBV1: {}, | ||||
| 		}, | ||||
| 	) | ||||
| 	AddSupportedProofTypes(abi.RegisteredSealProof_StackedDrg8MiBV1) | ||||
| 	require.EqualValues(t, | ||||
| 		miner0.SupportedProofTypes, | ||||
| 		map[abi.RegisteredSealProof]struct{}{ | ||||
| 			abi.RegisteredSealProof_StackedDrg2KiBV1: {}, | ||||
| 			abi.RegisteredSealProof_StackedDrg8MiBV1: {}, | ||||
| 		}, | ||||
| 	) | ||||
| } | ||||
| @ -16,7 +16,7 @@ const ( | ||||
| // Converts a network version into an actors adt version.
 | ||||
| func VersionForNetwork(version network.Version) Version { | ||||
| 	switch version { | ||||
| 	case network.Version0, network.Version1, network.Version2: | ||||
| 	case network.Version0, network.Version1, network.Version2, network.Version3: | ||||
| 		return Version0 | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("unsupported network version %d", version)) | ||||
|  | ||||
| @ -1,44 +1,59 @@ | ||||
| package stmgr | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"encoding/binary" | ||||
| 	"math" | ||||
| 
 | ||||
| 	multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/lotus/chain/actors/builtin/multisig" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/lotus/chain/state" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/specs-actors/actors/migration/nv3" | ||||
| 
 | ||||
| 	"github.com/ipfs/go-cid" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/go-address" | ||||
| 	"github.com/filecoin-project/go-state-types/abi" | ||||
| 	"github.com/filecoin-project/go-state-types/big" | ||||
| 
 | ||||
| 	builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" | ||||
| 	init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" | ||||
| 	miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" | ||||
| 	power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" | ||||
| 	adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/lotus/build" | ||||
| 	"github.com/filecoin-project/lotus/chain/types" | ||||
| 	"github.com/filecoin-project/lotus/chain/vm" | ||||
| 	cbor "github.com/ipfs/go-ipld-cbor" | ||||
| 	"golang.org/x/xerrors" | ||||
| ) | ||||
| 
 | ||||
| var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, types.StateTree, *types.TipSet) error{ | ||||
| 	build.UpgradeBreezeHeight: UpgradeFaucetBurnRecovery, | ||||
| var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, ExecCallback, cid.Cid, *types.TipSet) (cid.Cid, error){ | ||||
| 	build.UpgradeBreezeHeight:   UpgradeFaucetBurnRecovery, | ||||
| 	build.UpgradeIgnitionHeight: UpgradeIgnition, | ||||
| 	build.UpgradeLiftoffHeight:  UpgradeLiftoff, | ||||
| } | ||||
| 
 | ||||
| func (sm *StateManager) handleStateForks(ctx context.Context, st types.StateTree, height abi.ChainEpoch, ts *types.TipSet) (err error) { | ||||
| func (sm *StateManager) handleStateForks(ctx context.Context, root cid.Cid, height abi.ChainEpoch, cb ExecCallback, ts *types.TipSet) (cid.Cid, error) { | ||||
| 	retCid := root | ||||
| 	var err error | ||||
| 	f, ok := ForksAtHeight[height] | ||||
| 	if ok { | ||||
| 		err := f(ctx, sm, st, ts) | ||||
| 		retCid, err = f(ctx, sm, cb, root, ts) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 			return cid.Undef, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| 	return retCid, nil | ||||
| } | ||||
| 
 | ||||
| type forEachTree interface { | ||||
| 	ForEach(func(address.Address, *types.Actor) error) error | ||||
| } | ||||
| 
 | ||||
| func doTransfer(tree types.StateTree, from, to address.Address, amt abi.TokenAmount) error { | ||||
| func doTransfer(cb ExecCallback, tree types.StateTree, from, to address.Address, amt abi.TokenAmount) error { | ||||
| 	fromAct, err := tree.GetActor(from) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("failed to get 'from' actor for transfer: %w", err) | ||||
| @ -64,10 +79,43 @@ func doTransfer(tree types.StateTree, from, to address.Address, amt abi.TokenAmo | ||||
| 		return xerrors.Errorf("failed to persist to actor: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	if cb != nil { | ||||
| 		// record the transfer in execution traces
 | ||||
| 
 | ||||
| 		fakeMsg := &types.Message{ | ||||
| 			From:  from, | ||||
| 			To:    to, | ||||
| 			Value: amt, | ||||
| 			Nonce: math.MaxUint64, | ||||
| 		} | ||||
| 		fakeRct := &types.MessageReceipt{ | ||||
| 			ExitCode: 0, | ||||
| 			Return:   nil, | ||||
| 			GasUsed:  0, | ||||
| 		} | ||||
| 
 | ||||
| 		if err := cb(fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{ | ||||
| 			MessageReceipt: *fakeRct, | ||||
| 			ActorErr:       nil, | ||||
| 			ExecutionTrace: types.ExecutionTrace{ | ||||
| 				Msg:        fakeMsg, | ||||
| 				MsgRct:     fakeRct, | ||||
| 				Error:      "", | ||||
| 				Duration:   0, | ||||
| 				GasCharges: nil, | ||||
| 				Subcalls:   nil, | ||||
| 			}, | ||||
| 			Duration: 0, | ||||
| 			GasCosts: vm.ZeroGasOutputs(), | ||||
| 		}); err != nil { | ||||
| 			return xerrors.Errorf("recording transfer: %w", err) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types.StateTree, ts *types.TipSet) error { | ||||
| func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { | ||||
| 	// Some initial parameters
 | ||||
| 	FundsForMiners := types.FromFil(1_000_000) | ||||
| 	LookbackEpoch := abi.ChainEpoch(32000) | ||||
| @ -94,22 +142,22 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types | ||||
| 	// Grab lookback state for account checks
 | ||||
| 	lbts, err := sm.ChainStore().GetTipsetByHeight(ctx, LookbackEpoch, ts, false) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("failed to get tipset at lookback height: %w", err) | ||||
| 		return cid.Undef, xerrors.Errorf("failed to get tipset at lookback height: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	lbtree, err := sm.ParentState(lbts) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("loading state tree failed: %w", err) | ||||
| 		return cid.Undef, xerrors.Errorf("loading state tree failed: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	ReserveAddress, err := address.NewFromString("t090") | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("failed to parse reserve address: %w", err) | ||||
| 		return cid.Undef, xerrors.Errorf("failed to parse reserve address: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	fetree, ok := tree.(forEachTree) | ||||
| 	if !ok { | ||||
| 		return xerrors.Errorf("fork transition state tree doesnt support ForEach (%T)", tree) | ||||
| 	tree, err := sm.StateTree(root) | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("getting state tree: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	type transfer struct { | ||||
| @ -121,7 +169,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types | ||||
| 	var transfers []transfer | ||||
| 
 | ||||
| 	// Take all excess funds away, put them into the reserve account
 | ||||
| 	err = fetree.ForEach(func(addr address.Address, act *types.Actor) error { | ||||
| 	err = tree.ForEach(func(addr address.Address, act *types.Actor) error { | ||||
| 		switch act.Code { | ||||
| 		case builtin0.AccountActorCodeID, builtin0.MultisigActorCodeID, builtin0.PaymentChannelActorCodeID: | ||||
| 			sysAcc, err := isSystemAccount(addr) | ||||
| @ -163,13 +211,13 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types | ||||
| 		return nil | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("foreach over state tree failed: %w", err) | ||||
| 		return cid.Undef, xerrors.Errorf("foreach over state tree failed: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Execute transfers from previous step
 | ||||
| 	for _, t := range transfers { | ||||
| 		if err := doTransfer(tree, t.From, t.To, t.Amt); err != nil { | ||||
| 			return xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err) | ||||
| 		if err := doTransfer(cb, tree, t.From, t.To, t.Amt); err != nil { | ||||
| 			return cid.Undef, xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| @ -177,19 +225,19 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types | ||||
| 	var ps power0.State | ||||
| 	powAct, err := tree.GetActor(builtin0.StoragePowerActorAddr) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("failed to load power actor: %w", err) | ||||
| 		return cid.Undef, xerrors.Errorf("failed to load power actor: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	cst := cbor.NewCborStore(sm.ChainStore().Blockstore()) | ||||
| 	if err := cst.Get(ctx, powAct.Head, &ps); err != nil { | ||||
| 		return xerrors.Errorf("failed to get power actor state: %w", err) | ||||
| 		return cid.Undef, xerrors.Errorf("failed to get power actor state: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	totalPower := ps.TotalBytesCommitted | ||||
| 
 | ||||
| 	var transfersBack []transfer | ||||
| 	// Now, we return some funds to places where they are needed
 | ||||
| 	err = fetree.ForEach(func(addr address.Address, act *types.Actor) error { | ||||
| 	err = tree.ForEach(func(addr address.Address, act *types.Actor) error { | ||||
| 		lbact, err := lbtree.GetActor(addr) | ||||
| 		if err != nil { | ||||
| 			if !xerrors.Is(err, types.ErrActorNotFound) { | ||||
| @ -267,53 +315,310 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types | ||||
| 		return nil | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("foreach over state tree failed: %w", err) | ||||
| 		return cid.Undef, xerrors.Errorf("foreach over state tree failed: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, t := range transfersBack { | ||||
| 		if err := doTransfer(tree, t.From, t.To, t.Amt); err != nil { | ||||
| 			return xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err) | ||||
| 		if err := doTransfer(cb, tree, t.From, t.To, t.Amt); err != nil { | ||||
| 			return cid.Undef, xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// transfer all burnt funds back to the reserve account
 | ||||
| 	burntAct, err := tree.GetActor(builtin0.BurntFundsActorAddr) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("failed to load burnt funds actor: %w", err) | ||||
| 		return cid.Undef, xerrors.Errorf("failed to load burnt funds actor: %w", err) | ||||
| 	} | ||||
| 	if err := doTransfer(tree, builtin0.BurntFundsActorAddr, ReserveAddress, burntAct.Balance); err != nil { | ||||
| 		return xerrors.Errorf("failed to unburn funds: %w", err) | ||||
| 	if err := doTransfer(cb, tree, builtin0.BurntFundsActorAddr, ReserveAddress, burntAct.Balance); err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("failed to unburn funds: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Top up the reimbursement service
 | ||||
| 	reimbAddr, err := address.NewFromString("t0111") | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("failed to parse reimbursement service address") | ||||
| 		return cid.Undef, xerrors.Errorf("failed to parse reimbursement service address") | ||||
| 	} | ||||
| 
 | ||||
| 	reimb, err := tree.GetActor(reimbAddr) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("failed to load reimbursement account actor: %w", err) | ||||
| 		return cid.Undef, xerrors.Errorf("failed to load reimbursement account actor: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	difference := types.BigSub(DesiredReimbursementBalance, reimb.Balance) | ||||
| 	if err := doTransfer(tree, ReserveAddress, reimbAddr, difference); err != nil { | ||||
| 		return xerrors.Errorf("failed to top up reimbursement account: %w", err) | ||||
| 	if err := doTransfer(cb, tree, ReserveAddress, reimbAddr, difference); err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("failed to top up reimbursement account: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Now, a final sanity check to make sure the balances all check out
 | ||||
| 	total := abi.NewTokenAmount(0) | ||||
| 	err = fetree.ForEach(func(addr address.Address, act *types.Actor) error { | ||||
| 	err = tree.ForEach(func(addr address.Address, act *types.Actor) error { | ||||
| 		total = types.BigAdd(total, act.Balance) | ||||
| 		return nil | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("checking final state balance failed: %w", err) | ||||
| 		return cid.Undef, xerrors.Errorf("checking final state balance failed: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	exp := types.FromFil(build.FilBase) | ||||
| 	if !exp.Equals(total) { | ||||
| 		return xerrors.Errorf("resultant state tree account balance was not correct: %s", total) | ||||
| 		return cid.Undef, xerrors.Errorf("resultant state tree account balance was not correct: %s", total) | ||||
| 	} | ||||
| 
 | ||||
| 	return tree.Flush(ctx) | ||||
| } | ||||
| 
 | ||||
| func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { | ||||
| 	store := sm.cs.Store(ctx) | ||||
| 
 | ||||
| 	nst, err := nv3.MigrateStateTree(ctx, store, root, build.UpgradeIgnitionHeight) | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("migrating actors state: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	tree, err := sm.StateTree(nst) | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("getting state tree: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	err = setNetworkName(ctx, store, tree, "ignition") | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("setting network name: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	split1, err := address.NewFromString("t0115") | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("first split address: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	split2, err := address.NewFromString("t0116") | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("second split address: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	err = resetGenesisMsigs(ctx, sm, store, tree) | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("resetting genesis msig start epochs: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	err = splitGenesisMultisig(ctx, cb, split1, store, tree, 50) | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("splitting first msig: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	err = splitGenesisMultisig(ctx, cb, split2, store, tree, 50) | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("splitting second msig: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	err = nv3.CheckStateTree(ctx, store, nst, build.UpgradeIgnitionHeight, builtin0.TotalFilecoin) | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("sanity check after ignition upgrade failed: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	return tree.Flush(ctx) | ||||
| } | ||||
| 
 | ||||
| func UpgradeLiftoff(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { | ||||
| 	tree, err := sm.StateTree(root) | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("getting state tree: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	err = setNetworkName(ctx, sm.cs.Store(ctx), tree, "mainnet") | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, xerrors.Errorf("setting network name: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	return tree.Flush(ctx) | ||||
| } | ||||
| 
 | ||||
| func setNetworkName(ctx context.Context, store adt0.Store, tree *state.StateTree, name string) error { | ||||
| 	ia, err := tree.GetActor(builtin0.InitActorAddr) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting init actor: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	var initState init0.State | ||||
| 	if err := store.Get(ctx, ia.Head, &initState); err != nil { | ||||
| 		return xerrors.Errorf("reading init state: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	initState.NetworkName = name | ||||
| 
 | ||||
| 	ia.Head, err = store.Put(ctx, &initState) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("writing new init state: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	if err := tree.SetActor(builtin0.InitActorAddr, ia); err != nil { | ||||
| 		return xerrors.Errorf("setting init actor: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func splitGenesisMultisig(ctx context.Context, cb ExecCallback, addr address.Address, store adt0.Store, tree *state.StateTree, portions uint64) error { | ||||
| 	if portions < 1 { | ||||
| 		return xerrors.Errorf("cannot split into 0 portions") | ||||
| 	} | ||||
| 
 | ||||
| 	mact, err := tree.GetActor(addr) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting msig actor: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	mst, err := multisig.Load(store, mact) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting msig state: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	signers, err := mst.Signers() | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting msig signers: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	thresh, err := mst.Threshold() | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting msig threshold: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	ibal, err := mst.InitialBalance() | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting msig initial balance: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	se, err := mst.StartEpoch() | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting msig start epoch: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	ud, err := mst.UnlockDuration() | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting msig unlock duration: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	pending, err := adt0.MakeEmptyMap(store).Root() | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("failed to create empty map: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	newIbal := big.Div(ibal, types.NewInt(portions)) | ||||
| 	newState := &multisig0.State{ | ||||
| 		Signers:               signers, | ||||
| 		NumApprovalsThreshold: thresh, | ||||
| 		NextTxnID:             0, | ||||
| 		InitialBalance:        newIbal, | ||||
| 		StartEpoch:            se, | ||||
| 		UnlockDuration:        ud, | ||||
| 		PendingTxns:           pending, | ||||
| 	} | ||||
| 
 | ||||
| 	scid, err := store.Put(ctx, newState) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("storing new state: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	newActor := types.Actor{ | ||||
| 		Code:    builtin0.MultisigActorCodeID, | ||||
| 		Head:    scid, | ||||
| 		Nonce:   0, | ||||
| 		Balance: big.Zero(), | ||||
| 	} | ||||
| 
 | ||||
| 	i := uint64(0) | ||||
| 	for i < portions { | ||||
| 		keyAddr, err := makeKeyAddr(addr, i) | ||||
| 		if err != nil { | ||||
| 			return xerrors.Errorf("creating key address: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		idAddr, err := tree.RegisterNewAddress(keyAddr) | ||||
| 		if err != nil { | ||||
| 			return xerrors.Errorf("registering new address: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		err = tree.SetActor(idAddr, &newActor) | ||||
| 		if err != nil { | ||||
| 			return xerrors.Errorf("setting new msig actor state: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		if err := doTransfer(cb, tree, addr, idAddr, newIbal); err != nil { | ||||
| 			return xerrors.Errorf("transferring split msig balance: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		i++ | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func makeKeyAddr(splitAddr address.Address, count uint64) (address.Address, error) { | ||||
| 	var b bytes.Buffer | ||||
| 	if err := splitAddr.MarshalCBOR(&b); err != nil { | ||||
| 		return address.Undef, xerrors.Errorf("marshalling split address: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	if err := binary.Write(&b, binary.BigEndian, count); err != nil { | ||||
| 		return address.Undef, xerrors.Errorf("writing count into a buffer: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	if err := binary.Write(&b, binary.BigEndian, []byte("Ignition upgrade")); err != nil { | ||||
| 		return address.Undef, xerrors.Errorf("writing fork name into a buffer: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	addr, err := address.NewActorAddress(b.Bytes()) | ||||
| 	if err != nil { | ||||
| 		return address.Undef, xerrors.Errorf("create actor address: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	return addr, nil | ||||
| } | ||||
| 
 | ||||
| func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store, tree *state.StateTree) error { | ||||
| 	gb, err := sm.cs.GetGenesis() | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting genesis block: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	gts, err := types.NewTipSet([]*types.BlockHeader{gb}) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting genesis tipset: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	cst := cbor.NewCborStore(sm.cs.Blockstore()) | ||||
| 	genesisTree, err := state.LoadStateTree(cst, gts.ParentState()) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("loading state tree: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	err = genesisTree.ForEach(func(addr address.Address, genesisActor *types.Actor) error { | ||||
| 		if genesisActor.Code == builtin0.MultisigActorCodeID { | ||||
| 			currActor, err := tree.GetActor(addr) | ||||
| 			if err != nil { | ||||
| 				return xerrors.Errorf("loading actor: %w", err) | ||||
| 			} | ||||
| 
 | ||||
| 			var currState multisig0.State | ||||
| 			if err := store.Get(ctx, currActor.Head, &currState); err != nil { | ||||
| 				return xerrors.Errorf("reading multisig state: %w", err) | ||||
| 			} | ||||
| 
 | ||||
| 			currState.StartEpoch = build.UpgradeLiftoffHeight | ||||
| 
 | ||||
| 			currActor.Head, err = store.Put(ctx, &currState) | ||||
| 			if err != nil { | ||||
| 				return xerrors.Errorf("writing new multisig state: %w", err) | ||||
| 			} | ||||
| 
 | ||||
| 			if err := tree.SetActor(addr, currActor); err != nil { | ||||
| 				return xerrors.Errorf("setting multisig actor: %w", err) | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| 
 | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("iterating over genesis actors: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
|  | ||||
| @ -129,33 +129,38 @@ func TestForkHeightTriggers(t *testing.T) { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	stmgr.ForksAtHeight[testForkHeight] = func(ctx context.Context, sm *StateManager, st types.StateTree, ts *types.TipSet) error { | ||||
| 	stmgr.ForksAtHeight[testForkHeight] = func(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) { | ||||
| 		cst := ipldcbor.NewCborStore(sm.ChainStore().Blockstore()) | ||||
| 
 | ||||
| 		st, err := sm.StateTree(root) | ||||
| 		if err != nil { | ||||
| 			return cid.Undef, xerrors.Errorf("getting state tree: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		act, err := st.GetActor(taddr) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 			return cid.Undef, err | ||||
| 		} | ||||
| 
 | ||||
| 		var tas testActorState | ||||
| 		if err := cst.Get(ctx, act.Head, &tas); err != nil { | ||||
| 			return xerrors.Errorf("in fork handler, failed to run get: %w", err) | ||||
| 			return cid.Undef, xerrors.Errorf("in fork handler, failed to run get: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		tas.HasUpgraded = 55 | ||||
| 
 | ||||
| 		ns, err := cst.Put(ctx, &tas) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 			return cid.Undef, err | ||||
| 		} | ||||
| 
 | ||||
| 		act.Head = ns | ||||
| 
 | ||||
| 		if err := st.SetActor(taddr, act); err != nil { | ||||
| 			return err | ||||
| 			return cid.Undef, err | ||||
| 		} | ||||
| 
 | ||||
| 		return nil | ||||
| 		return st.Flush(ctx) | ||||
| 	} | ||||
| 
 | ||||
| 	inv.Register(nil, testActor{}) | ||||
|  | ||||
| @ -40,12 +40,13 @@ var log = logging.Logger("statemgr") | ||||
| type StateManager struct { | ||||
| 	cs *store.ChainStore | ||||
| 
 | ||||
| 	stCache       map[string][]cid.Cid | ||||
| 	compWait      map[string]chan struct{} | ||||
| 	stlk          sync.Mutex | ||||
| 	genesisMsigLk sync.Mutex | ||||
| 	newVM         func(context.Context, *vm.VMOpts) (*vm.VM, error) | ||||
| 	genInfo       *genesisInfo | ||||
| 	stCache              map[string][]cid.Cid | ||||
| 	compWait             map[string]chan struct{} | ||||
| 	stlk                 sync.Mutex | ||||
| 	genesisMsigLk        sync.Mutex | ||||
| 	newVM                func(context.Context, *vm.VMOpts) (*vm.VM, error) | ||||
| 	preIgnitionGenInfos  *genesisInfo | ||||
| 	postIgnitionGenInfos *genesisInfo | ||||
| } | ||||
| 
 | ||||
| func NewStateManager(cs *store.ChainStore) *StateManager { | ||||
| @ -122,9 +123,8 @@ func (sm *StateManager) TipSetState(ctx context.Context, ts *types.TipSet) (st c | ||||
| 	return st, rec, nil | ||||
| } | ||||
| 
 | ||||
| func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (cid.Cid, []*api.InvocResult, error) { | ||||
| 	var trace []*api.InvocResult | ||||
| 	st, _, err := sm.computeTipSetState(ctx, ts, func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error { | ||||
| func traceFunc(trace *[]*api.InvocResult) func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error { | ||||
| 	return func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error { | ||||
| 		ir := &api.InvocResult{ | ||||
| 			Msg:            msg, | ||||
| 			MsgRct:         &ret.MessageReceipt, | ||||
| @ -134,9 +134,14 @@ func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (c | ||||
| 		if ret.ActorErr != nil { | ||||
| 			ir.Error = ret.ActorErr.Error() | ||||
| 		} | ||||
| 		trace = append(trace, ir) | ||||
| 		*trace = append(*trace, ir) | ||||
| 		return nil | ||||
| 	}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (cid.Cid, []*api.InvocResult, error) { | ||||
| 	var trace []*api.InvocResult | ||||
| 	st, _, err := sm.computeTipSetState(ctx, ts, traceFunc(&trace)) | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, nil, err | ||||
| 	} | ||||
| @ -148,20 +153,24 @@ 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, ts *types.TipSet) (cid.Cid, cid.Cid, error) { | ||||
| 
 | ||||
| 	vmopt := &vm.VMOpts{ | ||||
| 		StateBase:      pstate, | ||||
| 		Epoch:          epoch, | ||||
| 		Rand:           r, | ||||
| 		Bstore:         sm.cs.Blockstore(), | ||||
| 		Syscalls:       sm.cs.VMSys(), | ||||
| 		CircSupplyCalc: sm.GetCirculatingSupply, | ||||
| 		NtwkVersion:    sm.GetNtwkVersion, | ||||
| 		BaseFee:        baseFee, | ||||
| 	makeVmWithBaseState := func(base cid.Cid) (*vm.VM, error) { | ||||
| 		vmopt := &vm.VMOpts{ | ||||
| 			StateBase:      base, | ||||
| 			Epoch:          epoch, | ||||
| 			Rand:           r, | ||||
| 			Bstore:         sm.cs.Blockstore(), | ||||
| 			Syscalls:       sm.cs.VMSys(), | ||||
| 			CircSupplyCalc: sm.GetCirculatingSupply, | ||||
| 			NtwkVersion:    sm.GetNtwkVersion, | ||||
| 			BaseFee:        baseFee, | ||||
| 		} | ||||
| 
 | ||||
| 		return sm.newVM(ctx, vmopt) | ||||
| 	} | ||||
| 
 | ||||
| 	vmi, err := sm.newVM(ctx, vmopt) | ||||
| 	vmi, err := makeVmWithBaseState(pstate) | ||||
| 	if err != nil { | ||||
| 		return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err) | ||||
| 		return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	runCron := func() error { | ||||
| @ -201,19 +210,32 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp | ||||
| 	for i := parentEpoch; i < epoch; i++ { | ||||
| 		// handle state forks
 | ||||
| 		// XXX: The state tree
 | ||||
| 		err = sm.handleStateForks(ctx, vmi.StateTree(), i, ts) | ||||
| 		newState, err := sm.handleStateForks(ctx, pstate, i, cb, ts) | ||||
| 		if err != nil { | ||||
| 			return cid.Undef, cid.Undef, xerrors.Errorf("error handling state forks: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		if pstate != newState { | ||||
| 			vmi, err = makeVmWithBaseState(newState) | ||||
| 			if err != nil { | ||||
| 				return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if i > parentEpoch { | ||||
| 			// run cron for null rounds if any
 | ||||
| 			if err := runCron(); err != nil { | ||||
| 				return cid.Cid{}, cid.Cid{}, err | ||||
| 			} | ||||
| 
 | ||||
| 			newState, err = vmi.Flush(ctx) | ||||
| 			if err != nil { | ||||
| 				return cid.Undef, cid.Undef, xerrors.Errorf("flushing vm: %w", err) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		vmi.SetBlockHeight(i + 1) | ||||
| 		pstate = newState | ||||
| 	} | ||||
| 
 | ||||
| 	var receipts []cbg.CBORMarshaler | ||||
| @ -903,7 +925,7 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error { | ||||
| 		gi.genesisMsigs = append(gi.genesisMsigs, ns) | ||||
| 	} | ||||
| 
 | ||||
| 	sm.genInfo = &gi | ||||
| 	sm.preIgnitionGenInfos = &gi | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| @ -911,7 +933,7 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error { | ||||
| // sets up information about the actors in the genesis state
 | ||||
| // For testnet we use a hardcoded set of multisig states, instead of what's actually in the genesis multisigs
 | ||||
| // We also do not consider ANY account actors (including the faucet)
 | ||||
| func (sm *StateManager) setupGenesisActorsTestnet(ctx context.Context) error { | ||||
| func (sm *StateManager) setupPreIgnitionGenesisActorsTestnet(ctx context.Context) error { | ||||
| 
 | ||||
| 	gi := genesisInfo{} | ||||
| 
 | ||||
| @ -980,7 +1002,87 @@ func (sm *StateManager) setupGenesisActorsTestnet(ctx context.Context) error { | ||||
| 		gi.genesisMsigs = append(gi.genesisMsigs, ns) | ||||
| 	} | ||||
| 
 | ||||
| 	sm.genInfo = &gi | ||||
| 	sm.preIgnitionGenInfos = &gi | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // sets up information about the actors in the genesis state, post the ignition fork
 | ||||
| func (sm *StateManager) setupPostIgnitionGenesisActors(ctx context.Context) error { | ||||
| 
 | ||||
| 	gi := genesisInfo{} | ||||
| 
 | ||||
| 	gb, err := sm.cs.GetGenesis() | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting genesis block: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	gts, err := types.NewTipSet([]*types.BlockHeader{gb}) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting genesis tipset: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	st, _, err := sm.TipSetState(ctx, gts) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("getting genesis tipset state: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	cst := cbor.NewCborStore(sm.cs.Blockstore()) | ||||
| 	sTree, err := state.LoadStateTree(cst, st) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("loading state tree: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Unnecessary, should be removed
 | ||||
| 	gi.genesisMarketFunds, err = getFilMarketLocked(ctx, sTree) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("setting up genesis market funds: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Unnecessary, should be removed
 | ||||
| 	gi.genesisPledge, err = getFilPowerLocked(ctx, sTree) | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("setting up genesis pledge: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount) | ||||
| 
 | ||||
| 	// 6 months
 | ||||
| 	sixMonths := abi.ChainEpoch(183 * builtin0.EpochsInDay) | ||||
| 	totalsByEpoch[sixMonths] = big.NewInt(49_929_341) | ||||
| 	totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700)) | ||||
| 
 | ||||
| 	// 1 year
 | ||||
| 	oneYear := abi.ChainEpoch(365 * builtin0.EpochsInDay) | ||||
| 	totalsByEpoch[oneYear] = big.NewInt(22_421_712) | ||||
| 
 | ||||
| 	// 2 years
 | ||||
| 	twoYears := abi.ChainEpoch(2 * 365 * builtin0.EpochsInDay) | ||||
| 	totalsByEpoch[twoYears] = big.NewInt(7_223_364) | ||||
| 
 | ||||
| 	// 3 years
 | ||||
| 	threeYears := abi.ChainEpoch(3 * 365 * builtin0.EpochsInDay) | ||||
| 	totalsByEpoch[threeYears] = big.NewInt(87_637_883) | ||||
| 
 | ||||
| 	// 6 years
 | ||||
| 	sixYears := abi.ChainEpoch(6 * 365 * builtin0.EpochsInDay) | ||||
| 	totalsByEpoch[sixYears] = big.NewInt(100_000_000) | ||||
| 	totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_000_000)) | ||||
| 
 | ||||
| 	gi.genesisMsigs = make([]msig0.State, 0, len(totalsByEpoch)) | ||||
| 	for k, v := range totalsByEpoch { | ||||
| 		ns := msig0.State{ | ||||
| 			// In the pre-ignition logic, we incorrectly set this value in Fil, not attoFil, an off-by-10^18 error
 | ||||
| 			InitialBalance: big.Mul(v, big.NewInt(int64(build.FilecoinPrecision))), | ||||
| 			UnlockDuration: k, | ||||
| 			PendingTxns:    cid.Undef, | ||||
| 			// In the pre-ignition logic, the start epoch was 0. This changes in the fork logic of the Ignition upgrade itself.
 | ||||
| 			StartEpoch: build.UpgradeLiftoffHeight, | ||||
| 		} | ||||
| 		gi.genesisMsigs = append(gi.genesisMsigs, ns) | ||||
| 	} | ||||
| 
 | ||||
| 	sm.postIgnitionGenInfos = &gi | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| @ -990,13 +1092,23 @@ func (sm *StateManager) setupGenesisActorsTestnet(ctx context.Context) error { | ||||
| // - For Accounts, it counts max(currentBalance - genesisBalance, 0).
 | ||||
| func (sm *StateManager) GetFilVested(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) { | ||||
| 	vf := big.Zero() | ||||
| 	for _, v := range sm.genInfo.genesisMsigs { | ||||
| 		au := big.Sub(v.InitialBalance, v.AmountLocked(height)) | ||||
| 		vf = big.Add(vf, au) | ||||
| 	if height <= build.UpgradeIgnitionHeight { | ||||
| 		for _, v := range sm.preIgnitionGenInfos.genesisMsigs { | ||||
| 			au := big.Sub(v.InitialBalance, v.AmountLocked(height)) | ||||
| 			vf = big.Add(vf, au) | ||||
| 		} | ||||
| 	} else { | ||||
| 		for _, v := range sm.postIgnitionGenInfos.genesisMsigs { | ||||
| 			// In the pre-ignition logic, we simply called AmountLocked(height), assuming startEpoch was 0.
 | ||||
| 			// The start epoch changed in the Ignition upgrade.
 | ||||
| 			au := big.Sub(v.InitialBalance, v.AmountLocked(height-v.StartEpoch)) | ||||
| 			vf = big.Add(vf, au) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// there should not be any such accounts in testnet (and also none in mainnet?)
 | ||||
| 	for _, v := range sm.genInfo.genesisActors { | ||||
| 	// continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch
 | ||||
| 	for _, v := range sm.preIgnitionGenInfos.genesisActors { | ||||
| 		act, err := st.GetActor(v.addr) | ||||
| 		if err != nil { | ||||
| 			return big.Zero(), xerrors.Errorf("failed to get actor: %w", err) | ||||
| @ -1008,8 +1120,10 @@ func (sm *StateManager) GetFilVested(ctx context.Context, height abi.ChainEpoch, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	vf = big.Add(vf, sm.genInfo.genesisPledge) | ||||
| 	vf = big.Add(vf, sm.genInfo.genesisMarketFunds) | ||||
| 	// continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch
 | ||||
| 	vf = big.Add(vf, sm.preIgnitionGenInfos.genesisPledge) | ||||
| 	// continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch
 | ||||
| 	vf = big.Add(vf, sm.preIgnitionGenInfos.genesisMarketFunds) | ||||
| 
 | ||||
| 	return vf, nil | ||||
| } | ||||
| @ -1083,10 +1197,16 @@ func GetFilBurnt(ctx context.Context, st *state.StateTree) (abi.TokenAmount, err | ||||
| func (sm *StateManager) GetCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (api.CirculatingSupply, error) { | ||||
| 	sm.genesisMsigLk.Lock() | ||||
| 	defer sm.genesisMsigLk.Unlock() | ||||
| 	if sm.genInfo == nil { | ||||
| 		err := sm.setupGenesisActorsTestnet(ctx) | ||||
| 	if sm.preIgnitionGenInfos == nil { | ||||
| 		err := sm.setupPreIgnitionGenesisActorsTestnet(ctx) | ||||
| 		if err != nil { | ||||
| 			return api.CirculatingSupply{}, xerrors.Errorf("failed to setup genesis information: %w", err) | ||||
| 			return api.CirculatingSupply{}, xerrors.Errorf("failed to setup pre-ignition genesis information: %w", err) | ||||
| 		} | ||||
| 	} | ||||
| 	if sm.postIgnitionGenInfos == nil { | ||||
| 		err := sm.setupPostIgnitionGenesisActors(ctx) | ||||
| 		if err != nil { | ||||
| 			return api.CirculatingSupply{}, xerrors.Errorf("failed to setup post-ignition genesis information: %w", err) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| @ -1151,6 +1271,10 @@ func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoc | ||||
| 		return network.Version1 | ||||
| 	} | ||||
| 
 | ||||
| 	if height <= build.UpgradeIgnitionHeight { | ||||
| 		return network.Version2 | ||||
| 	} | ||||
| 
 | ||||
| 	return build.NewestNetworkVersion | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -95,6 +95,7 @@ func GetPowerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr addres | ||||
| 	} | ||||
| 
 | ||||
| 	var mpow power.Claim | ||||
| 	var minpow bool | ||||
| 	if maddr != address.Undef { | ||||
| 		var found bool | ||||
| 		mpow, found, err = pas.MinerPower(maddr) | ||||
| @ -102,11 +103,11 @@ func GetPowerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr addres | ||||
| 			// TODO: return an error when not found?
 | ||||
| 			return power.Claim{}, power.Claim{}, false, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	minpow, err := pas.MinerNominalPowerMeetsConsensusMinimum(maddr) | ||||
| 	if err != nil { | ||||
| 		return power.Claim{}, power.Claim{}, false, err | ||||
| 		minpow, err = pas.MinerNominalPowerMeetsConsensusMinimum(maddr) | ||||
| 		if err != nil { | ||||
| 			return power.Claim{}, power.Claim{}, false, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return mpow, tpow, minpow, nil | ||||
| @ -361,6 +362,16 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch, | ||||
| 		return cid.Undef, nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	for i := ts.Height(); i < height; i++ { | ||||
| 		// handle state forks
 | ||||
| 		base, err = sm.handleStateForks(ctx, base, i, traceFunc(&trace), ts) | ||||
| 		if err != nil { | ||||
| 			return cid.Undef, nil, xerrors.Errorf("error handling state forks: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		// TODO: should we also run cron here?
 | ||||
| 	} | ||||
| 
 | ||||
| 	r := store.NewChainRand(sm.cs, ts.Cids()) | ||||
| 	vmopt := &vm.VMOpts{ | ||||
| 		StateBase:      base, | ||||
| @ -377,16 +388,6 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch, | ||||
| 		return cid.Undef, nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	for i := ts.Height(); i < height; i++ { | ||||
| 		// handle state forks
 | ||||
| 		err = sm.handleStateForks(ctx, vmi.StateTree(), i, ts) | ||||
| 		if err != nil { | ||||
| 			return cid.Undef, nil, xerrors.Errorf("error handling state forks: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		// TODO: should we also run cron here?
 | ||||
| 	} | ||||
| 
 | ||||
| 	for i, msg := range msgs { | ||||
| 		// TODO: Use the signed message length for secp messages
 | ||||
| 		ret, err := vmi.ApplyMessage(ctx, msg) | ||||
|  | ||||
| @ -10,14 +10,18 @@ import ( | ||||
| 	"strconv" | ||||
| 	"sync" | ||||
| 
 | ||||
| 	"golang.org/x/sync/errgroup" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/go-state-types/crypto" | ||||
| 	"github.com/minio/blake2b-simd" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/go-address" | ||||
| 	"github.com/filecoin-project/go-state-types/abi" | ||||
| 	"github.com/filecoin-project/specs-actors/actors/builtin" | ||||
| 	"github.com/filecoin-project/specs-actors/actors/util/adt" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/lotus/api" | ||||
| 	"github.com/filecoin-project/lotus/build" | ||||
| 	"github.com/filecoin-project/lotus/chain/vm" | ||||
| 	"github.com/filecoin-project/lotus/journal" | ||||
| 	bstore "github.com/filecoin-project/lotus/lib/blockstore" | ||||
| @ -465,14 +469,25 @@ func (cs *ChainStore) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) { | ||||
| 		return v.(*types.TipSet), nil | ||||
| 	} | ||||
| 
 | ||||
| 	var blks []*types.BlockHeader | ||||
| 	for _, c := range tsk.Cids() { | ||||
| 		b, err := cs.GetBlock(c) | ||||
| 		if err != nil { | ||||
| 			return nil, xerrors.Errorf("get block %s: %w", c, err) | ||||
| 		} | ||||
| 	// Fetch tipset block headers from blockstore in parallel
 | ||||
| 	var eg errgroup.Group | ||||
| 	cids := tsk.Cids() | ||||
| 	blks := make([]*types.BlockHeader, len(cids)) | ||||
| 	for i, c := range cids { | ||||
| 		i, c := i, c | ||||
| 		eg.Go(func() error { | ||||
| 			b, err := cs.GetBlock(c) | ||||
| 			if err != nil { | ||||
| 				return xerrors.Errorf("get block %s: %w", c, err) | ||||
| 			} | ||||
| 
 | ||||
| 		blks = append(blks, b) | ||||
| 			blks[i] = b | ||||
| 			return nil | ||||
| 		}) | ||||
| 	} | ||||
| 	err := eg.Wait() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	ts, err := types.NewTipSet(blks) | ||||
| @ -1183,6 +1198,7 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo | ||||
| 	} | ||||
| 
 | ||||
| 	blocksToWalk := ts.Cids() | ||||
| 	currentMinHeight := ts.Height() | ||||
| 
 | ||||
| 	walkChain := func(blk cid.Cid) error { | ||||
| 		if !seen.Visit(blk) { | ||||
| @ -1203,6 +1219,13 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo | ||||
| 			return xerrors.Errorf("unmarshaling block header (cid=%s): %w", blk, err) | ||||
| 		} | ||||
| 
 | ||||
| 		if currentMinHeight > b.Height { | ||||
| 			currentMinHeight = b.Height | ||||
| 			if currentMinHeight%builtin.EpochsInDay == 0 { | ||||
| 				log.Infow("export", "height", currentMinHeight) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		var cids []cid.Cid | ||||
| 		if !skipOldMsgs || b.Height > ts.Height()-inclRecentRoots { | ||||
| 			mcids, err := recurseLinks(cs.bs, walked, b.Messages, []cid.Cid{b.Messages}) | ||||
| @ -1251,6 +1274,9 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	log.Infow("export started") | ||||
| 	exportStart := build.Clock.Now() | ||||
| 
 | ||||
| 	for len(blocksToWalk) > 0 { | ||||
| 		next := blocksToWalk[0] | ||||
| 		blocksToWalk = blocksToWalk[1:] | ||||
| @ -1259,6 +1285,8 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	log.Infow("export finished", "duration", build.Clock.Now().Sub(exportStart).Seconds()) | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -167,12 +167,16 @@ func (ts *TipSet) Equals(ots *TipSet) bool { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	if len(ts.blks) != len(ots.blks) { | ||||
| 	if ts.height != ots.height { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	for i, b := range ts.blks { | ||||
| 		if b.Cid() != ots.blks[i].Cid() { | ||||
| 	if len(ts.cids) != len(ots.cids) { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	for i, cid := range ts.cids { | ||||
| 		if cid != ots.cids[i] { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -1,9 +1,12 @@ | ||||
| package chain | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/rand" | ||||
| 	"encoding/json" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/lotus/build" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/go-address" | ||||
| 	"github.com/filecoin-project/lotus/chain/types" | ||||
| ) | ||||
| @ -35,3 +38,40 @@ func TestSignedMessageJsonRoundtrip(t *testing.T) { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestAddressType(t *testing.T) { | ||||
| 	build.SetAddressNetwork(address.Testnet) | ||||
| 	addr, err := makeRandomAddress() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	if string(addr[0]) != address.TestnetPrefix { | ||||
| 		t.Fatalf("address should start with %s", address.TestnetPrefix) | ||||
| 	} | ||||
| 
 | ||||
| 	build.SetAddressNetwork(address.Mainnet) | ||||
| 	addr, err = makeRandomAddress() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	if string(addr[0]) != address.MainnetPrefix { | ||||
| 		t.Fatalf("address should start with %s", address.MainnetPrefix) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func makeRandomAddress() (string, error) { | ||||
| 	bytes := make([]byte, 32) | ||||
| 	_, err := rand.Read(bytes) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 
 | ||||
| 	addr, err := address.NewActorAddress(bytes) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 
 | ||||
| 	return addr.String(), nil | ||||
| } | ||||
|  | ||||
							
								
								
									
										37
									
								
								cli/state.go
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								cli/state.go
									
									
									
									
									
								
							| @ -17,6 +17,7 @@ import ( | ||||
| 	"github.com/multiformats/go-multiaddr" | ||||
| 
 | ||||
| 	"github.com/ipfs/go-cid" | ||||
| 	cbor "github.com/ipfs/go-ipld-cbor" | ||||
| 	"github.com/libp2p/go-libp2p-core/peer" | ||||
| 	"github.com/multiformats/go-multihash" | ||||
| 	"github.com/urfave/cli/v2" | ||||
| @ -30,7 +31,9 @@ import ( | ||||
| 	"github.com/filecoin-project/specs-actors/actors/builtin" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/lotus/api" | ||||
| 	"github.com/filecoin-project/lotus/api/apibstore" | ||||
| 	"github.com/filecoin-project/lotus/build" | ||||
| 	"github.com/filecoin-project/lotus/chain/state" | ||||
| 	"github.com/filecoin-project/lotus/chain/stmgr" | ||||
| 	"github.com/filecoin-project/lotus/chain/types" | ||||
| ) | ||||
| @ -815,6 +818,10 @@ var stateComputeStateCmd = &cli.Command{ | ||||
| 			Name:  "html", | ||||
| 			Usage: "generate html report", | ||||
| 		}, | ||||
| 		&cli.BoolFlag{ | ||||
| 			Name:  "json", | ||||
| 			Usage: "generate json output", | ||||
| 		}, | ||||
| 	}, | ||||
| 	Action: func(cctx *cli.Context) error { | ||||
| 		api, closer, err := GetFullNodeAPI(cctx) | ||||
| @ -831,14 +838,14 @@ var stateComputeStateCmd = &cli.Command{ | ||||
| 		} | ||||
| 
 | ||||
| 		h := abi.ChainEpoch(cctx.Uint64("vm-height")) | ||||
| 		if h == 0 { | ||||
| 			if ts == nil { | ||||
| 				head, err := api.ChainHead(ctx) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				ts = head | ||||
| 		if ts == nil { | ||||
| 			head, err := api.ChainHead(ctx) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			ts = head | ||||
| 		} | ||||
| 		if h == 0 { | ||||
| 			h = ts.Height() | ||||
| 		} | ||||
| 
 | ||||
| @ -859,14 +866,28 @@ var stateComputeStateCmd = &cli.Command{ | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		if cctx.Bool("json") { | ||||
| 			out, err := json.Marshal(stout) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			fmt.Println(string(out)) | ||||
| 			return nil | ||||
| 		} | ||||
| 
 | ||||
| 		if cctx.Bool("html") { | ||||
| 			st, err := state.LoadStateTree(cbor.NewCborStore(apibstore.NewAPIBlockstore(api)), stout.Root) | ||||
| 			if err != nil { | ||||
| 				return xerrors.Errorf("loading state tree: %w", err) | ||||
| 			} | ||||
| 
 | ||||
| 			codeCache := map[address.Address]cid.Cid{} | ||||
| 			getCode := func(addr address.Address) (cid.Cid, error) { | ||||
| 				if c, found := codeCache[addr]; found { | ||||
| 					return c, nil | ||||
| 				} | ||||
| 
 | ||||
| 				c, err := api.StateGetActor(ctx, addr, ts.Key()) | ||||
| 				c, err := st.GetActor(addr) | ||||
| 				if err != nil { | ||||
| 					return cid.Cid{}, err | ||||
| 				} | ||||
|  | ||||
| @ -76,8 +76,6 @@ func main() { | ||||
| 
 | ||||
| 	log.Info("Starting lotus-bench") | ||||
| 
 | ||||
| 	policy.AddSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1) | ||||
| 
 | ||||
| 	app := &cli.App{ | ||||
| 		Name:    "lotus-bench", | ||||
| 		Usage:   "Benchmark performance of lotus on your hardware", | ||||
| @ -147,6 +145,8 @@ var sealBenchCmd = &cli.Command{ | ||||
| 		}, | ||||
| 	}, | ||||
| 	Action: func(c *cli.Context) error { | ||||
| 		policy.AddSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1) | ||||
| 
 | ||||
| 		if c.Bool("no-gpu") { | ||||
| 			err := os.Setenv("BELLMAN_NO_GPU", "1") | ||||
| 			if err != nil { | ||||
|  | ||||
| @ -3,9 +3,16 @@ package main | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| 
 | ||||
| 	"github.com/docker/go-units" | ||||
| 	lotusbuiltin "github.com/filecoin-project/lotus/chain/actors/builtin" | ||||
| 	"github.com/filecoin-project/lotus/chain/actors/builtin/power" | ||||
| 	"github.com/filecoin-project/lotus/chain/actors/builtin/reward" | ||||
| 
 | ||||
| 	"github.com/ipfs/go-cid" | ||||
| 	cbor "github.com/ipfs/go-ipld-cbor" | ||||
| 	logging "github.com/ipfs/go-log/v2" | ||||
| 	"github.com/urfave/cli/v2" | ||||
| 	"golang.org/x/xerrors" | ||||
| 
 | ||||
| @ -44,6 +51,7 @@ var auditsCmd = &cli.Command{ | ||||
| 	Subcommands: []*cli.Command{ | ||||
| 		chainBalanceCmd, | ||||
| 		chainBalanceStateCmd, | ||||
| 		chainPledgeCmd, | ||||
| 	}, | ||||
| } | ||||
| 
 | ||||
| @ -248,3 +256,133 @@ var chainBalanceStateCmd = &cli.Command{ | ||||
| 		return nil | ||||
| 	}, | ||||
| } | ||||
| 
 | ||||
| var chainPledgeCmd = &cli.Command{ | ||||
| 	Name:        "stateroot-pledge", | ||||
| 	Description: "Calculate sector pledge numbers", | ||||
| 	Flags: []cli.Flag{ | ||||
| 		&cli.StringFlag{ | ||||
| 			Name:  "repo", | ||||
| 			Value: "~/.lotus", | ||||
| 		}, | ||||
| 	}, | ||||
| 	ArgsUsage: "[stateroot epoch]", | ||||
| 	Action: func(cctx *cli.Context) error { | ||||
| 		logging.SetLogLevel("badger", "ERROR") | ||||
| 		ctx := context.TODO() | ||||
| 
 | ||||
| 		if !cctx.Args().Present() { | ||||
| 			return fmt.Errorf("must pass state root") | ||||
| 		} | ||||
| 
 | ||||
| 		sroot, err := cid.Decode(cctx.Args().First()) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("failed to parse input: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		epoch, err := strconv.ParseInt(cctx.Args().Get(1), 10, 64) | ||||
| 		if err != nil { | ||||
| 			return xerrors.Errorf("parsing epoch arg: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		fsrepo, err := repo.NewFS(cctx.String("repo")) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		lkrepo, err := fsrepo.Lock(repo.FullNode) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		defer lkrepo.Close() //nolint:errcheck
 | ||||
| 
 | ||||
| 		ds, err := lkrepo.Datastore("/chain") | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		mds, err := lkrepo.Datastore("/metadata") | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		bs := blockstore.NewBlockstore(ds) | ||||
| 
 | ||||
| 		cs := store.NewChainStore(bs, mds, vm.Syscalls(ffiwrapper.ProofVerifier)) | ||||
| 
 | ||||
| 		cst := cbor.NewCborStore(bs) | ||||
| 		store := adt.WrapStore(ctx, cst) | ||||
| 
 | ||||
| 		sm := stmgr.NewStateManager(cs) | ||||
| 
 | ||||
| 		state, err := state.LoadStateTree(cst, sroot) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		var ( | ||||
| 			powerSmoothed    lotusbuiltin.FilterEstimate | ||||
| 			pledgeCollateral abi.TokenAmount | ||||
| 		) | ||||
| 		if act, err := state.GetActor(power.Address); err != nil { | ||||
| 			return xerrors.Errorf("loading miner actor: %w", err) | ||||
| 		} else if s, err := power.Load(store, act); err != nil { | ||||
| 			return xerrors.Errorf("loading power actor state: %w", err) | ||||
| 		} else if p, err := s.TotalPowerSmoothed(); err != nil { | ||||
| 			return xerrors.Errorf("failed to determine total power: %w", err) | ||||
| 		} else if c, err := s.TotalLocked(); err != nil { | ||||
| 			return xerrors.Errorf("failed to determine pledge collateral: %w", err) | ||||
| 		} else { | ||||
| 			powerSmoothed = p | ||||
| 			pledgeCollateral = c | ||||
| 		} | ||||
| 
 | ||||
| 		circ, err := sm.GetCirculatingSupplyDetailed(ctx, abi.ChainEpoch(epoch), state) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		fmt.Println("(real) circulating supply: ", types.FIL(circ.FilCirculating)) | ||||
| 		if circ.FilCirculating.LessThan(big.Zero()) { | ||||
| 			circ.FilCirculating = big.Zero() | ||||
| 		} | ||||
| 
 | ||||
| 		rewardActor, err := state.GetActor(reward.Address) | ||||
| 		if err != nil { | ||||
| 			return xerrors.Errorf("loading miner actor: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		rewardState, err := reward.Load(store, rewardActor) | ||||
| 		if err != nil { | ||||
| 			return xerrors.Errorf("loading reward actor state: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		fmt.Println("FilVested", types.FIL(circ.FilVested)) | ||||
| 		fmt.Println("FilMined", types.FIL(circ.FilMined)) | ||||
| 		fmt.Println("FilBurnt", types.FIL(circ.FilBurnt)) | ||||
| 		fmt.Println("FilLocked", types.FIL(circ.FilLocked)) | ||||
| 		fmt.Println("FilCirculating", types.FIL(circ.FilCirculating)) | ||||
| 
 | ||||
| 		for _, sectorWeight := range []abi.StoragePower{ | ||||
| 			types.NewInt(32 << 30), | ||||
| 			types.NewInt(64 << 30), | ||||
| 			types.NewInt(32 << 30 * 10), | ||||
| 			types.NewInt(64 << 30 * 10), | ||||
| 		} { | ||||
| 			initialPledge, err := rewardState.InitialPledgeForPower( | ||||
| 				sectorWeight, | ||||
| 				pledgeCollateral, | ||||
| 				&powerSmoothed, | ||||
| 				circ.FilCirculating, | ||||
| 			) | ||||
| 			if err != nil { | ||||
| 				return xerrors.Errorf("calculating initial pledge: %w", err) | ||||
| 			} | ||||
| 
 | ||||
| 			fmt.Println("IP ", units.HumanSize(float64(sectorWeight.Uint64())), types.FIL(initialPledge)) | ||||
| 		} | ||||
| 
 | ||||
| 		return nil | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| @ -3,11 +3,14 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"context" | ||||
| 	"encoding/hex" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"runtime/pprof" | ||||
| 	"strings" | ||||
| @ -23,6 +26,7 @@ import ( | ||||
| 	"go.opencensus.io/stats/view" | ||||
| 	"go.opencensus.io/tag" | ||||
| 	"golang.org/x/xerrors" | ||||
| 	"gopkg.in/cheggaaa/pb.v1" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/lotus/api" | ||||
| 	"github.com/filecoin-project/lotus/build" | ||||
| @ -100,11 +104,11 @@ var DaemonCmd = &cli.Command{ | ||||
| 		}, | ||||
| 		&cli.StringFlag{ | ||||
| 			Name:  "import-chain", | ||||
| 			Usage: "on first run, load chain from given file and validate", | ||||
| 			Usage: "on first run, load chain from given file or url and validate", | ||||
| 		}, | ||||
| 		&cli.StringFlag{ | ||||
| 			Name:  "import-snapshot", | ||||
| 			Usage: "import chain state from a given chain export file", | ||||
| 			Usage: "import chain state from a given chain export file or url", | ||||
| 		}, | ||||
| 		&cli.BoolFlag{ | ||||
| 			Name:  "halt-after-import", | ||||
| @ -206,11 +210,6 @@ var DaemonCmd = &cli.Command{ | ||||
| 				issnapshot = true | ||||
| 			} | ||||
| 
 | ||||
| 			chainfile, err := homedir.Expand(chainfile) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			if err := ImportChain(r, chainfile, issnapshot); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| @ -326,12 +325,42 @@ func importKey(ctx context.Context, api api.FullNode, f string) error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func ImportChain(r repo.Repo, fname string, snapshot bool) error { | ||||
| 	fi, err := os.Open(fname) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| func ImportChain(r repo.Repo, fname string, snapshot bool) (err error) { | ||||
| 	var rd io.Reader | ||||
| 	var l int64 | ||||
| 	if strings.HasPrefix(fname, "http://") || strings.HasPrefix(fname, "https://") { | ||||
| 		resp, err := http.Get(fname) //nolint:gosec
 | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		defer resp.Body.Close() //nolint:errcheck
 | ||||
| 
 | ||||
| 		if resp.StatusCode != http.StatusOK { | ||||
| 			return xerrors.Errorf("non-200 response: %d", resp.StatusCode) | ||||
| 		} | ||||
| 
 | ||||
| 		rd = resp.Body | ||||
| 		l = resp.ContentLength | ||||
| 	} else { | ||||
| 		fname, err = homedir.Expand(fname) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		fi, err := os.Open(fname) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		defer fi.Close() //nolint:errcheck
 | ||||
| 
 | ||||
| 		st, err := os.Stat(fname) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		rd = fi | ||||
| 		l = st.Size() | ||||
| 	} | ||||
| 	defer fi.Close() //nolint:errcheck
 | ||||
| 
 | ||||
| 	lr, err := r.Lock(repo.FullNode) | ||||
| 	if err != nil { | ||||
| @ -353,8 +382,21 @@ func ImportChain(r repo.Repo, fname string, snapshot bool) error { | ||||
| 
 | ||||
| 	cst := store.NewChainStore(bs, mds, vm.Syscalls(ffiwrapper.ProofVerifier)) | ||||
| 
 | ||||
| 	log.Info("importing chain from file...") | ||||
| 	ts, err := cst.Import(fi) | ||||
| 	log.Infof("importing chain from %s...", fname) | ||||
| 
 | ||||
| 	bufr := bufio.NewReaderSize(rd, 1<<20) | ||||
| 
 | ||||
| 	bar := pb.New64(l) | ||||
| 	br := bar.NewProxyReader(bufr) | ||||
| 	bar.ShowTimeLeft = true | ||||
| 	bar.ShowPercent = true | ||||
| 	bar.ShowSpeed = true | ||||
| 	bar.Units = pb.U_BYTES | ||||
| 
 | ||||
| 	bar.Start() | ||||
| 	ts, err := cst.Import(br) | ||||
| 	bar.Finish() | ||||
| 
 | ||||
| 	if err != nil { | ||||
| 		return xerrors.Errorf("importing chain failed: %w", err) | ||||
| 	} | ||||
|  | ||||
| @ -3825,7 +3825,7 @@ Inputs: | ||||
| ] | ||||
| ``` | ||||
| 
 | ||||
| Response: `2` | ||||
| Response: `3` | ||||
| 
 | ||||
| ### StateReadState | ||||
| StateReadState returns the indicated actor's state. | ||||
|  | ||||
							
								
								
									
										9
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								go.mod
									
									
									
									
									
								
							| @ -21,13 +21,13 @@ require ( | ||||
| 	github.com/elastic/go-sysinfo v1.3.0 | ||||
| 	github.com/fatih/color v1.8.0 | ||||
| 	github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200716204036-cddc56607e1d | ||||
| 	github.com/filecoin-project/go-address v0.0.3 | ||||
| 	github.com/filecoin-project/go-address v0.0.4 | ||||
| 	github.com/filecoin-project/go-bitfield v0.2.0 | ||||
| 	github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 | ||||
| 	github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 | ||||
| 	github.com/filecoin-project/go-data-transfer v0.6.5 | ||||
| 	github.com/filecoin-project/go-data-transfer v0.6.6 | ||||
| 	github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f | ||||
| 	github.com/filecoin-project/go-fil-markets v0.6.2 | ||||
| 	github.com/filecoin-project/go-fil-markets v0.6.3 | ||||
| 	github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52 | ||||
| 	github.com/filecoin-project/go-multistore v0.0.3 | ||||
| 	github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 | ||||
| @ -61,7 +61,7 @@ require ( | ||||
| 	github.com/ipfs/go-ds-measure v0.1.0 | ||||
| 	github.com/ipfs/go-filestore v1.0.0 | ||||
| 	github.com/ipfs/go-fs-lock v0.0.6 | ||||
| 	github.com/ipfs/go-graphsync v0.2.0 | ||||
| 	github.com/ipfs/go-graphsync v0.2.1 | ||||
| 	github.com/ipfs/go-ipfs-blockstore v1.0.1 | ||||
| 	github.com/ipfs/go-ipfs-chunker v0.0.5 | ||||
| 	github.com/ipfs/go-ipfs-ds-help v1.0.0 | ||||
| @ -126,6 +126,7 @@ require ( | ||||
| 	golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 | ||||
| 	golang.org/x/time v0.0.0-20191024005414-555d28b269f0 | ||||
| 	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 | ||||
| 	gopkg.in/cheggaaa/pb.v1 v1.0.28 | ||||
| 	gotest.tools v2.2.0+incompatible | ||||
| 	launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect | ||||
| ) | ||||
|  | ||||
							
								
								
									
										14
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								go.sum
									
									
									
									
									
								
							| @ -214,6 +214,8 @@ github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGj | ||||
| github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= | ||||
| 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-address v0.0.4 h1:gSNMv0qWwH16fGQs7ycOUrDjY6YCSsgLUl0I0KLjo8w= | ||||
| github.com/filecoin-project/go-address v0.0.4/go.mod h1:jr8JxKsYx+lQlQZmF5i2U0Z+cGQ59wMIps/8YW/lDj8= | ||||
| github.com/filecoin-project/go-amt-ipld/v2 v2.1.0 h1:t6qDiuGYYngDqaLc2ZUvdtAg4UNxPeOYaXhBWSNsVaM= | ||||
| github.com/filecoin-project/go-amt-ipld/v2 v2.1.0/go.mod h1:nfFPoGyX0CU9SkXX8EoCcSuHN1XcbN0c6KBh7yvP5fs= | ||||
| github.com/filecoin-project/go-bitfield v0.2.0 h1:gCtLcjskIPtdg4NfN7gQZSQF9yrBQ7mkT0qCJxzGI2Q= | ||||
| @ -222,12 +224,12 @@ github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:a | ||||
| 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.5 h1:oP20la8Z0CLrw0uqvt6xVgw6rOevZeGJ9GNQeC0OCSU= | ||||
| github.com/filecoin-project/go-data-transfer v0.6.5/go.mod h1:I9Ylb/UiZyqnI41wUoCXq/le0nDLhlwpFQCtNPxEPOA= | ||||
| github.com/filecoin-project/go-data-transfer v0.6.6 h1:2TccLSxPYJENcYRdov2WvpTvQ1qUMrPkWe8sBrfj36g= | ||||
| github.com/filecoin-project/go-data-transfer v0.6.6/go.mod h1:C++k1U6+jMQODOaen5OPDo9XQbth9Yq3ie94vNjBJbk= | ||||
| 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.6.2 h1:9Z57KeaQSa1liCmT1pH6SIjrn9mGTDFJXmR2WQVuaiY= | ||||
| github.com/filecoin-project/go-fil-markets v0.6.2/go.mod h1:wtN4Hc/1hoVCpWhSWYxwUxH3PQtjSkWWuC1nQjiIWog= | ||||
| github.com/filecoin-project/go-fil-markets v0.6.3 h1:3kTxfquGvk3zQY+hJH1kEA28tRQ47phqSRqOI4+YcQM= | ||||
| github.com/filecoin-project/go-fil-markets v0.6.3/go.mod h1:Ug1yhGhzTYC6qrpKsR2QpU8QRCeBpwkTA9RICVKuOMM= | ||||
| github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= | ||||
| 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= | ||||
| @ -509,8 +511,8 @@ github.com/ipfs/go-filestore v1.0.0/go.mod h1:/XOCuNtIe2f1YPbiXdYvD0BKLA0JR1MgPi | ||||
| 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.2.0 h1:x94MvHLNuRwBlZzVal7tR1RYK7T7H6bqQLPopxDbIF0= | ||||
| github.com/ipfs/go-graphsync v0.2.0/go.mod h1:gEBvJUNelzMkaRPJTpg/jaKN4AQW/7wDWu0K92D8o10= | ||||
| github.com/ipfs/go-graphsync v0.2.1 h1:MdehhqBSuTI2LARfKLkpYnt0mUrqHs/mtuDnESXHBfU= | ||||
| github.com/ipfs/go-graphsync v0.2.1/go.mod h1:gEBvJUNelzMkaRPJTpg/jaKN4AQW/7wDWu0K92D8o10= | ||||
| 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= | ||||
| github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= | ||||
|  | ||||
| @ -211,6 +211,8 @@ minerLoop: | ||||
| 			base = prebase | ||||
| 		} | ||||
| 
 | ||||
| 		base.NullRounds += injectNulls // testing
 | ||||
| 
 | ||||
| 		if base.TipSet.Equals(lastBase.TipSet) && lastBase.NullRounds == base.NullRounds { | ||||
| 			log.Warnf("BestMiningCandidate from the previous round: %s (nulls:%d)", lastBase.TipSet.Cids(), lastBase.NullRounds) | ||||
| 			if !m.niceSleep(time.Duration(build.BlockDelaySecs) * time.Second) { | ||||
| @ -219,8 +221,6 @@ minerLoop: | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		base.NullRounds += injectNulls // testing
 | ||||
| 
 | ||||
| 		b, err := m.mineOne(ctx, base) | ||||
| 		if err != nil { | ||||
| 			log.Errorf("mining block failed: %+v", err) | ||||
|  | ||||
| @ -18,6 +18,7 @@ import ( | ||||
| 
 | ||||
| 	"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/lotus/build" | ||||
| 	"github.com/filecoin-project/lotus/chain" | ||||
| 	"github.com/filecoin-project/lotus/chain/beacon" | ||||
| 	"github.com/filecoin-project/lotus/chain/exchange" | ||||
| @ -157,6 +158,10 @@ func SetGenesis(cs *store.ChainStore, g Genesis) (dtypes.AfterGenesisSet, error) | ||||
| } | ||||
| 
 | ||||
| func NetworkName(mctx helpers.MetricsCtx, lc fx.Lifecycle, cs *store.ChainStore, _ dtypes.AfterGenesisSet) (dtypes.NetworkName, error) { | ||||
| 	if !build.Devnet { | ||||
| 		return "testnetnet", nil | ||||
| 	} | ||||
| 
 | ||||
| 	ctx := helpers.LifecycleCtx(mctx, lc) | ||||
| 
 | ||||
| 	netName, err := stmgr.GetNetworkName(ctx, stmgr.NewStateManager(cs), cs.GetHeaviestTipSet().ParentState()) | ||||
|  | ||||
| @ -109,6 +109,9 @@ func MinerID(ma dtypes.MinerAddress) (dtypes.MinerID, error) { | ||||
| } | ||||
| 
 | ||||
| func StorageNetworkName(ctx helpers.MetricsCtx, a lapi.FullNode) (dtypes.NetworkName, error) { | ||||
| 	if !build.Devnet { | ||||
| 		return "testnetnet", nil | ||||
| 	} | ||||
| 	return a.StateNetworkName(ctx) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -371,6 +371,10 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty | ||||
| 			return j | ||||
| 		}) | ||||
| 
 | ||||
| 		if ts.Height() > build.UpgradeIgnitionHeight { | ||||
| 			return // FORK: declaring faults after ignition upgrade makes no sense
 | ||||
| 		} | ||||
| 
 | ||||
| 		if faults, sigmsg, err = s.checkNextFaults(context.TODO(), declDeadline, partitions); err != nil { | ||||
| 			// TODO: This is also potentially really bad, but we try to post anyways
 | ||||
| 			log.Errorf("checking sector faults: %v", err) | ||||
|  | ||||
| @ -10,6 +10,7 @@ import ( | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/go-address" | ||||
| 	"github.com/filecoin-project/lotus/api" | ||||
| 	"github.com/filecoin-project/lotus/build" | ||||
| 	"github.com/filecoin-project/lotus/chain/actors/builtin/reward" | ||||
| @ -252,6 +253,14 @@ func RecordTipsetStatePoints(ctx context.Context, api api.FullNode, pl *PointLis | ||||
| 	p := NewPoint("network.balance", netBalFilFloat) | ||||
| 	pl.AddPoint(p) | ||||
| 
 | ||||
| 	totalPower, err := api.StateMinerPower(ctx, address.Address{}, tipset.Key()) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	p = NewPoint("chain.power", totalPower.TotalPower.QualityAdjPower.Int64()) | ||||
| 	pl.AddPoint(p) | ||||
| 
 | ||||
| 	miners, err := api.StateListMiners(ctx, tipset.Key()) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user