lotus/chain/gen/gen.go

712 lines
20 KiB
Go
Raw Normal View History

2019-07-25 22:15:33 +00:00
package gen
import (
"bytes"
2019-07-25 22:15:33 +00:00
"context"
"fmt"
"io"
"os"
2019-07-30 13:20:40 +00:00
"sync/atomic"
"time"
2019-07-25 22:15:33 +00:00
2020-10-08 21:57:03 +00:00
"github.com/google/uuid"
chore: migrate to boxo This migrates everything except the `go-car` librairy: https://github.com/ipfs/boxo/issues/218#issuecomment-1529922103 I didn't migrated everything in the previous release because all the boxo code wasn't compatible with the go-ipld-prime one due to a an in flight (/ aftermath) revert of github.com/ipfs/go-block-format. go-block-format has been unmigrated since slight bellow absolutely everything depends on it that would have required everything to be moved on boxo or everything to optin into using boxo which were all deal breakers for different groups. This worked fine because lotus's codebase could live hapely on the first multirepo setup however boost is now trying to use boxo's code with lotus's (still on multirepo) setup: https://filecoinproject.slack.com/archives/C03AQ3QAUG1/p1685022344779649 The alternative would be for boost to write shim types which just forward calls and return with the different interface definitions. Btw why is that an issue in the first place is because unlike what go's duck typing model suggest interfaces are not transparent https://github.com/golang/go/issues/58112, interfaces are strongly typed but they have implicit narrowing. The issue is if you return an interface from an interface Go does not have a function definition to insert the implicit conversion thus instead the type checker complains you are not returning the right type. Stubbing types were reverted https://github.com/ipfs/boxo/issues/218#issuecomment-1478650351 Last time I only migrated `go-bitswap` to `boxo/bitswap` because of the security issues and because we never had the interface return an interface problem (we had concrete wrappers where the implicit conversion took place).
2023-05-25 14:31:53 +00:00
"github.com/ipfs/boxo/blockservice"
offline "github.com/ipfs/boxo/exchange/offline"
"github.com/ipfs/boxo/ipld/merkledag"
"github.com/ipfs/go-cid"
2020-02-23 20:00:47 +00:00
format "github.com/ipfs/go-ipld-format"
logging "github.com/ipfs/go-log/v2"
"github.com/ipld/go-car"
2020-03-26 19:34:38 +00:00
"golang.org/x/xerrors"
2022-06-14 15:00:51 +00:00
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/network"
proof7 "github.com/filecoin-project/specs-actors/v7/actors/runtime/proof"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/blockstore"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/beacon"
"github.com/filecoin-project/lotus/chain/consensus"
2021-09-02 16:07:23 +00:00
"github.com/filecoin-project/lotus/chain/consensus/filcns"
2020-02-11 20:48:03 +00:00
genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis"
2023-03-12 13:25:07 +00:00
"github.com/filecoin-project/lotus/chain/index"
2022-06-14 15:00:51 +00:00
"github.com/filecoin-project/lotus/chain/rand"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/chain/wallet"
2019-11-29 03:38:18 +00:00
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
"github.com/filecoin-project/lotus/genesis"
"github.com/filecoin-project/lotus/journal"
"github.com/filecoin-project/lotus/node/repo"
"github.com/filecoin-project/lotus/storage/sealer/ffiwrapper"
2022-06-17 11:52:19 +00:00
"github.com/filecoin-project/lotus/storage/sealer/storiface"
2019-07-25 22:15:33 +00:00
)
2019-10-08 00:28:13 +00:00
const msgsPerBlock = 20
2019-07-30 13:20:40 +00:00
//nolint:deadcode,varcheck
var log = logging.Logger("gen")
2022-04-20 21:34:28 +00:00
var ValidWpostForTesting = []proof7.PoStProof{{
ProofBytes: []byte("valid proof"),
}}
2019-07-25 22:15:33 +00:00
type ChainGen struct {
msgsPerBlock int
bs blockstore.Blockstore
cs *store.ChainStore
beacon beacon.Schedule
sm *stmgr.StateManager
genesis *types.BlockHeader
CurTipset *store.FullTipSet
2019-07-25 22:15:33 +00:00
2020-02-08 02:18:32 +00:00
Timestamper func(*types.TipSet, abi.ChainEpoch) uint64
2019-10-10 03:04:10 +00:00
GetMessages func(*ChainGen) ([]*types.SignedMessage, error)
2020-09-04 20:17:28 +00:00
w *wallet.LocalWallet
2019-07-30 13:20:40 +00:00
eppProvs map[address.Address]WinningPoStProver
Miners []address.Address
receivers []address.Address
// a SecP address
2019-07-30 13:20:40 +00:00
banker address.Address
bankerNonce uint64
2019-07-29 19:34:09 +00:00
r repo.Repo
2019-07-29 19:34:09 +00:00
lr repo.LockedRepo
2019-07-25 22:15:33 +00:00
}
2020-07-24 09:22:50 +00:00
var rootkeyMultisig = genesis.MultisigMeta{
2020-08-19 20:32:53 +00:00
Signers: []address.Address{remAccTestKey},
2020-07-24 09:22:50 +00:00
Threshold: 1,
VestingDuration: 0,
VestingStart: 0,
}
var DefaultVerifregRootkeyActor = genesis.Actor{
Type: genesis.TMultisig,
Balance: big.NewInt(0),
Meta: rootkeyMultisig.ActorMeta(),
}
2020-08-18 21:30:49 +00:00
var remAccTestKey, _ = address.NewFromString("t1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy")
2020-08-19 20:32:53 +00:00
var remAccMeta = genesis.MultisigMeta{
Signers: []address.Address{remAccTestKey},
Threshold: 1,
2020-08-18 21:30:49 +00:00
}
var DefaultRemainderAccountActor = genesis.Actor{
2020-08-19 20:32:53 +00:00
Type: genesis.TMultisig,
2020-08-18 21:30:49 +00:00
Balance: big.NewInt(0),
Meta: remAccMeta.ActorMeta(),
}
func NewGeneratorWithSectorsAndUpgradeSchedule(numSectors int, us stmgr.UpgradeSchedule) (*ChainGen, error) {
j := journal.NilJournal()
// TODO: we really shouldn't modify a global variable here.
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
2020-05-12 16:58:43 +00:00
2019-07-25 22:15:33 +00:00
mr := repo.NewMemory(nil)
2019-11-12 17:59:38 +00:00
lr, err := mr.Lock(repo.StorageMiner)
2019-07-25 22:15:33 +00:00
if err != nil {
2019-08-15 18:45:32 +00:00
return nil, xerrors.Errorf("taking mem-repo lock failed: %w", err)
2019-07-25 22:15:33 +00:00
}
2021-01-26 10:25:34 +00:00
ds, err := lr.Datastore(context.TODO(), "/metadata")
2019-07-29 19:34:09 +00:00
if err != nil {
2019-08-15 18:45:32 +00:00
return nil, xerrors.Errorf("failed to get metadata datastore: %w", err)
2019-07-29 19:34:09 +00:00
}
bs, err := lr.Blockstore(context.TODO(), repo.UniversalBlockstore)
2019-07-25 22:15:33 +00:00
if err != nil {
return nil, err
2019-07-25 22:15:33 +00:00
}
2019-07-29 19:34:09 +00:00
defer func() {
if c, ok := bs.(io.Closer); ok {
if err := c.Close(); err != nil {
log.Warnf("failed to close blockstore: %s", err)
}
}
}()
2019-07-25 22:15:33 +00:00
ks, err := lr.KeyStore()
if err != nil {
2019-08-15 18:45:32 +00:00
return nil, xerrors.Errorf("getting repo keystore failed: %w", err)
2019-07-25 22:15:33 +00:00
}
w, err := wallet.NewWallet(ks)
if err != nil {
2019-08-15 18:45:32 +00:00
return nil, xerrors.Errorf("creating memrepo wallet failed: %w", err)
2019-07-25 22:15:33 +00:00
}
banker, err := w.WalletNew(context.Background(), types.KTSecp256k1)
2019-07-25 22:15:33 +00:00
if err != nil {
2019-08-15 18:45:32 +00:00
return nil, xerrors.Errorf("failed to generate banker key: %w", err)
2019-07-25 22:15:33 +00:00
}
2019-07-30 13:20:40 +00:00
receievers := make([]address.Address, msgsPerBlock)
for r := range receievers {
receievers[r], err = w.WalletNew(context.Background(), types.KTBLS)
2019-07-30 13:20:40 +00:00
if err != nil {
2019-08-15 18:45:32 +00:00
return nil, xerrors.Errorf("failed to generate receiver key: %w", err)
2019-07-30 13:20:40 +00:00
}
}
maddr1 := genesis2.MinerAddress(0)
2019-11-29 03:38:18 +00:00
m1temp, err := os.MkdirTemp("", "preseal")
2019-11-29 03:38:18 +00:00
if err != nil {
return nil, err
}
2020-07-03 01:29:06 +00:00
genm1, k1, err := seed.PreSeal(maddr1, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, numSectors, m1temp, []byte("some randomness"), nil, true)
2019-11-29 03:38:18 +00:00
if err != nil {
return nil, err
}
maddr2 := genesis2.MinerAddress(1)
m2temp, err := os.MkdirTemp("", "preseal")
if err != nil {
return nil, err
}
2020-07-03 01:29:06 +00:00
genm2, k2, err := seed.PreSeal(maddr2, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, numSectors, m2temp, []byte("some randomness"), nil, true)
if err != nil {
return nil, err
}
2020-09-04 20:17:28 +00:00
mk1, err := w.WalletImport(context.Background(), k1)
if err != nil {
return nil, err
}
2020-09-04 20:17:28 +00:00
mk2, err := w.WalletImport(context.Background(), k2)
if err != nil {
return nil, err
}
sys := vm.Syscalls(&genFakeVerifier{})
tpl := genesis.Template{
NetworkVersion: network.Version0,
2020-02-13 00:15:33 +00:00
Accounts: []genesis.Actor{
{
Type: genesis.TAccount,
2020-07-17 21:34:18 +00:00
Balance: types.FromFil(20_000_000),
Meta: (&genesis.AccountMeta{Owner: mk1}).ActorMeta(),
},
{
Type: genesis.TAccount,
2020-07-17 21:34:18 +00:00
Balance: types.FromFil(20_000_000),
Meta: (&genesis.AccountMeta{Owner: mk2}).ActorMeta(),
},
{
Type: genesis.TAccount,
Balance: types.FromFil(50000),
Meta: (&genesis.AccountMeta{Owner: banker}).ActorMeta(),
},
},
2020-02-13 00:15:33 +00:00
Miners: []genesis.Miner{
*genm1,
*genm2,
2019-11-29 03:38:18 +00:00
},
2020-08-18 21:30:49 +00:00
VerifregRootKey: DefaultVerifregRootkeyActor,
RemainderAccount: DefaultRemainderAccountActor,
2020-10-08 21:57:03 +00:00
NetworkName: uuid.New().String(),
2020-08-18 21:30:49 +00:00
Timestamp: uint64(build.Clock.Now().Add(-500 * time.Duration(build.BlockDelaySecs) * time.Second).Unix()),
2019-09-06 20:03:28 +00:00
}
genb, err := genesis2.MakeGenesisBlock(context.TODO(), j, bs, sys, tpl)
2019-07-25 22:15:33 +00:00
if err != nil {
2019-08-15 18:45:32 +00:00
return nil, xerrors.Errorf("make genesis block failed: %w", err)
2019-07-25 22:15:33 +00:00
}
2021-09-02 16:07:23 +00:00
cs := store.NewChainStore(bs, bs, ds, filcns.Weight, j)
2019-07-25 22:15:33 +00:00
genfb := &types.FullBlock{Header: genb.Genesis}
gents := store.NewFullTipSet([]*types.FullBlock{genfb})
2019-07-25 22:15:33 +00:00
2021-12-11 21:03:00 +00:00
if err := cs.SetGenesis(context.TODO(), genb.Genesis); err != nil {
2019-08-15 18:45:32 +00:00
return nil, xerrors.Errorf("set genesis failed: %w", err)
2019-07-26 12:19:27 +00:00
}
2020-04-10 21:07:18 +00:00
mgen := make(map[address.Address]WinningPoStProver)
for i := range tpl.Miners {
2020-04-10 21:07:18 +00:00
mgen[genesis2.MinerAddress(uint64(i))] = &wppProvider{}
2019-11-21 22:21:45 +00:00
}
miners := []address.Address{maddr1, maddr2}
beac := beacon.Schedule{{Start: 0, Beacon: beacon.NewMockBeacon(time.Second)}}
//beac, err := drand.NewDrandBeacon(tpl.Timestamp, build.BlockDelaySecs)
//if err != nil {
//return nil, xerrors.Errorf("creating drand beacon: %w", err)
//}
2023-03-12 13:25:07 +00:00
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), sys, us, beac, ds, index.DummyMsgIndex)
2021-09-18 17:57:04 +00:00
if err != nil {
return nil, xerrors.Errorf("initing stmgr: %w", err)
}
2019-07-25 22:15:33 +00:00
gen := &ChainGen{
bs: bs,
cs: cs,
sm: sm,
2019-07-25 22:15:33 +00:00
msgsPerBlock: msgsPerBlock,
genesis: genb.Genesis,
beacon: beac,
2019-07-30 13:20:40 +00:00
w: w,
GetMessages: getRandomMessages,
Miners: miners,
eppProvs: mgen,
banker: banker,
receivers: receievers,
2019-07-30 13:20:40 +00:00
CurTipset: gents,
2019-07-29 19:34:09 +00:00
r: mr,
2019-07-29 19:34:09 +00:00
lr: lr,
2019-07-25 22:15:33 +00:00
}
return gen, nil
}
2020-05-01 00:54:41 +00:00
func NewGenerator() (*ChainGen, error) {
return NewGeneratorWithSectors(1)
}
func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
2021-09-02 16:07:23 +00:00
return NewGeneratorWithSectorsAndUpgradeSchedule(numSectors, filcns.DefaultUpgradeSchedule())
}
func NewGeneratorWithUpgradeSchedule(us stmgr.UpgradeSchedule) (*ChainGen, error) {
return NewGeneratorWithSectorsAndUpgradeSchedule(1, us)
}
func (cg *ChainGen) Blockstore() blockstore.Blockstore {
return cg.bs
}
2020-08-09 00:20:37 +00:00
func (cg *ChainGen) StateManager() *stmgr.StateManager {
return cg.sm
}
func (cg *ChainGen) SetStateManager(sm *stmgr.StateManager) {
cg.sm = sm
}
func (cg *ChainGen) ChainStore() *store.ChainStore {
return cg.cs
}
2021-09-18 17:57:04 +00:00
func (cg *ChainGen) BeaconSchedule() beacon.Schedule {
return cg.beacon
}
2019-07-25 22:15:33 +00:00
func (cg *ChainGen) Genesis() *types.BlockHeader {
return cg.genesis
}
func (cg *ChainGen) GenesisCar() ([]byte, error) {
offl := offline.Exchange(cg.bs)
blkserv := blockservice.New(cg.bs, offl)
dserv := merkledag.NewDAGService(blkserv)
out := new(bytes.Buffer)
2020-02-21 19:27:29 +00:00
if err := car.WriteCarWithWalker(context.TODO(), dserv, []cid.Cid{cg.Genesis().Cid()}, out, CarWalkFunc); err != nil {
2019-11-21 22:21:45 +00:00
return nil, xerrors.Errorf("genesis car write car failed: %w", err)
}
return out.Bytes(), nil
}
2020-02-21 19:27:29 +00:00
func CarWalkFunc(nd format.Node) (out []*format.Link, err error) {
for _, link := range nd.Links() {
pref := link.Cid.Prefix()
if pref.Codec == cid.FilCommitmentSealed || pref.Codec == cid.FilCommitmentUnsealed {
2020-02-21 19:27:29 +00:00
continue
}
out = append(out, link)
}
return out, nil
}
func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m address.Address, round abi.ChainEpoch) ([]types.BeaconEntry, *types.ElectionProof, *types.Ticket, error) {
2020-04-30 22:11:14 +00:00
mc := &mca{w: cg.w, sm: cg.sm, pv: ffiwrapper.ProofVerifier, bcn: cg.beacon}
2020-04-09 17:13:09 +00:00
mbi, err := mc.MinerGetBaseInfo(ctx, m, round, pts.Key())
if err != nil {
2020-04-09 17:13:09 +00:00
return nil, nil, nil, xerrors.Errorf("get miner base info: %w", err)
}
2020-12-02 12:05:01 +00:00
entries := mbi.BeaconEntries
rbase := mbi.PrevBeaconEntry
if len(entries) > 0 {
rbase = entries[len(entries)-1]
}
2020-04-09 17:13:09 +00:00
eproof, err := IsRoundWinner(ctx, pts, round, m, rbase, mbi, mc)
if err != nil {
return nil, nil, nil, xerrors.Errorf("checking round winner failed: %w", err)
}
buf := new(bytes.Buffer)
if err := m.MarshalCBOR(buf); err != nil {
return nil, nil, nil, xerrors.Errorf("failed to cbor marshal address: %w", err)
}
if round > build.UpgradeSmokeHeight {
buf.Write(pts.MinTicket().VRFProof)
}
2020-04-29 22:25:48 +00:00
2021-09-18 17:57:04 +00:00
ticketRand, err := rand.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_TicketProduction, round-build.TicketRandomnessLookback, buf.Bytes())
2020-02-23 20:00:47 +00:00
if err != nil {
return nil, nil, nil, err
2020-02-23 20:00:47 +00:00
}
st := pts.ParentState()
worker, err := stmgr.GetMinerWorkerRaw(ctx, cg.sm, st, m)
if err != nil {
return nil, nil, nil, xerrors.Errorf("get miner worker: %w", err)
}
2019-08-16 04:40:59 +00:00
sf := func(ctx context.Context, a address.Address, i []byte) (*crypto.Signature, error) {
return cg.w.WalletSign(ctx, a, i, api.MsgMeta{
2020-10-08 23:27:49 +00:00
Type: api.MTUnknown,
})
}
vrfout, err := ComputeVRF(ctx, sf, worker, ticketRand)
if err != nil {
return nil, nil, nil, xerrors.Errorf("compute VRF: %w", err)
2019-08-15 02:30:21 +00:00
}
return entries, eproof, &types.Ticket{VRFProof: vrfout}, nil
2019-07-25 22:15:33 +00:00
}
type MinedTipSet struct {
TipSet *store.FullTipSet
Messages []*types.SignedMessage
}
func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) {
2021-09-18 17:57:04 +00:00
return cg.NextTipSetWithNulls(0)
}
func (cg *ChainGen) NextTipSetWithNulls(nulls abi.ChainEpoch) (*MinedTipSet, error) {
mts, err := cg.NextTipSetFromMiners(cg.CurTipset.TipSet(), cg.Miners, nulls)
if err != nil {
return nil, err
}
return mts, nil
}
func (cg *ChainGen) SetWinningPoStProver(m address.Address, wpp WinningPoStProver) {
cg.eppProvs[m] = wpp
}
func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Address, nulls abi.ChainEpoch) (*MinedTipSet, error) {
2020-08-09 00:20:37 +00:00
ms, err := cg.GetMessages(cg)
2019-07-25 22:15:33 +00:00
if err != nil {
return nil, xerrors.Errorf("get random messages: %w", err)
2019-07-25 22:15:33 +00:00
}
2020-08-09 00:20:37 +00:00
msgs := make([][]*types.SignedMessage, len(miners))
for i := range msgs {
msgs[i] = ms
}
fts, err := cg.NextTipSetFromMinersWithMessagesAndNulls(base, miners, msgs, nulls)
2020-08-09 00:20:37 +00:00
if err != nil {
return nil, err
}
cg.CurTipset = fts
2020-08-09 00:20:37 +00:00
return &MinedTipSet{
TipSet: fts,
Messages: ms,
}, nil
}
func (cg *ChainGen) NextTipSetFromMinersWithMessagesAndNulls(base *types.TipSet, miners []address.Address, msgs [][]*types.SignedMessage, nulls abi.ChainEpoch) (*store.FullTipSet, error) {
ctx := context.TODO()
2020-08-09 00:20:37 +00:00
var blks []*types.FullBlock
for round := base.Height() + nulls + 1; len(blks) == 0; round++ {
2020-08-09 00:20:37 +00:00
for mi, m := range miners {
bvals, et, ticket, err := cg.nextBlockProof(ctx, base, m, round)
if err != nil {
return nil, xerrors.Errorf("next block proof: %w", err)
}
if et != nil {
2020-04-17 20:44:13 +00:00
// TODO: maybe think about passing in more real parameters to this?
wpost, err := cg.eppProvs[m].ComputeProof(ctx, nil, nil, round, network.Version0)
2020-04-17 20:44:13 +00:00
if err != nil {
return nil, err
}
2020-08-09 00:20:37 +00:00
fblk, err := cg.makeBlock(base, m, ticket, et, bvals, round, wpost, msgs[mi])
if err != nil {
return nil, xerrors.Errorf("making a block for next tipset failed: %w", err)
}
blks = append(blks, fblk)
}
}
}
fts := store.NewFullTipSet(blks)
if err := cg.cs.PersistTipsets(ctx, []*types.TipSet{fts.TipSet()}); err != nil {
return nil, xerrors.Errorf("failed to persist tipset: %w", err)
}
for _, blk := range blks {
if err := cg.cs.AddToTipSetTracker(ctx, blk.Header); err != nil {
return nil, xerrors.Errorf("failed to add to tipset tracker: %w", err)
}
}
if err := cg.cs.RefreshHeaviestTipSet(ctx, fts.TipSet().Height()); err != nil {
return nil, xerrors.Errorf("failed to put tipset: %w", err)
}
cg.CurTipset = fts
return fts, nil
}
func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticket *types.Ticket,
eticket *types.ElectionProof, bvals []types.BeaconEntry, height abi.ChainEpoch,
2022-04-20 21:34:28 +00:00
wpost []proof7.PoStProof, msgs []*types.SignedMessage) (*types.FullBlock, error) {
2019-10-10 03:04:10 +00:00
var ts uint64
if cg.Timestamper != nil {
ts = cg.Timestamper(parents, height-parents.Height())
2019-10-10 03:04:10 +00:00
} else {
2020-06-30 21:56:13 +00:00
ts = parents.MinTimestamp() + uint64(height-parents.Height())*build.BlockDelaySecs
2019-10-10 03:04:10 +00:00
}
2021-09-02 16:07:23 +00:00
fblk, err := filcns.NewFilecoinExpectedConsensus(cg.sm, nil, nil, nil).CreateBlock(context.TODO(), cg.w, &api.BlockTemplate{
2020-04-17 20:44:13 +00:00
Miner: m,
Parents: parents.Key(),
Ticket: vrfticket,
Eproof: eticket,
BeaconValues: bvals,
Messages: msgs,
Epoch: height,
Timestamp: ts,
WinningPoStProof: wpost,
2020-04-09 00:24:10 +00:00
})
if err != nil {
return nil, err
}
return fblk, err
}
// ResyncBankerNonce is used for dealing with messages made when
// simulating forks
func (cg *ChainGen) ResyncBankerNonce(ts *types.TipSet) error {
st, err := cg.sm.ParentState(ts)
if err != nil {
return err
}
act, err := st.GetActor(cg.banker)
if err != nil {
return err
}
cg.bankerNonce = act.Nonce
return nil
}
func (cg *ChainGen) Banker() address.Address {
return cg.banker
}
2020-09-04 20:17:28 +00:00
func (cg *ChainGen) Wallet() *wallet.LocalWallet {
return cg.w
}
func getRandomMessages(cg *ChainGen) ([]*types.SignedMessage, error) {
2019-07-30 13:20:40 +00:00
msgs := make([]*types.SignedMessage, cg.msgsPerBlock)
for m := range msgs {
msg := types.Message{
To: cg.receivers[m%len(cg.receivers)],
2019-07-30 13:20:40 +00:00
From: cg.banker,
Nonce: atomic.AddUint64(&cg.bankerNonce, 1) - 1,
Value: types.NewInt(uint64(m + 1)),
Method: 0,
GasLimit: 100_000_000,
GasFeeCap: types.NewInt(0),
GasPremium: types.NewInt(0),
2019-07-30 13:20:40 +00:00
}
sig, err := cg.w.WalletSign(context.TODO(), cg.banker, msg.Cid().Bytes(), api.MsgMeta{
2020-10-08 23:27:49 +00:00
Type: api.MTUnknown, // testing
})
2019-07-30 13:20:40 +00:00
if err != nil {
return nil, err
2019-07-30 13:20:40 +00:00
}
msgs[m] = &types.SignedMessage{
Message: msg,
Signature: *sig,
}
}
return msgs, nil
2019-07-25 22:15:33 +00:00
}
2019-07-29 19:34:09 +00:00
func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
if err := cg.lr.Close(); err != nil {
return nil, err
}
return cg.r, nil
}
type MiningCheckAPI interface {
StateGetRandomnessFromBeacon(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error)
StateGetRandomnessFromTickets(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error)
MinerGetBaseInfo(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error)
2019-11-25 04:45:13 +00:00
2020-02-12 23:52:36 +00:00
WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error)
}
type mca struct {
2020-09-04 20:17:28 +00:00
w *wallet.LocalWallet
2020-04-30 22:11:14 +00:00
sm *stmgr.StateManager
2022-06-17 11:52:19 +00:00
pv storiface.Verifier
bcn beacon.Schedule
}
func (mca mca) StateGetRandomnessFromTickets(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error) {
2021-09-18 17:57:04 +00:00
return mca.sm.GetRandomnessFromTickets(ctx, personalization, randEpoch, entropy, tsk)
}
func (mca mca) StateGetRandomnessFromBeacon(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error) {
2021-09-18 17:57:04 +00:00
return mca.sm.GetRandomnessFromBeacon(ctx, personalization, randEpoch, entropy, tsk)
2020-08-11 23:58:35 +00:00
}
func (mca mca) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoch abi.ChainEpoch, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
2020-04-30 22:11:14 +00:00
return stmgr.MinerGetBaseInfo(ctx, mca.sm, mca.bcn, tsk, epoch, maddr, mca.pv)
2019-11-25 04:45:13 +00:00
}
2020-02-12 23:52:36 +00:00
func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*crypto.Signature, error) {
return mca.w.WalletSign(ctx, a, v, api.MsgMeta{
2020-10-08 23:27:49 +00:00
Type: api.MTUnknown,
})
}
2020-04-10 21:07:18 +00:00
type WinningPoStProver interface {
GenerateCandidates(context.Context, abi.PoStRandomness, uint64) ([]uint64, error)
2022-04-20 21:34:28 +00:00
ComputeProof(context.Context, []proof7.ExtendedSectorInfo, abi.PoStRandomness, abi.ChainEpoch, network.Version) ([]proof7.PoStProof, error)
2019-11-21 22:21:45 +00:00
}
2020-04-10 21:07:18 +00:00
type wppProvider struct{}
2019-11-21 22:21:45 +00:00
2020-04-10 21:07:18 +00:00
func (wpp *wppProvider) GenerateCandidates(ctx context.Context, _ abi.PoStRandomness, _ uint64) ([]uint64, error) {
return []uint64{0}, nil
2019-11-21 22:21:45 +00:00
}
2022-04-20 21:34:28 +00:00
func (wpp *wppProvider) ComputeProof(context.Context, []proof7.ExtendedSectorInfo, abi.PoStRandomness, abi.ChainEpoch, network.Version) ([]proof7.PoStProof, error) {
return ValidWpostForTesting, nil
2019-11-21 22:21:45 +00:00
}
2020-04-08 15:11:42 +00:00
func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch,
2020-04-09 17:13:09 +00:00
miner address.Address, brand types.BeaconEntry, mbi *api.MiningBaseInfo, a MiningCheckAPI) (*types.ElectionProof, error) {
2020-04-08 15:11:42 +00:00
buf := new(bytes.Buffer)
if err := miner.MarshalCBOR(buf); err != nil {
return nil, xerrors.Errorf("failed to cbor marshal address: %w", err)
}
2021-09-18 17:57:04 +00:00
electionRand, err := rand.DrawRandomness(brand.Data, crypto.DomainSeparationTag_ElectionProofProduction, round, buf.Bytes())
if err != nil {
return nil, xerrors.Errorf("failed to draw randomness: %w", err)
}
2020-04-16 17:17:56 +00:00
vrfout, err := ComputeVRF(ctx, a.WalletSign, mbi.WorkerKey, electionRand)
if err != nil {
return nil, xerrors.Errorf("failed to compute VRF: %w", err)
}
ep := &types.ElectionProof{VRFProof: vrfout}
j := ep.ComputeWinCount(mbi.MinerPower, mbi.NetworkPower)
ep.WinCount = j
if j < 1 {
return nil, nil
2020-04-08 15:11:42 +00:00
}
return ep, nil
2019-12-03 18:25:56 +00:00
}
2020-02-12 23:52:36 +00:00
type SignFunc func(context.Context, address.Address, []byte) (*crypto.Signature, error)
2020-02-23 20:00:47 +00:00
func ComputeVRF(ctx context.Context, sign SignFunc, worker address.Address, sigInput []byte) ([]byte, error) {
2019-11-21 22:21:45 +00:00
sig, err := sign(ctx, worker, sigInput)
if err != nil {
return nil, err
}
2020-02-12 23:52:36 +00:00
if sig.Type != crypto.SigTypeBLS {
return nil, fmt.Errorf("miner worker address was not a BLS key")
}
return sig.Data, nil
}
type genFakeVerifier struct{}
2022-06-17 11:52:19 +00:00
var _ storiface.Verifier = (*genFakeVerifier)(nil)
2022-04-20 21:34:28 +00:00
func (m genFakeVerifier) VerifySeal(svi proof7.SealVerifyInfo) (bool, error) {
return true, nil
}
2022-04-20 21:34:28 +00:00
func (m genFakeVerifier) VerifyAggregateSeals(aggregate proof7.AggregateSealVerifyProofAndInfos) (bool, error) {
2020-04-17 14:47:19 +00:00
panic("not supported")
2020-04-10 21:07:18 +00:00
}
2021-11-04 15:59:29 +00:00
func (m genFakeVerifier) VerifyReplicaUpdate(update proof7.ReplicaUpdateInfo) (bool, error) {
panic("not supported")
}
func (m genFakeVerifier) VerifyWinningPoSt(ctx context.Context, info proof7.WinningPoStVerifyInfo) (bool, error) {
2021-03-10 15:16:44 +00:00
panic("not supported")
}
func (m genFakeVerifier) VerifyWindowPoSt(ctx context.Context, info proof7.WindowPoStVerifyInfo) (bool, error) {
2020-04-17 14:47:19 +00:00
panic("not supported")
}
2020-06-15 16:30:49 +00:00
func (m genFakeVerifier) GenerateWinningPoStSectorChallenge(ctx context.Context, proof abi.RegisteredPoStProof, id abi.ActorID, randomness abi.PoStRandomness, u uint64) ([]uint64, error) {
2020-04-17 14:47:19 +00:00
panic("not supported")
}