Merge branch 'feat/nv21' into feat/implement-SyntheticPoRep
This commit is contained in:
@@ -19,7 +19,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
|
||||
{{if (le .v 7)}}
|
||||
|
||||
Generated
+1
-1
@@ -11,13 +11,13 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -17,11 +17,11 @@ import (
|
||||
market10 "github.com/filecoin-project/go-state-types/builtin/v10/market"
|
||||
adt10 "github.com/filecoin-project/go-state-types/builtin/v10/util/adt"
|
||||
markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -17,11 +17,11 @@ import (
|
||||
market11 "github.com/filecoin-project/go-state-types/builtin/v11/market"
|
||||
adt11 "github.com/filecoin-project/go-state-types/builtin/v11/util/adt"
|
||||
markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -17,11 +17,11 @@ import (
|
||||
market12 "github.com/filecoin-project/go-state-types/builtin/v12/market"
|
||||
adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt"
|
||||
markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -11,13 +11,13 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
|
||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -11,13 +11,13 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
market3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/market"
|
||||
adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -11,13 +11,13 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
market4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/market"
|
||||
adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -11,13 +11,13 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
market5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/market"
|
||||
adt5 "github.com/filecoin-project/specs-actors/v5/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -13,13 +13,13 @@ import (
|
||||
rlepluslazy "github.com/filecoin-project/go-bitfield/rle"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
market6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/market"
|
||||
adt6 "github.com/filecoin-project/specs-actors/v6/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -13,13 +13,13 @@ import (
|
||||
rlepluslazy "github.com/filecoin-project/go-bitfield/rle"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
market7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/market"
|
||||
adt7 "github.com/filecoin-project/specs-actors/v7/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -16,11 +16,11 @@ import (
|
||||
market8 "github.com/filecoin-project/go-state-types/builtin/v8/market"
|
||||
adt8 "github.com/filecoin-project/go-state-types/builtin/v8/util/adt"
|
||||
markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -17,11 +17,11 @@ import (
|
||||
market9 "github.com/filecoin-project/go-state-types/builtin/v9/market"
|
||||
markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market"
|
||||
adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt"
|
||||
verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
|
||||
@@ -230,8 +230,37 @@ type PendingBeneficiaryChange = minertypes.PendingBeneficiaryChange
|
||||
type WorkerKeyChange = minertypes.WorkerKeyChange
|
||||
type SectorPreCommitOnChainInfo = minertypes.SectorPreCommitOnChainInfo
|
||||
type SectorPreCommitInfo = minertypes.SectorPreCommitInfo
|
||||
type SubmitWindowedPoStParams = minertypes.SubmitWindowedPoStParams
|
||||
type PoStPartition = minertypes.PoStPartition
|
||||
type RecoveryDeclaration = minertypes.RecoveryDeclaration
|
||||
type FaultDeclaration = minertypes.FaultDeclaration
|
||||
type DeclareFaultsRecoveredParams = minertypes.DeclareFaultsRecoveredParams
|
||||
type DeclareFaultsParams = minertypes.DeclareFaultsParams
|
||||
type ProveCommitAggregateParams = minertypes.ProveCommitAggregateParams
|
||||
type ProveCommitSectorParams = minertypes.ProveCommitSectorParams
|
||||
type ProveReplicaUpdatesParams = minertypes.ProveReplicaUpdatesParams
|
||||
type ReplicaUpdate = minertypes.ReplicaUpdate
|
||||
type PreCommitSectorBatchParams = minertypes.PreCommitSectorBatchParams
|
||||
type PreCommitSectorBatchParams2 = minertypes.PreCommitSectorBatchParams2
|
||||
type ExtendSectorExpiration2Params = minertypes.ExtendSectorExpiration2Params
|
||||
type SectorClaim = minertypes.SectorClaim
|
||||
type ExpirationExtension2 = minertypes.ExpirationExtension2
|
||||
type CompactPartitionsParams = minertypes.CompactPartitionsParams
|
||||
type WithdrawBalanceParams = minertypes.WithdrawBalanceParams
|
||||
|
||||
var QAPowerMax = minertypes.QAPowerMax
|
||||
|
||||
type WindowPostVerifyInfo = proof.WindowPoStVerifyInfo
|
||||
|
||||
var WPoStProvingPeriod = func() abi.ChainEpoch { return minertypes.WPoStProvingPeriod }
|
||||
var WPoStChallengeWindow = func() abi.ChainEpoch { return minertypes.WPoStChallengeWindow }
|
||||
|
||||
const WPoStPeriodDeadlines = minertypes.WPoStPeriodDeadlines
|
||||
const WPoStChallengeLookback = minertypes.WPoStChallengeLookback
|
||||
const FaultDeclarationCutoff = minertypes.FaultDeclarationCutoff
|
||||
const MinAggregatedSectors = minertypes.MinAggregatedSectors
|
||||
const MinSectorExpiration = minertypes.MinSectorExpiration
|
||||
|
||||
type SectorExpiration struct {
|
||||
OnTime abi.ChainEpoch
|
||||
|
||||
|
||||
@@ -290,8 +290,37 @@ type PendingBeneficiaryChange = minertypes.PendingBeneficiaryChange
|
||||
type WorkerKeyChange = minertypes.WorkerKeyChange
|
||||
type SectorPreCommitOnChainInfo = minertypes.SectorPreCommitOnChainInfo
|
||||
type SectorPreCommitInfo = minertypes.SectorPreCommitInfo
|
||||
type SubmitWindowedPoStParams = minertypes.SubmitWindowedPoStParams
|
||||
type PoStPartition = minertypes.PoStPartition
|
||||
type RecoveryDeclaration = minertypes.RecoveryDeclaration
|
||||
type FaultDeclaration = minertypes.FaultDeclaration
|
||||
type DeclareFaultsRecoveredParams = minertypes.DeclareFaultsRecoveredParams
|
||||
type DeclareFaultsParams = minertypes.DeclareFaultsParams
|
||||
type ProveCommitAggregateParams = minertypes.ProveCommitAggregateParams
|
||||
type ProveCommitSectorParams = minertypes.ProveCommitSectorParams
|
||||
type ProveReplicaUpdatesParams = minertypes.ProveReplicaUpdatesParams
|
||||
type ReplicaUpdate = minertypes.ReplicaUpdate
|
||||
type PreCommitSectorBatchParams = minertypes.PreCommitSectorBatchParams
|
||||
type PreCommitSectorBatchParams2 = minertypes.PreCommitSectorBatchParams2
|
||||
type ExtendSectorExpiration2Params = minertypes.ExtendSectorExpiration2Params
|
||||
type SectorClaim = minertypes.SectorClaim
|
||||
type ExpirationExtension2 = minertypes.ExpirationExtension2
|
||||
type CompactPartitionsParams = minertypes.CompactPartitionsParams
|
||||
type WithdrawBalanceParams = minertypes.WithdrawBalanceParams
|
||||
|
||||
var QAPowerMax = minertypes.QAPowerMax
|
||||
|
||||
type WindowPostVerifyInfo = proof.WindowPoStVerifyInfo
|
||||
|
||||
var WPoStProvingPeriod = func() abi.ChainEpoch { return minertypes.WPoStProvingPeriod }
|
||||
var WPoStChallengeWindow = func() abi.ChainEpoch { return minertypes.WPoStChallengeWindow }
|
||||
|
||||
const WPoStPeriodDeadlines = minertypes.WPoStPeriodDeadlines
|
||||
const WPoStChallengeLookback = minertypes.WPoStChallengeLookback
|
||||
const FaultDeclarationCutoff = minertypes.FaultDeclarationCutoff
|
||||
const MinAggregatedSectors = minertypes.MinAggregatedSectors
|
||||
const MinSectorExpiration = minertypes.MinSectorExpiration
|
||||
|
||||
type SectorExpiration struct {
|
||||
OnTime abi.ChainEpoch
|
||||
|
||||
|
||||
@@ -97,4 +97,6 @@ func AllCodes() []cid.Cid {
|
||||
type Allocation = verifregtypes.Allocation
|
||||
type AllocationId = verifregtypes.AllocationId
|
||||
type Claim = verifregtypes.Claim
|
||||
type ClaimId = verifregtypes.ClaimId
|
||||
type ClaimId = verifregtypes.ClaimId
|
||||
|
||||
const NoAllocationID = verifregtypes.NoAllocationID
|
||||
|
||||
+2
@@ -168,3 +168,5 @@ type Allocation = verifregtypes.Allocation
|
||||
type AllocationId = verifregtypes.AllocationId
|
||||
type Claim = verifregtypes.Claim
|
||||
type ClaimId = verifregtypes.ClaimId
|
||||
|
||||
const NoAllocationID = verifregtypes.NoAllocationID
|
||||
|
||||
@@ -81,7 +81,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
|
||||
pstate cid.Cid,
|
||||
bms []FilecoinBlockMessages,
|
||||
epoch abi.ChainEpoch,
|
||||
r vm.Rand,
|
||||
r rand.Rand,
|
||||
em stmgr.ExecMonitor,
|
||||
vmTracing bool,
|
||||
baseFee abi.TokenAmount,
|
||||
@@ -136,6 +136,10 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
|
||||
return xerrors.Errorf("running cron: %w", err)
|
||||
}
|
||||
|
||||
if !ret.ExitCode.IsSuccess() {
|
||||
return xerrors.Errorf("cron failed with exit code %d: %w", ret.ExitCode, ret.ActorErr)
|
||||
}
|
||||
|
||||
cronGas += ret.GasUsed
|
||||
|
||||
if em != nil {
|
||||
|
||||
@@ -80,6 +80,11 @@ var RewardFunc = func(ctx context.Context, vmi vm.Interface, em stmgr.ExecMonito
|
||||
if actErr != nil {
|
||||
return xerrors.Errorf("failed to apply reward message: %w", actErr)
|
||||
}
|
||||
|
||||
if !ret.ExitCode.IsSuccess() {
|
||||
return xerrors.Errorf("reward actor failed with exit code %d: %w", ret.ExitCode, ret.ActorErr)
|
||||
}
|
||||
|
||||
if em != nil {
|
||||
if err := em.MessageApplied(ctx, ts, rwMsg.Cid(), rwMsg, ret, true); err != nil {
|
||||
return xerrors.Errorf("callback failed on reward message: %w", err)
|
||||
@@ -196,7 +201,7 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
|
||||
return xerrors.Errorf("failed to marshal miner address to cbor: %w", err)
|
||||
}
|
||||
|
||||
vrfBase, err := rand.DrawRandomness(rBeacon.Data, crypto.DomainSeparationTag_ElectionProofProduction, h.Height, buf.Bytes())
|
||||
vrfBase, err := rand.DrawRandomnessFromBase(rBeacon.Data, crypto.DomainSeparationTag_ElectionProofProduction, h.Height, buf.Bytes())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("could not draw randomness: %w", err)
|
||||
}
|
||||
@@ -262,7 +267,7 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
|
||||
beaconBase = h.BeaconEntries[len(h.BeaconEntries)-1]
|
||||
}
|
||||
|
||||
vrfBase, err := rand.DrawRandomness(beaconBase.Data, crypto.DomainSeparationTag_TicketProduction, h.Height-build.TicketRandomnessLookback, buf.Bytes())
|
||||
vrfBase, err := rand.DrawRandomnessFromBase(beaconBase.Data, crypto.DomainSeparationTag_TicketProduction, h.Height-build.TicketRandomnessLookback, buf.Bytes())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to compute vrf base for ticket: %w", err)
|
||||
}
|
||||
@@ -340,7 +345,7 @@ func (filec *FilecoinEC) VerifyWinningPoStProof(ctx context.Context, nv network.
|
||||
rbase = h.BeaconEntries[len(h.BeaconEntries)-1]
|
||||
}
|
||||
|
||||
rand, err := rand.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, h.Height, buf.Bytes())
|
||||
rand, err := rand.DrawRandomnessFromBase(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, h.Height, buf.Bytes())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get randomness for verifying winning post proof: %w", err)
|
||||
}
|
||||
|
||||
+2
-2
@@ -376,7 +376,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
|
||||
buf.Write(pts.MinTicket().VRFProof)
|
||||
}
|
||||
|
||||
ticketRand, err := rand.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_TicketProduction, round-build.TicketRandomnessLookback, buf.Bytes())
|
||||
ticketRand, err := rand.DrawRandomnessFromBase(rbase.Data, crypto.DomainSeparationTag_TicketProduction, round-build.TicketRandomnessLookback, buf.Bytes())
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
@@ -636,7 +636,7 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch,
|
||||
return nil, xerrors.Errorf("failed to cbor marshal address: %w", err)
|
||||
}
|
||||
|
||||
electionRand, err := rand.DrawRandomness(brand.Data, crypto.DomainSeparationTag_ElectionProofProduction, round, buf.Bytes())
|
||||
electionRand, err := rand.DrawRandomnessFromBase(brand.Data, crypto.DomainSeparationTag_ElectionProofProduction, round, buf.Bytes())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to draw randomness: %w", err)
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/consensus"
|
||||
lrand "github.com/filecoin-project/lotus/chain/rand"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -590,19 +591,21 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
|
||||
return c, nil
|
||||
}
|
||||
|
||||
var _ lrand.Rand = new(fakeRand)
|
||||
|
||||
// TODO: copied from actors test harness, deduplicate or remove from here
|
||||
type fakeRand struct{}
|
||||
|
||||
func (fr *fakeRand) GetChainRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
func (fr *fakeRand) GetChainRandomness(ctx context.Context, randEpoch abi.ChainEpoch) ([32]byte, error) {
|
||||
out := make([]byte, 32)
|
||||
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out) //nolint
|
||||
return out, nil
|
||||
return *(*[32]byte)(out), nil
|
||||
}
|
||||
|
||||
func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, randEpoch abi.ChainEpoch) ([32]byte, error) {
|
||||
out := make([]byte, 32)
|
||||
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
|
||||
return out, nil
|
||||
return *(*[32]byte)(out), nil
|
||||
}
|
||||
|
||||
func currentTotalPower(ctx context.Context, vm vm.Interface, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) {
|
||||
|
||||
@@ -26,20 +26,30 @@ func New(dstore ds.Batching) *SlashFilter {
|
||||
}
|
||||
}
|
||||
|
||||
func (f *SlashFilter) MinedBlock(ctx context.Context, bh *types.BlockHeader, parentEpoch abi.ChainEpoch) (cid.Cid, error) {
|
||||
func (f *SlashFilter) MinedBlock(ctx context.Context, bh *types.BlockHeader, parentEpoch abi.ChainEpoch) (cid.Cid, bool, error) {
|
||||
epochKey := ds.NewKey(fmt.Sprintf("/%s/%d", bh.Miner, bh.Height))
|
||||
{
|
||||
// double-fork mining (2 blocks at one epoch)
|
||||
if witness, err := checkFault(ctx, f.byEpoch, epochKey, bh, "double-fork mining faults"); err != nil {
|
||||
return witness, xerrors.Errorf("check double-fork mining faults: %w", err)
|
||||
doubleForkWitness, doubleForkFault, err := checkFault(ctx, f.byEpoch, epochKey, bh, "double-fork mining faults")
|
||||
if err != nil {
|
||||
return cid.Undef, false, xerrors.Errorf("check double-fork mining faults: %w", err)
|
||||
}
|
||||
|
||||
if doubleForkFault {
|
||||
return doubleForkWitness, doubleForkFault, nil
|
||||
}
|
||||
}
|
||||
|
||||
parentsKey := ds.NewKey(fmt.Sprintf("/%s/%x", bh.Miner, types.NewTipSetKey(bh.Parents...).Bytes()))
|
||||
{
|
||||
// time-offset mining faults (2 blocks with the same parents)
|
||||
if witness, err := checkFault(ctx, f.byParents, parentsKey, bh, "time-offset mining faults"); err != nil {
|
||||
return witness, xerrors.Errorf("check time-offset mining faults: %w", err)
|
||||
timeOffsetWitness, timeOffsetFault, err := checkFault(ctx, f.byParents, parentsKey, bh, "time-offset mining faults")
|
||||
if err != nil {
|
||||
return cid.Undef, false, xerrors.Errorf("check time-offset mining faults: %w", err)
|
||||
}
|
||||
|
||||
if timeOffsetFault {
|
||||
return timeOffsetWitness, timeOffsetFault, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,19 +60,19 @@ func (f *SlashFilter) MinedBlock(ctx context.Context, bh *types.BlockHeader, par
|
||||
parentEpochKey := ds.NewKey(fmt.Sprintf("/%s/%d", bh.Miner, parentEpoch))
|
||||
have, err := f.byEpoch.Has(ctx, parentEpochKey)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return cid.Undef, false, xerrors.Errorf("failed to read from db: %w", err)
|
||||
}
|
||||
|
||||
if have {
|
||||
// If we had, make sure it's in our parent tipset
|
||||
cidb, err := f.byEpoch.Get(ctx, parentEpochKey)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("getting other block cid: %w", err)
|
||||
return cid.Undef, false, xerrors.Errorf("getting other block cid: %w", err)
|
||||
}
|
||||
|
||||
_, parent, err := cid.CidFromBytes(cidb)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return cid.Undef, false, xerrors.Errorf("failed to read cid from bytes: %w", err)
|
||||
}
|
||||
|
||||
var found bool
|
||||
@@ -73,45 +83,45 @@ func (f *SlashFilter) MinedBlock(ctx context.Context, bh *types.BlockHeader, par
|
||||
}
|
||||
|
||||
if !found {
|
||||
return parent, xerrors.Errorf("produced block would trigger 'parent-grinding fault' consensus fault; miner: %s; bh: %s, expected parent: %s", bh.Miner, bh.Cid(), parent)
|
||||
return parent, true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := f.byParents.Put(ctx, parentsKey, bh.Cid().Bytes()); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("putting byEpoch entry: %w", err)
|
||||
return cid.Undef, false, xerrors.Errorf("putting byEpoch entry: %w", err)
|
||||
}
|
||||
|
||||
if err := f.byEpoch.Put(ctx, epochKey, bh.Cid().Bytes()); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("putting byEpoch entry: %w", err)
|
||||
return cid.Undef, false, xerrors.Errorf("putting byEpoch entry: %w", err)
|
||||
}
|
||||
|
||||
return cid.Undef, nil
|
||||
return cid.Undef, false, nil
|
||||
}
|
||||
|
||||
func checkFault(ctx context.Context, t ds.Datastore, key ds.Key, bh *types.BlockHeader, faultType string) (cid.Cid, error) {
|
||||
func checkFault(ctx context.Context, t ds.Datastore, key ds.Key, bh *types.BlockHeader, faultType string) (cid.Cid, bool, error) {
|
||||
fault, err := t.Has(ctx, key)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to read from datastore: %w", err)
|
||||
return cid.Undef, false, xerrors.Errorf("failed to read from datastore: %w", err)
|
||||
}
|
||||
|
||||
if fault {
|
||||
cidb, err := t.Get(ctx, key)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("getting other block cid: %w", err)
|
||||
return cid.Undef, false, xerrors.Errorf("getting other block cid: %w", err)
|
||||
}
|
||||
|
||||
_, other, err := cid.CidFromBytes(cidb)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return cid.Undef, false, xerrors.Errorf("failed to read cid of other block: %w", err)
|
||||
}
|
||||
|
||||
if other == bh.Cid() {
|
||||
return cid.Undef, nil
|
||||
return cid.Undef, false, nil
|
||||
}
|
||||
|
||||
return other, xerrors.Errorf("produced block would trigger '%s' consensus fault; miner: %s; bh: %s, other: %s", faultType, bh.Miner, bh.Cid(), other)
|
||||
return other, true, nil
|
||||
}
|
||||
|
||||
return cid.Undef, nil
|
||||
return cid.Undef, false, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
package slashsvc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
levelds "github.com/ipfs/go-ds-leveldb"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
ldbopts "github.com/syndtr/goleveldb/leveldb/opt"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
cborutil "github.com/filecoin-project/go-cbor-util"
|
||||
"github.com/filecoin-project/go-state-types/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
|
||||
lapi "github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var log = logging.Logger("slashsvc")
|
||||
|
||||
type ConsensusSlasherApi interface {
|
||||
ChainHead(context.Context) (*types.TipSet, error)
|
||||
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
||||
MpoolPushMessage(ctx context.Context, msg *types.Message, spec *lapi.MessageSendSpec) (*types.SignedMessage, error)
|
||||
SyncIncomingBlocks(context.Context) (<-chan *types.BlockHeader, error)
|
||||
WalletDefaultAddress(context.Context) (address.Address, error)
|
||||
}
|
||||
|
||||
func SlashConsensus(ctx context.Context, a ConsensusSlasherApi, p string, from string) error {
|
||||
var fromAddr address.Address
|
||||
|
||||
ds, err := levelds.NewDatastore(p, &levelds.Options{
|
||||
Compression: ldbopts.NoCompression,
|
||||
NoSync: false,
|
||||
Strict: ldbopts.StrictAll,
|
||||
ReadOnly: false,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("open leveldb: %w", err)
|
||||
}
|
||||
sf := slashfilter.New(ds)
|
||||
if from == "" {
|
||||
defaddr, err := a.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fromAddr = defaddr
|
||||
} else {
|
||||
addr, err := address.NewFromString(from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fromAddr = addr
|
||||
}
|
||||
|
||||
blocks, err := a.SyncIncomingBlocks(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("sync incoming blocks failed: %w", err)
|
||||
}
|
||||
|
||||
log.Infow("consensus fault reporter", "from", fromAddr)
|
||||
go func() {
|
||||
for block := range blocks {
|
||||
otherBlock, extraBlock, fault, err := slashFilterMinedBlock(ctx, sf, a, block)
|
||||
if err != nil {
|
||||
log.Errorf("slash detector errored: %s", err)
|
||||
continue
|
||||
}
|
||||
if fault {
|
||||
log.Errorf("<!!> SLASH FILTER DETECTED FAULT DUE TO BLOCKS %s and %s", otherBlock.Cid(), block.Cid())
|
||||
bh1, err := cborutil.Dump(otherBlock)
|
||||
if err != nil {
|
||||
log.Errorf("could not dump otherblock:%s, err:%s", otherBlock.Cid(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
bh2, err := cborutil.Dump(block)
|
||||
if err != nil {
|
||||
log.Errorf("could not dump block:%s, err:%s", block.Cid(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
params := miner.ReportConsensusFaultParams{
|
||||
BlockHeader1: bh1,
|
||||
BlockHeader2: bh2,
|
||||
}
|
||||
if extraBlock != nil {
|
||||
be, err := cborutil.Dump(extraBlock)
|
||||
if err != nil {
|
||||
log.Errorf("could not dump block:%s, err:%s", block.Cid(), err)
|
||||
continue
|
||||
}
|
||||
params.BlockHeaderExtra = be
|
||||
}
|
||||
|
||||
enc, err := actors.SerializeParams(¶ms)
|
||||
if err != nil {
|
||||
log.Errorf("could not serialize declare faults parameters: %s", err)
|
||||
continue
|
||||
}
|
||||
for {
|
||||
head, err := a.ChainHead(ctx)
|
||||
if err != nil || head.Height() > block.Height {
|
||||
break
|
||||
}
|
||||
time.Sleep(time.Second * 10)
|
||||
}
|
||||
message, err := a.MpoolPushMessage(ctx, &types.Message{
|
||||
To: block.Miner,
|
||||
From: fromAddr,
|
||||
Value: types.NewInt(0),
|
||||
Method: builtin.MethodsMiner.ReportConsensusFault,
|
||||
Params: enc,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
log.Errorf("ReportConsensusFault to messagepool error:%s", err)
|
||||
continue
|
||||
}
|
||||
log.Infof("ReportConsensusFault message CID:%s", message.Cid())
|
||||
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func slashFilterMinedBlock(ctx context.Context, sf *slashfilter.SlashFilter, a ConsensusSlasherApi, blockB *types.BlockHeader) (*types.BlockHeader, *types.BlockHeader, bool, error) {
|
||||
blockC, err := a.ChainGetBlock(ctx, blockB.Parents[0])
|
||||
if err != nil {
|
||||
return nil, nil, false, xerrors.Errorf("chain get block error:%s", err)
|
||||
}
|
||||
|
||||
blockACid, fault, err := sf.MinedBlock(ctx, blockB, blockC.Height)
|
||||
if err != nil {
|
||||
return nil, nil, false, xerrors.Errorf("slash filter check block error:%s", err)
|
||||
}
|
||||
|
||||
if !fault {
|
||||
return nil, nil, false, nil
|
||||
}
|
||||
|
||||
blockA, err := a.ChainGetBlock(ctx, blockACid)
|
||||
if err != nil {
|
||||
return nil, nil, false, xerrors.Errorf("failed to get blockA: %w", err)
|
||||
}
|
||||
|
||||
// (a) double-fork mining (2 blocks at one epoch)
|
||||
if blockA.Height == blockB.Height {
|
||||
return blockA, nil, true, nil
|
||||
}
|
||||
|
||||
// (b) time-offset mining faults (2 blocks with the same parents)
|
||||
if types.CidArrsEqual(blockB.Parents, blockA.Parents) {
|
||||
return blockA, nil, true, nil
|
||||
}
|
||||
|
||||
// (c) parent-grinding fault
|
||||
// Here extra is the "witness", a third block that shows the connection between A and B as
|
||||
// A's sibling and B's parent.
|
||||
// Specifically, since A is of lower height, it must be that B was mined omitting A from its tipset
|
||||
//
|
||||
// B
|
||||
// |
|
||||
// [A, C]
|
||||
if types.CidArrsEqual(blockA.Parents, blockC.Parents) && blockA.Height == blockC.Height &&
|
||||
types.CidArrsContains(blockB.Parents, blockC.Cid()) && !types.CidArrsContains(blockB.Parents, blockA.Cid()) {
|
||||
return blockA, blockC, true, nil
|
||||
}
|
||||
|
||||
log.Error("unexpectedly reached end of slashFilterMinedBlock despite fault being reported!")
|
||||
return nil, nil, false, nil
|
||||
}
|
||||
+66
-37
@@ -17,18 +17,20 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/beacon"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
)
|
||||
|
||||
var log = logging.Logger("rand")
|
||||
|
||||
func DrawRandomness(rbase []byte, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
func DrawRandomnessFromBase(rbase []byte, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
return DrawRandomnessFromDigest(blake2b.Sum256(rbase), pers, round, entropy)
|
||||
}
|
||||
|
||||
func DrawRandomnessFromDigest(digest [32]byte, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
h := blake2b.New256()
|
||||
if err := binary.Write(h, binary.BigEndian, int64(pers)); err != nil {
|
||||
return nil, xerrors.Errorf("deriving randomness: %w", err)
|
||||
}
|
||||
VRFDigest := blake2b.Sum256(rbase)
|
||||
_, err := h.Write(VRFDigest[:])
|
||||
_, err := h.Write(digest[:])
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("hashing VRFDigest: %w", err)
|
||||
}
|
||||
@@ -70,18 +72,18 @@ func (sr *stateRand) GetBeaconRandomnessTipset(ctx context.Context, round abi.Ch
|
||||
return randTs, nil
|
||||
}
|
||||
|
||||
func (sr *stateRand) getChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte, lookback bool) ([]byte, error) {
|
||||
func (sr *stateRand) getChainRandomness(ctx context.Context, round abi.ChainEpoch, lookback bool) ([32]byte, error) {
|
||||
_, span := trace.StartSpan(ctx, "store.GetChainRandomness")
|
||||
defer span.End()
|
||||
span.AddAttributes(trace.Int64Attribute("round", int64(round)))
|
||||
|
||||
ts, err := sr.cs.LoadTipSet(ctx, types.NewTipSetKey(sr.blks...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return [32]byte{}, err
|
||||
}
|
||||
|
||||
if round > ts.Height() {
|
||||
return nil, xerrors.Errorf("cannot draw randomness from the future")
|
||||
return [32]byte{}, xerrors.Errorf("cannot draw randomness from the future")
|
||||
}
|
||||
|
||||
searchHeight := round
|
||||
@@ -91,14 +93,10 @@ func (sr *stateRand) getChainRandomness(ctx context.Context, pers crypto.DomainS
|
||||
|
||||
randTs, err := sr.cs.GetTipsetByHeight(ctx, searchHeight, ts, lookback)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return [32]byte{}, err
|
||||
}
|
||||
|
||||
mtb := randTs.MinTicketBlock()
|
||||
|
||||
// if at (or just past -- for null epochs) appropriate epoch
|
||||
// or at genesis (works for negative epochs)
|
||||
return DrawRandomness(mtb.Ticket.VRFProof, pers, round, entropy)
|
||||
return blake2b.Sum256(randTs.MinTicketBlock().Ticket.VRFProof), nil
|
||||
}
|
||||
|
||||
type NetworkVersionGetter func(context.Context, abi.ChainEpoch) network.Version
|
||||
@@ -110,7 +108,12 @@ type stateRand struct {
|
||||
networkVersionGetter NetworkVersionGetter
|
||||
}
|
||||
|
||||
func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule, networkVersionGetter NetworkVersionGetter) vm.Rand {
|
||||
type Rand interface {
|
||||
GetChainRandomness(ctx context.Context, round abi.ChainEpoch) ([32]byte, error)
|
||||
GetBeaconRandomness(ctx context.Context, round abi.ChainEpoch) ([32]byte, error)
|
||||
}
|
||||
|
||||
func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule, networkVersionGetter NetworkVersionGetter) Rand {
|
||||
return &stateRand{
|
||||
cs: cs,
|
||||
blks: blks,
|
||||
@@ -120,76 +123,102 @@ func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule, netwo
|
||||
}
|
||||
|
||||
// network v0-12
|
||||
func (sr *stateRand) getBeaconRandomnessV1(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
func (sr *stateRand) getBeaconRandomnessV1(ctx context.Context, round abi.ChainEpoch) ([32]byte, error) {
|
||||
randTs, err := sr.GetBeaconRandomnessTipset(ctx, round, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return [32]byte{}, err
|
||||
}
|
||||
|
||||
be, err := sr.cs.GetLatestBeaconEntry(ctx, randTs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return [32]byte{}, err
|
||||
}
|
||||
|
||||
// if at (or just past -- for null epochs) appropriate epoch
|
||||
// or at genesis (works for negative epochs)
|
||||
return DrawRandomness(be.Data, pers, round, entropy)
|
||||
return blake2b.Sum256(be.Data), nil
|
||||
}
|
||||
|
||||
// network v13
|
||||
func (sr *stateRand) getBeaconRandomnessV2(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
func (sr *stateRand) getBeaconRandomnessV2(ctx context.Context, round abi.ChainEpoch) ([32]byte, error) {
|
||||
randTs, err := sr.GetBeaconRandomnessTipset(ctx, round, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return [32]byte{}, err
|
||||
}
|
||||
|
||||
be, err := sr.cs.GetLatestBeaconEntry(ctx, randTs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return [32]byte{}, err
|
||||
}
|
||||
|
||||
// if at (or just past -- for null epochs) appropriate epoch
|
||||
// or at genesis (works for negative epochs)
|
||||
return DrawRandomness(be.Data, pers, round, entropy)
|
||||
return blake2b.Sum256(be.Data), nil
|
||||
}
|
||||
|
||||
// network v14 and on
|
||||
func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([32]byte, error) {
|
||||
if filecoinEpoch < 0 {
|
||||
return sr.getBeaconRandomnessV2(ctx, pers, filecoinEpoch, entropy)
|
||||
return sr.getBeaconRandomnessV2(ctx, filecoinEpoch)
|
||||
}
|
||||
|
||||
be, err := sr.extractBeaconEntryForEpoch(ctx, filecoinEpoch)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get beacon entry as expected: %s", err)
|
||||
return nil, err
|
||||
return [32]byte{}, err
|
||||
}
|
||||
|
||||
return DrawRandomness(be.Data, pers, filecoinEpoch, entropy)
|
||||
return blake2b.Sum256(be.Data), nil
|
||||
}
|
||||
|
||||
func (sr *stateRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
func (sr *stateRand) GetChainRandomness(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([32]byte, error) {
|
||||
nv := sr.networkVersionGetter(ctx, filecoinEpoch)
|
||||
|
||||
if nv >= network.Version13 {
|
||||
return sr.getChainRandomness(ctx, pers, filecoinEpoch, entropy, false)
|
||||
return sr.getChainRandomness(ctx, filecoinEpoch, false)
|
||||
}
|
||||
|
||||
return sr.getChainRandomness(ctx, pers, filecoinEpoch, entropy, true)
|
||||
return sr.getChainRandomness(ctx, filecoinEpoch, true)
|
||||
}
|
||||
|
||||
func (sr *stateRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
func (sr *stateRand) GetBeaconRandomness(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([32]byte, error) {
|
||||
nv := sr.networkVersionGetter(ctx, filecoinEpoch)
|
||||
|
||||
if nv >= network.Version14 {
|
||||
return sr.getBeaconRandomnessV3(ctx, pers, filecoinEpoch, entropy)
|
||||
return sr.getBeaconRandomnessV3(ctx, filecoinEpoch)
|
||||
} else if nv == network.Version13 {
|
||||
return sr.getBeaconRandomnessV2(ctx, pers, filecoinEpoch, entropy)
|
||||
return sr.getBeaconRandomnessV2(ctx, filecoinEpoch)
|
||||
} else {
|
||||
return sr.getBeaconRandomnessV1(ctx, pers, filecoinEpoch, entropy)
|
||||
return sr.getBeaconRandomnessV1(ctx, filecoinEpoch)
|
||||
}
|
||||
}
|
||||
|
||||
func (sr *stateRand) DrawChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
digest, err := sr.GetChainRandomness(ctx, filecoinEpoch)
|
||||
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get chain randomness: %w", err)
|
||||
}
|
||||
|
||||
ret, err := DrawRandomnessFromDigest(digest, pers, filecoinEpoch, entropy)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to draw chain randomness: %w", err)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (sr *stateRand) DrawBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
digest, err := sr.GetBeaconRandomness(ctx, filecoinEpoch)
|
||||
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get beacon randomness: %w", err)
|
||||
}
|
||||
|
||||
ret, err := DrawRandomnessFromDigest(digest, pers, filecoinEpoch, entropy)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to draw beacon randomness: %w", err)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (sr *stateRand) extractBeaconEntryForEpoch(ctx context.Context, filecoinEpoch abi.ChainEpoch) (*types.BeaconEntry, error) {
|
||||
randTs, err := sr.GetBeaconRandomnessTipset(ctx, filecoinEpoch, false)
|
||||
if err != nil {
|
||||
|
||||
@@ -69,7 +69,7 @@ func TestNullRandomnessV1(t *testing.T) {
|
||||
}
|
||||
|
||||
//stm: @BLOCKCHAIN_RAND_DRAW_RANDOMNESS_01
|
||||
rand2, err := rand.DrawRandomness(resp.Entry.Data, pers, randEpoch, entropy)
|
||||
rand2, err := rand.DrawRandomnessFromBase(resp.Entry.Data, pers, randEpoch, entropy)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -148,8 +148,8 @@ func TestNullRandomnessV2(t *testing.T) {
|
||||
}
|
||||
|
||||
//stm: @BLOCKCHAIN_RAND_DRAW_RANDOMNESS_01, @BLOCKCHAIN_RAND_EXTRACT_BEACON_ENTRY_FOR_EPOCH_01, @BLOCKCHAIN_RAND_GET_BEACON_RANDOMNESS_TIPSET_03
|
||||
// note that the randEpoch passed to DrawRandomness is still randEpoch (not the latest ts height)
|
||||
rand2, err := rand.DrawRandomness(resp.Entry.Data, pers, randEpoch, entropy)
|
||||
// note that the randEpoch passed to DrawRandomnessFromBase is still randEpoch (not the latest ts height)
|
||||
rand2, err := rand.DrawRandomnessFromBase(resp.Entry.Data, pers, randEpoch, entropy)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -232,7 +232,7 @@ func TestNullRandomnessV3(t *testing.T) {
|
||||
}
|
||||
|
||||
//stm: @BLOCKCHAIN_RAND_DRAW_RANDOMNESS_01
|
||||
rand2, err := rand.DrawRandomness(resp.Entry.Data, pers, randEpoch, entropy)
|
||||
rand2, err := rand.DrawRandomnessFromBase(resp.Entry.Data, pers, randEpoch, entropy)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
|
||||
return nil, xerrors.Errorf("failed to marshal miner address: %w", err)
|
||||
}
|
||||
|
||||
prand, err := rand.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, round, buf.Bytes())
|
||||
prand, err := rand.DrawRandomnessFromBase(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, round, buf.Bytes())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get randomness for winning post: %w", err)
|
||||
}
|
||||
|
||||
+10
-4
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-datastore"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@@ -177,11 +179,15 @@ func (sm *StateManager) HandleStateForks(ctx context.Context, root cid.Cid, heig
|
||||
u := sm.stateMigrations[height]
|
||||
if u != nil && u.upgrade != nil {
|
||||
migCid, ok, err := u.migrationResultCache.Get(ctx, root)
|
||||
if err == nil && ok {
|
||||
log.Infow("CACHED migration", "height", height, "from", root, "to", migCid)
|
||||
return migCid, nil
|
||||
} else if err != nil {
|
||||
if err == nil {
|
||||
if ok {
|
||||
log.Infow("CACHED migration", "height", height, "from", root, "to", migCid)
|
||||
return migCid, nil
|
||||
}
|
||||
} else if !errors.Is(err, datastore.ErrNotFound) {
|
||||
log.Errorw("failed to lookup previous migration result", "err", err)
|
||||
} else {
|
||||
log.Debug("no cached migration found, migrating from scratch")
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
|
||||
+45
-2
@@ -509,7 +509,17 @@ func (sm *StateManager) GetRandomnessFromBeacon(ctx context.Context, personaliza
|
||||
|
||||
r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion)
|
||||
|
||||
return r.GetBeaconRandomness(ctx, personalization, randEpoch, entropy)
|
||||
digest, err := r.GetBeaconRandomness(ctx, randEpoch)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting beacon randomness: %w", err)
|
||||
}
|
||||
|
||||
ret, err := rand.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("drawing beacon randomness: %w", err)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -521,5 +531,38 @@ func (sm *StateManager) GetRandomnessFromTickets(ctx context.Context, personaliz
|
||||
|
||||
r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion)
|
||||
|
||||
return r.GetChainRandomness(ctx, personalization, randEpoch, entropy)
|
||||
digest, err := r.GetChainRandomness(ctx, randEpoch)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting chain randomness: %w", err)
|
||||
}
|
||||
|
||||
ret, err := rand.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("drawing chain randomness: %w", err)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) GetRandomnessDigestFromBeacon(ctx context.Context, randEpoch abi.ChainEpoch, tsk types.TipSetKey) ([32]byte, error) {
|
||||
pts, err := sm.ChainStore().GetTipSetFromKey(ctx, tsk)
|
||||
if err != nil {
|
||||
return [32]byte{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
|
||||
r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion)
|
||||
|
||||
return r.GetBeaconRandomness(ctx, randEpoch)
|
||||
|
||||
}
|
||||
|
||||
func (sm *StateManager) GetRandomnessDigestFromTickets(ctx context.Context, randEpoch abi.ChainEpoch, tsk types.TipSetKey) ([32]byte, error) {
|
||||
pts, err := sm.ChainStore().LoadTipSet(ctx, tsk)
|
||||
if err != nil {
|
||||
return [32]byte{}, xerrors.Errorf("loading tipset key: %w", err)
|
||||
}
|
||||
|
||||
r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion)
|
||||
|
||||
return r.GetChainRandomness(ctx, randEpoch)
|
||||
}
|
||||
|
||||
+2
-5
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/rand"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
@@ -43,7 +44,7 @@ var _ Interface = (*FVM)(nil)
|
||||
var _ ffi_cgo.Externs = (*FvmExtern)(nil)
|
||||
|
||||
type FvmExtern struct {
|
||||
Rand
|
||||
rand.Rand
|
||||
blockstore.Blockstore
|
||||
epoch abi.ChainEpoch
|
||||
lbState LookbackStateGetter
|
||||
@@ -520,10 +521,6 @@ func (vm *FVM) ApplyImplicitMessage(ctx context.Context, cmsg *types.Message) (*
|
||||
}
|
||||
}
|
||||
|
||||
if ret.ExitCode != 0 {
|
||||
return applyRet, fmt.Errorf("implicit message failed with exit code: %d and error: %w", ret.ExitCode, applyRet.ActorErr)
|
||||
}
|
||||
|
||||
return applyRet, nil
|
||||
}
|
||||
|
||||
|
||||
+20
-5
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/rand"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
@@ -229,21 +230,35 @@ func (rt *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool)
|
||||
}
|
||||
|
||||
func (rt *Runtime) GetRandomnessFromTickets(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
|
||||
res, err := rt.vm.rand.GetChainRandomness(rt.ctx, personalization, randEpoch, entropy)
|
||||
digest, err := rt.vm.rand.GetChainRandomness(rt.ctx, randEpoch)
|
||||
|
||||
if err != nil {
|
||||
panic(aerrors.Fatalf("could not get ticket randomness: %s", err))
|
||||
}
|
||||
return res
|
||||
|
||||
ret, err := rand.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy)
|
||||
|
||||
if err != nil {
|
||||
panic(aerrors.Fatalf("could not draw ticket randomness: %s", err))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (rt *Runtime) GetRandomnessFromBeacon(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
|
||||
res, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, personalization, randEpoch, entropy)
|
||||
digest, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, randEpoch)
|
||||
|
||||
if err != nil {
|
||||
panic(aerrors.Fatalf("could not get beacon randomness: %s", err))
|
||||
panic(aerrors.Fatalf("could not get ticket randomness: %s", err))
|
||||
}
|
||||
return res
|
||||
|
||||
ret, err := rand.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy)
|
||||
|
||||
if err != nil {
|
||||
panic(aerrors.Fatalf("could not draw ticket randomness: %s", err))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (rt *Runtime) NewActorAddress() address.Address {
|
||||
|
||||
+3
-8
@@ -21,7 +21,6 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
builtin_types "github.com/filecoin-project/go-state-types/builtin"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
@@ -32,6 +31,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/account"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
|
||||
"github.com/filecoin-project/lotus/chain/rand"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/metrics"
|
||||
@@ -224,7 +224,7 @@ type LegacyVM struct {
|
||||
buf *blockstore.BufferedBlockstore
|
||||
blockHeight abi.ChainEpoch
|
||||
areg *ActorRegistry
|
||||
rand Rand
|
||||
rand rand.Rand
|
||||
circSupplyCalc CircSupplyCalculator
|
||||
networkVersion network.Version
|
||||
baseFee abi.TokenAmount
|
||||
@@ -238,7 +238,7 @@ type VMOpts struct {
|
||||
StateBase cid.Cid
|
||||
Epoch abi.ChainEpoch
|
||||
Timestamp uint64
|
||||
Rand Rand
|
||||
Rand rand.Rand
|
||||
Bstore blockstore.Blockstore
|
||||
Actors *ActorRegistry
|
||||
Syscalls SyscallBuilder
|
||||
@@ -287,11 +287,6 @@ func NewLegacyVM(ctx context.Context, opts *VMOpts) (*LegacyVM, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
type Rand interface {
|
||||
GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
|
||||
GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
|
||||
}
|
||||
|
||||
type ApplyRet struct {
|
||||
types.MessageReceipt
|
||||
ActorErr aerrors.ActorError
|
||||
|
||||
Reference in New Issue
Block a user