diff --git a/app/node/builder.go b/app/node/builder.go index 23f7f46ddd..acc54f56fb 100644 --- a/app/node/builder.go +++ b/app/node/builder.go @@ -7,6 +7,7 @@ import ( "github.com/filecoin-project/venus/app/submodule/dagservice" "github.com/filecoin-project/venus/app/submodule/eth" + "github.com/filecoin-project/venus/app/submodule/f3" "github.com/filecoin-project/venus/app/submodule/network" "github.com/ipfs-force-community/sophon-auth/core" "github.com/ipfs-force-community/sophon-auth/jwtclient" @@ -103,9 +104,6 @@ func (b *Builder) build(ctx context.Context) (*Node, error) { chainClock: b.chainClock, } - // modules - nd.circulatiingSupplyCalculator = chain2.NewCirculatingSupplyCalculator(b.repo.Datastore(), b.genBlk.ParentStateRoot, b.repo.Config().NetworkParams.ForkUpgradeParam) - // services nd.configModule = config2.NewConfigModule(b.repo) @@ -114,7 +112,7 @@ func (b *Builder) build(ctx context.Context) (*Node, error) { return nil, errors.Wrap(err, "failed to build node.blockstore") } - nd.chain, err = chain.NewChainSubmodule(ctx, (*builder)(b), nd.circulatiingSupplyCalculator) + nd.chain, err = chain.NewChainSubmodule(ctx, (*builder)(b)) if err != nil { return nil, errors.Wrap(err, "failed to build node.Chain") } @@ -129,7 +127,7 @@ func (b *Builder) build(ctx context.Context) (*Node, error) { return nil, errors.Wrap(err, "failed to build node.dagservice") } - nd.syncer, err = syncer.NewSyncerSubmodule(ctx, (*builder)(b), nd.blockstore, nd.network, nd.chain, nd.circulatiingSupplyCalculator) + nd.syncer, err = syncer.NewSyncerSubmodule(ctx, (*builder)(b), nd.blockstore, nd.network, nd.chain, nd.chain.CirculatingSupplyCalculator) if err != nil { return nil, errors.Wrap(err, "failed to build node.Syncer") } @@ -139,6 +137,11 @@ func (b *Builder) build(ctx context.Context) (*Node, error) { return nil, errors.Wrap(err, "failed to build node.wallet") } + nd.f3, err = f3.NewF3Submodule(ctx, nd.repo, nd.chain, nd.network, nd.wallet.API()) + if err != nil { + return nil, errors.Wrap(err, "failed to build node.f3") + } + nd.mpool, err = mpool.NewMpoolSubmodule(ctx, (*builder)(b), nd.network, nd.chain, nd.wallet) if err != nil { return nil, errors.Wrap(err, "failed to build node.mpool") @@ -194,6 +197,7 @@ func (b *Builder) build(ctx context.Context) (*Node, error) { nd.common, nd.eth, nd.actorEvent, + nd.f3, ) if err != nil { diff --git a/app/node/env.go b/app/node/env.go index 1e7812f801..719d4fd76b 100644 --- a/app/node/env.go +++ b/app/node/env.go @@ -7,6 +7,7 @@ import ( "github.com/filecoin-project/venus/app/submodule/storagenetworking" v1api "github.com/filecoin-project/venus/venus-shared/api/chain/v1" + "github.com/filecoin-project/venus/venus-shared/api/f3" ) // Env is the environment for command API handlers. @@ -26,6 +27,7 @@ type Env struct { PaychAPI v1api.IPaychan CommonAPI v1api.ICommon EthAPI v1api.IETH + F3API f3.F3 } var _ cmds.Environment = (*Env)(nil) diff --git a/app/node/node.go b/app/node/node.go index 58e9458692..91e8b817f5 100644 --- a/app/node/node.go +++ b/app/node/node.go @@ -18,6 +18,7 @@ import ( configModule "github.com/filecoin-project/venus/app/submodule/config" "github.com/filecoin-project/venus/app/submodule/dagservice" "github.com/filecoin-project/venus/app/submodule/eth" + "github.com/filecoin-project/venus/app/submodule/f3" "github.com/filecoin-project/venus/app/submodule/market" "github.com/filecoin-project/venus/app/submodule/mining" "github.com/filecoin-project/venus/app/submodule/mpool" @@ -26,7 +27,6 @@ import ( "github.com/filecoin-project/venus/app/submodule/storagenetworking" syncer2 "github.com/filecoin-project/venus/app/submodule/syncer" "github.com/filecoin-project/venus/app/submodule/wallet" - "github.com/filecoin-project/venus/pkg/chain" "github.com/filecoin-project/venus/pkg/clock" "github.com/filecoin-project/venus/pkg/config" _ "github.com/filecoin-project/venus/pkg/crypto/bls" // enable bls signatures @@ -71,8 +71,6 @@ type Node struct { // It contains all persistent artifacts of the filecoin node. repo repo.Repo - // moduls - circulatiingSupplyCalculator chain.ICirculatingSupplyCalcualtor // // Core services // @@ -94,6 +92,7 @@ type Node struct { wallet *wallet.WalletSubmodule mpool *mpool.MessagePoolSubmodule storageNetworking *storagenetworking.StorageNetworkingSubmodule + f3 *f3.F3Submodule // paychannel and market market *market.MarketSubmodule @@ -381,6 +380,7 @@ func (node *Node) createServerEnv(ctx context.Context) *Env { MarketAPI: node.market.API(), CommonAPI: node.common, EthAPI: node.eth.API(), + F3API: node.f3.API(), } return &env diff --git a/app/node/rpc.go b/app/node/rpc.go index 549e48eecf..319544a5ab 100644 --- a/app/node/rpc.go +++ b/app/node/rpc.go @@ -210,6 +210,7 @@ func aliasETHAPI(rpcServer *jsonrpc.RPCServer) { rpcServer.AliasMethod("trace_block", "Filecoin.EthTraceBlock") rpcServer.AliasMethod("trace_replayBlockTransactions", "Filecoin.EthTraceReplayBlockTransactions") + rpcServer.AliasMethod("trace_transaction", "Filecoin.EthTraceTransaction") rpcServer.AliasMethod("net_version", "Filecoin.NetVersion") rpcServer.AliasMethod("net_listening", "Filecoin.NetListening") diff --git a/app/submodule/chain/chain_submodule.go b/app/submodule/chain/chain_submodule.go index 502e5cb912..d28eb1cc5f 100644 --- a/app/submodule/chain/chain_submodule.go +++ b/app/submodule/chain/chain_submodule.go @@ -26,11 +26,12 @@ import ( // ChainSubmodule enhances the `Node` with chain capabilities. type ChainSubmodule struct { //nolint - ChainReader *chain.Store - MessageStore *chain.MessageStore - Processor *consensus.DefaultProcessor - Fork fork.IFork - SystemCall vm.SyscallsImpl + ChainReader *chain.Store + MessageStore *chain.MessageStore + Processor *consensus.DefaultProcessor + Fork fork.IFork + SystemCall vm.SyscallsImpl + CirculatingSupplyCalculator *chain.CirculatingSupplyCalculator CheckPoint types.TipSetKey Drand beacon.Schedule @@ -52,11 +53,10 @@ type chainConfig interface { // NewChainSubmodule creates a new chain submodule. func NewChainSubmodule(ctx context.Context, config chainConfig, - circulatiingSupplyCalculator chain.ICirculatingSupplyCalcualtor, ) (*ChainSubmodule, error) { repo := config.Repo() // initialize chain store - chainStore := chain.NewStore(repo.ChainDatastore(), repo.Datastore(), config.GenesisCid(), circulatiingSupplyCalculator, chainselector.Weight) + chainStore := chain.NewStore(repo.ChainDatastore(), repo.Datastore(), config.GenesisCid(), chainselector.Weight) // drand genBlk, err := chainStore.GetGenesisBlock(context.TODO()) if err != nil { @@ -73,22 +73,26 @@ func NewChainSubmodule(ctx context.Context, if err != nil { return nil, err } + + circulatingSupplyCalculator := chain.NewCirculatingSupplyCalculator(repo.Datastore(), genBlk.ParentStateRoot, repo.Config().NetworkParams.ForkUpgradeParam, fork.GetNetworkVersion) + faultChecker := consensusfault.NewFaultChecker(chainStore, fork) syscalls := vmsupport.NewSyscalls(faultChecker, config.Verifier()) - processor := consensus.NewDefaultProcessor(syscalls, circulatiingSupplyCalculator, chainStore, config.Repo().Config().NetworkParams) + processor := consensus.NewDefaultProcessor(syscalls, circulatingSupplyCalculator, chainStore, config.Repo().Config().NetworkParams) waiter := chain.NewWaiter(chainStore, messageStore, config.Repo().Datastore(), cbor.NewCborStore(config.Repo().Datastore())) store := &ChainSubmodule{ - ChainReader: chainStore, - MessageStore: messageStore, - Processor: processor, - SystemCall: syscalls, - Fork: fork, - Drand: drand, - config: config, - Waiter: waiter, - CheckPoint: chainStore.GetCheckPoint(), + ChainReader: chainStore, + MessageStore: messageStore, + Processor: processor, + SystemCall: syscalls, + Fork: fork, + CirculatingSupplyCalculator: circulatingSupplyCalculator, + Drand: drand, + config: config, + Waiter: waiter, + CheckPoint: chainStore.GetCheckPoint(), } err = store.ChainReader.Load(context.TODO()) if err != nil { diff --git a/app/submodule/chain/chaininfo_api.go b/app/submodule/chain/chaininfo_api.go index 60db4cd206..61fcdbb0b0 100644 --- a/app/submodule/chain/chaininfo_api.go +++ b/app/submodule/chain/chaininfo_api.go @@ -744,6 +744,7 @@ func (cia *chainInfoAPI) StateGetNetworkParams(ctx context.Context) (*types.Netw UpgradeWatermelonHeight: cfg.NetworkParams.ForkUpgradeParam.UpgradeWatermelonHeight, UpgradeDragonHeight: cfg.NetworkParams.ForkUpgradeParam.UpgradeDragonHeight, UpgradePhoenixHeight: cfg.NetworkParams.ForkUpgradeParam.UpgradePhoenixHeight, + UpgradeWaffleHeight: cfg.NetworkParams.ForkUpgradeParam.UpgradeWaffleHeight, }, Eip155ChainID: cfg.NetworkParams.Eip155ChainID, } diff --git a/app/submodule/chain/miner_api.go b/app/submodule/chain/miner_api.go index 989f1b7164..6817d2fa4f 100644 --- a/app/submodule/chain/miner_api.go +++ b/app/submodule/chain/miner_api.go @@ -80,7 +80,7 @@ func (msa *minerStateAPI) StateSectorPreCommitInfo(ctx context.Context, maddr ad // NOTE: returned info.Expiration may not be accurate in some cases, use StateSectorExpiration to get accurate // expiration epoch // return nil if sector not found -func (msa *minerStateAPI) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*types.SectorOnChainInfo, error) { +func (msa *minerStateAPI) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorOnChainInfo, error) { _, view, err := msa.Stmgr.ParentStateViewTsk(ctx, tsk) if err != nil { return nil, fmt.Errorf("loading tipset %s: %v", tsk, err) @@ -141,8 +141,21 @@ func (msa *minerStateAPI) StateMinerInfo(ctx context.Context, maddr address.Addr ConsensusFaultElapsed: minfo.ConsensusFaultElapsed, PendingOwnerAddress: minfo.PendingOwnerAddress, Beneficiary: minfo.Beneficiary, - BeneficiaryTerm: &minfo.BeneficiaryTerm, - PendingBeneficiaryTerm: minfo.PendingBeneficiaryTerm, + BeneficiaryTerm: &types.BeneficiaryTerm{ + Quota: minfo.BeneficiaryTerm.Quota, + UsedQuota: minfo.BeneficiaryTerm.UsedQuota, + Expiration: minfo.BeneficiaryTerm.Expiration, + }, + } + + if minfo.PendingBeneficiaryTerm != nil { + ret.PendingBeneficiaryTerm = &types.PendingBeneficiaryChange{ + NewBeneficiary: minfo.PendingBeneficiaryTerm.NewBeneficiary, + NewQuota: minfo.PendingBeneficiaryTerm.NewQuota, + NewExpiration: minfo.PendingBeneficiaryTerm.NewExpiration, + ApprovedByBeneficiary: minfo.PendingBeneficiaryTerm.ApprovedByBeneficiary, + ApprovedByNominee: minfo.PendingBeneficiaryTerm.ApprovedByNominee, + } } if minfo.PendingWorkerKey != nil { @@ -320,7 +333,7 @@ func (msa *minerStateAPI) StateMinerDeadlines(ctx context.Context, maddr address } // StateMinerSectors returns info about the given miner's sectors. If the filter bitfield is nil, all sectors are included. -func (msa *minerStateAPI) StateMinerSectors(ctx context.Context, maddr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*types.SectorOnChainInfo, error) { +func (msa *minerStateAPI) StateMinerSectors(ctx context.Context, maddr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) { _, view, err := msa.Stmgr.ParentStateViewTsk(ctx, tsk) if err != nil { return nil, fmt.Errorf("Stmgr.ParentStateViewTsk failed:%v", err) @@ -856,7 +869,7 @@ func (msa *minerStateAPI) StateVMCirculatingSupplyInternal(ctx context.Context, return types.CirculatingSupply{}, err } - return msa.ChainReader.GetCirculatingSupplyDetailed(ctx, ts.Height(), sTree) + return msa.CirculatingSupplyCalculator.GetCirculatingSupplyDetailed(ctx, ts.Height(), sTree) } // StateCirculatingSupply returns the exact circulating supply of Filecoin at the given tipset. @@ -869,7 +882,22 @@ func (msa *minerStateAPI) StateCirculatingSupply(ctx context.Context, tsk types. tsk.String(), err) } - return msa.ChainReader.StateCirculatingSupply(ctx, parent.Key()) + ts, err := msa.ChainReader.GetTipSet(ctx, parent.Key()) + if err != nil { + return abi.TokenAmount{}, err + } + + root, err := msa.ChainReader.GetTipSetStateRoot(ctx, ts) + if err != nil { + return abi.TokenAmount{}, err + } + + sTree, err := tree.LoadState(ctx, msa.ChainReader.StateStore(), root) + if err != nil { + return abi.TokenAmount{}, err + } + + return msa.CirculatingSupplyCalculator.GetCirculatingSupply(ctx, ts.Height(), sTree) } // StateMarketDeals returns information about every deal in the Storage Market @@ -882,7 +910,7 @@ func (msa *minerStateAPI) StateMarketDeals(ctx context.Context, tsk types.TipSet } // StateMinerActiveSectors returns info about sectors that a given miner is actively proving. -func (msa *minerStateAPI) StateMinerActiveSectors(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]*types.SectorOnChainInfo, error) { // TODO: only used in cli +func (msa *minerStateAPI) StateMinerActiveSectors(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) { // TODO: only used in cli _, view, err := msa.Stmgr.ParentStateViewTsk(ctx, tsk) if err != nil { return nil, fmt.Errorf("Stmgr.ParentStateViewTsk failed:%v", err) diff --git a/app/submodule/eth/dummy.go b/app/submodule/eth/dummy.go index 09b0b69139..254d01a282 100644 --- a/app/submodule/eth/dummy.go +++ b/app/submodule/eth/dummy.go @@ -153,6 +153,10 @@ func (e *ethAPIDummy) EthTraceReplayBlockTransactions(ctx context.Context, blkNu return nil, ErrModuleDisabled } +func (e *ethAPIDummy) EthTraceTransaction(ctx context.Context, txHash string) ([]*types.EthTraceTransaction, error) { + return nil, ErrModuleDisabled +} + func (e *ethAPIDummy) start(_ context.Context) error { return nil } diff --git a/app/submodule/eth/eth_api.go b/app/submodule/eth/eth_api.go index 8fdc36ce83..ba30028c7c 100644 --- a/app/submodule/eth/eth_api.go +++ b/app/submodule/eth/eth_api.go @@ -181,7 +181,7 @@ func (a *ethAPI) EthGetBlockByHash(ctx context.Context, blkHash types.EthHash, f if err != nil { return types.EthBlock{}, fmt.Errorf("error loading tipset %s: %w", ts, err) } - return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.em.chainModule.MessageStore, a.chain) + return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.em.chainModule.MessageStore, a.em.chainModule.Stmgr) } func (a *ethAPI) parseBlkParam(ctx context.Context, blkParam string, strict bool) (tipset *types.TipSet, err error) { @@ -227,7 +227,7 @@ func (a *ethAPI) EthGetBlockByNumber(ctx context.Context, blkParam string, fullT if err != nil { return types.EthBlock{}, err } - return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.em.chainModule.MessageStore, a.chain) + return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.em.chainModule.MessageStore, a.em.chainModule.Stmgr) } func (a *ethAPI) EthGetTransactionByHash(ctx context.Context, txHash *types.EthHash) (*types.EthTx, error) { @@ -253,7 +253,7 @@ func (a *ethAPI) EthGetTransactionByHashLimited(ctx context.Context, txHash *typ // first, try to get the cid from mined transactions msgLookup, err := a.chain.StateSearchMsg(ctx, types.EmptyTSK, c, limit, true) if err == nil && msgLookup != nil { - tx, err := newEthTxFromMessageLookup(ctx, msgLookup, -1, a.em.chainModule.MessageStore, a.chain) + tx, err := newEthTxFromMessageLookup(ctx, msgLookup, -1, a.em.chainModule.MessageStore, a.em.chainModule.ChainReader) if err == nil { return &tx, nil } @@ -269,10 +269,23 @@ func (a *ethAPI) EthGetTransactionByHashLimited(ctx context.Context, txHash *typ for _, p := range pending { if p.Cid() == c { - tx, err := newEthTxFromSignedMessage(ctx, p, a.chain) + // We only return pending eth-account messages because we can't guarantee + // that the from/to addresses of other messages are conversable to 0x-style + // addresses. So we just ignore them. + // + // This should be "fine" as anyone using an "Ethereum-centric" block + // explorer shouldn't care about seeing pending messages from native + // accounts. + ethtx, err := types.EthTransactionFromSignedFilecoinMessage(p) if err != nil { - return nil, fmt.Errorf("could not convert Filecoin message into tx: %v", err) + return nil, fmt.Errorf("could not convert Filecoin message into tx: %w", err) } + + tx, err := ethtx.ToEthTx(p) + if err != nil { + return nil, fmt.Errorf("could not convert Eth transaction to EthTx: %w", err) + } + return &tx, nil } } @@ -318,7 +331,7 @@ func (a *ethAPI) EthGetMessageCidByTransactionHash(ctx context.Context, txHash * } func (a *ethAPI) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*types.EthHash, error) { - hash, err := ethTxHashFromMessageCid(ctx, cid, a.em.chainModule.MessageStore, a.chain) + hash, err := ethTxHashFromMessageCid(ctx, cid, a.em.chainModule.MessageStore) if hash == types.EmptyEthHash { // not found return nil, nil @@ -384,7 +397,7 @@ func (a *ethAPI) EthGetTransactionReceiptLimited(ctx context.Context, txHash typ return nil, nil } - tx, err := newEthTxFromMessageLookup(ctx, msgLookup, -1, a.em.chainModule.MessageStore, a.chain) + tx, err := newEthTxFromMessageLookup(ctx, msgLookup, -1, a.em.chainModule.MessageStore, a.em.chainModule.ChainReader) if err != nil { return nil, nil } @@ -397,7 +410,7 @@ func (a *ethAPI) EthGetTransactionReceiptLimited(ctx context.Context, txHash typ } } - receipt, err := newEthTxReceipt(ctx, tx, msgLookup, events, a.chain) + receipt, err := newEthTxReceipt(ctx, tx, msgLookup, events, a.chain, a.em.chainModule.ChainReader) if err != nil { return nil, nil } @@ -701,6 +714,7 @@ func (a *ethAPI) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (types. ) for blocksIncluded < int(params.BlkCount) && ts.Height() > 0 { + basefee = ts.Blocks()[0].ParentBaseFee msgs, rcpts, err := messagesAndReceipts(ctx, ts, a.em.chainModule.MessageStore, a.em.chainModule.Stmgr) if err != nil { return types.EthFeeHistory{}, fmt.Errorf("failed to retrieve messages and receipts for height %d: %w", ts.Height(), err) @@ -800,12 +814,12 @@ func (a *ethAPI) EthGasPrice(ctx context.Context) (types.EthBigInt, error) { } func (a *ethAPI) EthSendRawTransaction(ctx context.Context, rawTx types.EthBytes) (types.EthHash, error) { - txArgs, err := types.ParseEthTxArgs(rawTx) + txArgs, err := types.ParseEthTransaction(rawTx) if err != nil { return types.EmptyEthHash, err } - smsg, err := txArgs.ToSignedMessage() + smsg, err := types.ToSignedFilecoinMessage(txArgs) if err != nil { return types.EmptyEthHash, err } @@ -823,34 +837,30 @@ func (a *ethAPI) applyMessage(ctx context.Context, msg *types.Message, tsk types return nil, fmt.Errorf("failed to got tipset %v", err) } - applyTSMessages := true - if os.Getenv("VENUS_SKIP_APPLY_TS_MESSAGE_CALL_WITH_GAS") == "1" { - applyTSMessages = false - } - - // Try calling until we find a height with no migration. - var res *types.InvocResult - for { - res, err = a.em.chainModule.Stmgr.CallWithGas(ctx, msg, []types.ChainMsg{}, ts, applyTSMessages) - if err != fork.ErrExpensiveFork { - break - } - ts, err = a.chain.ChainGetTipSet(ctx, ts.Parents()) + if ts.Height() > 0 { + pts, err := a.chain.ChainGetTipSet(ctx, ts.Parents()) if err != nil { - return nil, fmt.Errorf("getting parent tipset: %w", err) + return nil, fmt.Errorf("failed to find a non-forking epoch: %w", err) + } + // Check for expensive forks from the parents to the tipset, including nil tipsets + if a.em.chainModule.Fork.HasExpensiveForkBetween(pts.Height(), ts.Height()+1) { + return nil, fork.ErrExpensiveFork } } + + st, err := a.em.chainModule.ChainReader.GetTipSetStateRoot(ctx, ts) if err != nil { - return nil, fmt.Errorf("CallWithGas failed: %w", err) + return nil, fmt.Errorf("cannot get tipset state: %w", err) } - if res.MsgRct == nil { - return nil, fmt.Errorf("no message receipt") + res, err := a.em.chainModule.Stmgr.ApplyOnStateWithGas(ctx, st, msg, ts) + if err != nil { + return nil, fmt.Errorf("ApplyWithGasOnState failed: %w", err) } + if res.MsgRct.ExitCode.IsError() { reason := parseEthRevert(res.MsgRct.Return) return nil, fmt.Errorf("message execution failed: exit %s, revert reason: %s, vm error: %s", res.MsgRct.ExitCode, reason, res.Error) } - return res, nil } @@ -1065,18 +1075,9 @@ func (a *ethAPI) EthTraceBlock(ctx context.Context, blkNum string) ([]*types.Eth return nil, fmt.Errorf("failed when calling ExecutionTrace: %w", err) } - head, err := a.chain.ChainHead(ctx) - if err != nil { - return nil, err - } - tsParent, err := a.chain.ChainGetTipSetByHeight(ctx, ts.Height()+1, head.Key()) + state, err := a.em.chainModule.ChainReader.GetTipSetState(ctx, ts) if err != nil { - return nil, fmt.Errorf("cannot get tipset at height: %v", ts.Height()+1) - } - - msgs, err := a.chain.ChainGetParentMessages(ctx, tsParent.Blocks()[0].Cid()) - if err != nil { - return nil, fmt.Errorf("failed to get parent messages: %w", err) + return nil, fmt.Errorf("failed to get state view: %w", err) } cid, err := ts.Key().Cid() @@ -1097,11 +1098,6 @@ func (a *ethAPI) EthTraceBlock(ctx context.Context, blkNum string) ([]*types.Eth continue } - // as we include TransactionPosition in the results, lets do sanity checking that the - // traces are indeed in the message execution order - if ir.Msg.Cid() != msgs[msgIdx].Message.Cid() { - return nil, fmt.Errorf("traces are not in message execution order") - } msgIdx++ txHash, err := a.EthGetTransactionHashByCid(ctx, ir.MsgCid) @@ -1112,7 +1108,7 @@ func (a *ethAPI) EthTraceBlock(ctx context.Context, blkNum string) ([]*types.Eth return nil, fmt.Errorf("cannot find transaction hash for cid %s", ir.MsgCid) } - env, err := baseEnvironment(ctx, ir.Msg.From, a.chain) + env, err := baseEnvironment(ctx, ir.Msg.From, state) if err != nil { return nil, fmt.Errorf("when processing message %s: %w", ir.MsgCid, err) } @@ -1151,6 +1147,11 @@ func (a *ethAPI) EthTraceReplayBlockTransactions(ctx context.Context, blkNum str return nil, fmt.Errorf("failed when calling ExecutionTrace: %w", err) } + state, err := a.em.chainModule.ChainReader.GetTipSetState(ctx, ts) + if err != nil { + return nil, fmt.Errorf("failed to get state view: %w", err) + } + allTraces := make([]*types.EthTraceReplayBlockTransaction, 0, len(trace)) for _, ir := range trace { // ignore messages from system actor @@ -1166,7 +1167,7 @@ func (a *ethAPI) EthTraceReplayBlockTransactions(ctx context.Context, blkNum str return nil, fmt.Errorf("cannot find transaction hash for cid %s", ir.MsgCid) } - env, err := baseEnvironment(ctx, ir.Msg.From, a.chain) + env, err := baseEnvironment(ctx, ir.Msg.From, state) if err != nil { return nil, fmt.Errorf("when processing message %s: %w", ir.MsgCid, err) } @@ -1198,6 +1199,51 @@ func (a *ethAPI) EthTraceReplayBlockTransactions(ctx context.Context, blkNum str return allTraces, nil } +func (a *ethAPI) EthTraceTransaction(ctx context.Context, txHash string) ([]*types.EthTraceTransaction, error) { + + // convert from string to internal type + ethTxHash, err := types.ParseEthHash(txHash) + if err != nil { + return nil, fmt.Errorf("cannot parse eth hash: %w", err) + } + + tx, err := a.EthGetTransactionByHash(ctx, ðTxHash) + if err != nil { + return nil, fmt.Errorf("cannot get transaction by hash: %w", err) + } + + if tx == nil { + return nil, fmt.Errorf("transaction not found") + } + + // tx.BlockNumber is nil when the transaction is still in the mpool/pending + if tx.BlockNumber == nil { + return nil, fmt.Errorf("no trace for pending transactions") + } + + blockTraces, err := a.EthTraceBlock(ctx, strconv.FormatUint(uint64(*tx.BlockNumber), 10)) + if err != nil { + return nil, fmt.Errorf("cannot get trace for block: %w", err) + } + + txTraces := make([]*types.EthTraceTransaction, 0, len(blockTraces)) + for _, blockTrace := range blockTraces { + if blockTrace.TransactionHash == ethTxHash { + // Create a new EthTraceTransaction from the block trace + txTrace := types.EthTraceTransaction{ + EthTrace: blockTrace.EthTrace, + BlockHash: blockTrace.BlockHash, + BlockNumber: blockTrace.BlockNumber, + TransactionHash: blockTrace.TransactionHash, + TransactionPosition: blockTrace.TransactionPosition, + } + txTraces = append(txTraces, &txTrace) + } + } + + return txTraces, nil +} + func calculateRewardsAndGasUsed(rewardPercentiles []float64, txGasRewards gasRewardSorter) ([]types.EthBigInt, int64) { var gasUsedTotal int64 for _, tx := range txGasRewards { diff --git a/app/submodule/eth/eth_event_api.go b/app/submodule/eth/eth_event_api.go index f71f0fa9cf..2d4e8c3f08 100644 --- a/app/submodule/eth/eth_event_api.go +++ b/app/submodule/eth/eth_event_api.go @@ -16,6 +16,7 @@ import ( "github.com/filecoin-project/venus/pkg/chain" "github.com/filecoin-project/venus/pkg/events" "github.com/filecoin-project/venus/pkg/events/filter" + "github.com/filecoin-project/venus/pkg/statemanger" "github.com/filecoin-project/venus/venus-shared/api" v1 "github.com/filecoin-project/venus/venus-shared/api/chain/v1" "github.com/filecoin-project/venus/venus-shared/types" @@ -29,7 +30,6 @@ var _ v1.IETHEvent = (*ethEventAPI)(nil) func newEthEventAPI(ctx context.Context, em *EthSubModule) (*ethEventAPI, error) { chainAPI := em.chainModule.API() - bsstore := em.chainModule.ChainReader.Blockstore() cfg := em.cfg.FevmConfig ee := ðEventAPI{ em: em, @@ -47,6 +47,7 @@ func newEthEventAPI(ctx context.Context, em *EthSubModule) (*ethEventAPI, error) ee.SubManager = &EthSubscriptionManager{ ChainAPI: chainAPI, + stmgr: ee.em.chainModule.Stmgr, messageStore: ee.em.chainModule.MessageStore, } ee.FilterStore = filter.NewMemFilterStore(cfg.Event.MaxFilters) @@ -70,7 +71,7 @@ func newEthEventAPI(ctx context.Context, em *EthSubModule) (*ethEventAPI, error) ee.EventFilterManager = &filter.EventFilterManager{ MessageStore: ee.em.chainModule.MessageStore, - ChainStore: bsstore, + ChainStore: ee.em.chainModule.ChainReader, EventIndex: eventIndex, // will be nil unless EnableHistoricFilterAPI is true AddressResolver: func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { // we only want to match using f4 addresses @@ -80,11 +81,11 @@ func newEthEventAPI(ctx context.Context, em *EthSubModule) (*ethEventAPI, error) } actor, err := em.chainModule.Stmgr.GetActorAt(ctx, idAddr, ts) - if err != nil || actor.Address == nil { + if err != nil || actor.DelegatedAddress == nil { return idAddr, true } - return *actor.Address, true + return *actor.DelegatedAddress, true }, MaxFilterResults: cfg.Event.MaxFilterResults, @@ -160,7 +161,7 @@ func (e *ethEventAPI) EthGetLogs(ctx context.Context, filterSpec *types.EthFilte _ = e.uninstallFilter(ctx, f) - return ethFilterResultFromEvents(ces, e.em.chainModule.MessageStore, e.ChainAPI) + return ethFilterResultFromEvents(ces, e.em.chainModule.MessageStore) } func (e *ethEventAPI) EthGetFilterChanges(ctx context.Context, id types.EthFilterID) (*types.EthFilterResult, error) { @@ -175,11 +176,11 @@ func (e *ethEventAPI) EthGetFilterChanges(ctx context.Context, id types.EthFilte switch fc := f.(type) { case filterEventCollector: - return ethFilterResultFromEvents(fc.TakeCollectedEvents(ctx), e.em.chainModule.MessageStore, e.ChainAPI) + return ethFilterResultFromEvents(fc.TakeCollectedEvents(ctx), e.em.chainModule.MessageStore) case filterTipSetCollector: return ethFilterResultFromTipSets(fc.TakeCollectedTipSets(ctx)) case filterMessageCollector: - return ethFilterResultFromMessages(fc.TakeCollectedMessages(ctx), e.ChainAPI) + return ethFilterResultFromMessages(fc.TakeCollectedMessages(ctx)) } return nil, fmt.Errorf("unknown filter type") @@ -197,7 +198,7 @@ func (e *ethEventAPI) EthGetFilterLogs(ctx context.Context, id types.EthFilterID switch fc := f.(type) { case filterEventCollector: - return ethFilterResultFromEvents(fc.TakeCollectedEvents(ctx), e.em.chainModule.MessageStore, e.ChainAPI) + return ethFilterResultFromEvents(fc.TakeCollectedEvents(ctx), e.em.chainModule.MessageStore) } return nil, fmt.Errorf("wrong filter type") @@ -626,7 +627,7 @@ func ethLogFromEvent(entries []types.EventEntry) (data []byte, topics []types.Et return data, topics, true } -func ethFilterResultFromEvents(evs []*filter.CollectedEvent, ms *chain.MessageStore, ca v1.IChain) (*types.EthFilterResult, error) { +func ethFilterResultFromEvents(evs []*filter.CollectedEvent, ms *chain.MessageStore) (*types.EthFilterResult, error) { res := &types.EthFilterResult{} for _, ev := range evs { log := types.EthLog{ @@ -650,10 +651,14 @@ func ethFilterResultFromEvents(evs []*filter.CollectedEvent, ms *chain.MessageSt return nil, err } - log.TransactionHash, err = ethTxHashFromMessageCid(context.TODO(), ev.MsgCid, ms, ca) + log.TransactionHash, err = ethTxHashFromMessageCid(context.TODO(), ev.MsgCid, ms) if err != nil { return nil, err } + if log.TransactionHash == types.EmptyEthHash { + // We've garbage collected the message, ignore the events and continue. + continue + } c, err := ev.TipSetKey.Cid() if err != nil { @@ -689,11 +694,11 @@ func ethFilterResultFromTipSets(tsks []types.TipSetKey) (*types.EthFilterResult, return res, nil } -func ethFilterResultFromMessages(cs []*types.SignedMessage, ca v1.IChain) (*types.EthFilterResult, error) { +func ethFilterResultFromMessages(cs []*types.SignedMessage) (*types.EthFilterResult, error) { res := &types.EthFilterResult{} for _, c := range cs { - hash, err := ethTxHashFromSignedMessage(context.TODO(), c, ca) + hash, err := ethTxHashFromSignedMessage(c) if err != nil { return nil, err } @@ -707,6 +712,7 @@ func ethFilterResultFromMessages(cs []*types.SignedMessage, ca v1.IChain) (*type type EthSubscriptionManager struct { // nolint ChainAPI v1.IChain messageStore *chain.MessageStore + stmgr *statemanger.Stmgr mu sync.Mutex subs map[types.EthSubscriptionID]*ethSubscription } @@ -723,6 +729,7 @@ func (e *EthSubscriptionManager) StartSubscription(ctx context.Context, out ethS sub := ðSubscription{ chainAPI: e.ChainAPI, + stmgr: e.stmgr, messageStore: e.messageStore, uninstallFilter: dropFilter, id: id, @@ -767,6 +774,7 @@ const maxSendQueue = 20000 type ethSubscription struct { chainAPI v1.IChain + stmgr *statemanger.Stmgr messageStore *chain.MessageStore uninstallFilter func(context.Context, filter.Filter) error id types.EthSubscriptionID @@ -781,6 +789,8 @@ type ethSubscription struct { sendQueueLen int toSend *queue.Queue[[]byte] sendCond chan struct{} + + lastSentTipset *types.TipSetKey } func (e *ethSubscription) addFilter(_ context.Context, f filter.Filter) { @@ -852,39 +862,56 @@ func (e *ethSubscription) send(_ context.Context, v interface{}) { } func (e *ethSubscription) start(ctx context.Context) { - for { - select { - case <-ctx.Done(): - return - case v := <-e.in: - switch vt := v.(type) { - case *filter.CollectedEvent: - evs, err := ethFilterResultFromEvents([]*filter.CollectedEvent{vt}, e.messageStore, e.chainAPI) - if err != nil { - continue - } - - for _, r := range evs.Results { - e.send(ctx, r) - } - case *types.TipSet: - ev, err := newEthBlockFromFilecoinTipSet(ctx, vt, true, e.messageStore, e.chainAPI) - if err != nil { - break - } - - e.send(ctx, ev) - case *types.SignedMessage: // mpool txid - evs, err := ethFilterResultFromMessages([]*types.SignedMessage{vt}, e.chainAPI) - if err != nil { - continue - } - - for _, r := range evs.Results { - e.send(ctx, r) + if ctx.Err() == nil { + for { + select { + case <-ctx.Done(): + return + case v := <-e.in: + switch vt := v.(type) { + case *filter.CollectedEvent: + evs, err := ethFilterResultFromEvents([]*filter.CollectedEvent{vt}, e.messageStore) + if err != nil { + continue + } + + for _, r := range evs.Results { + e.send(ctx, r) + } + case *types.TipSet: + // Skip processing for tipset at epoch 0 as it has no parent + if vt.Height() == 0 { + continue + } + // Check if the parent has already been processed + parentTipSetKey := vt.Parents() + if e.lastSentTipset != nil && (*e.lastSentTipset) == parentTipSetKey { + continue + } + parentTipSet, loadErr := e.chainAPI.ChainGetTipSet(ctx, parentTipSetKey) + if loadErr != nil { + log.Warnw("failed to load parent tipset", "tipset", parentTipSetKey, "error", loadErr) + continue + } + ethBlock, ethBlockErr := newEthBlockFromFilecoinTipSet(ctx, parentTipSet, true, e.messageStore, e.stmgr) + if ethBlockErr != nil { + continue + } + + e.send(ctx, ethBlock) + e.lastSentTipset = &parentTipSetKey + case *types.SignedMessage: // mpool txid + evs, err := ethFilterResultFromMessages([]*types.SignedMessage{vt}) + if err != nil { + continue + } + + for _, r := range evs.Results { + e.send(ctx, r) + } + default: + log.Warnf("unexpected subscription value type: %T", vt) } - default: - log.Warnf("unexpected subscription value type: %T", vt) } } } diff --git a/app/submodule/eth/eth_trace.go b/app/submodule/eth/eth_trace.go index d794015ce3..4af7dae2b2 100644 --- a/app/submodule/eth/eth_trace.go +++ b/app/submodule/eth/eth_trace.go @@ -15,8 +15,8 @@ import ( evm12 "github.com/filecoin-project/go-state-types/builtin/v12/evm" init12 "github.com/filecoin-project/go-state-types/builtin/v12/init" "github.com/filecoin-project/go-state-types/exitcode" + "github.com/filecoin-project/venus/pkg/state/tree" "github.com/filecoin-project/venus/venus-shared/actors/builtin/evm" - v1 "github.com/filecoin-project/venus/venus-shared/api/chain/v1" builtinactors "github.com/filecoin-project/venus/venus-shared/actors/builtin" "github.com/filecoin-project/venus/venus-shared/types" @@ -93,8 +93,8 @@ type environment struct { lastByteCode *types.EthAddress } -func baseEnvironment(ctx context.Context, from address.Address, ca v1.IChain) (*environment, error) { - sender, err := lookupEthAddress(ctx, from, ca) +func baseEnvironment(ctx context.Context, from address.Address, state tree.Tree) (*environment, error) { + sender, err := lookupEthAddress(ctx, from, state) if err != nil { return nil, fmt.Errorf("top-level message sender %s s could not be found: %w", from, err) } @@ -102,8 +102,8 @@ func baseEnvironment(ctx context.Context, from address.Address, ca v1.IChain) (* } func traceToAddress(act *types.ActorTrace) types.EthAddress { - if act.State.Address != nil { - if addr, err := types.EthAddressFromFilecoinAddress(*act.State.Address); err == nil { + if act.State.DelegatedAddress != nil { + if addr, err := types.EthAddressFromFilecoinAddress(*act.State.DelegatedAddress); err == nil { return addr } } diff --git a/app/submodule/eth/eth_utils.go b/app/submodule/eth/eth_utils.go index ce23f587e7..697852ef7c 100644 --- a/app/submodule/eth/eth_utils.go +++ b/app/submodule/eth/eth_utils.go @@ -8,6 +8,8 @@ import ( "fmt" "github.com/ipfs/go-cid" + "github.com/multiformats/go-multicodec" + "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" @@ -18,6 +20,7 @@ import ( "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/venus/pkg/chain" "github.com/filecoin-project/venus/pkg/constants" + "github.com/filecoin-project/venus/pkg/state/tree" "github.com/filecoin-project/venus/pkg/statemanger" "github.com/filecoin-project/venus/pkg/vm/gas" "github.com/filecoin-project/venus/venus-shared/actors" @@ -26,6 +29,18 @@ import ( "github.com/filecoin-project/venus/venus-shared/types" ) +// The address used in messages to actors that have since been deleted. +// +// 0xff0000000000000000000000ffffffffffffffff +var revertedEthAddress types.EthAddress + +func init() { + revertedEthAddress[0] = 0xff + for i := 20 - 8; i < 20; i++ { + revertedEthAddress[i] = 0xff + } +} + func getTipsetByBlockNumber(ctx context.Context, store *chain.Store, blkParam string, strict bool) (*types.TipSet, error) { if blkParam == "earliest" { return nil, fmt.Errorf("block param \"earliest\" is not supported") @@ -41,6 +56,22 @@ func getTipsetByBlockNumber(ctx context.Context, store *chain.Store, blkParam st return nil, fmt.Errorf("cannot get parent tipset") } return parent, nil + case "safe": + latestHeight := head.Height() - 1 + safeHeight := latestHeight - types.SafeEpochDelay + ts, err := store.GetTipSetByHeight(ctx, head, safeHeight, true) + if err != nil { + return nil, fmt.Errorf("cannot get tipset at height: %v", safeHeight) + } + return ts, nil + case "finalized": + latestHeight := head.Height() - 1 + safeHeight := latestHeight - constants.Finality + ts, err := store.GetTipSetByHeight(ctx, head, safeHeight, true) + if err != nil { + return nil, fmt.Errorf("cannot get tipset at height: %v", safeHeight) + } + return ts, nil default: var num types.EthUint64 err := num.UnmarshalJSON([]byte(`"` + blkParam + `"`)) @@ -177,7 +208,7 @@ func ethCallToFilecoinMessage(_ context.Context, tx types.EthCall) (*types.Messa }, nil } -func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTxInfo bool, ms *chain.MessageStore, ca v1.IChain) (types.EthBlock, error) { +func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTxInfo bool, ms *chain.MessageStore, stmgr *statemanger.Stmgr) (types.EthBlock, error) { parentKeyCid, err := ts.Parents().Cid() if err != nil { return types.EthBlock{}, err @@ -189,7 +220,8 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx bn := types.EthUint64(ts.Height()) - blkCid, err := ts.Key().Cid() + tsk := ts.Key() + blkCid, err := tsk.Cid() if err != nil { return types.EthBlock{}, err } @@ -198,40 +230,42 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx return types.EthBlock{}, err } - msgs, err := ms.MessagesForTipset(ts) + stRoot, msgs, rcpts, err := executeTipset(ctx, ts, ms, stmgr) if err != nil { - return types.EthBlock{}, fmt.Errorf("error loading messages for tipset: %v: %w", ts, err) + return types.EthBlock{}, fmt.Errorf("failed to retrieve messages and receipts: %w", err) } - block := types.NewEthBlock(len(msgs) > 0) - - gasUsed := int64(0) - compOutput, err := ca.StateCompute(ctx, ts.Height(), nil, ts.Key()) + st, err := stmgr.TipsetState(ctx, ts) if err != nil { - return types.EthBlock{}, fmt.Errorf("failed to compute state: %w", err) + return types.EthBlock{}, fmt.Errorf("failed to load state-tree root %q: %w", stRoot, err) } - txIdx := 0 - for _, msg := range compOutput.Trace { - // skip system messages like reward application and cron - if msg.Msg.From == builtin.SystemActorAddr { - continue - } - - ti := types.EthUint64(txIdx) - txIdx++ + block := types.NewEthBlock(len(msgs) > 0, len(ts.Blocks())) - gasUsed += msg.MsgRct.GasUsed - smsgCid, err := getSignedMessage(ctx, ms, msg.MsgCid) - if err != nil { - return types.EthBlock{}, fmt.Errorf("failed to get signed msg %s: %w", msg.MsgCid, err) + gasUsed := int64(0) + for i, msg := range msgs { + rcpt := rcpts[i] + ti := types.EthUint64(i) + gasUsed += rcpt.GasUsed + var smsg *types.SignedMessage + switch msg := msg.(type) { + case *types.SignedMessage: + smsg = msg + case *types.Message: + smsg = &types.SignedMessage{ + Message: *msg, + Signature: crypto.Signature{ + Type: crypto.SigTypeBLS, + }, + } + default: + return types.EthBlock{}, xerrors.Errorf("failed to get signed msg %s: %w", msg.Cid(), err) } - tx, err := newEthTxFromSignedMessage(ctx, smsgCid, ca) + tx, err := newEthTxFromSignedMessage(ctx, smsg, st) if err != nil { return types.EthBlock{}, fmt.Errorf("failed to convert msg to ethTx: %w", err) } - tx.ChainID = types.EthUint64(types2.Eip155ChainID) tx.BlockHash = &blkHash tx.BlockNumber = &bn tx.TransactionIndex = &ti @@ -275,6 +309,29 @@ func messagesAndReceipts(ctx context.Context, ts *types.TipSet, ms *chain.Messag return msgs, rcpts, nil } +func executeTipset(ctx context.Context, ts *types.TipSet, ms *chain.MessageStore, stmgr *statemanger.Stmgr) (cid.Cid, []types.ChainMsg, []types.MessageReceipt, error) { + msgs, err := ms.MessagesForTipset(ts) + if err != nil { + return cid.Undef, nil, nil, fmt.Errorf("error loading messages for tipset: %v: %w", ts, err) + } + + stRoot, rcptRoot, err := stmgr.RunStateTransition(ctx, ts, nil, false) + if err != nil { + return cid.Undef, nil, nil, fmt.Errorf("failed to compute state: %w", err) + } + + rcpts, err := ms.LoadReceipts(ctx, rcptRoot) + if err != nil { + return cid.Undef, nil, nil, fmt.Errorf("error loading receipts for tipset: %v: %w", ts, err) + } + + if len(msgs) != len(rcpts) { + return cid.Undef, nil, nil, fmt.Errorf("receipts and message array lengths didn't match for tipset: %v: %w", ts, err) + } + + return stRoot, msgs, rcpts, nil +} + const errorFunctionSelector = "\x08\xc3\x79\xa0" // Error(string) const panicFunctionSelector = "\x4e\x48\x7b\x71" // Panic(uint256) // Eth ABI (solidity) panic codes. @@ -364,7 +421,7 @@ func parseEthRevert(ret []byte) string { // 4. Otherwise, we fetch the actor's ID from the state tree and form the masked ID with it. // // If the actor doesn't exist in the state-tree but we have its ID, we use a masked ID address. It could have been deleted. -func lookupEthAddress(ctx context.Context, addr address.Address, ca v1.IChain) (types.EthAddress, error) { +func lookupEthAddress(ctx context.Context, addr address.Address, state tree.Tree) (types.EthAddress, error) { // Attempt to convert directly, if it's an f4 address. ethAddr, err := types.EthAddressFromFilecoinAddress(addr) if err == nil && !ethAddr.IsMaskedID() { @@ -372,20 +429,22 @@ func lookupEthAddress(ctx context.Context, addr address.Address, ca v1.IChain) ( } // Otherwise, resolve the ID addr. - idAddr, err := ca.StateLookupID(ctx, addr, types.EmptyTSK) + idAddr, err := state.LookupID(addr) if err != nil { return types.EthAddress{}, err } + // revive:disable:empty-block easier to grok when the cases are explicit + // Lookup on the target actor and try to get an f410 address. - if actor, err := ca.GetActor(ctx, idAddr); errors.Is(err, types.ErrActorNotFound) { + if actor, found, err := state.GetActor(ctx, idAddr); errors.Is(err, types.ErrActorNotFound) && !found { // Not found -> use a masked ID address } else if err != nil { // Any other error -> fail. return types.EthAddress{}, err - } else if actor.Address == nil { + } else if actor.DelegatedAddress == nil { // No delegated address -> use masked ID address. - } else if ethAddr, err := types.EthAddressFromFilecoinAddress(*actor.Address); err == nil && !ethAddr.IsMaskedID() { + } else if ethAddr, err := types.EthAddressFromFilecoinAddress(*actor.DelegatedAddress); err == nil && !ethAddr.IsMaskedID() { // Conversable into an eth address, use it. return ethAddr, nil } @@ -394,63 +453,68 @@ func lookupEthAddress(ctx context.Context, addr address.Address, ca v1.IChain) ( return types.EthAddressFromFilecoinAddress(idAddr) } -func ethTxHashFromMessageCid(ctx context.Context, c cid.Cid, ms *chain.MessageStore, ca v1.IChain) (types.EthHash, error) { +func ethTxHashFromMessageCid(ctx context.Context, c cid.Cid, ms *chain.MessageStore) (types.EthHash, error) { smsg, err := ms.LoadSignedMessage(ctx, c) if err == nil { // This is an Eth Tx, Secp message, Or BLS message in the mpool - return ethTxHashFromSignedMessage(ctx, smsg, ca) + return ethTxHashFromSignedMessage(smsg) + } + + _, err = ms.LoadMessage(ctx, c) + if err == nil { + // This is a BLS message + return types.EthHashFromCid(c) } return types.EthHashFromCid(c) } -func ethTxHashFromSignedMessage(ctx context.Context, smsg *types.SignedMessage, ca v1.IChain) (types.EthHash, error) { +func ethTxHashFromSignedMessage(smsg *types.SignedMessage) (types.EthHash, error) { if smsg.Signature.Type == crypto.SigTypeDelegated { - ethTx, err := newEthTxFromSignedMessage(ctx, smsg, ca) + tx, err := types.EthTransactionFromSignedFilecoinMessage(smsg) if err != nil { - return types.EmptyEthHash, err + return types.EthHash{}, fmt.Errorf("failed to convert from signed message: %w", err) } - return ethTx.Hash, nil + + return tx.TxHash() } else if smsg.Signature.Type == crypto.SigTypeSecp256k1 { return types.EthHashFromCid(smsg.Cid()) - } else { // BLS message - return types.EthHashFromCid(smsg.Message.Cid()) } + // else BLS message + return types.EthHashFromCid(smsg.Message.Cid()) } -func newEthTxFromSignedMessage(ctx context.Context, smsg *types.SignedMessage, ca v1.IChain) (types.EthTx, error) { +func newEthTxFromSignedMessage(ctx context.Context, smsg *types.SignedMessage, state tree.Tree) (types.EthTx, error) { var tx types.EthTx var err error // This is an eth tx if smsg.Signature.Type == crypto.SigTypeDelegated { - tx, err = types.EthTxFromSignedEthMessage(smsg) + ethTx, err := types.EthTransactionFromSignedFilecoinMessage(smsg) if err != nil { return types.EthTx{}, fmt.Errorf("failed to convert from signed message: %w", err) } - - tx.Hash, err = tx.TxHash() + tx, err = ethTx.ToEthTx(smsg) if err != nil { - return types.EthTx{}, fmt.Errorf("failed to calculate hash for ethTx: %w", err) + return types.EthTx{}, fmt.Errorf("failed to convert from signed message: %w", err) } - - fromAddr, err := lookupEthAddress(ctx, smsg.Message.From, ca) + } else if smsg.Signature.Type == crypto.SigTypeSecp256k1 { // Secp Filecoin Message + tx, err = ethTxFromNativeMessage(ctx, smsg.VMMessage(), state) if err != nil { - return types.EthTx{}, fmt.Errorf("failed to resolve Ethereum address: %w", err) + return types.EthTx{}, err } - - tx.From = fromAddr - } else if smsg.Signature.Type == crypto.SigTypeSecp256k1 { // Secp Filecoin Message - tx = ethTxFromNativeMessage(ctx, smsg.VMMessage(), ca) tx.Hash, err = types.EthHashFromCid(smsg.Cid()) if err != nil { - return tx, err + return types.EthTx{}, err } } else { // BLS Filecoin message - tx = ethTxFromNativeMessage(ctx, smsg.VMMessage(), ca) + tx, err = ethTxFromNativeMessage(ctx, smsg.VMMessage(), state) + if err != nil { + return types.EthTx{}, err + } tx.Hash, err = types.EthHashFromCid(smsg.Message.Cid()) if err != nil { - return tx, err + return types.EthTx{}, err } } @@ -473,44 +537,93 @@ func parseEthTopics(topics types.EthTopicSpec) (map[string][][]byte, error) { return keys, nil } +// Convert a native message to an eth transaction. +// +// - The state-tree must be from after the message was applied (ideally the following tipset). +// - In some cases, the "to" address may be `0xff0000000000000000000000ffffffffffffffff`. This +// means that the "to" address has not been assigned in the passed state-tree and can only +// happen if the transaction reverted. +// // ethTxFromNativeMessage does NOT populate: // - BlockHash // - BlockNumber // - TransactionIndex // - Hash -func ethTxFromNativeMessage(ctx context.Context, msg *types.Message, ca v1.IChain) types.EthTx { - // We don't care if we error here, conversion is best effort for non-eth transactions - from, _ := lookupEthAddress(ctx, msg.From, ca) - to, _ := lookupEthAddress(ctx, msg.To, ca) - return types.EthTx{ +func ethTxFromNativeMessage(ctx context.Context, msg *types.Message, state tree.Tree) (types.EthTx, error) { + // Lookup the from address. This must succeed. + from, err := lookupEthAddress(ctx, msg.From, state) + if err != nil { + return types.EthTx{}, fmt.Errorf("failed to lookup sender address %s when converting a native message to an eth txn: %w", msg.From, err) + } + // Lookup the to address. If the recipient doesn't exist, we replace the address with a + // known sentinel address. + to, err := lookupEthAddress(ctx, msg.To, state) + if err != nil { + if !errors.Is(err, types.ErrActorNotFound) { + return types.EthTx{}, fmt.Errorf("failed to lookup receiver address %s when converting a native message to an eth txn: %w", msg.To, err) + } + to = revertedEthAddress + } + + // For empty, we use "0" as the codec. Otherwise, we use CBOR for message + // parameters. + var codec uint64 + if len(msg.Params) > 0 { + codec = uint64(multicodec.Cbor) + } + + maxFeePerGas := types.EthBigInt(msg.GasFeeCap) + maxPriorityFeePerGas := types.EthBigInt(msg.GasPremium) + + // We decode as a native call first. + ethTx := types.EthTx{ To: &to, From: from, + Input: encodeFilecoinParamsAsABI(msg.Method, codec, msg.Params), Nonce: types.EthUint64(msg.Nonce), ChainID: types.EthUint64(types2.Eip155ChainID), Value: types.EthBigInt(msg.Value), - Type: types.Eip1559TxType, + Type: types.EIP1559TxType, Gas: types.EthUint64(msg.GasLimit), - MaxFeePerGas: types.EthBigInt(msg.GasFeeCap), - MaxPriorityFeePerGas: types.EthBigInt(msg.GasPremium), + MaxFeePerGas: &maxFeePerGas, + MaxPriorityFeePerGas: &maxPriorityFeePerGas, AccessList: []types.EthHash{}, } + + // Then we try to see if it's "special". If we fail, we ignore the error and keep treating + // it as a native message. Unfortunately, the user is free to send garbage that may not + // properly decode. + if msg.Method == builtin.MethodsEVM.InvokeContract { + // try to decode it as a contract invocation first. + if inp, err := decodePayload(msg.Params, codec); err == nil { + ethTx.Input = []byte(inp) + } + } else if msg.To == builtin.EthereumAddressManagerActorAddr && msg.Method == builtin.MethodsEAM.CreateExternal { + // Then, try to decode it as a contract deployment from an EOA. + if inp, err := decodePayload(msg.Params, codec); err == nil { + ethTx.Input = []byte(inp) + ethTx.To = nil + } + } + + return ethTx, nil } // newEthTxFromMessageLookup creates an ethereum transaction from filecoin message lookup. If a negative txIdx is passed // into the function, it looks up the transaction index of the message in the tipset, otherwise it uses the txIdx passed into the // function -func newEthTxFromMessageLookup(ctx context.Context, msgLookup *types.MsgLookup, txIdx int, ms *chain.MessageStore, ca v1.IChain) (types.EthTx, error) { +func newEthTxFromMessageLookup(ctx context.Context, msgLookup *types.MsgLookup, txIdx int, ms *chain.MessageStore, cr *chain.Store) (types.EthTx, error) { if msgLookup == nil { return types.EthTx{}, fmt.Errorf("msg does not exist") } - ts, err := ca.ChainGetTipSet(ctx, msgLookup.TipSet) + ts, err := cr.GetTipSet(ctx, msgLookup.TipSet) if err != nil { return types.EthTx{}, err } // This tx is located in the parent tipset - parentTS, err := ca.ChainGetTipSet(ctx, ts.Parents()) + parentTS, err := cr.GetTipSet(ctx, ts.Parents()) if err != nil { return types.EthTx{}, err } @@ -547,7 +660,12 @@ func newEthTxFromMessageLookup(ctx context.Context, msgLookup *types.MsgLookup, return types.EthTx{}, fmt.Errorf("failed to get signed msg: %w", err) } - tx, err := newEthTxFromSignedMessage(ctx, smsg, ca) + state, err := cr.GetTipSetState(ctx, parentTS) + if err != nil { + return types.EthTx{}, xerrors.Errorf("failed to load message state tree: %w", err) + } + + tx, err := newEthTxFromSignedMessage(ctx, smsg, state) if err != nil { return types.EthTx{}, err } @@ -564,7 +682,13 @@ func newEthTxFromMessageLookup(ctx context.Context, msgLookup *types.MsgLookup, return tx, nil } -func newEthTxReceipt(ctx context.Context, tx types.EthTx, lookup *types.MsgLookup, events []types.Event, ca v1.IChain) (types.EthTxReceipt, error) { +func newEthTxReceipt(ctx context.Context, + tx types.EthTx, + lookup *types.MsgLookup, + events []types.Event, + ca v1.IChain, + cr *chain.Store, +) (types.EthTxReceipt, error) { var ( transactionIndex types.EthUint64 blockHash types.EthHash @@ -617,8 +741,24 @@ func newEthTxReceipt(ctx context.Context, tx types.EthTx, lookup *types.MsgLooku return types.EthTxReceipt{}, fmt.Errorf("failed to lookup tipset %s when constructing the eth txn receipt: %w", ts.Parents(), err) } + state, err := cr.GetTipSetState(ctx, parentTS) + if err != nil { + return types.EthTxReceipt{}, fmt.Errorf("failed to load the state %s when constructing the eth txn receipt: %w", ts.ParentState(), err) + } + baseFee := parentTS.Blocks()[0].ParentBaseFee - gasOutputs := gas.ComputeGasOutputs(lookup.Receipt.GasUsed, int64(tx.Gas), baseFee, big.Int(tx.MaxFeePerGas), big.Int(tx.MaxPriorityFeePerGas), true) + + gasFeeCap, err := tx.GasFeeCap() + if err != nil { + return types.EthTxReceipt{}, fmt.Errorf("failed to get gas fee cap: %w", err) + } + gasPremium, err := tx.GasPremium() + if err != nil { + return types.EthTxReceipt{}, fmt.Errorf("failed to get gas premium: %w", err) + } + + gasOutputs := gas.ComputeGasOutputs(lookup.Receipt.GasUsed, int64(tx.Gas), baseFee, big.Int(gasFeeCap), + big.Int(gasPremium), true) totalSpent := big.Sum(gasOutputs.BaseFeeBurn, gasOutputs.MinerTip, gasOutputs.OverEstimationBurn) effectiveGasPrice := big.Zero() @@ -665,7 +805,7 @@ func newEthTxReceipt(ctx context.Context, tx types.EthTx, lookup *types.MsgLooku return types.EthTxReceipt{}, fmt.Errorf("failed to create ID address: %w", err) } - l.Address, err = lookupEthAddress(ctx, addr, ca) + l.Address, err = lookupEthAddress(ctx, addr, state) if err != nil { return types.EthTxReceipt{}, fmt.Errorf("failed to resolve Ethereum address: %w", err) } diff --git a/app/submodule/eth/txhashmanager.go b/app/submodule/eth/txhashmanager.go index b45b7c0297..235d419626 100644 --- a/app/submodule/eth/txhashmanager.go +++ b/app/submodule/eth/txhashmanager.go @@ -32,7 +32,7 @@ func (m *ethTxHashManager) Apply(ctx context.Context, from, to *types.TipSet) er continue } - hash, err := ethTxHashFromSignedMessage(ctx, smsg, m.chainAPI) + hash, err := ethTxHashFromSignedMessage(smsg) if err != nil { return err } @@ -89,13 +89,18 @@ func (m *ethTxHashManager) ProcessSignedMessage(ctx context.Context, msg *types. return } - ethTx, err := newEthTxFromSignedMessage(ctx, msg, m.chainAPI) + ethTx, err := types.EthTransactionFromSignedFilecoinMessage(msg) if err != nil { log.Errorf("error converting filecoin message to eth tx: %s", err) return } - err = m.TransactionHashLookup.UpsertHash(ethTx.Hash, msg.Cid()) + txHash, err := ethTx.TxHash() + if err != nil { + log.Errorf("error hashing transaction: %s", err) + return + } + err = m.TransactionHashLookup.UpsertHash(txHash, msg.Cid()) if err != nil { log.Errorf("error inserting tx mapping to db: %s", err) return diff --git a/app/submodule/f3/f3_api.go b/app/submodule/f3/f3_api.go new file mode 100644 index 0000000000..32fbc96e04 --- /dev/null +++ b/app/submodule/f3/f3_api.go @@ -0,0 +1,53 @@ +package f3 + +import ( + "context" + "errors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-f3/certs" + "github.com/filecoin-project/venus/venus-shared/api/f3" + "golang.org/x/xerrors" +) + +var _ f3.F3 = &f3API{} + +type f3API struct { + f3module *F3Submodule +} + +var ErrF3Disabled = errors.New("f3 is disabled") + +func (f3api *f3API) F3Participate(ctx context.Context, miner address.Address) (<-chan string, error) { + if f3api.f3module.F3 == nil { + log.Infof("F3Participate called for %v, F3 is disabled", miner) + return nil, ErrF3Disabled + } + + // Make channel with some buffer to avoid blocking under higher load. + errCh := make(chan string, 4) + log.Infof("starting F3 participation for %v", miner) + + actorID, err := address.IDFromAddress(miner) + if err != nil { + return nil, xerrors.Errorf("miner address in F3Participate not of ID type: %w", err) + } + + // Participate takes control of closing the channel + go f3api.f3module.F3.Participate(ctx, actorID, errCh) + return errCh, nil +} + +func (f3api *f3API) F3GetCertificate(ctx context.Context, instance uint64) (*certs.FinalityCertificate, error) { + if f3api.f3module.F3 == nil { + return nil, ErrF3Disabled + } + return f3api.f3module.F3.GetCert(ctx, instance) +} + +func (f3api *f3API) F3GetLatestCertificate(ctx context.Context) (*certs.FinalityCertificate, error) { + if f3api.f3module.F3 == nil { + return nil, ErrF3Disabled + } + return f3api.f3module.F3.GetLatestCert(ctx) +} diff --git a/app/submodule/f3/f3_submodule.go b/app/submodule/f3/f3_submodule.go new file mode 100644 index 0000000000..f9815fa35d --- /dev/null +++ b/app/submodule/f3/f3_submodule.go @@ -0,0 +1,60 @@ +package f3 + +import ( + "context" + + "github.com/filecoin-project/venus/app/submodule/chain" + "github.com/filecoin-project/venus/app/submodule/network" + "github.com/filecoin-project/venus/pkg/repo" + "github.com/filecoin-project/venus/pkg/vf3" + v1api "github.com/filecoin-project/venus/venus-shared/api/chain/v1" + "github.com/filecoin-project/venus/venus-shared/api/f3" + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("f3") + +type F3Submodule struct { + F3 *vf3.F3 +} + +func NewF3Submodule(ctx context.Context, + repo repo.Repo, + chain *chain.ChainSubmodule, + network *network.NetworkSubmodule, + walletAPI v1api.IWallet, +) (*F3Submodule, error) { + netConf := repo.Config().NetworkParams + if !netConf.F3Enabled { + return &F3Submodule{ + F3: nil, + }, nil + } + m, err := vf3.New(ctx, vf3.F3Params{ + ManifestServerID: netConf.ManifestServerID, + PubSub: network.Pubsub, + Host: network.Host, + ChainStore: chain.ChainReader, + StateManager: chain.Stmgr, + Datastore: repo.ChainDatastore(), + Wallet: walletAPI, + ManifestProvider: vf3.NewManifestProvider(network.NetworkName, chain.ChainReader, chain.Stmgr, network.Pubsub, netConf), + }) + if err != nil { + return nil, err + } + + return &F3Submodule{m}, nil +} + +func (m *F3Submodule) API() f3.F3 { + return &f3API{ + f3module: m, + } +} + +func (m *F3Submodule) V0API() f3.F3 { + return &f3API{ + f3module: m, + } +} diff --git a/app/submodule/mpool/mpool_api.go b/app/submodule/mpool/mpool_api.go index 19b4ee35b2..98b6efb5f3 100644 --- a/app/submodule/mpool/mpool_api.go +++ b/app/submodule/mpool/mpool_api.go @@ -33,11 +33,19 @@ func (a *MessagePoolAPI) MpoolPublishByAddr(ctx context.Context, addr address.Ad } func (a *MessagePoolAPI) MpoolPublishMessage(ctx context.Context, smsg *types.SignedMessage) error { + if err := sanityCheckOutgoingMessage(&smsg.Message); err != nil { + return fmt.Errorf("message %s from %s with nonce %d failed sanity check: %w", smsg.Cid(), + smsg.Message.From, smsg.Message.Nonce, err) + } return a.mp.MPool.PublishMsg(ctx, smsg) } // MpoolPush pushes a signed message to mempool. func (a *MessagePoolAPI) MpoolPush(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) { + if err := sanityCheckOutgoingMessage(&smsg.Message); err != nil { + return cid.Undef, fmt.Errorf("message %s from %s with nonce %d failed sanity check: %w", smsg.Cid(), + smsg.Message.From, smsg.Message.Nonce, err) + } return a.mp.MPool.Push(ctx, smsg) } @@ -170,6 +178,10 @@ func (a *MessagePoolAPI) MpoolClear(ctx context.Context, local bool) error { // MpoolPushUntrusted pushes a signed message to mempool from untrusted sources. func (a *MessagePoolAPI) MpoolPushUntrusted(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) { + if err := sanityCheckOutgoingMessage(&smsg.Message); err != nil { + return cid.Undef, fmt.Errorf("message %s from %s with nonce %d failed sanity check: %w", smsg.Cid(), + smsg.Message.From, smsg.Message.Nonce, err) + } return a.mp.MPool.PushUntrusted(ctx, smsg) } @@ -180,6 +192,11 @@ func (a *MessagePoolAPI) MpoolPushUntrusted(ctx context.Context, smsg *types.Sig // When maxFee is set to 0, MpoolPushMessage will guess appropriate fee // based on current chain conditions func (a *MessagePoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, spec *types.MessageSendSpec) (*types.SignedMessage, error) { + if err := sanityCheckOutgoingMessage(msg); err != nil { + return nil, fmt.Errorf("message %s from %s with nonce %d failed sanity check: %w", msg.Cid(), + msg.From, msg.Nonce, err) + } + cp := *msg msg = &cp inMsg := *msg @@ -245,6 +262,10 @@ func (a *MessagePoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Messag func (a *MessagePoolAPI) MpoolBatchPush(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) { var messageCids []cid.Cid for _, smsg := range smsgs { + if err := sanityCheckOutgoingMessage(&smsg.Message); err != nil { + return nil, fmt.Errorf("message %s from %s with nonce %d failed sanity check: %w", smsg.Cid(), + smsg.Message.From, smsg.Message.Nonce, err) + } smsgCid, err := a.mp.MPool.Push(ctx, smsg) if err != nil { return messageCids, err @@ -258,6 +279,10 @@ func (a *MessagePoolAPI) MpoolBatchPush(ctx context.Context, smsgs []*types.Sign func (a *MessagePoolAPI) MpoolBatchPushUntrusted(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) { var messageCids []cid.Cid for _, smsg := range smsgs { + if err := sanityCheckOutgoingMessage(&smsg.Message); err != nil { + return nil, fmt.Errorf("message %s from %s with nonce %d failed sanity check: %w", smsg.Cid(), + smsg.Message.From, smsg.Message.Nonce, err) + } smsgCid, err := a.mp.MPool.PushUntrusted(ctx, smsg) if err != nil { return messageCids, err @@ -271,6 +296,10 @@ func (a *MessagePoolAPI) MpoolBatchPushUntrusted(ctx context.Context, smsgs []*t func (a *MessagePoolAPI) MpoolBatchPushMessage(ctx context.Context, msgs []*types.Message, spec *types.MessageSendSpec) ([]*types.SignedMessage, error) { var smsgs []*types.SignedMessage for _, msg := range msgs { + if err := sanityCheckOutgoingMessage(msg); err != nil { + return nil, fmt.Errorf("message %s from %s with nonce %d failed sanity check: %w", msg.Cid(), + msg.From, msg.Nonce, err) + } smsg, err := a.MpoolPushMessage(ctx, msg, spec) if err != nil { return smsgs, err @@ -325,3 +354,19 @@ func (a *MessagePoolAPI) MpoolCheckPendingMessages(ctx context.Context, addr add func (a *MessagePoolAPI) MpoolCheckReplaceMessages(ctx context.Context, msg []*types.Message) ([][]types.MessageCheckStatus, error) { return a.mp.MPool.CheckReplaceMessages(ctx, msg) } + +func sanityCheckOutgoingMessage(msg *types.Message) error { + // Check that the message's TO address is a _valid_ Eth address if it's a delegated address. + // + // It's legal (from a consensus perspective) to send funds to any 0xf410f address as long as + // the payload is at most 54 bytes, but the vast majority of this address space is + // essentially a black-hole. Unfortunately, the conversion from 0x addresses to Filecoin + // native addresses has a few pitfalls (especially with respect to masked ID addresses), so + // we've added this check to the API to avoid accidentally (and avoidably) sending messages + // to these black-hole addresses. + if msg.To.Protocol() == address.Delegated && !types.IsEthAddress(msg.To) { + return fmt.Errorf("message recipient %s is a delegated address but not a valid Eth Address", msg.To) + } + + return nil +} diff --git a/app/submodule/network/network_submodule.go b/app/submodule/network/network_submodule.go index b8ee6f3f4b..d36f99b258 100644 --- a/app/submodule/network/network_submodule.go +++ b/app/submodule/network/network_submodule.go @@ -178,7 +178,7 @@ func NewNetworkSubmodule(ctx context.Context, } sk := net.NewScoreKeeper() - gsub, err := net.NewGossipSub(ctx, peerHost, sk, networkName, cfg.NetworkParams.DrandSchedule, bootNodes, cfg.PubsubConfig.Bootstrapper) + gsub, err := net.NewGossipSub(ctx, peerHost, sk, networkName, cfg.NetworkParams.DrandSchedule, bootNodes, cfg.PubsubConfig.Bootstrapper, config.Repo().Config().NetworkParams.F3Enabled) if err != nil { return nil, errors.Wrap(err, "failed to set up network") } diff --git a/app/submodule/syncer/syncer_submodule.go b/app/submodule/syncer/syncer_submodule.go index 2f7f42ec7a..d47bd456df 100644 --- a/app/submodule/syncer/syncer_submodule.go +++ b/app/submodule/syncer/syncer_submodule.go @@ -90,7 +90,7 @@ func NewSyncerSubmodule(ctx context.Context, cborStore, config.Verifier(), &stateViewer, - chn.ChainReader, + chain.ChainReaderWrapper(chn.ChainReader, chn.CirculatingSupplyCalculator), chn.Fork, config.Repo().Config().NetworkParams, gasPriceSchedule) @@ -116,7 +116,7 @@ func NewSyncerSubmodule(ctx context.Context, ) stmgr, err := statemanger.NewStateManager(chn.ChainReader, chn.MessageStore, nodeConsensus, chn.Drand, - chn.Fork, gasPriceSchedule, chn.SystemCall, config.Repo().Config().NetworkParams.ActorDebugging) + chn.Fork, gasPriceSchedule, chn.SystemCall, config.Repo().Config().NetworkParams.ActorDebugging, chn.CirculatingSupplyCalculator) if err != nil { return nil, err } diff --git a/cmd/evm.go b/cmd/evm.go index f042403a00..11fac3d89f 100644 --- a/cmd/evm.go +++ b/cmd/evm.go @@ -504,8 +504,8 @@ func ethAddrFromFilecoinAddress(ctx context.Context, addr address.Address, chain if err != nil { return types.EthAddress{}, addr, err } - if fAct.Address != nil && (*fAct.Address).Protocol() == address.Delegated { - faddr = *fAct.Address + if fAct.DelegatedAddress != nil && (*fAct.DelegatedAddress).Protocol() == address.Delegated { + faddr = *fAct.DelegatedAddress } case address.Delegated: faddr = addr diff --git a/cmd/import.go b/cmd/import.go index 43975bea5a..a2e1cf0179 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -11,11 +11,11 @@ import ( "github.com/filecoin-project/venus/pkg/consensus/chainselector" "github.com/filecoin-project/venus/pkg/httpreader" - "github.com/DataDog/zstd" "github.com/filecoin-project/venus/pkg/chain" "github.com/filecoin-project/venus/pkg/repo" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" + "github.com/klauspost/compress/zstd" "github.com/mitchellh/go-homedir" "gopkg.in/cheggaaa/pb.v1" ) @@ -62,7 +62,7 @@ func importChain(ctx context.Context, r repo.Repo, fname string) error { bs := r.Datastore() // setup a ipldCbor on top of the local store - chainStore := chain.NewStore(r.ChainDatastore(), bs, cid.Undef, chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight) + chainStore := chain.NewStore(r.ChainDatastore(), bs, cid.Undef, chainselector.Weight) bufr := bufio.NewReaderSize(rd, 1<<20) @@ -80,12 +80,11 @@ func importChain(ctx context.Context, r repo.Repo, fname string) error { var ir io.Reader = br if string(header[1:]) == "\xB5\x2F\xFD" { // zstd - zr := zstd.NewReader(br) - defer func() { - if err := zr.Close(); err != nil { - log.Errorw("closing zstd reader", "error", err) - } - }() + zr, err := zstd.NewReader(br) + if err != nil { + return err + } + defer zr.Close() ir = zr } diff --git a/cmd/seed.go b/cmd/seed.go index 546bb1ae65..45615aeb03 100644 --- a/cmd/seed.go +++ b/cmd/seed.go @@ -599,7 +599,8 @@ var preSealCmd = &cmds.Command{ nv = network.Version(ver) } - spt, err := miner.SealProofTypeFromSectorSize(sectorSize, nv, false) + var variant = miner.SealProofVariant_Standard // there's little reason to have this for a seed. + spt, err := miner.SealProofTypeFromSectorSize(sectorSize, nv, variant) if err != nil { return err } diff --git a/cmd/state.go b/cmd/state.go index d004b17826..80185178b4 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -349,7 +349,7 @@ var stateGetActorCmd = &cmds.Command{ writer.Printf("Nonce:\t\t%d\n", a.Nonce) writer.Printf("Code:\t\t%s (%s)\n", a.Code, strtype) writer.Printf("Head:\t\t%s\n", a.Head) - writer.Printf("Delegated address:\t\t%s\n", a.Address) + writer.Printf("Delegated address:\t\t%s\n", a.DelegatedAddress) return re.Emit(buf) }, diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index b715c9403f..e467d2992e 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit b715c9403faf919e95fdc702cd651e842f18d890 +Subproject commit e467d2992e3f9bd09beb71ecf84323b45d2a3511 diff --git a/fixtures/assets/genesis-car/butterflynet.car b/fixtures/assets/genesis-car/butterflynet.car index 1ba3a8a1be..cacc110e12 100644 Binary files a/fixtures/assets/genesis-car/butterflynet.car and b/fixtures/assets/genesis-car/butterflynet.car differ diff --git a/fixtures/networks/butterfly.go b/fixtures/networks/butterfly.go index 2f664615f4..d75f3432f0 100644 --- a/fixtures/networks/butterfly.go +++ b/fixtures/networks/butterfly.go @@ -12,15 +12,15 @@ func ButterflySnapNet() *NetworkConf { nc := &NetworkConf{ Bootstrap: config.BootstrapConfig{ Addresses: []string{ - "/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWNwAkUtWuLtKCyyFP2vBzmpTHSrQao7KQx7Xfa8YvSg1N", - "/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWPn8BDeNcctAcAGuxxiic8uMw2pAi3G5vgdFtfgRs5zBu", + "/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWE9GZUna2UpMMtcCcpmSwiEB7jcKse8gixzwVomgbQysC", + "/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWJGtqGX2XBssujaMn3FsybJu1xJhFZzhVjNnWvC6a26iG", }, Period: "30s", }, Network: config.NetworkParamsConfig{ DevNet: true, NetworkType: types.NetworkButterfly, - GenesisNetworkVersion: network.Version21, + GenesisNetworkVersion: network.Version22, ReplaceProofTypes: []abi.RegisteredSealProof{ abi.RegisteredSealProof_StackedDrg512MiBV1, abi.RegisteredSealProof_StackedDrg32GiBV1, @@ -58,20 +58,22 @@ func ButterflySnapNet() *NetworkConf { UpgradeWatermelonHeight: -24, UpgradeWatermelonFixHeight: -100, // This fix upgrade only ran on calibrationnet UpgradeWatermelonFix2Height: -101, // This fix upgrade only ran on calibrationnet - UpgradeDragonHeight: 5760, + UpgradeDragonHeight: -25, UpgradeCalibrationDragonFixHeight: -102, // This fix upgrade only ran on calibrationnet + UpgradePhoenixHeight: -26, + UpgradeWaffleHeight: 100, }, - DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: 1}, + DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: config.DrandQuicknet}, AddressNetwork: address.Testnet, PropagationDelaySecs: 6, AllowableClockDriftSecs: 1, Eip155ChainID: 3141592, ActorDebugging: false, + F3Enabled: true, + F3BootstrapEpoch: 200, + ManifestServerID: "12D3KooWJr9jy4ngtJNR7JC1xgLFra3DjEtyxskRYWvBK9TC3Yn6", }, } - nc.Network.ForkUpgradeParam.UpgradePhoenixHeight = nc.Network.ForkUpgradeParam.UpgradeDragonHeight + 120 - nc.Network.DrandSchedule[nc.Network.ForkUpgradeParam.UpgradePhoenixHeight] = config.DrandQuicknet - return nc } diff --git a/fixtures/networks/calibration.go b/fixtures/networks/calibration.go index 6cc6c04dea..f832dafb31 100644 --- a/fixtures/networks/calibration.go +++ b/fixtures/networks/calibration.go @@ -18,10 +18,10 @@ func Calibration() *NetworkConf { nc := &NetworkConf{ Bootstrap: config.BootstrapConfig{ Addresses: []string{ - "/dns4/calibration.node.glif.io/tcp/1237/p2p/12D3KooWQPYouEAsUQKzvFUA9sQ8tz4rfpqtTzh2eL6USd9bwg7x", - "/dns4/bootstrap-calibnet-0.chainsafe-fil.io/tcp/34000/p2p/12D3KooWABQ5gTDHPWyvhJM7jPhtNwNJruzTEo32Lo4gcS5ABAMm", - "/dns4/bootstrap-calibnet-1.chainsafe-fil.io/tcp/34000/p2p/12D3KooWS3ZRhMYL67b4bD5XQ6fcpTyVQXnDe8H89LvwrDqaSbiT", - "/dns4/bootstrap-calibnet-2.chainsafe-fil.io/tcp/34000/p2p/12D3KooWEiBN8jBX8EBoM3M47pVRLRWV812gDRUJhMxgyVkUoR48", + "/dns/calibration.node.glif.io/tcp/1237/p2p/12D3KooWQPYouEAsUQKzvFUA9sQ8tz4rfpqtTzh2eL6USd9bwg7x", + "/dns/bootstrap-calibnet-0.chainsafe-fil.io/tcp/34000/p2p/12D3KooWABQ5gTDHPWyvhJM7jPhtNwNJruzTEo32Lo4gcS5ABAMm", + "/dns/bootstrap-calibnet-1.chainsafe-fil.io/tcp/34000/p2p/12D3KooWS3ZRhMYL67b4bD5XQ6fcpTyVQXnDe8H89LvwrDqaSbiT", + "/dns/bootstrap-calibnet-2.chainsafe-fil.io/tcp/34000/p2p/12D3KooWEiBN8jBX8EBoM3M47pVRLRWV812gDRUJhMxgyVkUoR48", }, Period: "30s", }, @@ -67,6 +67,7 @@ func Calibration() *NetworkConf { UpgradeWatermelonFix2Height: 1108174, // 2023-11-21T13:00:00Z UpgradeDragonHeight: 1427974, // 2024-03-11T14:00:00Z UpgradeCalibrationDragonFixHeight: 1493854, // 2024-04-03T11:00:00Z + UpgradeWaffleHeight: 1779094, // 2024-07-11T12:00:00Z }, DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: 1}, AddressNetwork: address.Testnet, @@ -74,11 +75,14 @@ func Calibration() *NetworkConf { AllowableClockDriftSecs: 1, Eip155ChainID: 314159, ActorDebugging: false, + F3Enabled: true, }, } nc.Network.ForkUpgradeParam.UpgradePhoenixHeight = nc.Network.ForkUpgradeParam.UpgradeDragonHeight + 120 nc.Network.DrandSchedule[nc.Network.ForkUpgradeParam.UpgradePhoenixHeight] = config.DrandQuicknet + nc.Network.F3BootstrapEpoch = nc.Network.ForkUpgradeParam.UpgradeWaffleHeight + 100 + return nc } diff --git a/fixtures/networks/forcenet.go b/fixtures/networks/forcenet.go index 4f9352d756..0e35d9798c 100644 --- a/fixtures/networks/forcenet.go +++ b/fixtures/networks/forcenet.go @@ -18,7 +18,7 @@ func ForceNet() *NetworkConf { Network: config.NetworkParamsConfig{ DevNet: true, NetworkType: types.NetworkForce, - GenesisNetworkVersion: network.Version21, + GenesisNetworkVersion: network.Version22, ReplaceProofTypes: []abi.RegisteredSealProof{ abi.RegisteredSealProof_StackedDrg8MiBV1, abi.RegisteredSealProof_StackedDrg512MiBV1, @@ -60,19 +60,22 @@ func ForceNet() *NetworkConf { UpgradeWatermelonHeight: -24, UpgradeWatermelonFixHeight: -100, // This fix upgrade only ran on calibrationnet UpgradeWatermelonFix2Height: -101, // This fix upgrade only ran on calibrationnet - UpgradeDragonHeight: 20, + UpgradeDragonHeight: -25, UpgradeCalibrationDragonFixHeight: -102, // This fix upgrade only ran on calibrationnet + UpgradePhoenixHeight: -26, + UpgradeWaffleHeight: 200, }, - DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: config.DrandMainnet}, + DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: config.DrandQuicknet}, AddressNetwork: address.Testnet, PropagationDelaySecs: 1, AllowableClockDriftSecs: 1, Eip155ChainID: 31415926, ActorDebugging: true, + F3Enabled: true, + F3BootstrapEpoch: 100, + ManifestServerID: "12D3KooWHcNBkqXEBrsjoveQvj6zDF3vK5S9tAfqyYaQF1LGSJwG", }, } - nc.Network.ForkUpgradeParam.UpgradePhoenixHeight = nc.Network.ForkUpgradeParam.UpgradeDragonHeight + 120 - nc.Network.DrandSchedule[nc.Network.ForkUpgradeParam.UpgradePhoenixHeight] = config.DrandQuicknet return nc } diff --git a/fixtures/networks/integrationtestnet.go b/fixtures/networks/integrationtestnet.go index 2f64705ea3..1563412da7 100644 --- a/fixtures/networks/integrationtestnet.go +++ b/fixtures/networks/integrationtestnet.go @@ -53,8 +53,9 @@ func IntegrationNet() *NetworkConf { UpgradeWatermelonHeight: 3431940, UpgradeWatermelonFixHeight: -100, // This fix upgrade only ran on calibrationnet UpgradeWatermelonFix2Height: -101, // This fix upgrade only ran on calibrationnet - UpgradeDragonHeight: 9999999999999, + UpgradeDragonHeight: 3855360, UpgradeCalibrationDragonFixHeight: -102, // This fix upgrade only ran on calibrationnet + UpgradeWaffleHeight: 9999999999999, }, DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: 5, 51000: 1}, AddressNetwork: address.Testnet, @@ -62,6 +63,9 @@ func IntegrationNet() *NetworkConf { AllowableClockDriftSecs: 1, Eip155ChainID: 314, ActorDebugging: false, + F3Enabled: false, + F3BootstrapEpoch: -1, + ManifestServerID: "12D3KooWENMwUF9YxvQxar7uBWJtZkA6amvK4xWmKXfSiHUo2Qq7", }, } diff --git a/fixtures/networks/interopnet.go b/fixtures/networks/interopnet.go index 01f9cf22c3..bd03847baa 100644 --- a/fixtures/networks/interopnet.go +++ b/fixtures/networks/interopnet.go @@ -20,7 +20,7 @@ func InteropNet() *NetworkConf { Network: config.NetworkParamsConfig{ DevNet: true, NetworkType: types.NetworkInterop, - GenesisNetworkVersion: network.Version16, + GenesisNetworkVersion: network.Version22, ReplaceProofTypes: []abi.RegisteredSealProof{ abi.RegisteredSealProof_StackedDrg2KiBV1, abi.RegisteredSealProof_StackedDrg8MiBV1, @@ -58,20 +58,22 @@ func InteropNet() *NetworkConf { UpgradeWatermelonHeight: -24, UpgradeWatermelonFixHeight: -100, // This fix upgrade only ran on calibrationnet UpgradeWatermelonFix2Height: -101, // This fix upgrade only ran on calibrationnet - UpgradeDragonHeight: 50, + UpgradeDragonHeight: -25, UpgradeCalibrationDragonFixHeight: -102, // This fix upgrade only ran on calibrationnet + UpgradePhoenixHeight: -26, + UpgradeWaffleHeight: 50, }, - DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: 1}, + DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: config.DrandQuicknet}, AddressNetwork: address.Testnet, PropagationDelaySecs: 6, AllowableClockDriftSecs: 1, Eip155ChainID: 3141592, ActorDebugging: false, + F3Enabled: true, + F3BootstrapEpoch: 1000, + ManifestServerID: "12D3KooWQJ2rdVnG4okDUB6yHQhAjNutGNemcM7XzqC9Eo4z9Jce", }, } - nc.Network.ForkUpgradeParam.UpgradePhoenixHeight = nc.Network.ForkUpgradeParam.UpgradeDragonHeight + 100 - nc.Network.DrandSchedule[nc.Network.ForkUpgradeParam.UpgradePhoenixHeight] = config.DrandQuicknet - return nc } diff --git a/fixtures/networks/mainnet.go b/fixtures/networks/mainnet.go index 91f6196abe..3da7ac771c 100644 --- a/fixtures/networks/mainnet.go +++ b/fixtures/networks/mainnet.go @@ -13,17 +13,11 @@ func Mainnet() *NetworkConf { nc := &NetworkConf{ Bootstrap: config.BootstrapConfig{ Addresses: []string{ - "/dns4/lotus-bootstrap.forceup.cn/tcp/41778/p2p/12D3KooWFQsv3nRMUevZNWWsY1Wu6NUzUbawnWU5NcRhgKuJA37C", - "/dns4/bootstrap-0.starpool.in/tcp/12757/p2p/12D3KooWGHpBMeZbestVEWkfdnC9u7p6uFHXL1n7m1ZBqsEmiUzz", - "/dns4/bootstrap-1.starpool.in/tcp/12757/p2p/12D3KooWQZrGH1PxSNZPum99M1zNvjNFM33d1AAu5DcvdHptuU7u", - "/dns4/node.glif.io/tcp/1235/p2p/12D3KooWBF8cpp65hp2u9LK5mh19x67ftAam84z9LsfaquTDSBpt", - "/dns4/bootstrap-0.ipfsmain.cn/tcp/34721/p2p/12D3KooWQnwEGNqcM2nAcPtRR9rAX8Hrg4k9kJLCHoTR5chJfz6d", - "/dns4/bootstrap-1.ipfsmain.cn/tcp/34723/p2p/12D3KooWMKxMkD5DMpSWsW7dBddKxKT7L2GgbNuckz9otxvkvByP", - "/dns4/bootstarp-0.1475.io/tcp/61256/p2p/12D3KooWRzCVDwHUkgdK7eRgnoXbjDAELhxPErjHzbRLguSV1aRt", - "/dns4/bootstrap-venus.mainnet.filincubator.com/tcp/8888/p2p/QmQu8C6deXwKvJP2D8B6QGyhngc3ZiDnFzEHBDx8yeBXST", - "/dns4/bootstrap-mainnet-0.chainsafe-fil.io/tcp/34000/p2p/12D3KooWKKkCZbcigsWTEu1cgNetNbZJqeNtysRtFpq7DTqw3eqH", - "/dns4/bootstrap-mainnet-1.chainsafe-fil.io/tcp/34000/p2p/12D3KooWGnkd9GQKo3apkShQDaq1d6cKJJmsVe6KiQkacUk1T8oZ", - "/dns4/bootstrap-mainnet-2.chainsafe-fil.io/tcp/34000/p2p/12D3KooWHQRSDFv4FvAjtU32shQ7znz7oRbLBryXzZ9NMK2feyyH", + "/dns/node.glif.io/tcp/1235/p2p/12D3KooWBF8cpp65hp2u9LK5mh19x67ftAam84z9LsfaquTDSBpt", + "/dns/bootstrap-venus.mainnet.filincubator.com/tcp/8888/p2p/QmQu8C6deXwKvJP2D8B6QGyhngc3ZiDnFzEHBDx8yeBXST", + "/dns/bootstrap-mainnet-0.chainsafe-fil.io/tcp/34000/p2p/12D3KooWKKkCZbcigsWTEu1cgNetNbZJqeNtysRtFpq7DTqw3eqH", + "/dns/bootstrap-mainnet-1.chainsafe-fil.io/tcp/34000/p2p/12D3KooWGnkd9GQKo3apkShQDaq1d6cKJJmsVe6KiQkacUk1T8oZ", + "/dns/bootstrap-mainnet-2.chainsafe-fil.io/tcp/34000/p2p/12D3KooWHQRSDFv4FvAjtU32shQ7znz7oRbLBryXzZ9NMK2feyyH", }, Period: "30s", }, @@ -72,6 +66,7 @@ func Mainnet() *NetworkConf { UpgradeWatermelonFix2Height: -101, // This fix upgrade only ran on calibrationnet UpgradeDragonHeight: 3855360, // 2024-04-24T14:00:00Z UpgradeCalibrationDragonFixHeight: -102, // This fix upgrade only ran on calibrationnet + UpgradeWaffleHeight: 999999999999, // }, DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: 5, 51000: 1}, AddressNetwork: address.Mainnet, @@ -79,6 +74,9 @@ func Mainnet() *NetworkConf { AllowableClockDriftSecs: 1, Eip155ChainID: 314, ActorDebugging: false, + F3Enabled: false, + F3BootstrapEpoch: -1, + ManifestServerID: "12D3KooWENMwUF9YxvQxar7uBWJtZkA6amvK4xWmKXfSiHUo2Qq7", }, } diff --git a/fixtures/networks/net_2k.go b/fixtures/networks/net_2k.go index 423031733d..4cf71e2655 100644 --- a/fixtures/networks/net_2k.go +++ b/fixtures/networks/net_2k.go @@ -17,7 +17,7 @@ func Net2k() *NetworkConf { Network: config.NetworkParamsConfig{ DevNet: true, NetworkType: types.Network2k, - GenesisNetworkVersion: network.Version21, + GenesisNetworkVersion: network.Version22, ReplaceProofTypes: []abi.RegisteredSealProof{ abi.RegisteredSealProof_StackedDrg2KiBV1, abi.RegisteredSealProof_StackedDrg8MiBV1, @@ -54,20 +54,22 @@ func Net2k() *NetworkConf { UpgradeWatermelonHeight: -24, UpgradeWatermelonFixHeight: -100, // This fix upgrade only ran on calibrationnet UpgradeWatermelonFix2Height: -101, // This fix upgrade only ran on calibrationnet - UpgradeDragonHeight: 20, + UpgradeDragonHeight: -25, UpgradeCalibrationDragonFixHeight: -102, // This fix upgrade only ran on calibrationnet + UpgradePhoenixHeight: -26, + UpgradeWaffleHeight: 200, }, - DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: 1}, + DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: config.DrandQuicknet}, AddressNetwork: address.Testnet, PropagationDelaySecs: 1, AllowableClockDriftSecs: 1, Eip155ChainID: 31415926, ActorDebugging: true, + F3Enabled: true, + F3BootstrapEpoch: 100, + ManifestServerID: "12D3KooWHcNBkqXEBrsjoveQvj6zDF3vK5S9tAfqyYaQF1LGSJwG", }, } - nc.Network.ForkUpgradeParam.UpgradePhoenixHeight = nc.Network.ForkUpgradeParam.UpgradeDragonHeight + 120 - nc.Network.DrandSchedule[nc.Network.ForkUpgradeParam.UpgradePhoenixHeight] = config.DrandQuicknet - return nc } diff --git a/go.mod b/go.mod index a73fbc79b1..186c27f611 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.21 require ( contrib.go.opencensus.io/exporter/prometheus v0.4.2 github.com/BurntSushi/toml v1.3.0 - github.com/DataDog/zstd v1.4.5 github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d github.com/ahmetb/go-linq/v3 v3.2.0 @@ -15,8 +14,8 @@ require ( github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e github.com/dgraph-io/badger/v2 v2.2007.4 github.com/docker/go-units v0.5.0 - github.com/drand/drand v1.5.7 - github.com/drand/kyber v1.2.0 + github.com/drand/drand v1.5.11 + github.com/drand/kyber v1.3.1 github.com/dustin/go-humanize v1.0.1 github.com/etherlabsio/healthcheck/v2 v2.0.0 github.com/fatih/color v1.15.0 @@ -28,11 +27,12 @@ require ( github.com/filecoin-project/go-commp-utils v0.1.3 github.com/filecoin-project/go-crypto v0.0.1 github.com/filecoin-project/go-data-transfer/v2 v2.0.0-rc6 + github.com/filecoin-project/go-f3 v0.0.3-0.20240702063402-d48771055cf4 github.com/filecoin-project/go-fil-commcid v0.1.0 github.com/filecoin-project/go-fil-markets v1.28.2 github.com/filecoin-project/go-jsonrpc v0.1.5 github.com/filecoin-project/go-paramfetch v0.0.4 - github.com/filecoin-project/go-state-types v0.13.1 + github.com/filecoin-project/go-state-types v0.14.0-rc5 github.com/filecoin-project/pubsub v1.0.0 github.com/filecoin-project/specs-actors v0.9.15 github.com/filecoin-project/specs-actors/v2 v2.3.6 @@ -76,7 +76,7 @@ require ( github.com/ipld/go-car v0.6.2 github.com/ipld/go-car/v2 v2.13.1 github.com/jbenet/goprocess v0.1.4 - github.com/libp2p/go-libp2p v0.34.1 + github.com/libp2p/go-libp2p v0.35.0 github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-pubsub v0.11.0 github.com/libp2p/go-msgio v0.3.0 @@ -115,6 +115,7 @@ require ( ) require ( + github.com/Kubuxu/go-broadcast v0.0.0-20240621161059-1a8c90734cd6 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/ipfs/go-blockservice v0.5.2 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.1 // indirect @@ -161,7 +162,7 @@ require ( github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -244,7 +245,7 @@ require ( github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kilic/bls12-381 v0.1.0 // indirect - github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/compress v1.17.8 github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect @@ -316,7 +317,7 @@ require ( github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect go.opentelemetry.io/otel v1.26.0 go.opentelemetry.io/otel/metric v1.26.0 // indirect go.opentelemetry.io/otel/sdk/metric v0.39.0 // indirect diff --git a/go.sum b/go.sum index f6bfada13b..881f56fe09 100644 --- a/go.sum +++ b/go.sum @@ -73,10 +73,10 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee h1:8doiS7ib3zi6/K172oDhSKU0dJ/miJramo9NITOMyZQ= github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee/go.mod h1:W0GbEAA4uFNYOGG2cJpmFJ04E6SD1NLELPYZB57/7AY= +github.com/Kubuxu/go-broadcast v0.0.0-20240621161059-1a8c90734cd6 h1:yh2/1fz3ajTaeKskSWxtSBNScdRZfQ/A5nyd9+64T6M= +github.com/Kubuxu/go-broadcast v0.0.0-20240621161059-1a8c90734cd6/go.mod h1:5LOj/fF3Oc/cvJqzDiyfx4XwtBPRWUYEz+V+b13sH5U= github.com/Kubuxu/go-os-helper v0.0.1 h1:EJiD2VUQyh5A9hWJLmc6iWg6yIcJ7jpBcwC8GMGXfDk= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= @@ -148,6 +148,8 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -171,8 +173,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 h1:ZFUue+PNxmHlu7pYv+IYMtqlaO/0VwaGEqKepZf9JpA= github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= @@ -213,10 +215,10 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUn github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/drand/drand v1.5.7 h1:5f2D5aH1nEfVI9S6tl2p9bgIDMZ92oltmiY12Kh+eYU= -github.com/drand/drand v1.5.7/go.mod h1:jrJ0244yOHNL5V04vazk3mFatjAWm3i6dg6URWwgbXk= -github.com/drand/kyber v1.2.0 h1:22SbBxsKbgQnJUoyYKIfG909PhBsj0vtANeu4BX5xgE= -github.com/drand/kyber v1.2.0/go.mod h1:6TqFlCc7NGOiNVTF9pF2KcDRfllPd9XOkExuG5Xtwfo= +github.com/drand/drand v1.5.11 h1:7sskUTCsX2lgFiWdGvPh3/P0ZDQKi1lCtI7RQKK010k= +github.com/drand/drand v1.5.11/go.mod h1:TvJjCJ/s4Usn4pKRpDC0N1QaCwSt3YC8fRqhZdpOUU0= +github.com/drand/kyber v1.3.1 h1:E0p6M3II+loMVwTlAp5zu4+GGZFNiRfq02qZxzw2T+Y= +github.com/drand/kyber v1.3.1/go.mod h1:f+mNHjiGT++CuueBrpeMhFNdKZAsy0tu03bKq9D5LPA= github.com/drand/kyber-bls12381 v0.3.1 h1:KWb8l/zYTP5yrvKTgvhOrk2eNPscbMiUOIeWBnmUxGo= github.com/drand/kyber-bls12381 v0.3.1/go.mod h1:H4y9bLPu7KZA/1efDg+jtJ7emKx+ro3PU7/jWUVt140= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -275,6 +277,8 @@ github.com/filecoin-project/go-data-transfer/v2 v2.0.0-rc6 h1:EsbXTWsBKT764qtX4M github.com/filecoin-project/go-data-transfer/v2 v2.0.0-rc6/go.mod h1:cX1acvFVWC5EXnnmFPWEFXbO7nLUdSZa+nqgi1QpTpw= github.com/filecoin-project/go-ds-versioning v0.1.2 h1:to4pTadv3IeV1wvgbCbN6Vqd+fu+7tveXgv/rCEZy6w= github.com/filecoin-project/go-ds-versioning v0.1.2/go.mod h1:C9/l9PnB1+mwPa26BBVpCjG/XQCB0yj/q5CK2J8X1I4= +github.com/filecoin-project/go-f3 v0.0.3-0.20240702063402-d48771055cf4 h1:eQW2fyKyMuiweuySEb/zMIc3WLSAnIOY8lpqCVQM7pU= +github.com/filecoin-project/go-f3 v0.0.3-0.20240702063402-d48771055cf4/go.mod h1:Wry0mNa8z767TBHb7N0cVb+9j00KsHbD2pzsC3li4R8= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commcid v0.1.0 h1:3R4ds1A9r6cr8mvZBfMYxTS88OqLYEo6roi+GiIeOh8= github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= @@ -301,9 +305,9 @@ github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psS github.com/filecoin-project/go-state-types v0.1.4/go.mod h1:xCA/WfKlC2zcn3fUmDv4IrzznwS98X5XW/irUP3Lhxg= github.com/filecoin-project/go-state-types v0.1.6/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= github.com/filecoin-project/go-state-types v0.1.10/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= -github.com/filecoin-project/go-state-types v0.11.2-0.20230712101859-8f37624fa540/go.mod h1:SyNPwTsU7I22gL2r0OAPcImvLoTVfgRwdK/Y5rR1zz8= -github.com/filecoin-project/go-state-types v0.13.1 h1:4CivvlcHAIoAtFFVVlZtokynaMQu5XLXGoTKhQkfG1I= -github.com/filecoin-project/go-state-types v0.13.1/go.mod h1:cHpOPup9H1g2T29dKHAjC2sc7/Ef5ypjuW9A3I+e9yY= +github.com/filecoin-project/go-state-types v0.14.0-rc1/go.mod h1:cHpOPup9H1g2T29dKHAjC2sc7/Ef5ypjuW9A3I+e9yY= +github.com/filecoin-project/go-state-types v0.14.0-rc5 h1:c8jo2mRx02u8smiCZsSDt1dsOGSu4gwfvHRqSKAl8Lc= +github.com/filecoin-project/go-state-types v0.14.0-rc5/go.mod h1:cHpOPup9H1g2T29dKHAjC2sc7/Ef5ypjuW9A3I+e9yY= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v1.0.3 h1:N07o6alys+V1tNoSTi4WuuoeNC4erS/6jE74+NsgQuk= github.com/filecoin-project/go-statemachine v1.0.3/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54= @@ -790,8 +794,8 @@ github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= -github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg= -github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= +github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -820,6 +824,7 @@ github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ib github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -859,8 +864,8 @@ github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFG github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= -github.com/libp2p/go-libp2p v0.34.1 h1:fxn9vyLo7vJcXQRNvdRbyPjbzuQgi2UiqC8hEbn8a18= -github.com/libp2p/go-libp2p v0.34.1/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ= +github.com/libp2p/go-libp2p v0.35.0 h1:1xS1Bkr9X7GtdvV6ntLnDV9xB1kNjHK1lZ0eaO6gnhc= +github.com/libp2p/go-libp2p v0.35.0/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= @@ -1375,6 +1380,7 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163/go.mod h1:f github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20210303213153-67a261a1d291/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20220323183124-98fa8256a799/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.1.0/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/cbor-gen v0.1.1 h1:eKfcJIoxivjMtwfCfmJAqSF56MHcWqyIScXwaC1VBgw= github.com/whyrusleeping/cbor-gen v0.1.1/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= @@ -1396,8 +1402,8 @@ github.com/xorcare/golden v0.6.0/go.mod h1:7T39/ZMvaSEZlBPoYfVFmsBLmUl3uz9IuzWj/ github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542 h1:oWgZJmC1DorFZDpfMfWg7xk29yEOZiXmo/wZl+utTI8= github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542/go.mod h1:7T39/ZMvaSEZlBPoYfVFmsBLmUl3uz9IuzWj/U6FtvQ= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/pkg/chain/chain_reader.go b/pkg/chain/chain_reader.go new file mode 100644 index 0000000000..5a8f62a1c1 --- /dev/null +++ b/pkg/chain/chain_reader.go @@ -0,0 +1,57 @@ +package chain + +import ( + "context" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/network" + appstate "github.com/filecoin-project/venus/pkg/state" + "github.com/filecoin-project/venus/pkg/state/tree" + "github.com/filecoin-project/venus/venus-shared/types" + cid "github.com/ipfs/go-cid" +) + +type ChainReader interface { + GetTipSet(ctx context.Context, key types.TipSetKey) (*types.TipSet, error) + GetHead() *types.TipSet + StateView(ctx context.Context, ts *types.TipSet) (*appstate.View, error) + GetTipSetStateRoot(context.Context, *types.TipSet) (cid.Cid, error) + GetTipSetReceiptsRoot(context.Context, *types.TipSet) (cid.Cid, error) + GetGenesisBlock(context.Context) (*types.BlockHeader, error) + GetLatestBeaconEntry(context.Context, *types.TipSet) (*types.BeaconEntry, error) + GetTipSetByHeight(context.Context, *types.TipSet, abi.ChainEpoch, bool) (*types.TipSet, error) + GetLookbackTipSetForRound(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch, version network.Version) (*types.TipSet, cid.Cid, error) + GetTipsetMetadata(context.Context, *types.TipSet) (*TipSetMetadata, error) + PutTipSetMetadata(context.Context, *TipSetMetadata) error + Weight(context.Context, *types.TipSet) (big.Int, error) + + ICirculatingSupplyCalcualtor +} + +type chainReader struct { + *Store + circulatingSupplyCalculator ICirculatingSupplyCalcualtor +} + +func ChainReaderWrapper(store *Store, circulatingSupplyCalculator ICirculatingSupplyCalcualtor) ChainReader { + return &chainReader{ + Store: store, + circulatingSupplyCalculator: circulatingSupplyCalculator, + } +} + +// GetCirculatingSupply implements ChainReader. +func (c *chainReader) GetCirculatingSupply(ctx context.Context, height abi.ChainEpoch, st tree.Tree) (big.Int, error) { + return c.circulatingSupplyCalculator.GetCirculatingSupply(ctx, height, st) +} + +// GetCirculatingSupplyDetailed implements ChainReader. +func (c *chainReader) GetCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st tree.Tree) (types.CirculatingSupply, error) { + return c.circulatingSupplyCalculator.GetCirculatingSupplyDetailed(ctx, height, st) +} + +// GetFilVested implements ChainReader. +func (c *chainReader) GetFilVested(ctx context.Context, height abi.ChainEpoch) (big.Int, error) { + return c.circulatingSupplyCalculator.GetFilVested(ctx, height) +} diff --git a/pkg/chain/circulating_supply.go b/pkg/chain/circulating_supply.go index 946107f99e..b8c3a96ee0 100644 --- a/pkg/chain/circulating_supply.go +++ b/pkg/chain/circulating_supply.go @@ -5,12 +5,14 @@ import ( "fmt" "sync" + "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/network" "github.com/filecoin-project/venus/pkg/constants" "github.com/filecoin-project/venus/venus-shared/types" "github.com/ipfs/go-cid" - cbornode "github.com/ipfs/go-ipld-cbor" + cbor "github.com/ipfs/go-ipld-cbor" // Used for genesis. msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" @@ -19,15 +21,22 @@ import ( "github.com/filecoin-project/venus/pkg/state/tree" "github.com/filecoin-project/venus/venus-shared/actors/adt" "github.com/filecoin-project/venus/venus-shared/actors/builtin" + _init "github.com/filecoin-project/venus/venus-shared/actors/builtin/init" "github.com/filecoin-project/venus/venus-shared/actors/builtin/market" + "github.com/filecoin-project/venus/venus-shared/actors/builtin/miner" + "github.com/filecoin-project/venus/venus-shared/actors/builtin/multisig" "github.com/filecoin-project/venus/venus-shared/actors/builtin/power" "github.com/filecoin-project/venus/venus-shared/actors/builtin/reward" + "github.com/filecoin-project/venus/venus-shared/actors/builtin/verifreg" blockstoreutil "github.com/filecoin-project/venus/venus-shared/blockstore" ) +type GetNetworkVersionFunc func(ctx context.Context, height abi.ChainEpoch) network.Version + type ICirculatingSupplyCalcualtor interface { GetCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st tree.Tree) (types.CirculatingSupply, error) GetFilVested(ctx context.Context, height abi.ChainEpoch) (abi.TokenAmount, error) + GetCirculatingSupply(ctx context.Context, height abi.ChainEpoch, st tree.Tree) (abi.TokenAmount, error) } // CirculatingSupplyCalculator used to calculate the funds at a specific block height @@ -42,17 +51,28 @@ type CirculatingSupplyCalculator struct { genesisPledge abi.TokenAmount - genesisMsigLk sync.Mutex - upgradeConfig *config.ForkUpgradeConfig + genesisMsigLk sync.Mutex + upgradeConfig *config.ForkUpgradeConfig + getNetworkVersion GetNetworkVersionFunc } // NewCirculatingSupplyCalculator create new circulating supply calculator -func NewCirculatingSupplyCalculator(bstore blockstoreutil.Blockstore, genesisRoot cid.Cid, upgradeConfig *config.ForkUpgradeConfig) *CirculatingSupplyCalculator { - return &CirculatingSupplyCalculator{bstore: bstore, genesisRoot: genesisRoot, upgradeConfig: upgradeConfig} +func NewCirculatingSupplyCalculator(bstore blockstoreutil.Blockstore, + genesisRoot cid.Cid, + upgradeConfig *config.ForkUpgradeConfig, + getNetworkVersion GetNetworkVersionFunc, +) *CirculatingSupplyCalculator { + return &CirculatingSupplyCalculator{ + bstore: bstore, + genesisRoot: genesisRoot, + upgradeConfig: upgradeConfig, + getNetworkVersion: getNetworkVersion, + } } // GetCirculatingSupplyDetailed query contract and calculate circulation status at specific height and tree state func (caculator *CirculatingSupplyCalculator) GetCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st tree.Tree) (types.CirculatingSupply, error) { + nv := caculator.getNetworkVersion(ctx, height) filVested, err := caculator.GetFilVested(ctx, height) if err != nil { return types.CirculatingSupply{}, fmt.Errorf("failed to calculate filVested: %v", err) @@ -74,7 +94,7 @@ func (caculator *CirculatingSupplyCalculator) GetCirculatingSupplyDetailed(ctx c if err != nil { return types.CirculatingSupply{}, fmt.Errorf("failed to calculate filBurnt: %v", err) } - filLocked, err := caculator.GetFilLocked(ctx, st) + filLocked, err := caculator.GetFilLocked(ctx, st, nv) if err != nil { return types.CirculatingSupply{}, fmt.Errorf("failed to calculate filLocked: %v", err) } @@ -97,47 +117,117 @@ func (caculator *CirculatingSupplyCalculator) GetCirculatingSupplyDetailed(ctx c }, nil } -/*func (c *Expected) processBlock(ctx context.Context, ts *block.TipSet) (cid.Cid, []types.MessageReceipt, error) { - var secpMessages [][]*types.SignedMessage - var blsMessages [][]*types.Message - for i := 0; i < ts.Len(); i++ { - blk := ts.At(i) - secpMsgs, blsMsgs, err := c.messageStore.LoadMetaMessages(ctx, blk.Messages.Cid) - if err != nil { - return cid.Undef, []types.MessageReceipt{}, xerrors.Wrapf(err, "syncing tip %s failed loading message list %s for block %s", ts.Key(), blk.Messages, blk.Cid()) +func (caculator *CirculatingSupplyCalculator) GetCirculatingSupply(ctx context.Context, height abi.ChainEpoch, st tree.Tree) (abi.TokenAmount, error) { + adtStore := adt.WrapStore(ctx, cbor.NewCborStore(caculator.bstore)) + circ := big.Zero() + unCirc := big.Zero() + nv := caculator.getNetworkVersion(ctx, height) + err := st.ForEach(func(a address.Address, actor *types.Actor) error { + // this can be a lengthy operation, we need to cancel early when + // the context is cancelled to avoid resource exhaustion + select { + case <-ctx.Done(): + // this will cause ForEach to return + return ctx.Err() + default: } - blsMessages = append(blsMessages, blsMsgs) - secpMessages = append(secpMessages, secpMsgs) - } + switch { + case actor.Balance.IsZero(): + // Do nothing for zero-balance actors + break + case a == _init.Address || + a == reward.Address || + a == verifreg.Address || + // The power actor itself should never receive funds + a == power.Address || + a == builtin.SystemActorAddr || + a == builtin.CronActorAddr || + a == builtin.BurntFundsActorAddr || + a == builtin.SaftAddress || + a == builtin.ReserveAddress || + a == builtin.EthereumAddressManagerActorAddr: + + unCirc = big.Add(unCirc, actor.Balance) + + case a == market.Address: + if nv >= network.Version23 { + circ = big.Add(circ, actor.Balance) + } else { + mst, err := market.Load(adtStore, actor) + if err != nil { + return err + } + + lb, err := mst.TotalLocked() + if err != nil { + return err + } + + circ = big.Add(circ, big.Sub(actor.Balance, lb)) + unCirc = big.Add(unCirc, lb) + } + + case builtin.IsAccountActor(actor.Code) || + builtin.IsPaymentChannelActor(actor.Code) || + builtin.IsEthAccountActor(actor.Code) || + builtin.IsEvmActor(actor.Code) || + builtin.IsPlaceholderActor(actor.Code): + + circ = big.Add(circ, actor.Balance) + + case builtin.IsStorageMinerActor(actor.Code): + mst, err := miner.Load(adtStore, actor) + if err != nil { + return err + } + + ab, err := mst.AvailableBalance(actor.Balance) + + if err == nil { + circ = big.Add(circ, ab) + unCirc = big.Add(unCirc, big.Sub(actor.Balance, ab)) + } else { + // Assume any error is because the miner state is "broken" (lower actor balance than locked funds) + // In this case, the actor's entire balance is considered "uncirculating" + unCirc = big.Add(unCirc, actor.Balance) + } + + case builtin.IsMultisigActor(actor.Code): + mst, err := multisig.Load(adtStore, actor) + if err != nil { + return err + } + + lb, err := mst.LockedBalance(height) + if err != nil { + return err + } + + ab := big.Sub(actor.Balance, lb) + circ = big.Add(circ, big.Max(ab, big.Zero())) + unCirc = big.Add(unCirc, big.Min(actor.Balance, lb)) + default: + return fmt.Errorf("unexpected actor: %s", a) + } - vms := vm.NewStorage(c.bstore) - priorState, err := state.LoadState(ctx, vms, ts.At(0).StateRoot.Cid) + return nil + }) if err != nil { - return cid.Undef, []types.MessageReceipt{}, err + return abi.TokenAmount{}, err } - var newState state.Tree - newState, receipts, err := c.runMessages(ctx, priorState, vms, ts, blsMessages, secpMessages) - if err != nil { - return cid.Undef, []types.MessageReceipt{}, err - } - err = vms.Flush() - if err != nil { - return cid.Undef, []types.MessageReceipt{}, err + total := big.Add(circ, unCirc) + if !total.Equals(types.TotalFilecoinInt) { + return abi.TokenAmount{}, fmt.Errorf("total filecoin didn't add to expected amount: %s != %s", total, types.TotalFilecoinInt) } - root, err := newState.Flush(ctx) - if err != nil { - return cid.Undef, []types.MessageReceipt{}, err - } - return root, receipts, err + return circ, nil } -*/ // sets up information about the vesting schedule func (caculator *CirculatingSupplyCalculator) setupGenesisVestingSchedule(ctx context.Context) error { - cst := cbornode.NewCborStore(caculator.bstore) + cst := cbor.NewCborStore(caculator.bstore) sTree, err := tree.LoadState(ctx, cst, caculator.genesisRoot) if err != nil { return fmt.Errorf("loading state tree: %v", err) @@ -190,7 +280,7 @@ func (caculator *CirculatingSupplyCalculator) setupGenesisVestingSchedule(ctx co } // sets up information about the vesting schedule post the ignition upgrade -func (caculator *CirculatingSupplyCalculator) setupPostIgnitionVesting(ctx context.Context) error { +func (caculator *CirculatingSupplyCalculator) setupPostIgnitionVesting(_ context.Context) error { totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount) // 6 months @@ -234,7 +324,7 @@ func (caculator *CirculatingSupplyCalculator) setupPostIgnitionVesting(ctx conte } // sets up information about the vesting schedule post the calico upgrade -func (caculator *CirculatingSupplyCalculator) setupPostCalicoVesting(ctx context.Context) error { +func (caculator *CirculatingSupplyCalculator) setupPostCalicoVesting(_ context.Context) error { totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount) // 0 days @@ -375,7 +465,11 @@ func GetFilBurnt(ctx context.Context, st tree.Tree) (abi.TokenAmount, error) { } // GetFilLocked query the market contract and power contract to get the amount of locked fils -func (caculator *CirculatingSupplyCalculator) GetFilLocked(ctx context.Context, st tree.Tree) (abi.TokenAmount, error) { +func (caculator *CirculatingSupplyCalculator) GetFilLocked(ctx context.Context, st tree.Tree, nv network.Version) (abi.TokenAmount, error) { + if nv >= network.Version23 { + return getFilPowerLocked(ctx, st) + } + filMarketLocked, err := getFilMarketLocked(ctx, st) if err != nil { return big.Zero(), fmt.Errorf("failed to get filMarketLocked: %v", err) diff --git a/pkg/chain/circulating_supply_mock.go b/pkg/chain/circulating_supply_mock.go index f5e02288c4..2d65257f87 100644 --- a/pkg/chain/circulating_supply_mock.go +++ b/pkg/chain/circulating_supply_mock.go @@ -30,3 +30,7 @@ func (m MockCirculatingSupplyCalculator) GetCirculatingSupplyDetailed(ctx contex func (m MockCirculatingSupplyCalculator) GetFilVested(ctx context.Context, height abi.ChainEpoch) (abi.TokenAmount, error) { return abi.TokenAmount{}, nil } + +func (m MockCirculatingSupplyCalculator) GetCirculatingSupply(ctx context.Context, height abi.ChainEpoch, st tree.Tree) (abi.TokenAmount, error) { + return abi.TokenAmount{}, nil +} diff --git a/pkg/chain/signatures.go b/pkg/chain/signatures.go index b2517cc452..d06afc24cc 100644 --- a/pkg/chain/signatures.go +++ b/pkg/chain/signatures.go @@ -17,33 +17,42 @@ import ( func AuthenticateMessage(msg *types.SignedMessage, signer address.Address) error { var digest []byte - typ := msg.Signature.Type - switch typ { + signatureType := msg.Signature.Type + signatureCopy := msg.Signature + + switch signatureType { case crypto.SigTypeDelegated: - txArgs, err := types.EthTxArgsFromUnsignedEthMessage(&msg.Message) + signatureCopy.Data = make([]byte, len(msg.Signature.Data)) + copy(signatureCopy.Data, msg.Signature.Data) + ethTx, err := types.EthTransactionFromSignedFilecoinMessage(msg) if err != nil { - return fmt.Errorf("failed to reconstruct eth transaction: %w", err) + return fmt.Errorf("failed to reconstruct Ethereum transaction: %w", err) } - roundTripMsg, err := txArgs.ToUnsignedMessage(msg.Message.From) + + filecoinMsg, err := ethTx.ToUnsignedFilecoinMessage(msg.Message.From) if err != nil { - return fmt.Errorf("failed to reconstruct filecoin msg: %w", err) + return fmt.Errorf("failed to reconstruct Filecoin message: %w", err) } - if !msg.Message.Equals(roundTripMsg) { - return fmt.Errorf("ethereum tx failed to roundtrip") + if !msg.Message.Equals(filecoinMsg) { + return fmt.Errorf("ethereum transaction roundtrip mismatch") } - rlpEncodedMsg, err := txArgs.ToRlpUnsignedMsg() + rlpEncodedMsg, err := ethTx.ToRlpUnsignedMsg() if err != nil { - return fmt.Errorf("failed to repack eth rlp message: %w", err) + return fmt.Errorf("failed to encode RLP message: %w", err) } digest = rlpEncodedMsg + signatureCopy.Data, err = ethTx.ToVerifiableSignature(signatureCopy.Data) + if err != nil { + return fmt.Errorf("failed to verify signature: %w", err) + } default: digest = msg.Message.Cid().Bytes() } - if err := crypto.Verify(&msg.Signature, signer, digest); err != nil { - return fmt.Errorf("message %s has invalid signature (type %d): %w", msg.Cid(), typ, err) + if err := crypto.Verify(&signatureCopy, signer, digest); err != nil { + return fmt.Errorf("invalid signature for message %s (type %d): %w", msg.Cid(), signatureType, err) } return nil } diff --git a/pkg/chain/store.go b/pkg/chain/store.go index fc344c4b05..d3b81b6754 100644 --- a/pkg/chain/store.go +++ b/pkg/chain/store.go @@ -43,13 +43,6 @@ import ( "github.com/filecoin-project/venus/venus-shared/actors/adt" "github.com/filecoin-project/venus/venus-shared/actors/builtin" - _init "github.com/filecoin-project/venus/venus-shared/actors/builtin/init" - "github.com/filecoin-project/venus/venus-shared/actors/builtin/market" - "github.com/filecoin-project/venus/venus-shared/actors/builtin/miner" - "github.com/filecoin-project/venus/venus-shared/actors/builtin/multisig" - "github.com/filecoin-project/venus/venus-shared/actors/builtin/power" - "github.com/filecoin-project/venus/venus-shared/actors/builtin/reward" - "github.com/filecoin-project/venus/venus-shared/actors/builtin/verifreg" "github.com/filecoin-project/venus/venus-shared/actors/policy" blockstoreutil "github.com/filecoin-project/venus/venus-shared/blockstore" "github.com/filecoin-project/venus/venus-shared/types" @@ -124,8 +117,6 @@ type Store struct { // Tracks tipsets by height/parentset for use by expected consensus. tipIndex *TipStateCache - circulatingSupplyCalculator ICirculatingSupplyCalcualtor - chainIndex *ChainIndex reorgCh chan reorg @@ -143,7 +134,6 @@ type Store struct { func NewStore(chainDs repo.Datastore, bsstore blockstoreutil.Blockstore, genesisCid cid.Cid, - circulatiingSupplyCalculator ICirculatingSupplyCalcualtor, weight WeightFunc, ) *Store { tsCache, _ := arc.NewARC[types.TipSetKey, *types.TipSet](DefaultTipsetLruCacheSize) @@ -163,7 +153,6 @@ func NewStore(chainDs repo.Datastore, // todo cycle reference , may think a better idea store.tipIndex = NewTipStateCache(store) store.chainIndex = NewChainIndex(store.GetTipSet) - store.circulatingSupplyCalculator = circulatiingSupplyCalculator val, err := store.ds.Get(context.TODO(), CheckPoint) if err != nil { @@ -520,37 +509,6 @@ func (store *Store) GetLatestBeaconEntry(ctx context.Context, ts *types.TipSet) return nil, fmt.Errorf("found NO beacon entries in the 20 blocks prior to given tipset") } -// nolint -func (store *Store) walkBack(ctx context.Context, from *types.TipSet, to abi.ChainEpoch) (*types.TipSet, error) { - if to > from.Height() { - return nil, fmt.Errorf("looking for tipset with height greater than start point") - } - - if to == from.Height() { - return from, nil - } - - ts := from - - for { - pts, err := store.GetTipSet(ctx, ts.Parents()) - if err != nil { - return nil, err - } - - if to > pts.Height() { - // in case pts is lower than the epoch we're looking for (null blocks) - // return a tipset above that height - return ts, nil - } - if to == pts.Height() { - return pts, nil - } - - ts = pts - } -} - // updateHead sets the passed in tipset as the new head of this chain. func (store *Store) updateHead(ctx context.Context, newTS *types.TipSet) ([]*types.TipSet, []*types.TipSet, bool, error) { var dropped []*types.TipSet @@ -1154,137 +1112,6 @@ func (store *Store) WriteCheckPoint(ctx context.Context, cids types.TipSetKey) e return store.ds.Put(ctx, CheckPoint, buf.Bytes()) } -func (store *Store) GetCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st tree.Tree) (types.CirculatingSupply, error) { - return store.circulatingSupplyCalculator.GetCirculatingSupplyDetailed(ctx, height, st) -} - -func (store *Store) GetFilVested(ctx context.Context, height abi.ChainEpoch) (abi.TokenAmount, error) { - return store.circulatingSupplyCalculator.GetFilVested(ctx, height) -} - -// StateCirculatingSupply get circulate supply at specify epoch -func (store *Store) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) { - ts, err := store.GetTipSet(ctx, tsk) - if err != nil { - return abi.TokenAmount{}, err - } - - root, err := store.GetTipSetStateRoot(ctx, ts) - if err != nil { - return abi.TokenAmount{}, err - } - - sTree, err := tree.LoadState(ctx, store.stateAndBlockSource, root) - if err != nil { - return abi.TokenAmount{}, err - } - - return store.getCirculatingSupply(ctx, ts.Height(), sTree) -} - -func (store *Store) getCirculatingSupply(ctx context.Context, height abi.ChainEpoch, st tree.Tree) (abi.TokenAmount, error) { - adtStore := adt.WrapStore(ctx, store.stateAndBlockSource) - circ := big.Zero() - unCirc := big.Zero() - err := st.ForEach(func(a address.Address, actor *types.Actor) error { - // this can be a lengthy operation, we need to cancel early when - // the context is cancelled to avoid resource exhaustion - select { - case <-ctx.Done(): - // this will cause ForEach to return - return ctx.Err() - default: - } - - switch { - case actor.Balance.IsZero(): - // Do nothing for zero-balance actors - break - case a == _init.Address || - a == reward.Address || - a == verifreg.Address || - // The power actor itself should never receive funds - a == power.Address || - a == builtin.SystemActorAddr || - a == builtin.CronActorAddr || - a == builtin.BurntFundsActorAddr || - a == builtin.SaftAddress || - a == builtin.ReserveAddress || - a == builtin.EthereumAddressManagerActorAddr: - - unCirc = big.Add(unCirc, actor.Balance) - - case a == market.Address: - mst, err := market.Load(adtStore, actor) - if err != nil { - return err - } - - lb, err := mst.TotalLocked() - if err != nil { - return err - } - - circ = big.Add(circ, big.Sub(actor.Balance, lb)) - unCirc = big.Add(unCirc, lb) - - case builtin.IsAccountActor(actor.Code) || - builtin.IsPaymentChannelActor(actor.Code) || - builtin.IsEthAccountActor(actor.Code) || - builtin.IsEvmActor(actor.Code) || - builtin.IsPlaceholderActor(actor.Code): - - circ = big.Add(circ, actor.Balance) - - case builtin.IsStorageMinerActor(actor.Code): - mst, err := miner.Load(adtStore, actor) - if err != nil { - return err - } - - ab, err := mst.AvailableBalance(actor.Balance) - - if err == nil { - circ = big.Add(circ, ab) - unCirc = big.Add(unCirc, big.Sub(actor.Balance, ab)) - } else { - // Assume any error is because the miner state is "broken" (lower actor balance than locked funds) - // In this case, the actor's entire balance is considered "uncirculating" - unCirc = big.Add(unCirc, actor.Balance) - } - - case builtin.IsMultisigActor(actor.Code): - mst, err := multisig.Load(adtStore, actor) - if err != nil { - return err - } - - lb, err := mst.LockedBalance(height) - if err != nil { - return err - } - - ab := big.Sub(actor.Balance, lb) - circ = big.Add(circ, big.Max(ab, big.Zero())) - unCirc = big.Add(unCirc, big.Min(actor.Balance, lb)) - default: - return fmt.Errorf("unexpected actor: %s", a) - } - - return nil - }) - if err != nil { - return abi.TokenAmount{}, err - } - - total := big.Add(circ, unCirc) - if !total.Equals(types.TotalFilecoinInt) { - return abi.TokenAmount{}, fmt.Errorf("total filecoin didn't add to expected amount: %s != %s", total, types.TotalFilecoinInt) - } - - return circ, nil -} - // GetCheckPoint get the check point from store or disk. func (store *Store) GetCheckPoint() types.TipSetKey { return store.checkPoint @@ -1521,6 +1348,10 @@ func (store *Store) Store(ctx context.Context) adt.Store { return adt.WrapStore(ctx, cbor.NewCborStore(store.bsstore)) } +func (store *Store) StateStore() cbor.IpldStore { + return store.stateAndBlockSource +} + func (store *Store) Weight(ctx context.Context, ts *types.TipSet) (big.Int, error) { return store.weight(ctx, store.stateAndBlockSource, ts) } diff --git a/pkg/chain/store_test.go b/pkg/chain/store_test.go index 462bacc120..15fab6420e 100644 --- a/pkg/chain/store_test.go +++ b/pkg/chain/store_test.go @@ -44,7 +44,7 @@ func newChainStore(r repo.Repo, genTS *types.TipSet) *CborBlockStore { tempBlock := r.Datastore() cborStore := cbor.NewCborStore(tempBlock) return &CborBlockStore{ - Store: chain.NewStore(r.ChainDatastore(), tempBlock, genTS.At(0).Cid(), chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight), + Store: chain.NewStore(r.ChainDatastore(), tempBlock, genTS.At(0).Cid(), chainselector.Weight), cborStore: cborStore, } } @@ -221,9 +221,9 @@ func TestHead(t *testing.T) { genTS := builder.Genesis() r := builder.Repo() bs := builder.BlockStore() - cs := chain.NewStore(r.ChainDatastore(), bs, genTS.At(0).Cid(), chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight) + cs := chain.NewStore(r.ChainDatastore(), bs, genTS.At(0).Cid(), chainselector.Weight) cboreStore := &CborBlockStore{ - Store: chain.NewStore(r.ChainDatastore(), bs, genTS.At(0).Cid(), chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight), + Store: chain.NewStore(r.ChainDatastore(), bs, genTS.At(0).Cid(), chainselector.Weight), } // Construct test chain data link1 := builder.AppendOn(ctx, genTS, 2) @@ -328,7 +328,7 @@ func TestLoadAndReboot(t *testing.T) { requirePutBlocksToCborStore(t, cst, link4.ToSlice()...) cborStore := &CborBlockStore{ - Store: chain.NewStore(ds, bs, genTS.At(0).Cid(), chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight), + Store: chain.NewStore(ds, bs, genTS.At(0).Cid(), chainselector.Weight), cborStore: cst, } requirePutTestChain(ctx, t, cborStore, link4.Key(), builder, 5) @@ -338,7 +338,7 @@ func TestLoadAndReboot(t *testing.T) { cborStore.Store.Stop() // rebuild chain with same datastore and cborstore - rebootChain := chain.NewStore(ds, bs, genTS.At(0).Cid(), chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight) + rebootChain := chain.NewStore(ds, bs, genTS.At(0).Cid(), chainselector.Weight) rebootCbore := &CborBlockStore{ Store: rebootChain, } @@ -357,7 +357,7 @@ func TestLoadAndReboot(t *testing.T) { { assert.NoError(t, rebootChain.Blockstore().DeleteBlock(ctx, link3.Blocks()[0].Cid())) - newStore := chain.NewStore(ds, bs, genTS.At(0).Cid(), chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight) + newStore := chain.NewStore(ds, bs, genTS.At(0).Cid(), chainselector.Weight) // error occurs while getting tipset identified by parent's cid block, // because block[0] has been deleted. // stm: @CHAIN_STORE_LOAD_003 @@ -366,7 +366,7 @@ func TestLoadAndReboot(t *testing.T) { { assert.NoError(t, ds.Put(ctx, chain.HeadKey, []byte("bad chain head data"))) - newStore := chain.NewStore(ds, bs, genTS.At(0).Cid(), chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight) + newStore := chain.NewStore(ds, bs, genTS.At(0).Cid(), chainselector.Weight) // error occurs while getting tipset identified by parent's cid block // stm: @CHAIN_STORE_LOAD_002 assert.Error(t, newStore.Load(ctx)) @@ -402,7 +402,7 @@ func TestLoadTipsetMeta(t *testing.T) { _ = os.Setenv("CHAIN_INDEX_CACHE", "2") chain.DefaultTipsetLruCacheSize = 2 - cs := chain.NewStore(ds, bs, genTS.At(0).Cid(), chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight) + cs := chain.NewStore(ds, bs, genTS.At(0).Cid(), chainselector.Weight) cborStore := &CborBlockStore{Store: cs, cborStore: cst} requirePutTestChain(ctx, t, cborStore, head.Key(), builder, 5) diff --git a/pkg/chain/testing.go b/pkg/chain/testing.go index 5af6d17619..e4bdaa6b3c 100644 --- a/pkg/chain/testing.go +++ b/pkg/chain/testing.go @@ -50,18 +50,19 @@ const defaultMinerCount = 15 // The builder is deterministic: two builders receiving the same sequence of calls will produce // exactly the same chain. type Builder struct { - t *testing.T - genesis *types.TipSet - store *Store - minerAddress []address.Address - stateBuilder StateBuilder - stamper TimeStamper - repo repo.Repo - bs blockstoreutil.Blockstore - cstore cbor.IpldStore - mstore *MessageStore - seq uint64 // For unique tickets - eval *FakeStateEvaluator + t *testing.T + genesis *types.TipSet + store *Store + minerAddress []address.Address + stateBuilder StateBuilder + stamper TimeStamper + repo repo.Repo + bs blockstoreutil.Blockstore + cstore cbor.IpldStore + mstore *MessageStore + seq uint64 // For unique tickets + eval *FakeStateEvaluator + circulatingSupplyCalculator ICirculatingSupplyCalcualtor // Cache of the state root CID computed for each tipset key. tipStateCids map[string]cid.Cid @@ -176,6 +177,10 @@ func (f *Builder) MessageStore() *MessageStore { return f.mstore } +func (f *Builder) CirculatingSupplyCalcualtor() ICirculatingSupplyCalcualtor { + return f.circulatingSupplyCalculator +} + func (f *Builder) RemovePeer(peer peer.ID) {} func (f *Builder) GenMiners(str string) []address.Address { @@ -229,13 +234,14 @@ func NewBuilderWithDeps(t *testing.T, miner address.Address, stamper TimeStamper cst := cbor.NewCborStore(bs) b := &Builder{ - t: t, - stamper: stamper, - repo: repo, - bs: bs, - cstore: cst, - mstore: NewMessageStore(bs, config.DefaultForkUpgradeParam), - tipStateCids: make(map[string]cid.Cid), + t: t, + stamper: stamper, + repo: repo, + bs: bs, + cstore: cst, + mstore: NewMessageStore(bs, config.DefaultForkUpgradeParam), + tipStateCids: make(map[string]cid.Cid), + circulatingSupplyCalculator: NewMockCirculatingSupplyCalculator(), } if !miner.Empty() { @@ -255,7 +261,7 @@ func NewBuilderWithDeps(t *testing.T, miner address.Address, stamper TimeStamper // create a fixed genesis b.genesis = b.GeneratorGenesis() - b.store = NewStore(ds, bs, b.genesis.At(0).Cid(), NewMockCirculatingSupplyCalculator(), chainselector.Weight) + b.store = NewStore(ds, bs, b.genesis.At(0).Cid(), chainselector.Weight) b.stateBuilder = &FakeStateBuilder{b.store} for _, block := range b.genesis.Blocks() { diff --git a/pkg/chainsync/syncer/syncer.go b/pkg/chainsync/syncer/syncer.go index 2caf411156..db369c33cf 100644 --- a/pkg/chainsync/syncer/syncer.go +++ b/pkg/chainsync/syncer/syncer.go @@ -454,7 +454,8 @@ loop: return chainTipsets, nil } - logSyncer.Warnf("(fork detected) synced header chain") + logSyncer.Warnf("(fork detected) synced header chain, base: %v(%d), knownTip: %v(%d)", base.Key(), base.Height(), + knownTip.Key(), knownTip.Height()) fork, err := syncer.syncFork(ctx, base, knownTip) if err != nil { if errors.Is(err, ErrForkTooLong) { @@ -515,6 +516,12 @@ func (syncer *Syncer) syncFork(ctx context.Context, incoming *types.TipSet, know return []*types.TipSet{incomingParents}, nil } + now := time.Now() + defer func() { + logSyncer.Infof("fork detected, fetch blocks %d(%v) took: %v", incoming.Height(), incoming.Parents(), + time.Since(now)) + }() + // TODO: Does this mean we always ask for ForkLengthThreshold blocks from the network, even if we just need, like, 2? // Would it not be better to ask in smaller chunks, given that an ~ForkLengthThreshold is very rare? tips, err := syncer.exchangeClient.GetBlocks(ctx, incoming.Parents(), int(policy.ChainFinality)) diff --git a/pkg/chainsync/syncer/syncer_integration_test.go b/pkg/chainsync/syncer/syncer_integration_test.go index ba59e69784..39644988af 100644 --- a/pkg/chainsync/syncer/syncer_integration_test.go +++ b/pkg/chainsync/syncer/syncer_integration_test.go @@ -39,7 +39,7 @@ func TestLoadFork(t *testing.T) { // *not* as the bsstore, to which the syncer must ensure to put blocks. blockValidator := builder.FakeStateEvaluator() - stmgr, err := statemanger.NewStateManager(builder.Store(), builder.MessageStore(), blockValidator, nil, nil, nil, nil, false) + stmgr, err := statemanger.NewStateManager(builder.Store(), builder.MessageStore(), blockValidator, nil, nil, nil, nil, false, builder.CirculatingSupplyCalcualtor()) require.NoError(t, err) s, err := syncer.NewSyncer(stmgr, blockValidator, builder.Store(), @@ -90,7 +90,7 @@ func TestLoadFork(t *testing.T) { // Load a new chain bsstore on the underlying data. It will only compute state for the // left (heavy) branch. It has a fetcher that can't provide blocks. - newStore := chain.NewStore(builder.Repo().ChainDatastore(), builder.BlockStore(), genesis.At(0).Cid(), chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight) + newStore := chain.NewStore(builder.Repo().ChainDatastore(), builder.BlockStore(), genesis.At(0).Cid(), chainselector.Weight) newStore.SetCheckPoint(genesis.Key()) require.NoError(t, newStore.Load(ctx)) _, err = syncer.NewSyncer(stmgr, diff --git a/pkg/chainsync/syncer/syncer_test.go b/pkg/chainsync/syncer/syncer_test.go index fcd4b57269..4d104f3686 100644 --- a/pkg/chainsync/syncer/syncer_test.go +++ b/pkg/chainsync/syncer/syncer_test.go @@ -319,7 +319,7 @@ func TestNoUncessesaryFetch(t *testing.T) { // A new syncer unable to fetch blocks from the network can handle a tipset that's already // in the bsstore and linked to genesis. eval := builder.FakeStateEvaluator() - stmgr, err := statemanger.NewStateManager(builder.Store(), builder.MessageStore(), eval, nil, nil, nil, nil, false) + stmgr, err := statemanger.NewStateManager(builder.Store(), builder.MessageStore(), eval, nil, nil, nil, nil, false, builder.CirculatingSupplyCalcualtor()) assert.NoError(t, err) newSyncer, err := syncer.NewSyncer(stmgr, @@ -501,7 +501,7 @@ func TestSemanticallyBadTipSetFails(t *testing.T) { eval := newPoisonValidator(t, 98, 99) builder := chain.NewBuilder(t, address.Undef) - stmgr, err := statemanger.NewStateManager(builder.Store(), builder.MessageStore(), eval, nil, nil, nil, nil, false) + stmgr, err := statemanger.NewStateManager(builder.Store(), builder.MessageStore(), eval, nil, nil, nil, nil, false, builder.CirculatingSupplyCalcualtor()) require.NoError(t, err) builder, syncer := setupWithValidator(ctx, t, builder, stmgr, eval) @@ -582,7 +582,7 @@ func setup(ctx context.Context, t *testing.T) (*chain.Builder, *syncer.Syncer) { builder := chain.NewBuilder(t, address.Undef) eval := builder.FakeStateEvaluator() - stmgr, err := statemanger.NewStateManager(builder.Store(), builder.MessageStore(), eval, nil, nil, nil, nil, false) + stmgr, err := statemanger.NewStateManager(builder.Store(), builder.MessageStore(), eval, nil, nil, nil, nil, false, builder.CirculatingSupplyCalcualtor()) require.NoError(t, err) return setupWithValidator(ctx, t, builder, stmgr, eval) diff --git a/pkg/config/config.go b/pkg/config/config.go index e04cb3ce82..df647d0e5c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -305,7 +305,10 @@ type NetworkParamsConfig struct { // As per https://github.com/ethereum-lists/chains Eip155ChainID int `json:"-"` // NOTE: DO NOT change this unless you REALLY know what you're doing. This is consensus critical. - ActorDebugging bool `json:"-"` + ActorDebugging bool `json:"-"` + F3Enabled bool `json:"f3Enabled"` + F3BootstrapEpoch abi.ChainEpoch `json:"f3BootstrapEpoch"` + ManifestServerID string `json:"manifestServerID"` } // ForkUpgradeConfig record upgrade parameters @@ -341,6 +344,7 @@ type ForkUpgradeConfig struct { UpgradeDragonHeight abi.ChainEpoch `json:"upgradeDragonHeight"` UpgradePhoenixHeight abi.ChainEpoch `json:"upgradePhoenixHeight"` UpgradeCalibrationDragonFixHeight abi.ChainEpoch `json:"upgradeCalibrationDragonFixHeight"` + UpgradeWaffleHeight abi.ChainEpoch `json:"upgradeWaffleHeight"` } func IsNearUpgrade(epoch, upgradeEpoch abi.ChainEpoch) bool { @@ -381,6 +385,7 @@ var DefaultForkUpgradeParam = &ForkUpgradeConfig{ UpgradePhoenixHeight: 3855360 + 120, // This fix upgrade only ran on calibrationnet UpgradeCalibrationDragonFixHeight: -3, + UpgradeWaffleHeight: 999999999999, } func newDefaultNetworkParamsConfig() *NetworkParamsConfig { diff --git a/pkg/consensus/block_validator.go b/pkg/consensus/block_validator.go index ccc33d29b4..0a47bc3ea7 100644 --- a/pkg/consensus/block_validator.go +++ b/pkg/consensus/block_validator.go @@ -747,6 +747,18 @@ func (bv *BlockValidator) VerifyWinningPoStProof(ctx context.Context, nv network return nil } +func IsValidEthTxForSending(nv network.Version, smsg *types.SignedMessage) bool { + ethTx, err := types.EthTransactionFromSignedFilecoinMessage(smsg) + if err != nil { + return false + } + + if nv < network.Version23 && ethTx.Type() != types.EIP1559TxType { + return false + } + return true +} + func IsValidForSending(nv network.Version, act *types.Actor) bool { // Before nv18 (Hygge), we only supported built-in account actors as senders. // @@ -771,12 +783,12 @@ func IsValidForSending(nv network.Version, act *types.Actor) bool { // Allow placeholder actors with a delegated address and nonce 0 to send a message. // These will be converted to an EthAccount actor on first send. - if !builtin.IsPlaceholderActor(act.Code) || act.Nonce != 0 || act.Address == nil || act.Address.Protocol() != address.Delegated { + if !builtin.IsPlaceholderActor(act.Code) || act.Nonce != 0 || act.DelegatedAddress == nil || act.DelegatedAddress.Protocol() != address.Delegated { return false } // Only allow such actors to send if their delegated address is in the EAM's namespace. - id, _, err := varint.FromUvarint(act.Address.Payload()) + id, _, err := varint.FromUvarint(act.DelegatedAddress.Payload()) return err == nil && id == builtintypes.EthereumAddressManagerActorID } @@ -893,6 +905,10 @@ func (bv *BlockValidator) checkBlockMessages(ctx context.Context, return fmt.Errorf("block had invalid secpk message at index %d: %v", i, err) } + if m.Signature.Type == crypto.SigTypeDelegated && !IsValidEthTxForSending(nv, m) { + return fmt.Errorf("network version should be atleast NV23 for sending legacy ETH transactions; but current network version is %d", nv) + } + secpMsgs[i] = m } diff --git a/pkg/consensus/expected.go b/pkg/consensus/expected.go index eb979b4080..42d33b22e2 100644 --- a/pkg/consensus/expected.go +++ b/pkg/consensus/expected.go @@ -94,8 +94,6 @@ type chainReader interface { Weight(context.Context, *types.TipSet) (big.Int, error) } -var _ chainReader = (*chain.Store)(nil) - // Expected implements expected consensus. type Expected struct { // cstore is used for loading state trees during message running. @@ -153,7 +151,7 @@ func NewExpected(cs cbor.IpldStore, syscallsImpl: syscalls, cstore: cs, bstore: bs, - chainState: chainState, + chainState: chain.ChainReaderWrapper(chainState, circulatingSupplyCalculator), messageStore: messageStore, beacon: beacon, fork: fork, diff --git a/pkg/constants/chain_parameters.go b/pkg/constants/chain_parameters.go index be4d408ae5..4268fc9e8a 100644 --- a/pkg/constants/chain_parameters.go +++ b/pkg/constants/chain_parameters.go @@ -1,9 +1,10 @@ package constants import ( + "math" + "github.com/filecoin-project/go-state-types/abi" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - "math" ) const ( diff --git a/pkg/constants/shared_vals.go b/pkg/constants/shared_vals.go index 71e0685db3..158a405b9c 100644 --- a/pkg/constants/shared_vals.go +++ b/pkg/constants/shared_vals.go @@ -16,7 +16,7 @@ const TestNetworkVersion = network.Version{{.latestNetworkVersion}} /* inline-gen start */ -const TestNetworkVersion = network.Version22 +const TestNetworkVersion = network.Version23 /* inline-gen end */ diff --git a/pkg/events/filter/event.go b/pkg/events/filter/event.go index da2adfff49..3d801bc12d 100644 --- a/pkg/events/filter/event.go +++ b/pkg/events/filter/event.go @@ -18,7 +18,6 @@ import ( blockadt "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/venus/pkg/chain" "github.com/filecoin-project/venus/venus-shared/actors/adt" - "github.com/filecoin-project/venus/venus-shared/blockstore" "github.com/filecoin-project/venus/venus-shared/types" cbor "github.com/ipfs/go-ipld-cbor" ) @@ -303,7 +302,7 @@ func (e *executedMessage) Events() []*types.Event { type EventFilterManager struct { MessageStore *chain.MessageStore - ChainStore blockstore.Blockstore + ChainStore *chain.Store AddressResolver func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) MaxFilterResults int EventIndex *EventIndex @@ -378,6 +377,10 @@ func (m *EventFilterManager) Revert(ctx context.Context, from, to *types.TipSet) func (m *EventFilterManager) Install(ctx context.Context, minHeight, maxHeight abi.ChainEpoch, tipsetCid cid.Cid, addresses []address.Address, keysWithCodec map[string][]types.ActorEventBlock, excludeReverted bool) (EventFilter, error) { m.mu.Lock() + if m.currentHeight == 0 { + // sync in progress, we haven't had an Apply + m.currentHeight = m.ChainStore.GetHead().Height() + } currentHeight := m.currentHeight m.mu.Unlock() @@ -433,7 +436,7 @@ func (m *EventFilterManager) loadExecutedMessages(ctx context.Context, msgTS, rc return nil, xerrors.Errorf("read messages: %w", err) } - st := adt.WrapStore(ctx, cbor.NewCborStore(m.ChainStore)) + st := adt.WrapStore(ctx, cbor.NewCborStore(m.ChainStore.Blockstore())) arr, err := blockadt.AsArray(st, rctTS.Blocks()[0].ParentMessageReceipts) if err != nil { diff --git a/pkg/events/filter/index.go b/pkg/events/filter/index.go index 7249133abc..cc9257bec6 100644 --- a/pkg/events/filter/index.go +++ b/pkg/events/filter/index.go @@ -27,7 +27,8 @@ var pragmas = []string{ "PRAGMA auto_vacuum = NONE", "PRAGMA automatic_index = OFF", "PRAGMA journal_mode = WAL", - "PRAGMA read_uncommitted = ON", + "PRAGMA wal_autocheckpoint = 256", // checkpoint @ 256 pages + "PRAGMA journal_size_limit = 0", // always reset journal and wal files } var ddls = []string{ @@ -283,6 +284,9 @@ func NewEventIndex(ctx context.Context, path string, chainStore *chain.Store) (* eventIndex := EventIndex{db: db} q, err := db.Query("SELECT name FROM sqlite_master WHERE type='table' AND name='_meta';") + if q != nil { + defer func() { _ = q.Close() }() + } if err == sql.ErrNoRows || !q.Next() { // empty database, create the schema for _, ddl := range ddls { @@ -347,7 +351,7 @@ func (ei *EventIndex) Close() error { } func (ei *EventIndex) CollectEvents(ctx context.Context, te *TipSetEvents, revert bool, resolver func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool)) error { - tx, err := ei.db.Begin() + tx, err := ei.db.BeginTx(ctx, nil) if err != nil { return fmt.Errorf("begin transaction: %w", err) } @@ -562,6 +566,7 @@ func (ei *EventIndex) prefillFilter(ctx context.Context, f *eventFilter, exclude if err != nil { return fmt.Errorf("prepare prefill query: %w", err) } + defer func() { _ = stmt.Close() }() q, err := stmt.QueryContext(ctx, values...) if err != nil { @@ -570,6 +575,7 @@ func (ei *EventIndex) prefillFilter(ctx context.Context, f *eventFilter, exclude } return fmt.Errorf("exec prefill query: %w", err) } + defer func() { _ = q.Close() }() var ces []*CollectedEvent var currentID int64 = -1 diff --git a/pkg/fork/fork.go b/pkg/fork/fork.go index 25945fe315..cafe73ce5d 100644 --- a/pkg/fork/fork.go +++ b/pkg/fork/fork.go @@ -39,6 +39,7 @@ import ( nv19 "github.com/filecoin-project/go-state-types/builtin/v11/migration" nv21 "github.com/filecoin-project/go-state-types/builtin/v12/migration" nv22 "github.com/filecoin-project/go-state-types/builtin/v13/migration" + nv23 "github.com/filecoin-project/go-state-types/builtin/v14/migration" nv17 "github.com/filecoin-project/go-state-types/builtin/v9/migration" "github.com/filecoin-project/go-state-types/migration" "github.com/filecoin-project/specs-actors/actors/migration/nv3" @@ -432,6 +433,18 @@ func DefaultUpgradeSchedule(cf *ChainFork, upgradeHeight *config.ForkUpgradeConf Network: network.Version22, Migration: cf.upgradeActorsV13VerifregFix(calibnetv13BuggyVerifregCID1, calibnetv13CorrectManifestCID1), }, + { + Height: upgradeHeight.UpgradeWaffleHeight, + Network: network.Version23, + Migration: cf.UpgradeActorsV14, + PreMigrations: []PreMigration{{ + PreMigration: cf.PreUpgradeActorsV14, + StartWithin: 120, + DontStartWithin: 15, + StopWithin: 10, + }}, + Expensive: true, + }, } for _, u := range updates { @@ -3097,11 +3110,11 @@ func (c *ChainFork) buildUpgradeActorsV12MinerFix(oldBuggyMinerCID, newManifestC } return actorsOut.SetActor(ctx, a, &types.Actor{ - Code: newCid, - Head: actor.Head, - Nonce: actor.Nonce, - Balance: actor.Balance, - Address: actor.Address, + Code: newCid, + Head: actor.Head, + Nonce: actor.Nonce, + Balance: actor.Balance, + DelegatedAddress: actor.DelegatedAddress, }) }) if err != nil { @@ -3138,8 +3151,8 @@ func (c *ChainFork) buildUpgradeActorsV12MinerFix(oldBuggyMinerCID, newManifestC return fmt.Errorf("mismatched balance for actor %s: %d != %d", a, inActor.Balance, outActor.Balance) } - if inActor.Address != outActor.Address && inActor.Address.String() != outActor.Address.String() { - return fmt.Errorf("mismatched address for actor %s: %s != %s", a, inActor.Address, outActor.Address) + if inActor.DelegatedAddress != outActor.DelegatedAddress && inActor.DelegatedAddress.String() != outActor.DelegatedAddress.String() { + return fmt.Errorf("mismatched address for actor %s: %s != %s", a, inActor.DelegatedAddress, outActor.DelegatedAddress) } if inActor.Head != outActor.Head && a != builtin.SystemActorAddr { @@ -3260,11 +3273,11 @@ func (c *ChainFork) upgradeActorsV13VerifregFix(oldBuggyVerifregCID, newManifest } return actorsOut.SetActor(ctx, a, &types.Actor{ - Code: newCid, - Head: actor.Head, - Nonce: actor.Nonce, - Balance: actor.Balance, - Address: actor.Address, + Code: newCid, + Head: actor.Head, + Nonce: actor.Nonce, + Balance: actor.Balance, + DelegatedAddress: actor.DelegatedAddress, }) }) if err != nil { @@ -3301,8 +3314,8 @@ func (c *ChainFork) upgradeActorsV13VerifregFix(oldBuggyVerifregCID, newManifest return fmt.Errorf("mismatched balance for actor %s: %d != %d", a, inActor.Balance, outActor.Balance) } - if inActor.Address != outActor.Address && inActor.Address.String() != outActor.Address.String() { - return fmt.Errorf("mismatched address for actor %s: %s != %s", a, inActor.Address, outActor.Address) + if inActor.DelegatedAddress != outActor.DelegatedAddress && inActor.DelegatedAddress.String() != outActor.DelegatedAddress.String() { + return fmt.Errorf("mismatched address for actor %s: %s != %s", a, inActor.DelegatedAddress, outActor.DelegatedAddress) } if inActor.Head != outActor.Head && a != builtin.SystemActorAddr { @@ -3330,6 +3343,116 @@ func (c *ChainFork) upgradeActorsV13VerifregFix(oldBuggyVerifregCID, newManifest } } +func (c *ChainFork) PreUpgradeActorsV14(ctx context.Context, cache MigrationCache, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) error { + // Use half the CPUs for pre-migration, but leave at least 3. + workerCount := MigrationMaxWorkerCount + if workerCount <= 4 { + workerCount = 1 + } else { + workerCount /= 2 + } + + nv := c.GetNetworkVersion(ctx, epoch) + _, lbRoot, err := c.cr.GetLookbackTipSetForRound(ctx, ts, epoch, nv) + if err != nil { + return fmt.Errorf("error getting lookback ts for premigration: %w", err) + } + + config := migration.Config{ + MaxWorkers: uint(workerCount), + ProgressLogPeriod: time.Minute * 5, + } + + _, err = c.upgradeActorsV14Common(ctx, cache, lbRoot, epoch, config) + return err +} + +func (c *ChainFork) UpgradeActorsV14(ctx context.Context, + cache MigrationCache, + root cid.Cid, + epoch abi.ChainEpoch, + ts *types.TipSet, +) (cid.Cid, error) { + // Use all the CPUs except 2. + workerCount := MigrationMaxWorkerCount - 3 + if workerCount <= 0 { + workerCount = 1 + } + config := migration.Config{ + MaxWorkers: uint(workerCount), + JobQueueSize: 1000, + ResultQueueSize: 100, + ProgressLogPeriod: 10 * time.Second, + } + newRoot, err := c.upgradeActorsV14Common(ctx, cache, root, epoch, config) + if err != nil { + return cid.Undef, fmt.Errorf("migrating actors v14 state: %w", err) + } + return newRoot, nil +} + +func (c *ChainFork) upgradeActorsV14Common( + ctx context.Context, + cache MigrationCache, + root cid.Cid, + epoch abi.ChainEpoch, + config migration.Config, +) (cid.Cid, error) { + writeStore := blockstoreutil.NewAutobatch(ctx, c.bs, units.GiB/4) + adtStore := adt.WrapStore(ctx, cbor.NewCborStore(writeStore)) + + // ensure that the manifest is loaded in the blockstore + if err := actors.LoadBundles(ctx, writeStore, actorstypes.Version14); err != nil { + return cid.Undef, fmt.Errorf("failed to load manifest bundle: %w", err) + } + + // Load the state root. + var stateRoot vmstate.StateRoot + if err := adtStore.Get(ctx, root, &stateRoot); err != nil { + return cid.Undef, fmt.Errorf("failed to decode state root: %w", err) + } + + if stateRoot.Version != vmstate.StateTreeVersion5 { + return cid.Undef, fmt.Errorf( + "expected state root version 5 for actors v14 upgrade, got %d", + stateRoot.Version, + ) + } + + manifest, ok := actors.GetManifest(actorstypes.Version14) + if !ok { + return cid.Undef, fmt.Errorf("no manifest CID for v14 upgrade") + } + + // Perform the migration + newHamtRoot, err := nv23.MigrateStateTree(ctx, adtStore, manifest, stateRoot.Actors, epoch, config, + migrationLogger{}, cache) + if err != nil { + return cid.Undef, fmt.Errorf("upgrading to actors v14: %w", err) + } + + // Persist the result. + newRoot, err := adtStore.Put(ctx, &vmstate.StateRoot{ + Version: vmstate.StateTreeVersion5, + Actors: newHamtRoot, + Info: stateRoot.Info, + }) + if err != nil { + return cid.Undef, fmt.Errorf("failed to persist new state root: %w", err) + } + + // Persists the new tree and shuts down the flush worker + if err := writeStore.Flush(ctx); err != nil { + return cid.Undef, fmt.Errorf("writeStore flush failed: %w", err) + } + + if err := writeStore.Shutdown(ctx); err != nil { + return cid.Undef, fmt.Errorf("writeStore shutdown failed: %w", err) + } + + return newRoot, nil +} + func (c *ChainFork) GetForkUpgrade() *config.ForkUpgradeConfig { return c.forkUpgrade } diff --git a/pkg/gen/genesis/genesis.go b/pkg/gen/genesis/genesis.go index b27a14ed74..dce93435cd 100644 --- a/pkg/gen/genesis/genesis.go +++ b/pkg/gen/genesis/genesis.go @@ -400,10 +400,10 @@ func makeAccountActor(ctx context.Context, cst cbor.IpldStore, av actorstypes.Ve } act := &types.Actor{ - Code: actcid, - Head: statecid, - Balance: bal, - Address: &addr, + Code: actcid, + Head: statecid, + Balance: bal, + DelegatedAddress: &addr, } return act, nil @@ -592,7 +592,7 @@ func MakeGenesisBlock(ctx context.Context, rep repo.Repo, bs bstore.Blockstore, } // temp chainstore - cs := chain.NewStore(rep.ChainDatastore(), bs, cid.Undef, chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight) + cs := chain.NewStore(rep.ChainDatastore(), bs, cid.Undef, chainselector.Weight) // Verify PreSealed Data stateroot, err = VerifyPreSealedData(ctx, cs, stateroot, template, keyIDs, template.NetworkVersion, para) diff --git a/pkg/gen/genesis/genesis_eth.go b/pkg/gen/genesis/genesis_eth.go index 8841ae0201..30b3ec3c7b 100644 --- a/pkg/gen/genesis/genesis_eth.go +++ b/pkg/gen/genesis/genesis_eth.go @@ -41,10 +41,10 @@ func SetupEAM(ctx context.Context, nst tree.Tree, nv network.Version) error { } header := &types.Actor{ - Code: codecid, - Head: vmcontext.EmptyObjectCid, - Balance: big.Zero(), - Address: &builtintypes.EthereumAddressManagerActorAddr, // so that it can create ETH0 + Code: codecid, + Head: vmcontext.EmptyObjectCid, + Balance: big.Zero(), + DelegatedAddress: &builtintypes.EthereumAddressManagerActorAddr, // so that it can create ETH0 } return nst.SetActor(ctx, builtintypes.EthereumAddressManagerActorAddr, header) } @@ -57,11 +57,11 @@ func MakeEthNullAddressActor(av actorstypes.Version, addr address.Address) (*typ } act := &types.Actor{ - Code: actcid, - Head: vmcontext.EmptyObjectCid, - Nonce: 0, - Balance: big.Zero(), - Address: &addr, + Code: actcid, + Head: vmcontext.EmptyObjectCid, + Nonce: 0, + Balance: big.Zero(), + DelegatedAddress: &addr, } return act, nil diff --git a/pkg/gen/genesis/miners.go b/pkg/gen/genesis/miners.go index d1759ddddd..fe019d3909 100644 --- a/pkg/gen/genesis/miners.go +++ b/pkg/gen/genesis/miners.go @@ -28,10 +28,13 @@ import ( "github.com/filecoin-project/go-state-types/network" builtintypes "github.com/filecoin-project/go-state-types/builtin" + miner14 "github.com/filecoin-project/go-state-types/builtin/v14/miner" minertypes "github.com/filecoin-project/go-state-types/builtin/v8/miner" + miner9 "github.com/filecoin-project/go-state-types/builtin/v9/miner" "github.com/filecoin-project/venus/venus-shared/actors/builtin/power" "github.com/filecoin-project/venus/venus-shared/actors/builtin/reward" + "github.com/filecoin-project/venus/venus-shared/actors/builtin/system" "github.com/filecoin-project/venus/venus-shared/actors/builtin/market" "github.com/filecoin-project/venus/venus-shared/actors/builtin/miner" @@ -158,7 +161,11 @@ func SetupStorageMiners(ctx context.Context, i := i m := m - spt, err := miner.SealProofTypeFromSectorSize(m.SectorSize, nv, synthetic) + variant := miner.SealProofVariant_Standard + if synthetic { + variant = miner.SealProofVariant_Synthetic + } + spt, err := miner.SealProofTypeFromSectorSize(m.SectorSize, nv, variant) if err != nil { return cid.Undef, err } @@ -331,9 +338,6 @@ func SetupStorageMiners(ctx context.Context, if err != nil { return cid.Undef, fmt.Errorf("flushing vm: %w", err) } - if err != nil { - return cid.Undef, fmt.Errorf("flushing vm: %w", err) - } nst, err := tree.LoadState(ctx, cst, nh) if err != nil { @@ -511,9 +515,10 @@ func SetupStorageMiners(ctx context.Context, return cid.Undef, fmt.Errorf("getting current total power: %w", err) } - pcd := types.PreCommitDepositForPower(smoothing9.FilterEstimate(rewardSmoothed), smoothing9.FilterEstimate(*tpow.QualityAdjPowerSmoothed), types.QAPowerMax(m.SectorSize)) + pcd := miner9.PreCommitDepositForPower(smoothing9.FilterEstimate(rewardSmoothed), + smoothing9.FilterEstimate(*tpow.QualityAdjPowerSmoothed), types.QAPowerMax(m.SectorSize)) - pledge := types.InitialPledgeForPower( + pledge := miner9.InitialPledgeForPower( sectorWeight, baselinePower, smoothing9.FilterEstimate(rewardSmoothed), @@ -531,8 +536,12 @@ func SetupStorageMiners(ctx context.Context, // Commit one-by-one, otherwise pledge math tends to explode var paramBytes []byte - - if av >= actorstypes.Version6 { + if av >= actorstypes.Version14 { + confirmParams := &miner14.InternalSectorSetupForPresealParams{ + Sectors: []abi.SectorNumber{preseal.SectorID}, + } + paramBytes = mustEnc(confirmParams) + } else if av >= actorstypes.Version6 { // TODO: fixup confirmParams := &builtin6.ConfirmSectorProofsParams{ Sectors: []abi.SectorNumber{preseal.SectorID}, @@ -547,9 +556,17 @@ func SetupStorageMiners(ctx context.Context, paramBytes = mustEnc(confirmParams) } - _, err = doExecValue(ctx, genesisVM, minerInfos[i].maddr, power.Address, big.Zero(), builtintypes.MethodsMiner.ConfirmSectorProofsValid, paramBytes) - if err != nil { - return cid.Undef, fmt.Errorf("failed to confirm presealed sectors: %w", err) + var csErr error + if nv >= network.Version23 { + _, csErr = doExecValue(ctx, genesisVM, minerInfos[i].maddr, system.Address, big.Zero(), builtintypes.MethodsMiner.InternalSectorSetupForPreseal, + paramBytes) + } else { + _, csErr = doExecValue(ctx, genesisVM, minerInfos[i].maddr, power.Address, big.Zero(), builtintypes.MethodsMiner.InternalSectorSetupForPreseal, + paramBytes) + } + + if csErr != nil { + return cid.Undef, fmt.Errorf("failed to confirm presealed sectors: %w", csErr) } if av > actorstypes.Version2 { diff --git a/pkg/genesis/init.go b/pkg/genesis/init.go index fee9a3ca6a..265a50d4e9 100644 --- a/pkg/genesis/init.go +++ b/pkg/genesis/init.go @@ -4,7 +4,6 @@ import ( "context" "github.com/filecoin-project/venus/pkg/chain" - "github.com/filecoin-project/venus/pkg/config" "github.com/filecoin-project/venus/pkg/consensus/chainselector" blockstoreutil "github.com/filecoin-project/venus/venus-shared/blockstore" "github.com/filecoin-project/venus/venus-shared/types" @@ -30,7 +29,7 @@ func Init(ctx context.Context, r repo.Repo, bs blockstoreutil.Blockstore, cst cb } // todo give fork params - chainStore := chain.NewStore(r.ChainDatastore(), bs, genesis.Cid(), chain.NewCirculatingSupplyCalculator(bs, genesis.Cid(), config.DefaultForkUpgradeParam), chainselector.Weight) + chainStore := chain.NewStore(r.ChainDatastore(), bs, genesis.Cid(), chainselector.Weight) // Persist the genesis tipset to the repo. genTsas := &chain.TipSetMetadata{ diff --git a/pkg/messagepool/messagepool.go b/pkg/messagepool/messagepool.go index f9ea785568..49754e38cf 100644 --- a/pkg/messagepool/messagepool.go +++ b/pkg/messagepool/messagepool.go @@ -958,6 +958,11 @@ func (mp *MessagePool) addTS(ctx context.Context, m *types.SignedMessage, curTS nv := mp.api.StateNetworkVersion(ctx, epoch) // TODO: I'm not thrilled about depending on filcns here, but I prefer this to duplicating logic + + if m.Signature.Type == crypto.SigTypeDelegated && !consensus.IsValidEthTxForSending(nv, m) { + return false, fmt.Errorf("network version should be atleast NV23 for sending legacy ETH transactions; but current network version is %d", nv) + } + if !consensus.IsValidForSending(nv, senderAct) { return false, fmt.Errorf("sender actor %s is not a valid top-level sender", m.Message.From) } diff --git a/pkg/messagepool/messagepool_test.go b/pkg/messagepool/messagepool_test.go index 26ef4e9bf6..2c167cef25 100644 --- a/pkg/messagepool/messagepool_test.go +++ b/pkg/messagepool/messagepool_test.go @@ -360,7 +360,7 @@ func newWalletAndMpool(t *testing.T, tma *testMpoolAPI) (*wallet.Wallet, *Messag builder := chain.NewBuilder(t, address.Undef) eval := builder.FakeStateEvaluator() - stmgr, err := statemanger.NewStateManager(builder.Store(), builder.MessageStore(), eval, nil, fork.NewMockFork(), nil, nil, false) + stmgr, err := statemanger.NewStateManager(builder.Store(), builder.MessageStore(), eval, nil, fork.NewMockFork(), nil, nil, false, builder.CirculatingSupplyCalcualtor()) if err != nil { t.Fatal(err) } diff --git a/pkg/migration/migrate.go b/pkg/migration/migrate.go index a2a3d2fddd..6d499ab324 100644 --- a/pkg/migration/migrate.go +++ b/pkg/migration/migrate.go @@ -35,6 +35,7 @@ var versionMap = []versionInfo{ {version: 10, upgrade: Version10Upgrade}, {version: 11, upgrade: Version11Upgrade}, {version: 12, upgrade: Version12Upgrade}, + {version: 13, upgrade: Version13Upgrade}, } // TryToMigrate used to migrate data(db,config,file,etc) in local repo @@ -436,3 +437,29 @@ func Version12Upgrade(repoPath string) (err error) { return repo.WriteVersion(repoPath, 12) } + +// Version13Upgrade will modify mainnet bootstrap +func Version13Upgrade(repoPath string) (err error) { + var fsrRepo repo.Repo + if fsrRepo, err = repo.OpenFSRepo(repoPath, 12); err != nil { + return + } + cfg := fsrRepo.Config() + + switch cfg.NetworkParams.NetworkType { + case types.NetworkMainnet: + cfg.Bootstrap = &networks.Mainnet().Bootstrap + case types.NetworkCalibnet: + cfg.Bootstrap = &networks.Calibration().Bootstrap + } + + if err = fsrRepo.ReplaceConfig(cfg); err != nil { + return + } + + if err = fsrRepo.Close(); err != nil { + return + } + + return repo.WriteVersion(repoPath, 13) +} diff --git a/pkg/net/exchange/peer_tracker.go b/pkg/net/exchange/peer_tracker.go index 2d37ac19c6..86fbc2b1b8 100644 --- a/pkg/net/exchange/peer_tracker.go +++ b/pkg/net/exchange/peer_tracker.go @@ -88,7 +88,7 @@ func (bpt *bsPeerTracker) prefSortedPeers() []peer.ID { var costI, costJ float64 - getPeerInitLat := func(p peer.ID) float64 { + getPeerInitLat := func(_ peer.ID) float64 { return float64(bpt.avgGlobalTime) * newPeerMul } diff --git a/pkg/net/exchange/protocol.go b/pkg/net/exchange/protocol.go index e29777ee09..9eeb1e2454 100644 --- a/pkg/net/exchange/protocol.go +++ b/pkg/net/exchange/protocol.go @@ -19,6 +19,7 @@ const ( ReadResMinSpeed = 50 << 10 ShufflePeersPrefix = 16 WriteResDeadline = 60 * time.Second + streamReadDeadline = 10 * time.Second ) // `Request` processed and validated to query the tipsets needed. diff --git a/pkg/net/exchange/server.go b/pkg/net/exchange/server.go index fd677e2b7b..37f127efdc 100644 --- a/pkg/net/exchange/server.go +++ b/pkg/net/exchange/server.go @@ -66,10 +66,14 @@ func (s *server) handleStream(stream inet.Stream) { defer stream.Close() //nolint:errcheck var req exchange.Request + _ = stream.SetReadDeadline(time.Now().Add(streamReadDeadline)) if err := cborutil.ReadCborRPC(bufio.NewReader(stream), &req); err != nil { + _ = stream.SetReadDeadline(time.Time{}) exchangeServerLog.Warnf("failed to read block sync request: %s", err) return } + _ = stream.SetReadDeadline(time.Time{}) + exchangeServerLog.Debugw("block sync request", "start", req.Head, "len", req.Length, "remote peer", stream.Conn().RemotePeer()) resp, err := s.processRequest(ctx, &req) diff --git a/pkg/net/gossipsub.go b/pkg/net/gossipsub.go index 903e22df70..c5d1a4c294 100644 --- a/pkg/net/gossipsub.go +++ b/pkg/net/gossipsub.go @@ -2,6 +2,7 @@ package net import ( "context" + "fmt" "net" "time" @@ -13,6 +14,8 @@ import ( "github.com/libp2p/go-libp2p/core/peer" blake2b "github.com/minio/blake2b-simd" + "github.com/filecoin-project/go-f3/gpbft" + "github.com/filecoin-project/go-f3/manifest" "github.com/filecoin-project/venus/pkg/config" "github.com/filecoin-project/venus/venus-shared/types" ) @@ -39,6 +42,12 @@ const ( GraylistScoreThreshold = -2500 AcceptPXScoreThreshold = 1000 OpportunisticGraftScoreThreshold = 3.5 + + // Determines the max. number of configuration changes + // that are allowed for the dynamic manifest. + // If the manifest changes more than this number, the F3 + // message topic will be filtered + MaxDynamicManifestChangesAllowed = 1000 ) func NewGossipSub(ctx context.Context, @@ -48,6 +57,7 @@ func NewGossipSub(ctx context.Context, drandSchedule map[abi.ChainEpoch]config.DrandEnum, bootNodes []peer.AddrInfo, bs bool, + f3enabled bool, ) (*pubsub.PubSub, error) { bootstrappers := make(map[peer.ID]struct{}) for _, info := range bootNodes { @@ -310,6 +320,30 @@ func NewGossipSub(ctx context.Context, indexerIngestTopic, } allowTopics = append(allowTopics, drandTopics...) + if f3enabled { + f3TopicName := manifest.PubSubTopicFromNetworkName(gpbft.NetworkName(networkName)) + allowTopics = append(allowTopics, f3TopicName) + + // allow dynamic manifest topic and the new topic names after a reconfiguration. + // Note: This is pretty ugly, but I tried to use a regex subscription filter + // as the commented code below, but unfortunately it overwrites previous filters. A simple fix would + // be to allow combining several topic filters, but for now this works. + // + // pattern := fmt.Sprintf(`^\/f3\/%s\/0\.0\.1\/?[0-9]*$`, in.Nn) + // rx, err := regexp.Compile(pattern) + // if err != nil { + // return nil, xerrors.Errorf("failed to compile manifest topic regex: %w", err) + // } + // options = append(options, + // pubsub.WithSubscriptionFilter( + // pubsub.WrapLimitSubscriptionFilter( + // pubsub.NewRegexpSubscriptionFilter(rx), + // 100))) + allowTopics = append(allowTopics, manifest.ManifestPubSubTopicName) + for i := 0; i < MaxDynamicManifestChangesAllowed; i++ { + allowTopics = append(allowTopics, f3TopicName+"/"+fmt.Sprintf("%d", i)) + } + } options = append(options, pubsub.WithSubscriptionFilter( pubsub.WrapLimitSubscriptionFilter( diff --git a/pkg/net/helloprotocol/hello_protocol.go b/pkg/net/helloprotocol/hello_protocol.go index 5325f2017c..8d0f10dd26 100644 --- a/pkg/net/helloprotocol/hello_protocol.go +++ b/pkg/net/helloprotocol/hello_protocol.go @@ -149,6 +149,7 @@ func (h *HelloProtocolHandler) handleNewStream(s net.Stream) { // can't process a hello received in error, but leave this connection // open because we connections are innocent until proven guilty // (with bad genesis) + _ = s.Conn().Close() return } latencyMsg := &LatencyMessage{TArrival: time.Now().UnixNano()} @@ -186,18 +187,23 @@ func (h *HelloProtocolHandler) handleNewStream(s net.Stream) { fullTipSet, err := h.loadLocalFullTipset(ctx, types.NewTipSetKey(hello.HeaviestTipSetCids...)) if err != nil { + // We're trying to fetch the tipset from the peer that just said hello to us. No point in + // triggering any dials. + ctx := net.WithNoDial(ctx, "fetching filecoin hello tipset") fullTipSet, err = h.exchange.GetFullTipSet(ctx, []peer.ID{from}, types.NewTipSetKey(hello.HeaviestTipSetCids...)) //nolint - h.host.ConnManager().TagPeer(from, "new-block", 40) - } - if err != nil { - log.Warnf("failed to get tipset message from peer %s", from) - return + if err != nil { + log.Warnf("failed to get tipset message from peer %s", from) + return + } } + if fullTipSet == nil { log.Warnf("handleNewStream get null full tipset, it's scarce!") return } + h.host.ConnManager().TagPeer(from, "new-block", 40) + // notify the local node of the new `block.ChainInfo` ci := types.NewChainInfo(from, from, fullTipSet) h.peerDiscovered(ci) @@ -230,13 +236,13 @@ func (h *HelloProtocolHandler) loadLocalFullTipset(ctx context.Context, tsk type // ErrBadGenesis is the error returned when a mismatch in genesis blocks happens. var ErrBadGenesis = fmt.Errorf("bad genesis block") -func (h *HelloProtocolHandler) receiveHello(ctx context.Context, s net.Stream) (*HelloMessage, error) { +func (h *HelloProtocolHandler) receiveHello(_ context.Context, s net.Stream) (*HelloMessage, error) { var hello HelloMessage err := hello.UnmarshalCBOR(s) return &hello, err } -func (h *HelloProtocolHandler) receiveLatency(ctx context.Context, s net.Stream) (*LatencyMessage, error) { +func (h *HelloProtocolHandler) receiveLatency(_ context.Context, s net.Stream) (*LatencyMessage, error) { var latency LatencyMessage err := latency.UnmarshalCBOR(s) if err != nil { diff --git a/pkg/repo/fsrepo.go b/pkg/repo/fsrepo.go index 88b4906111..cd31a2846c 100644 --- a/pkg/repo/fsrepo.go +++ b/pkg/repo/fsrepo.go @@ -24,7 +24,7 @@ import ( ) // Version is the version of repo schema that this code understands. -const LatestVersion uint = 12 +const LatestVersion uint = 13 const ( // apiFile is the filename containing the filecoin node's api address. @@ -203,7 +203,7 @@ func (r *FSRepo) loadFromDisk() error { } if localVersion > r.version { - return fmt.Errorf("binary needs update to handle repo version, got %d expected %d. Update binary to latest release", localVersion, LatestVersion) + return fmt.Errorf("binary needs update to handle repo version, got %d expected %d. Update binary to latest release", localVersion, r.version) } if err := r.loadConfig(); err != nil { diff --git a/pkg/repo/fsrepo_test.go b/pkg/repo/fsrepo_test.go index 8151fd594a..3e8182f492 100644 --- a/pkg/repo/fsrepo_test.go +++ b/pkg/repo/fsrepo_test.go @@ -72,7 +72,7 @@ func TestFSRepoOpen(t *testing.T) { assert.NoError(t, WriteVersion(repoPath, 99)) _, err := OpenFSRepo(repoPath, 1) - expected := fmt.Sprintf("binary needs update to handle repo version, got 99 expected %d. Update binary to latest release", LatestVersion) + expected := fmt.Sprintf("binary needs update to handle repo version, got 99 expected %d. Update binary to latest release", 1) assert.EqualError(t, err, expected) }) diff --git a/pkg/state/tree/state.go b/pkg/state/tree/state.go index 91b0f40470..dafbd329f9 100644 --- a/pkg/state/tree/state.go +++ b/pkg/state/tree/state.go @@ -143,7 +143,7 @@ func VersionForNetwork(ver network.Version) (StateTreeVersion, error) { return StateTreeVersion3, nil case network.Version13, network.Version14, network.Version15, network.Version16, network.Version17: return StateTreeVersion4, nil - case network.Version18, network.Version19, network.Version20, network.Version21, network.Version22: + case network.Version18, network.Version19, network.Version20, network.Version21, network.Version22, network.Version23: return StateTreeVersion5, nil default: panic(fmt.Sprintf("unsupported network version %d", ver)) diff --git a/pkg/state/view.go b/pkg/state/view.go index 042d12c7a9..396630b077 100644 --- a/pkg/state/view.go +++ b/pkg/state/view.go @@ -127,7 +127,7 @@ func (v *View) MinerInfo(ctx context.Context, maddr addr.Address, nv network.Ver } // Loads sector info from miner state. -func (v *View) MinerSectorInfo(ctx context.Context, maddr addr.Address, sectorNum abi.SectorNumber) (*types.SectorOnChainInfo, error) { +func (v *View) MinerSectorInfo(ctx context.Context, maddr addr.Address, sectorNum abi.SectorNumber) (*lminer.SectorOnChainInfo, error) { minerState, err := v.LoadMinerState(ctx, maddr) if err != nil { return nil, err @@ -283,21 +283,6 @@ func (v *View) MinerExists(ctx context.Context, maddr addr.Address) (bool, error return false, err } -// MinerGetPrecommittedSector Looks up info for a miners precommitted sector. -// NOTE: exposes on-chain structures directly for storage FSM API. -func (v *View) MinerGetPrecommittedSector(ctx context.Context, maddr addr.Address, sectorNum abi.SectorNumber) (*types.SectorPreCommitOnChainInfo, bool, error) { - minerState, err := v.LoadMinerState(ctx, maddr) - if err != nil { - return nil, false, err - } - - info, err := minerState.GetPrecommittedSector(sectorNum) - if err != nil { - return nil, false, err - } - return info, true, nil -} - // MarketEscrowBalance looks up a token amount in the escrow table for the given address func (v *View) MarketEscrowBalance(ctx context.Context, addr addr.Address) (found bool, amount abi.TokenAmount, err error) { marketState, err := v.LoadMarketState(ctx) @@ -657,7 +642,7 @@ func (v *View) StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (map[s } // StateMinerActiveSectors returns info about sectors that a given miner is actively proving. -func (v *View) StateMinerActiveSectors(ctx context.Context, maddr addr.Address, tsk types.TipSetKey) ([]*types.SectorOnChainInfo, error) { +func (v *View) StateMinerActiveSectors(ctx context.Context, maddr addr.Address, tsk types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) { mas, err := v.LoadMinerState(ctx, maddr) if err != nil { return nil, fmt.Errorf("failed to load miner actor state: %v", err) @@ -715,9 +700,9 @@ func (v *View) ResolveToDeterministicAddress(ctx context.Context, address addr.A } if tree.Version() >= vmstate.StateTreeVersion5 { - if act.Address != nil { + if act.DelegatedAddress != nil { // If there _is_ an f4 address, return it as "key" address - return *act.Address, nil + return *act.DelegatedAddress, nil } } diff --git a/pkg/state/view_test.go b/pkg/state/view_test.go index dc520cee6c..24fa01302c 100644 --- a/pkg/state/view_test.go +++ b/pkg/state/view_test.go @@ -68,11 +68,6 @@ func TestView(t *testing.T) { _, err = view.SectorPreCommitInfo(ctx, m, 0) assert.NoError(t, err) - // stm: @STATE_VIEW_MINER_GET_PRECOMMITED_SECTOR - _, find, err = view.MinerGetPrecommittedSector(ctx, m, abi.SectorNumber(0)) - assert.NoError(t, err) - assert.True(t, find) - // stm: @STATE_VIEW_STATE_SECTOR_PARTITION_001 _, err = view.StateSectorPartition(ctx, m, 0) assert.NoError(t, err) diff --git a/pkg/statemanger/call.go b/pkg/statemanger/call.go index 0951bd1f17..f3663091c5 100644 --- a/pkg/statemanger/call.go +++ b/pkg/statemanger/call.go @@ -26,6 +26,14 @@ import ( "github.com/filecoin-project/venus/pkg/vm" ) +type execMessageStrategy int + +const ( + execNoMessages execMessageStrategy = iota // apply no prior or current tipset messages + execAllMessages // apply all prior and current tipset messages + execSameSenderMessages // apply all prior messages and any current tipset messages from the same sender +) + // Call applies the given message to the given tipset's parent state, at the epoch following the // tipset's parent. In the presence of null blocks, the height at which the message is invoked may // be less than the specified tipset. @@ -47,12 +55,23 @@ func (s *Stmgr) Call(ctx context.Context, msg *types.Message, ts *types.TipSet) msg.Value = types.NewInt(0) } - return s.callInternal(ctx, msg, nil, ts, cid.Undef, s.GetNetworkVersion, false, false) + return s.callInternal(ctx, msg, nil, ts, cid.Undef, s.GetNetworkVersion, false, execSameSenderMessages) +} + +// ApplyOnStateWithGas applies the given message on top of the given state root with gas tracing enabled +func (s *Stmgr) ApplyOnStateWithGas(ctx context.Context, stateCid cid.Cid, msg *types.Message, ts *types.TipSet) (*types.InvocResult, error) { + return s.callInternal(ctx, msg, nil, ts, stateCid, s.GetNetworkVersion, true, execNoMessages) } // CallWithGas calculates the state for a given tipset, and then applies the given message on top of that state. func (s *Stmgr) CallWithGas(ctx context.Context, msg *types.Message, priorMsgs []types.ChainMsg, ts *types.TipSet, applyTSMessages bool) (*types.InvocResult, error) { - return s.callInternal(ctx, msg, priorMsgs, ts, cid.Undef, s.GetNetworkVersion, true, applyTSMessages) + var strategy execMessageStrategy + if applyTSMessages { + strategy = execAllMessages + } else { + strategy = execSameSenderMessages + } + return s.callInternal(ctx, msg, priorMsgs, ts, cid.Undef, s.GetNetworkVersion, true, strategy) } // CallAtStateAndVersion allows you to specify a message to execute on the given stateCid and network version. @@ -64,13 +83,21 @@ func (s *Stmgr) CallAtStateAndVersion(ctx context.Context, msg *types.Message, s return v } - return s.callInternal(ctx, msg, nil, nil, stateCid, nvGetter, true, false) + return s.callInternal(ctx, msg, nil, nil, stateCid, nvGetter, true, execSameSenderMessages) } // - If no tipset is specified, the first tipset without an expensive migration or one in its parent is used. // - If executing a message at a given tipset or its parent would trigger an expensive migration, the call will // fail with ErrExpensiveFork. -func (s *Stmgr) callInternal(ctx context.Context, msg *types.Message, priorMsgs []types.ChainMsg, ts *types.TipSet, stateCid cid.Cid, nvGetter chain.NetworkVersionGetter, checkGas, applyTSMessages bool) (*types.InvocResult, error) { +func (s *Stmgr) callInternal(ctx context.Context, + msg *types.Message, + priorMsgs []types.ChainMsg, + ts *types.TipSet, + stateCid cid.Cid, + nvGetter chain.NetworkVersionGetter, + checkGas bool, + strategy execMessageStrategy, +) (*types.InvocResult, error) { ctx, span := trace.StartSpan(ctx, "statemanager.callInternal") defer span.End() @@ -116,22 +143,6 @@ func (s *Stmgr) callInternal(ctx context.Context, msg *types.Message, priorMsgs if stateCid == cid.Undef { stateCid = ts.ParentState() } - tsMsgs, err := s.ms.MessagesForTipset(ts) - if err != nil { - return nil, fmt.Errorf("failed to lookup messages for parent tipset: %w", err) - } - if applyTSMessages { - priorMsgs = append(tsMsgs, priorMsgs...) - } else { - var filteredTSMsgs []types.ChainMsg - for _, tsMsg := range tsMsgs { - //TODO we should technically be normalizing the filecoin address of from when we compare here - if tsMsg.VMMessage().From == msg.VMMessage().From { - filteredTSMsgs = append(filteredTSMsgs, tsMsg) - } - } - priorMsgs = append(filteredTSMsgs, priorMsgs...) - } // Technically, the tipset we're passing in here should be ts+1, but that may not exist. stateCid, err = s.fork.HandleStateForks(ctx, stateCid, ts.Height(), ts) @@ -151,7 +162,7 @@ func (s *Stmgr) callInternal(ctx context.Context, msg *types.Message, priorMsgs buffStore := blockstoreutil.NewTieredBstore(s.cs.Blockstore(), blockstoreutil.NewTemporarySync()) vmopt := vm.VmOption{ CircSupplyCalculator: func(ctx context.Context, epoch abi.ChainEpoch, tree tree.Tree) (abi.TokenAmount, error) { - cs, err := s.cs.GetCirculatingSupplyDetailed(ctx, epoch, tree) + cs, err := s.circulatingSupplyCalculator.GetCirculatingSupplyDetailed(ctx, epoch, tree) if err != nil { return abi.TokenAmount{}, err } @@ -176,18 +187,40 @@ func (s *Stmgr) callInternal(ctx context.Context, msg *types.Message, priorMsgs if err != nil { return nil, fmt.Errorf("failed to set up vm: %w", err) } - for i, m := range priorMsgs { - _, err = vmi.ApplyMessage(ctx, m) + + switch strategy { + case execNoMessages: + // Do nothing + case execAllMessages, execSameSenderMessages: + tsMsgs, err := s.ms.MessagesForTipset(ts) if err != nil { - return nil, fmt.Errorf("applying prior message (%d, %s): %w", i, m.Cid(), err) + return nil, fmt.Errorf("failed to lookup messages for parent tipset: %w", err) + } + if strategy == execAllMessages { + priorMsgs = append(tsMsgs, priorMsgs...) + } else if strategy == execSameSenderMessages { + var filteredTSMsgs []types.ChainMsg + for _, tsMsg := range tsMsgs { + //TODO we should technically be normalizing the filecoin address of from when we compare here + if tsMsg.VMMessage().From == msg.VMMessage().From { + filteredTSMsgs = append(filteredTSMsgs, tsMsg) + } + } + priorMsgs = append(filteredTSMsgs, priorMsgs...) + } + for i, m := range priorMsgs { + _, err = vmi.ApplyMessage(ctx, m) + if err != nil { + return nil, fmt.Errorf("applying prior message (%d, %s): %w", i, m.Cid(), err) + } } - } - // We flush to get the VM's view of the state tree after applying the above messages - // This is needed to get the correct nonce from the actor state to match the VM - stateCid, err = vmi.Flush(ctx) - if err != nil { - return nil, fmt.Errorf("flushing vm: %w", err) + // We flush to get the VM's view of the state tree after applying the above messages + // This is needed to get the correct nonce from the actor state to match the VM + stateCid, err = vmi.Flush(ctx) + if err != nil { + return nil, fmt.Errorf("flushing vm: %w", err) + } } st, err := tree.LoadState(ctx, cbor.NewCborStore(buffStore), stateCid) diff --git a/pkg/statemanger/state_manger.go b/pkg/statemanger/state_manger.go index 26a1eb4608..aa6741d1b0 100644 --- a/pkg/statemanger/state_manger.go +++ b/pkg/statemanger/state_manger.go @@ -57,10 +57,11 @@ var _ IStateManager = &Stmgr{} var log = logging.Logger("statemanager") type Stmgr struct { - cs *chain.Store - ms *chain.MessageStore - cp consensus.StateTransformer - beacon beacon.Schedule + cs *chain.Store + ms *chain.MessageStore + cp consensus.StateTransformer + beacon beacon.Schedule + circulatingSupplyCalculator chain.ICirculatingSupplyCalcualtor fork fork.IFork gasSchedule *gas.PricesSchedule @@ -92,6 +93,7 @@ func NewStateManager(cs *chain.Store, gasSchedule *gas.PricesSchedule, syscallsImpl vm.SyscallsImpl, actorDebugging bool, + circulatingSupplyCalculator chain.ICirculatingSupplyCalcualtor, ) (*Stmgr, error) { log.Debugf("execTraceCache size: %d", execTraceCacheSize) var execTraceCache *arc.ARCCache[types.TipSetKey, tipSetCacheEntry] @@ -104,17 +106,18 @@ func NewStateManager(cs *chain.Store, } return &Stmgr{ - cs: cs, - ms: ms, - fork: fork, - cp: cp, - beacon: beacon, - gasSchedule: gasSchedule, - syscallsImpl: syscallsImpl, - stCache: make(map[types.TipSetKey]stateComputeResult), - chsWorkingOn: make(map[types.TipSetKey]chan struct{}, 1), - actorDebugging: actorDebugging, - execTraceCache: execTraceCache, + cs: cs, + ms: ms, + fork: fork, + cp: cp, + beacon: beacon, + circulatingSupplyCalculator: circulatingSupplyCalculator, + gasSchedule: gasSchedule, + syscallsImpl: syscallsImpl, + stCache: make(map[types.TipSetKey]stateComputeResult), + chsWorkingOn: make(map[types.TipSetKey]chan struct{}, 1), + actorDebugging: actorDebugging, + execTraceCache: execTraceCache, }, nil } @@ -589,7 +592,7 @@ func ComputeState(ctx context.Context, s *Stmgr, height abi.ChainEpoch, msgs []* buffStore := blockstoreutil.NewTieredBstore(s.cs.Blockstore(), blockstoreutil.NewTemporarySync()) vmopt := vm.VmOption{ CircSupplyCalculator: func(ctx context.Context, epoch abi.ChainEpoch, tree tree.Tree) (abi.TokenAmount, error) { - cs, err := s.cs.GetCirculatingSupplyDetailed(ctx, epoch, tree) + cs, err := s.circulatingSupplyCalculator.GetCirculatingSupplyDetailed(ctx, epoch, tree) if err != nil { return abi.TokenAmount{}, err } diff --git a/pkg/vf3/ec.go b/pkg/vf3/ec.go new file mode 100644 index 0000000000..0b0676fbb0 --- /dev/null +++ b/pkg/vf3/ec.go @@ -0,0 +1,216 @@ +package vf3 + +import ( + "context" + "sort" + "time" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-f3/ec" + "github.com/filecoin-project/go-f3/gpbft" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/venus/pkg/chain" + "github.com/filecoin-project/venus/pkg/statemanger" + "github.com/filecoin-project/venus/pkg/vm" + "github.com/filecoin-project/venus/venus-shared/actors/builtin/miner" + "github.com/filecoin-project/venus/venus-shared/actors/builtin/power" + "github.com/filecoin-project/venus/venus-shared/types" + "golang.org/x/xerrors" +) + +type ecWrapper struct { + ChainStore *chain.Store + StateManager *statemanger.Stmgr +} + +type f3TipSet types.TipSet + +func (ts *f3TipSet) cast() *types.TipSet { + return (*types.TipSet)(ts) +} + +func (ts *f3TipSet) Key() gpbft.TipSetKey { + return ts.cast().Key().Bytes() +} + +func (ts *f3TipSet) Beacon() []byte { + entries := ts.cast().Blocks()[0].BeaconEntries + if len(entries) == 0 { + // Set beacon to a non-nil slice to force the message builder to generate a + // ticket. Otherwise, messages that require ticket, i.e. CONVERGE will fail + // validation due to the absence of ticket. This is a convoluted way of doing it. + // TODO: Rework the F3 message builder APIs to include ticket when needed instead + // of relying on the nil check of beacon. + return []byte{} + } + return entries[len(entries)-1].Data +} + +func (ts *f3TipSet) Epoch() int64 { + return int64(ts.cast().Height()) +} + +func (ts *f3TipSet) Timestamp() time.Time { + return time.Unix(int64(ts.cast().Blocks()[0].Timestamp), 0) +} + +func wrapTS(ts *types.TipSet) ec.TipSet { + if ts == nil { + return nil + } + return (*f3TipSet)(ts) +} + +// GetTipsetByEpoch should return a tipset before the one requested if the requested +// tipset does not exist due to null epochs +func (ec *ecWrapper) GetTipsetByEpoch(ctx context.Context, epoch int64) (ec.TipSet, error) { + ts, err := ec.ChainStore.GetTipSetByHeight(ctx, nil, abi.ChainEpoch(epoch), true) + if err != nil { + return nil, xerrors.Errorf("getting tipset by height: %w", err) + } + return wrapTS(ts), nil +} + +func (ec *ecWrapper) GetTipset(ctx context.Context, tsk gpbft.TipSetKey) (ec.TipSet, error) { + tskLotus, err := types.TipSetKeyFromBytes(tsk) + if err != nil { + return nil, xerrors.Errorf("decoding tsk: %w", err) + } + + ts, err := ec.ChainStore.GetTipSet(ctx, tskLotus) + if err != nil { + return nil, xerrors.Errorf("getting tipset by key: %w", err) + } + + return wrapTS(ts), nil +} + +func (ec *ecWrapper) GetHead(_ context.Context) (ec.TipSet, error) { + return wrapTS(ec.ChainStore.GetHead()), nil +} + +func (ec *ecWrapper) GetParent(ctx context.Context, tsF3 ec.TipSet) (ec.TipSet, error) { + var ts *types.TipSet + if tsW, ok := tsF3.(*f3TipSet); ok { + ts = tsW.cast() + } else { + // There are only two implementations of ec.TipSet: f3TipSet, and one in fake EC + // backend. + // + // TODO: Revisit the type check here and remove as needed once testing + // is over and fake EC backend goes away. + tskLotus, err := types.TipSetKeyFromBytes(tsF3.Key()) + if err != nil { + return nil, xerrors.Errorf("decoding tsk: %w", err) + } + ts, err = ec.ChainStore.GetTipSet(ctx, tskLotus) + if err != nil { + return nil, xerrors.Errorf("getting tipset by key for get parent: %w", err) + } + } + parentTS, err := ec.ChainStore.GetTipSet(ctx, ts.Parents()) + if err != nil { + return nil, xerrors.Errorf("getting parent tipset: %w", err) + } + return wrapTS(parentTS), nil +} + +func (ec *ecWrapper) GetPowerTable(ctx context.Context, tskF3 gpbft.TipSetKey) (gpbft.PowerEntries, error) { + tskLotus, err := types.TipSetKeyFromBytes(tskF3) + if err != nil { + return nil, xerrors.Errorf("decoding tsk: %w", err) + } + ts, err := ec.ChainStore.GetTipSet(ctx, tskLotus) + if err != nil { + return nil, xerrors.Errorf("getting tipset by key for get parent: %w", err) + } + + _, state, err := ec.StateManager.ParentState(ctx, ts) + if err != nil { + return nil, xerrors.Errorf("loading the state tree: %w", err) + } + powerAct, found, err := state.GetActor(ctx, power.Address) + if err != nil { + return nil, xerrors.Errorf("getting the power actor: %w", err) + } + if !found { + return nil, xerrors.Errorf("not found the power actor by address: %s", power.Address) + } + + powerState, err := power.Load(ec.ChainStore.Store(ctx), powerAct) + if err != nil { + return nil, xerrors.Errorf("loading power actor state: %w", err) + } + + var powerEntries gpbft.PowerEntries + err = powerState.ForEachClaim(func(minerAddr address.Address, claim power.Claim) error { + if claim.QualityAdjPower.Sign() <= 0 { + return nil + } + + // TODO: optimize + ok, err := powerState.MinerNominalPowerMeetsConsensusMinimum(minerAddr) + if err != nil { + return xerrors.Errorf("checking consensus minimums: %w", err) + } + if !ok { + return nil + } + + id, err := address.IDFromAddress(minerAddr) + if err != nil { + return xerrors.Errorf("transforming address to ID: %w", err) + } + + pe := gpbft.PowerEntry{ + ID: gpbft.ActorID(id), + Power: claim.QualityAdjPower.Int, + } + + act, found, err := state.GetActor(ctx, minerAddr) + if err != nil { + return xerrors.Errorf("(get sset) failed to load miner actor: %w", err) + } + if !found { + return xerrors.Errorf("(get sset) failed to find miner actor by address: %s", minerAddr) + } + mstate, err := miner.Load(ec.ChainStore.Store(ctx), act) + if err != nil { + return xerrors.Errorf("(get sset) failed to load miner actor state: %w", err) + } + + info, err := mstate.Info() + if err != nil { + return xerrors.Errorf("failed to load actor info: %w", err) + } + // check fee debt + if debt, err := mstate.FeeDebt(); err != nil { + return err + } else if !debt.IsZero() { + // fee debt don't add the miner to power table + return nil + } + // check consensus faults + if ts.Height() <= info.ConsensusFaultElapsed { + return nil + } + + waddr, err := vm.ResolveToDeterministicAddress(ctx, state, info.Worker, ec.ChainStore.Store(ctx)) + if err != nil { + return xerrors.Errorf("resolve miner worker address: %w", err) + } + + if waddr.Protocol() != address.BLS { + return xerrors.Errorf("wrong type of worker address") + } + pe.PubKey = gpbft.PubKey(waddr.Payload()) + powerEntries = append(powerEntries, pe) + return nil + }) + if err != nil { + return nil, xerrors.Errorf("collecting the power table: %w", err) + } + + sort.Sort(powerEntries) + return powerEntries, nil +} diff --git a/pkg/vf3/f3.go b/pkg/vf3/f3.go new file mode 100644 index 0000000000..e8982c4575 --- /dev/null +++ b/pkg/vf3/f3.go @@ -0,0 +1,147 @@ +package vf3 + +import ( + "context" + "errors" + + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/namespace" + pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-f3" + "github.com/filecoin-project/go-f3/blssig" + "github.com/filecoin-project/go-f3/certs" + "github.com/filecoin-project/go-f3/gpbft" + "github.com/filecoin-project/go-f3/manifest" + "github.com/filecoin-project/venus/pkg/chain" + "github.com/filecoin-project/venus/pkg/statemanger" + v1api "github.com/filecoin-project/venus/venus-shared/api/chain/v1" + logging "github.com/ipfs/go-log" +) + +type F3 struct { + inner *f3.F3 + + signer gpbft.Signer +} + +type F3Params struct { + ManifestServerID string + ManifestProvider manifest.ManifestProvider + PubSub *pubsub.PubSub + Host host.Host + ChainStore *chain.Store + StateManager *statemanger.Stmgr + Datastore datastore.Batching + Wallet v1api.IWallet +} + +var log = logging.Logger("f3") + +func New(mctx context.Context, params F3Params) (*F3, error) { + ds := namespace.Wrap(params.Datastore, datastore.NewKey("/f3")) + ec := &ecWrapper{ + ChainStore: params.ChainStore, + StateManager: params.StateManager, + } + verif := blssig.VerifierWithKeyOnG1() + + senderID, err := peer.Decode(params.ManifestServerID) + if err != nil { + return nil, xerrors.Errorf("decoding F3 manifest server identity: %w", err) + } + + module, err := f3.New(mctx, params.ManifestProvider, ds, + params.Host, senderID, params.PubSub, verif, ec, log, nil) + + if err != nil { + return nil, xerrors.Errorf("creating F3: %w", err) + } + params.ManifestProvider.SetManifestChangeCallback(f3.ManifestChangeCallback(module)) + + fff := &F3{ + inner: module, + signer: &signer{params.Wallet}, + } + + go func() { + err := fff.inner.Run(mctx) + if err != nil { + log.Errorf("running f3: %+v", err) + } + }() + + return fff, nil +} + +// Participate runs the participation loop for givine minerID +// It is blocking +func (fff *F3) Participate(ctx context.Context, minerIDAddress uint64, errCh chan<- string) { + defer close(errCh) + + for ctx.Err() == nil { + + // create channel for some buffer so we don't get dropped under high load + msgCh := make(chan *gpbft.MessageBuilder, 4) + // SubscribeForMessagesToSign will close the channel if it fills up + // so using the closer is not necessary, we can just drop it on the floor + _ = fff.inner.SubscribeForMessagesToSign(msgCh) + + participateOnce := func(mb *gpbft.MessageBuilder) error { + signatureBuilder, err := mb.PrepareSigningInputs(gpbft.ActorID(minerIDAddress)) + if errors.Is(err, gpbft.ErrNoPower) { + // we don't have any power in F3, continue + log.Debug("no power to participate in F3: %+v", err) + return nil + } + if err != nil { + log.Errorf("preparing signing inputs: %+v", err) + return err + } + // if worker keys were stored not in the node, the signatureBuilder can be send there + // the sign can be called where the keys are stored and then + // {signatureBuilder, payloadSig, vrfSig} can be sent back to lotus for broadcast + payloadSig, vrfSig, err := signatureBuilder.Sign(fff.signer) + if err != nil { + log.Errorf("signing message: %+v", err) + return err + } + log.Infof("miner with id %d is sending message in F3", minerIDAddress) + fff.inner.Broadcast(ctx, signatureBuilder, payloadSig, vrfSig) + return nil + } + + inner: + for ctx.Err() == nil { + select { + case mb, ok := <-msgCh: + if !ok { + // the broadcast bus kicked us out + log.Warnf("lost message bus subscription, retrying") + break inner + } + + err := participateOnce(mb) + if err != nil { + errCh <- err.Error() + } else { + errCh <- "" + } + + case <-ctx.Done(): + return + } + } + } +} + +func (fff *F3) GetCert(ctx context.Context, instance uint64) (*certs.FinalityCertificate, error) { + return fff.inner.GetCert(ctx, instance) +} + +func (fff *F3) GetLatestCert(ctx context.Context) (*certs.FinalityCertificate, error) { + return fff.inner.GetLatestCert(ctx) +} diff --git a/pkg/vf3/manifest.go b/pkg/vf3/manifest.go new file mode 100644 index 0000000000..f6b654fbe9 --- /dev/null +++ b/pkg/vf3/manifest.go @@ -0,0 +1,38 @@ +package vf3 + +import ( + "time" + + pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/libp2p/go-libp2p/core/peer" + + "github.com/filecoin-project/go-f3/gpbft" + "github.com/filecoin-project/go-f3/manifest" + "github.com/filecoin-project/venus/pkg/chain" + "github.com/filecoin-project/venus/pkg/config" + "github.com/filecoin-project/venus/pkg/constants" + "github.com/filecoin-project/venus/pkg/statemanger" +) + +func NewManifestProvider(nn string, cs *chain.Store, sm *statemanger.Stmgr, ps *pubsub.PubSub, networkParams *config.NetworkParamsConfig) manifest.ManifestProvider { + m := manifest.LocalDevnetManifest() + m.NetworkName = gpbft.NetworkName(nn) + m.ECDelay = 2 * time.Duration(networkParams.BlockDelay) * time.Second + m.ECPeriod = m.ECDelay + m.BootstrapEpoch = int64(networkParams.F3BootstrapEpoch) + m.ECFinality = int64(constants.Finality) + m.CommiteeLookback = 5 + + ec := &ecWrapper{ + ChainStore: cs, + StateManager: sm, + } + + switch manifestServerID, err := peer.Decode(networkParams.ManifestServerID); { + case err != nil: + log.Warnw("Cannot decode F3 manifest sever identity; falling back on static manifest provider", "err", err) + return manifest.NewStaticManifestProvider(m) + default: + return manifest.NewDynamicManifestProvider(m, ps, ec, manifestServerID) + } +} diff --git a/pkg/vf3/signer.go b/pkg/vf3/signer.go new file mode 100644 index 0000000000..eabd80fe7e --- /dev/null +++ b/pkg/vf3/signer.go @@ -0,0 +1,37 @@ +package vf3 + +import ( + "context" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-f3/gpbft" + v1api "github.com/filecoin-project/venus/venus-shared/api/chain/v1" + "github.com/filecoin-project/venus/venus-shared/types" + "golang.org/x/xerrors" +) + +type signer struct { + wallet v1api.IWallet +} + +// Sign signs a message with the private key corresponding to a public key. +// The the key must be known by the wallet and be of BLS type. +func (s *signer) Sign(sender gpbft.PubKey, msg []byte) ([]byte, error) { + addr, err := address.NewBLSAddress(sender) + if err != nil { + return nil, xerrors.Errorf("converting pubkey to address: %w", err) + } + sig, err := s.wallet.WalletSign(context.TODO(), addr, msg, types.MsgMeta{Type: types.MTUnknown}) + if err != nil { + return nil, xerrors.Errorf("error while signing: %w", err) + } + return sig.Data, nil +} + +// MarshalPayloadForSigning marshals the given payload into the bytes that should be signed. +// This should usually call `Payload.MarshalForSigning(NetworkName)` except when testing as +// that method is slow (computes a merkle tree that's necessary for testing). +// Implementations must be safe for concurrent use. +func (s *signer) MarshalPayloadForSigning(nn gpbft.NetworkName, p *gpbft.Payload) []byte { + return p.MarshalForSigning(nn) +} diff --git a/pkg/vm/register/default.go b/pkg/vm/register/default.go index c2b3a55eac..57dc645f1c 100644 --- a/pkg/vm/register/default.go +++ b/pkg/vm/register/default.go @@ -43,6 +43,7 @@ func GetDefaultActros() *dispatch.CodeLoader { DefaultActorBuilder.AddMany(actorstypes.Version11, dispatch.ActorsVersionPredicate(actorstypes.Version11), builtin.MakeRegistry(actorstypes.Version11)) DefaultActorBuilder.AddMany(actorstypes.Version12, dispatch.ActorsVersionPredicate(actorstypes.Version12), builtin.MakeRegistry(actorstypes.Version12)) DefaultActorBuilder.AddMany(actorstypes.Version13, dispatch.ActorsVersionPredicate(actorstypes.Version13), builtin.MakeRegistry(actorstypes.Version13)) + DefaultActorBuilder.AddMany(actorstypes.Version14, dispatch.ActorsVersionPredicate(actorstypes.Version14), builtin.MakeRegistry(actorstypes.Version14)) defaultActors = DefaultActorBuilder.Build() }) diff --git a/pkg/vm/vmcontext/execution.go b/pkg/vm/vmcontext/execution.go index 4a661790b8..cfa8468441 100644 --- a/pkg/vm/vmcontext/execution.go +++ b/pkg/vm/vmcontext/execution.go @@ -75,39 +75,28 @@ type executionEnv struct { } func (e *executionEnv) getToken(lane ExecutionLane) *executionToken { - e.mx.Lock() - defer e.mx.Unlock() - switch lane { - case ExecutionLaneDefault: + reserving := 0 + if lane == ExecutionLaneDefault { for e.available <= e.reserved { e.cond.Wait() } - e.available-- - - return &executionToken{lane: lane, reserved: 0} - - case ExecutionLanePriority: + } else { for e.available == 0 { e.cond.Wait() } - - e.available-- - - reserving := 0 if e.reserved > 0 { e.reserved-- reserving = 1 } + } - return &executionToken{lane: lane, reserved: reserving} + e.available-- + e.mx.Unlock() - default: - // already checked at interface boundary in NewVM, so this is appropriate - panic("bogus execution lane") - } + return &executionToken{lane: lane, reserved: reserving} } func (e *executionEnv) putToken(token *executionToken) { @@ -118,9 +107,8 @@ func (e *executionEnv) putToken(token *executionToken) { e.reserved += token.reserved // Note: Signal is unsound, because a priority token could wake up a non-priority - // goroutnie and lead to deadlock. So Broadcast it must be. + // goroutine and lead to deadlock. So Broadcast it must be. e.cond.Broadcast() - } func init() { diff --git a/pkg/vm/vmcontext/invocation_context.go b/pkg/vm/vmcontext/invocation_context.go index cd824b7631..ed22c2e39e 100644 --- a/pkg/vm/vmcontext/invocation_context.go +++ b/pkg/vm/vmcontext/invocation_context.go @@ -520,11 +520,11 @@ func (ctx *invocationContext) CreateActor(codeID cid.Cid, addr address.Address) newActor := &types.Actor{ // make this the right 'type' of actor - Code: codeID, - Balance: abi.NewTokenAmount(0), - Head: EmptyObjectCid, - Nonce: 0, - Address: &addr, + Code: codeID, + Balance: abi.NewTokenAmount(0), + Head: EmptyObjectCid, + Nonce: 0, + DelegatedAddress: &addr, } if err := ctx.vm.State.SetActor(ctx.vm.context, addr, newActor); err != nil { panic(err) diff --git a/pkg/vm/vmcontext/types.go b/pkg/vm/vmcontext/types.go index de7bc386fc..c7721650de 100644 --- a/pkg/vm/vmcontext/types.go +++ b/pkg/vm/vmcontext/types.go @@ -160,9 +160,9 @@ func ResolveToDeterministicAddress(ctx context.Context, state tree.Tree, addr ad } if state.Version() >= tree.StateTreeVersion5 { - if act.Address != nil { + if act.DelegatedAddress != nil { // If there _is_ an f4 address, return it as "key" address - return *act.Address, nil + return *act.DelegatedAddress, nil } } diff --git a/tools/conformance/driver.go b/tools/conformance/driver.go index c7f229a297..be708815c9 100644 --- a/tools/conformance/driver.go +++ b/tools/conformance/driver.go @@ -101,7 +101,7 @@ func (d *Driver) ExecuteTipset(bs blockstoreutil.Blockstore, chainDs ds.Batching mainNetParams := networks.Mainnet() node.SetNetParams(&mainNetParams.Network) // chainstore - chainStore := chain.NewStore(chainDs, bs, cid.Undef, chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight) // load genesis from car + chainStore := chain.NewStore(chainDs, bs, cid.Undef, chainselector.Weight) // load genesis from car // chain fork chainFork, err := fork.NewChainFork(context.TODO(), chainStore, ipldStore, bs, &mainNetParams.Network, chainDs) @@ -174,7 +174,7 @@ func (d *Driver) ExecuteTipset(bs blockstoreutil.Blockstore, chainDs ds.Batching results []*vm.Ret ) - circulatingSupplyCalculator := chain.NewCirculatingSupplyCalculator(bs, preroot, mainNetParams.Network.ForkUpgradeParam) + circulatingSupplyCalculator := chain.NewCirculatingSupplyCalculator(bs, preroot, mainNetParams.Network.ForkUpgradeParam, chainFork.GetNetworkVersion) processor := consensus.NewDefaultProcessor(syscalls, circulatingSupplyCalculator, chainStore, &mainNetParams.Network) postcid, receipt, err := processor.ApplyBlocks(ctx, blocks, nil, preroot, parentEpoch, execEpoch, vmOption, func(_ cid.Cid, msg *types.Message, ret *vm.Ret) error { @@ -202,6 +202,7 @@ func (d *Driver) ExecuteTipset(bs blockstoreutil.Blockstore, chainDs ds.Batching type ExecuteMessageParams struct { Preroot cid.Cid Epoch abi.ChainEpoch + Timestamp uint64 Message *types.Message CircSupply abi.TokenAmount BaseFee abi.TokenAmount @@ -256,7 +257,7 @@ func (d *Driver) ExecuteMessage(bs blockstoreutil.Blockstore, params ExecuteMess ipldStore := cbor.NewCborStore(bs) chainDs := ds.NewMapDatastore() // just mock one // chainstore - chainStore := chain.NewStore(chainDs, bs, cid.Undef, chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight) // load genesis from car + chainStore := chain.NewStore(chainDs, bs, cid.Undef, chainselector.Weight) // load genesis from car // chain fork chainFork, err := fork.NewChainFork(context.TODO(), chainStore, ipldStore, bs, &mainNetParams.Network, chainDs) @@ -278,6 +279,7 @@ func (d *Driver) ExecuteMessage(bs blockstoreutil.Blockstore, params ExecuteMess Fork: chainFork, ActorCodeLoader: &coderLoader, Epoch: params.Epoch, + Timestamp: params.Timestamp, GasPriceSchedule: gas.NewPricesSchedule(mainNetParams.Network.ForkUpgradeParam), PRoot: params.Preroot, Bsstore: bs, diff --git a/tools/gengen/util/generator.go b/tools/gengen/util/generator.go index 1b37e3c466..dc427fbf9d 100644 --- a/tools/gengen/util/generator.go +++ b/tools/gengen/util/generator.go @@ -78,7 +78,7 @@ func NewGenesisGenerator(bs blockstore.Blockstore) *GenesisGenerator { chainRand := chain.NewGenesisRandomnessSource(genesis.Ticket.VRFProof) chainDs := ds.NewMapDatastore() // just mock one // chainstore - chainStore := chain.NewStore(chainDs, bs, cid.Undef, chain.NewMockCirculatingSupplyCalculator(), chainselector.Weight) // load genesis from car + chainStore := chain.NewStore(chainDs, bs, cid.Undef, chainselector.Weight) // load genesis from car chainFork, err := fork.NewChainFork(context.TODO(), chainStore, cst, bs, config.NewDefaultConfig().NetworkParams, chainDs) if err != nil { panic(xerrors.Errorf("create chain fork error %v", err)) diff --git a/venus-devtool/api-gen/common/common.go b/venus-devtool/api-gen/common/common.go index b4e1102c9e..6c6984ab8f 100644 --- a/venus-devtool/api-gen/common/common.go +++ b/venus-devtool/api-gen/common/common.go @@ -9,6 +9,7 @@ import ( "reflect" "github.com/filecoin-project/venus/venus-devtool/util" + "github.com/filecoin-project/venus/venus-shared/api/f3" gatewayv0 "github.com/filecoin-project/venus/venus-shared/api/gateway/v0" gatewayv1 "github.com/filecoin-project/venus/venus-shared/api/gateway/v1" gatewayv2 "github.com/filecoin-project/venus/venus-shared/api/gateway/v2" @@ -112,6 +113,17 @@ func init() { MethodNamespace: "VENUS_MARKET_CLIENT", }, }, + util.APIMeta{ + Type: reflect.TypeOf((*f3.F3)(nil)).Elem(), + ParseOpt: util.InterfaceParseOption{ + ImportPath: "github.com/filecoin-project/venus/venus-shared/api/f3", + IncludeAll: true, + }, + RPCMeta: util.RPCMeta{ + Version: 0, + MethodNamespace: "F3", + }, + }, ) } diff --git a/venus-devtool/api-gen/example.go b/venus-devtool/api-gen/example.go index 708b5d70da..030968bac6 100644 --- a/venus-devtool/api-gen/example.go +++ b/venus-devtool/api-gen/example.go @@ -20,6 +20,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/exitcode" + lminer "github.com/filecoin-project/venus/venus-shared/actors/builtin/miner" "github.com/filecoin-project/venus/venus-shared/types/gateway" "github.com/filecoin-project/venus/venus-shared/types/market" auuid "github.com/google/uuid" @@ -34,6 +35,7 @@ import ( "github.com/libp2p/go-libp2p/core/protocol" "github.com/multiformats/go-multiaddr" + "github.com/filecoin-project/go-f3/certs" "github.com/filecoin-project/venus/pkg/constants" "github.com/filecoin-project/venus/venus-shared/api/chain" "github.com/filecoin-project/venus/venus-shared/types" @@ -221,6 +223,7 @@ func init() { addExample(types.CheckStatusCode(0)) addExample(map[string]interface{}{"abc": 123}) addExample(types.HCApply) + addExample(lminer.SectorOnChainInfoFlags(0)) // messager i64 := int64(10000) @@ -325,6 +328,7 @@ func init() { addExample(retrievalmarket.CborGenCompatibleNode{}) addExample(gateway.HostNode) + addExample(&certs.FinalityCertificate{}) } func ExampleValue(method string, t, parent reflect.Type) interface{} { diff --git a/venus-devtool/go.mod b/venus-devtool/go.mod index 541dd082d4..e2cad64c69 100644 --- a/venus-devtool/go.mod +++ b/venus-devtool/go.mod @@ -6,17 +6,18 @@ require ( github.com/filecoin-project/go-address v1.1.0 github.com/filecoin-project/go-bitfield v0.2.4 github.com/filecoin-project/go-data-transfer/v2 v2.0.0-rc7 + github.com/filecoin-project/go-f3 v0.0.3-0.20240702063402-d48771055cf4 github.com/filecoin-project/go-fil-markets v1.28.3 - github.com/filecoin-project/go-jsonrpc v0.3.1 - github.com/filecoin-project/go-state-types v0.13.1 - github.com/filecoin-project/lotus v1.26.1 + github.com/filecoin-project/go-jsonrpc v0.3.2 + github.com/filecoin-project/go-state-types v0.14.0-rc5 + github.com/filecoin-project/lotus v1.28.0-rc3 github.com/filecoin-project/venus v0.0.0-00010101000000-000000000000 github.com/google/uuid v1.6.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-graphsync v0.16.0 github.com/ipld/go-ipld-selector-text-lite v0.0.1 - github.com/libp2p/go-libp2p v0.34.1 + github.com/libp2p/go-libp2p v0.35.0 github.com/libp2p/go-libp2p-pubsub v0.11.0 github.com/multiformats/go-multiaddr v0.12.4 github.com/urfave/cli/v2 v2.25.5 @@ -27,8 +28,7 @@ require ( require ( contrib.go.opencensus.io/exporter/graphite v0.0.0-20200424223504-26b90655e0ce // indirect contrib.go.opencensus.io/exporter/prometheus v0.4.2 // indirect - github.com/BurntSushi/toml v1.3.0 // indirect - github.com/DataDog/zstd v1.4.5 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect github.com/GeertJohan/go.incremental v1.0.0 // indirect github.com/GeertJohan/go.rice v1.0.3 // indirect github.com/StackExchange/wmi v1.2.1 // indirect @@ -36,14 +36,14 @@ require ( github.com/akavel/rsrc v0.8.0 // indirect github.com/awnumar/memcall v0.0.0-20191004114545-73db50fd9f80 // indirect github.com/awnumar/memguard v0.22.2 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect github.com/bluele/gcache v0.0.0-20190518031135-bc40bd653833 // indirect + github.com/buger/jsonparser v1.1.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect - github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/daaku/go.zipexe v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dchest/blake2b v1.0.0 // indirect @@ -52,14 +52,14 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/drand/drand v1.5.7 // indirect - github.com/drand/kyber v1.2.0 // indirect + github.com/drand/drand v1.5.11 // indirect + github.com/drand/kyber v1.3.1 // indirect github.com/drand/kyber-bls12381 v0.3.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/filecoin-project/filecoin-ffi v0.30.4-0.20220519234331-bfd1f5f9fe38 // indirect + github.com/filecoin-project/filecoin-ffi v1.28.0-rc2 // indirect github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349 // indirect github.com/filecoin-project/go-amt-ipld/v3 v3.1.0 // indirect - github.com/filecoin-project/go-amt-ipld/v4 v4.2.0 // indirect + github.com/filecoin-project/go-amt-ipld/v4 v4.3.0 // indirect github.com/filecoin-project/go-cbor-util v0.0.1 // indirect github.com/filecoin-project/go-commp-utils v0.1.3 // indirect github.com/filecoin-project/go-commp-utils/nonffi v0.0.0-20220905160352-62059082a837 // indirect @@ -72,7 +72,6 @@ require ( github.com/filecoin-project/go-padreader v0.0.1 // indirect github.com/filecoin-project/go-statemachine v1.0.3 // indirect github.com/filecoin-project/go-statestore v0.2.0 // indirect - github.com/filecoin-project/kubo-api-client v0.27.0 // indirect github.com/filecoin-project/pubsub v1.0.0 // indirect github.com/filecoin-project/specs-actors v0.9.15 // indirect github.com/filecoin-project/specs-actors/v2 v2.3.6 // indirect @@ -106,6 +105,7 @@ require ( github.com/hashicorp/golang-lru/arc/v2 v2.0.7 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/icza/backscanner v0.0.0-20210726202459-ac2ffc679f94 // indirect + github.com/invopop/jsonschema v0.12.0 // indirect github.com/ipfs-force-community/metrics v1.0.1-0.20231207081445-30178e706d09 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/boxo v0.20.0 // indirect @@ -114,7 +114,6 @@ require ( github.com/ipfs/go-ds-badger2 v0.1.3 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.1 // indirect - github.com/ipfs/go-ipfs-cmds v0.10.0 // indirect github.com/ipfs/go-ipfs-ds-help v1.1.1 // indirect github.com/ipfs/go-ipfs-exchange-interface v0.2.1 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect @@ -148,6 +147,7 @@ require ( github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect github.com/magefile/mage v1.13.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/miekg/dns v1.1.59 // indirect github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect @@ -179,21 +179,19 @@ require ( github.com/prometheus/statsd_exporter v0.23.0 // indirect github.com/puzpuzpuz/xsync/v2 v2.4.1 // indirect github.com/raulk/clock v1.1.0 // indirect - github.com/rs/cors v1.7.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/samber/lo v1.39.0 // indirect github.com/shirou/gopsutil v2.18.12+incompatible // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/stretchr/testify v1.9.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.1.0 // indirect - github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/go-logging v0.0.1 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.26.0 // indirect go.opentelemetry.io/otel/bridge/opencensus v0.39.0 // indirect diff --git a/venus-devtool/go.sum b/venus-devtool/go.sum index ab512cf4da..ee149dc71a 100644 --- a/venus-devtool/go.sum +++ b/venus-devtool/go.sum @@ -57,12 +57,10 @@ contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.0 h1:Ws8e5YmnrGEHzZEzg0YvK/7COGYtTC5PbaH9oSSbgfA= -github.com/BurntSushi/toml v1.3.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.3 h1:k5viR+xGtIhF61125vCE1cmJ5957RQGXG6dmbaWZSmI= @@ -94,6 +92,8 @@ github.com/awnumar/memcall v0.0.0-20191004114545-73db50fd9f80 h1:8kObYoBO4LNmQ+f github.com/awnumar/memcall v0.0.0-20191004114545-73db50fd9f80/go.mod h1:S911igBPR9CThzd/hYQQmTc9SWNu3ZHIlCGaWsWsoJo= github.com/awnumar/memguard v0.22.2 h1:tMxcq1WamhG13gigK8Yaj9i/CHNUO3fFlpS9ABBQAxw= github.com/awnumar/memguard v0.22.2/go.mod h1:33OwJBHC+T4eEfFcDrQb78TMlBMBvcOPCXWU9xE34gM= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= @@ -104,8 +104,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bluele/gcache v0.0.0-20190518031135-bc40bd653833 h1:yCfXxYaelOyqnia8F/Yng47qhmfC9nKTRIbYRrRueq4= github.com/bluele/gcache v0.0.0-20190518031135-bc40bd653833/go.mod h1:8c4/i2VlovMO2gBnHGQPN5EJw+H0lx1u/5p+cgsXtCk= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= @@ -119,6 +117,8 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -131,6 +131,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -150,8 +152,8 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 h1:ZFUue+PNxmHlu7pYv+IYMtqlaO/0VwaGEqKepZf9JpA= github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -186,10 +188,10 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/drand/drand v1.5.7 h1:5f2D5aH1nEfVI9S6tl2p9bgIDMZ92oltmiY12Kh+eYU= -github.com/drand/drand v1.5.7/go.mod h1:jrJ0244yOHNL5V04vazk3mFatjAWm3i6dg6URWwgbXk= -github.com/drand/kyber v1.2.0 h1:22SbBxsKbgQnJUoyYKIfG909PhBsj0vtANeu4BX5xgE= -github.com/drand/kyber v1.2.0/go.mod h1:6TqFlCc7NGOiNVTF9pF2KcDRfllPd9XOkExuG5Xtwfo= +github.com/drand/drand v1.5.11 h1:7sskUTCsX2lgFiWdGvPh3/P0ZDQKi1lCtI7RQKK010k= +github.com/drand/drand v1.5.11/go.mod h1:TvJjCJ/s4Usn4pKRpDC0N1QaCwSt3YC8fRqhZdpOUU0= +github.com/drand/kyber v1.3.1 h1:E0p6M3II+loMVwTlAp5zu4+GGZFNiRfq02qZxzw2T+Y= +github.com/drand/kyber v1.3.1/go.mod h1:f+mNHjiGT++CuueBrpeMhFNdKZAsy0tu03bKq9D5LPA= github.com/drand/kyber-bls12381 v0.3.1 h1:KWb8l/zYTP5yrvKTgvhOrk2eNPscbMiUOIeWBnmUxGo= github.com/drand/kyber-bls12381 v0.3.1/go.mod h1:H4y9bLPu7KZA/1efDg+jtJ7emKx+ro3PU7/jWUVt140= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -222,8 +224,9 @@ github.com/filecoin-project/go-amt-ipld/v3 v3.0.0/go.mod h1:Qa95YNAbtoVCTSVtX38a github.com/filecoin-project/go-amt-ipld/v3 v3.1.0 h1:ZNJ9tEG5bE72vBWYiuh5bkxJVM3ViHNOmQ7qew9n6RE= github.com/filecoin-project/go-amt-ipld/v3 v3.1.0/go.mod h1:UjM2QhDFrrjD5s1CdnkJkat4ga+LqZBZgTMniypABRo= github.com/filecoin-project/go-amt-ipld/v4 v4.0.0/go.mod h1:gF053YQ4BIpzTNDoEwHZas7U3oAwncDVGvOHyY8oDpE= -github.com/filecoin-project/go-amt-ipld/v4 v4.2.0 h1:DQTXQwMXxaetd+lhZGODjt5qC1WYT7tMAlYrWqI/fwI= github.com/filecoin-project/go-amt-ipld/v4 v4.2.0/go.mod h1:0eDVF7pROvxrsxvLJx+SJZXqRaXXcEPUcgb/rG0zGU4= +github.com/filecoin-project/go-amt-ipld/v4 v4.3.0 h1:bY42N1gR0DqrLMCKUPzX1VhYVgXaETQm0Um4ohvyEP8= +github.com/filecoin-project/go-amt-ipld/v4 v4.3.0/go.mod h1:39Ep/yBbF6xN94WevLG9qSbglBJepHa5zeEbAE1pYsc= github.com/filecoin-project/go-bitfield v0.2.0/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= github.com/filecoin-project/go-bitfield v0.2.3/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= github.com/filecoin-project/go-bitfield v0.2.4 h1:uZ7MeE+XfM5lqrHJZ93OnhQKc/rveW8p9au0C68JPgk= @@ -242,6 +245,8 @@ github.com/filecoin-project/go-data-transfer/v2 v2.0.0-rc7 h1:v+zJS5B6pA3ptWZS4t github.com/filecoin-project/go-data-transfer/v2 v2.0.0-rc7/go.mod h1:V3Y4KbttaCwyg1gwkP7iai8CbQx4mZUGjd3h9GZWLKE= github.com/filecoin-project/go-ds-versioning v0.1.2 h1:to4pTadv3IeV1wvgbCbN6Vqd+fu+7tveXgv/rCEZy6w= github.com/filecoin-project/go-ds-versioning v0.1.2/go.mod h1:C9/l9PnB1+mwPa26BBVpCjG/XQCB0yj/q5CK2J8X1I4= +github.com/filecoin-project/go-f3 v0.0.3-0.20240702063402-d48771055cf4 h1:eQW2fyKyMuiweuySEb/zMIc3WLSAnIOY8lpqCVQM7pU= +github.com/filecoin-project/go-f3 v0.0.3-0.20240702063402-d48771055cf4/go.mod h1:Wry0mNa8z767TBHb7N0cVb+9j00KsHbD2pzsC3li4R8= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commcid v0.1.0 h1:3R4ds1A9r6cr8mvZBfMYxTS88OqLYEo6roi+GiIeOh8= github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= @@ -256,8 +261,8 @@ github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0/go.mod h1:7aWZdaQ1b16BVoQUYR+ github.com/filecoin-project/go-hamt-ipld/v3 v3.0.1/go.mod h1:gXpNmr3oQx8l3o7qkGyDjJjYSRX7hp/FGOStdqrWyDI= github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0 h1:rVVNq0x6RGQIzCo1iiJlGFm9AGIZzeifggxtKMU7zmI= github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0/go.mod h1:bxmzgT8tmeVQA1/gvBwFmYdT8SOFUwB3ovSUfG1Ux0g= -github.com/filecoin-project/go-jsonrpc v0.3.1 h1:qwvAUc5VwAkooquKJmfz9R2+F8znhiqcNHYjEp/NM10= -github.com/filecoin-project/go-jsonrpc v0.3.1/go.mod h1:jBSvPTl8V1N7gSTuCR4bis8wnQnIjHbRPpROol6iQKM= +github.com/filecoin-project/go-jsonrpc v0.3.2 h1:uuAWTZe6B3AUUta+O26HlycGoej/yiaI1fXp3Du+D3I= +github.com/filecoin-project/go-jsonrpc v0.3.2/go.mod h1:jBSvPTl8V1N7gSTuCR4bis8wnQnIjHbRPpROol6iQKM= github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20/go.mod h1:mPn+LRRd5gEKNAtc+r3ScpW2JRU/pj4NBKdADYWHiak= github.com/filecoin-project/go-padreader v0.0.1 h1:8h2tVy5HpoNbr2gBRr+WD6zV6VD6XHig+ynSGJg8ZOs= github.com/filecoin-project/go-padreader v0.0.1/go.mod h1:VYVPJqwpsfmtoHnAmPx6MUwmrK6HIcDqZJiuZhtmfLQ= @@ -268,19 +273,17 @@ github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psS github.com/filecoin-project/go-state-types v0.1.4/go.mod h1:xCA/WfKlC2zcn3fUmDv4IrzznwS98X5XW/irUP3Lhxg= github.com/filecoin-project/go-state-types v0.1.6/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= github.com/filecoin-project/go-state-types v0.1.10/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= -github.com/filecoin-project/go-state-types v0.11.2-0.20230712101859-8f37624fa540/go.mod h1:SyNPwTsU7I22gL2r0OAPcImvLoTVfgRwdK/Y5rR1zz8= -github.com/filecoin-project/go-state-types v0.13.1 h1:4CivvlcHAIoAtFFVVlZtokynaMQu5XLXGoTKhQkfG1I= -github.com/filecoin-project/go-state-types v0.13.1/go.mod h1:cHpOPup9H1g2T29dKHAjC2sc7/Ef5ypjuW9A3I+e9yY= +github.com/filecoin-project/go-state-types v0.14.0-rc1/go.mod h1:cHpOPup9H1g2T29dKHAjC2sc7/Ef5ypjuW9A3I+e9yY= +github.com/filecoin-project/go-state-types v0.14.0-rc5 h1:c8jo2mRx02u8smiCZsSDt1dsOGSu4gwfvHRqSKAl8Lc= +github.com/filecoin-project/go-state-types v0.14.0-rc5/go.mod h1:cHpOPup9H1g2T29dKHAjC2sc7/Ef5ypjuW9A3I+e9yY= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v1.0.3 h1:N07o6alys+V1tNoSTi4WuuoeNC4erS/6jE74+NsgQuk= github.com/filecoin-project/go-statemachine v1.0.3/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54= github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-statestore v0.2.0 h1:cRRO0aPLrxKQCZ2UOQbzFGn4WDNdofHZoGPjfNaAo5Q= github.com/filecoin-project/go-statestore v0.2.0/go.mod h1:8sjBYbS35HwPzct7iT4lIXjLlYyPor80aU7t7a/Kspo= -github.com/filecoin-project/kubo-api-client v0.27.0 h1:rQNbReJCCQ8L107VIQR0qjAlEqdDQRYOhDKYcKGcnPI= -github.com/filecoin-project/kubo-api-client v0.27.0/go.mod h1:1+geFlaV8oJRJ4IlVTqL3QC3T1f5N0aGSptErrtcMQs= -github.com/filecoin-project/lotus v1.26.1 h1:l5My+fCvoEawcpTd9xo5BMPvIafPfBNchLUTsiEn6qs= -github.com/filecoin-project/lotus v1.26.1/go.mod h1:uTwgtAKXUCi2p8JGz5ycHeMkb8tPAdhnoUce5vJFNj4= +github.com/filecoin-project/lotus v1.28.0-rc3 h1:Vgxz9WmAeOcQhFrXqtikSGvCVAMLwRm/sdEEjniGh54= +github.com/filecoin-project/lotus v1.28.0-rc3/go.mod h1:VnrjAa0NAciJNwhTwOklGXoIP4sRndS892uPe+eT/qk= github.com/filecoin-project/pubsub v1.0.0 h1:ZTmT27U07e54qV1mMiQo4HDr0buo8I1LDHBYLXlsNXM= github.com/filecoin-project/pubsub v1.0.0/go.mod h1:GkpB33CcUtUNrLPhJgfdy4FDx4OMNR9k+46DHx/Lqrg= github.com/filecoin-project/specs-actors v0.9.13/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= @@ -470,8 +473,9 @@ github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99 github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk= github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= +github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -516,6 +520,8 @@ github.com/icza/backscanner v0.0.0-20210726202459-ac2ffc679f94/go.mod h1:GYeBD1C github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6 h1:8UsGZ2rr2ksmEru6lToqnXgA8Mz1DP11X4zSJ159C3k= github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6/go.mod h1:xQig96I1VNBDIWGCdTt54nHt6EeI639SmHycLYL7FkA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= +github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/ipfs-force-community/metrics v1.0.1-0.20231207081445-30178e706d09 h1:qEI6ItxKtgOupMMuGJwqK5zEzztKKPUP1QKq9g+X5bM= github.com/ipfs-force-community/metrics v1.0.1-0.20231207081445-30178e706d09/go.mod h1:wM6EmkEcnJgWOFcVytgvK0u15awEmt8He0f2kAdsFDA= github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= @@ -581,8 +587,6 @@ github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtL github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-cmds v0.10.0 h1:ZB4+RgYaH4UARfJY0uLKl5UXgApqnRjKbuCiJVcErYk= -github.com/ipfs/go-ipfs-cmds v0.10.0/go.mod h1:sX5d7jkCft9XLPnkgEfXY0z2UBOB5g6fh/obBS0enJE= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -705,8 +709,9 @@ github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGAR github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= -github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg= -github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= +github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -734,6 +739,7 @@ github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ib github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -767,8 +773,8 @@ github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFG github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= -github.com/libp2p/go-libp2p v0.34.1 h1:fxn9vyLo7vJcXQRNvdRbyPjbzuQgi2UiqC8hEbn8a18= -github.com/libp2p/go-libp2p v0.34.1/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ= +github.com/libp2p/go-libp2p v0.35.0 h1:1xS1Bkr9X7GtdvV6ntLnDV9xB1kNjHK1lZ0eaO6gnhc= +github.com/libp2p/go-libp2p v0.35.0/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= @@ -837,6 +843,8 @@ github.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQ github.com/magefile/mage v1.13.0 h1:XtLJl8bcCM7EFoO8FyH8XK3t7G5hQAeK+i4tq+veT9M= github.com/magefile/mage v1.13.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= @@ -1077,15 +1085,11 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= -github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= -github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= -github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/sercand/kuberesolver/v4 v4.0.0 h1:frL7laPDG/lFm5n98ODmWnn+cvPpzlkf3LhzuPhcHP4= github.com/sercand/kuberesolver/v4 v4.0.0/go.mod h1:F4RGyuRmMAjeXHKL+w4P7AwUnPceEAPAhxUgXZjKgvM= github.com/shirou/gopsutil v2.18.12+incompatible h1:1eaJvGomDnH74/5cF4CTmTbLHAriGFsTZppLXDX93OM= @@ -1166,8 +1170,6 @@ github.com/weaveworks/common v0.0.0-20230531151736-e2613bee6b73 h1:CMM9+/AgM77va github.com/weaveworks/common v0.0.0-20230531151736-e2613bee6b73/go.mod h1:rgbeLfJUtEr+G74cwFPR1k/4N0kDeaeSv/qhUNE4hm8= github.com/weaveworks/promrus v1.2.0 h1:jOLf6pe6/vss4qGHjXmGz4oDJQA+AOCqEL3FvvZGz7M= github.com/weaveworks/promrus v1.2.0/go.mod h1:SaE82+OJ91yqjrE1rsvBWVzNZKcHYFtMUyS1+Ogs/KA= -github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= -github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba h1:X4n8JG2e2biEZZXdBKt9HX7DN3bYGFUqljqqy0DqgnY= github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba/go.mod h1:CHQnYnQUEPydYCwuy8lmTHfGmdw9TKrhWV0xLx8l0oM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= @@ -1186,6 +1188,7 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163/go.mod h1:f github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20210303213153-67a261a1d291/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20220323183124-98fa8256a799/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.1.0/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/cbor-gen v0.1.1 h1:eKfcJIoxivjMtwfCfmJAqSF56MHcWqyIScXwaC1VBgw= github.com/whyrusleeping/cbor-gen v0.1.1/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= @@ -1199,14 +1202,16 @@ github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xorcare/golden v0.6.0/go.mod h1:7T39/ZMvaSEZlBPoYfVFmsBLmUl3uz9IuzWj/U6FtvQ= github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542 h1:oWgZJmC1DorFZDpfMfWg7xk29yEOZiXmo/wZl+utTI8= github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542/go.mod h1:7T39/ZMvaSEZlBPoYfVFmsBLmUl3uz9IuzWj/U6FtvQ= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1310,6 +1315,7 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= @@ -1408,6 +1414,7 @@ golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= @@ -1545,6 +1552,7 @@ golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1556,6 +1564,7 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -1570,6 +1579,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= diff --git a/venus-devtool/inline-gen/inlinegen-data.json b/venus-devtool/inline-gen/inlinegen-data.json index bee30099fb..447e2df1f0 100644 --- a/venus-devtool/inline-gen/inlinegen-data.json +++ b/venus-devtool/inline-gen/inlinegen-data.json @@ -1,7 +1,7 @@ { - "actorVersions": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - "latestActorsVersion": 13, + "actorVersions": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], + "latestActorsVersion": 14, - "networkVersions": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22], - "latestNetworkVersion": 22 + "networkVersions": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], + "latestNetworkVersion": 23 } diff --git a/venus-devtool/state-type-gen/main.go b/venus-devtool/state-type-gen/main.go index f04f2d300c..79d9abbb2f 100644 --- a/venus-devtool/state-type-gen/main.go +++ b/venus-devtool/state-type-gen/main.go @@ -111,6 +111,14 @@ var stateTypesOpt = option{ {pkgName: "multisig", newName: "MultisigConstructorParams"}, {pkgName: "paych", newName: "PaychConstructorParams"}, }, + "BatchReturn": { + {pkgName: "miner", newName: "MinerBatchReturn"}, + {pkgName: "verifreg", newName: "VerifregBatchReturn"}, + }, + "FailCode": { + {pkgName: "miner", newName: "MinerFailCode"}, + {pkgName: "verifreg", newName: "VerifregFailCode"}, + }, }, } diff --git a/venus-shared/actors/builtin-actors-code/v14.tar.zst b/venus-shared/actors/builtin-actors-code/v14.tar.zst new file mode 100644 index 0000000000..5407fb5298 Binary files /dev/null and b/venus-shared/actors/builtin-actors-code/v14.tar.zst differ diff --git a/venus-shared/actors/builtin/account/actor.go b/venus-shared/actors/builtin/account/actor.go index 652d9deb41..37ebc2a6bf 100644 --- a/venus-shared/actors/builtin/account/actor.go +++ b/venus-shared/actors/builtin/account/actor.go @@ -30,10 +30,10 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" - builtin13 "github.com/filecoin-project/go-state-types/builtin" + builtin14 "github.com/filecoin-project/go-state-types/builtin" ) -var Methods = builtin13.MethodsAccount +var Methods = builtin14.MethodsAccount func Load(store adt.Store, act *types.Actor) (State, error) { if name, av, ok := actors.GetActorMetaByCode(act.Code); ok { @@ -61,6 +61,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -134,6 +137,9 @@ func MakeState(store adt.Store, av actorstypes.Version, addr address.Address) (S case actorstypes.Version13: return make13(store, addr) + case actorstypes.Version14: + return make14(store, addr) + } return nil, fmt.Errorf("unknown actor version %d", av) } @@ -164,5 +170,6 @@ func AllCodes() []cid.Cid { (&state11{}).Code(), (&state12{}).Code(), (&state13{}).Code(), + (&state14{}).Code(), } } diff --git a/venus-shared/actors/builtin/account/state.v14.go b/venus-shared/actors/builtin/account/state.v14.go new file mode 100644 index 0000000000..7dfc527196 --- /dev/null +++ b/venus-shared/actors/builtin/account/state.v14.go @@ -0,0 +1,65 @@ +// FETCHED FROM LOTUS: builtin/account/state.go.template + +package account + +import ( + "fmt" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + + "github.com/filecoin-project/go-address" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-state-types/manifest" + "github.com/filecoin-project/venus/venus-shared/actors" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + + account14 "github.com/filecoin-project/go-state-types/builtin/v14/account" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store, addr address.Address) (State, error) { + out := state14{store: store} + out.State = account14.State{Address: addr} + return &out, nil +} + +type state14 struct { + account14.State + store adt.Store +} + +func (s *state14) PubkeyAddress() (address.Address, error) { + return s.Address, nil +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +func (s *state14) ActorKey() string { + return manifest.AccountKey +} + +func (s *state14) ActorVersion() actorstypes.Version { + return actorstypes.Version14 +} + +func (s *state14) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/venus-shared/actors/builtin/cron/actor.go b/venus-shared/actors/builtin/cron/actor.go index 713c0b9290..e298204555 100644 --- a/venus-shared/actors/builtin/cron/actor.go +++ b/venus-shared/actors/builtin/cron/actor.go @@ -26,7 +26,7 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" - builtin13 "github.com/filecoin-project/go-state-types/builtin" + builtin14 "github.com/filecoin-project/go-state-types/builtin" ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -55,6 +55,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -128,13 +131,16 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) { case actorstypes.Version13: return make13(store) + case actorstypes.Version14: + return make14(store) + } return nil, fmt.Errorf("unknown actor version %d", av) } var ( - Address = builtin13.CronActorAddr - Methods = builtin13.MethodsCron + Address = builtin14.CronActorAddr + Methods = builtin14.MethodsCron ) type State interface { @@ -160,5 +166,6 @@ func AllCodes() []cid.Cid { (&state11{}).Code(), (&state12{}).Code(), (&state13{}).Code(), + (&state14{}).Code(), } } diff --git a/venus-shared/actors/builtin/cron/state.v14.go b/venus-shared/actors/builtin/cron/state.v14.go new file mode 100644 index 0000000000..8a9e1d37f5 --- /dev/null +++ b/venus-shared/actors/builtin/cron/state.v14.go @@ -0,0 +1,59 @@ +// FETCHED FROM LOTUS: builtin/cron/state.go.template + +package cron + +import ( + "fmt" + + "github.com/ipfs/go-cid" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/filecoin-project/go-state-types/manifest" + "github.com/filecoin-project/venus/venus-shared/actors" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + + cron14 "github.com/filecoin-project/go-state-types/builtin/v14/cron" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store) (State, error) { + out := state14{store: store} + out.State = *cron14.ConstructState(cron14.BuiltInEntries()) + return &out, nil +} + +type state14 struct { + cron14.State + store adt.Store +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +func (s *state14) ActorKey() string { + return manifest.CronKey +} + +func (s *state14) ActorVersion() actorstypes.Version { + return actorstypes.Version14 +} + +func (s *state14) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/venus-shared/actors/builtin/datacap/actor.go b/venus-shared/actors/builtin/datacap/actor.go index 083276a7d9..64e2f4a599 100644 --- a/venus-shared/actors/builtin/datacap/actor.go +++ b/venus-shared/actors/builtin/datacap/actor.go @@ -10,7 +10,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" - builtin13 "github.com/filecoin-project/go-state-types/builtin" + builtin14 "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/manifest" @@ -20,8 +20,8 @@ import ( ) var ( - Address = builtin13.DatacapActorAddr - Methods = builtin13.MethodsDatacap + Address = builtin14.DatacapActorAddr + Methods = builtin14.MethodsDatacap ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -47,6 +47,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -71,6 +74,9 @@ func MakeState(store adt.Store, av actorstypes.Version, governor address.Address case actorstypes.Version13: return make13(store, governor, bitwidth) + case actorstypes.Version14: + return make14(store, governor, bitwidth) + default: return nil, fmt.Errorf("datacap actor only valid for actors v9 and above, got %d", av) } @@ -96,5 +102,6 @@ func AllCodes() []cid.Cid { (&state11{}).Code(), (&state12{}).Code(), (&state13{}).Code(), + (&state14{}).Code(), } } diff --git a/venus-shared/actors/builtin/datacap/state.v14.go b/venus-shared/actors/builtin/datacap/state.v14.go new file mode 100644 index 0000000000..fb45ff334c --- /dev/null +++ b/venus-shared/actors/builtin/datacap/state.v14.go @@ -0,0 +1,84 @@ +// FETCHED FROM LOTUS: builtin/datacap/state.go.template + +package datacap + +import ( + "fmt" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/filecoin-project/venus/venus-shared/actors" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + + datacap14 "github.com/filecoin-project/go-state-types/builtin/v14/datacap" + adt14 "github.com/filecoin-project/go-state-types/builtin/v14/util/adt" + "github.com/filecoin-project/go-state-types/manifest" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store, governor address.Address, bitwidth uint64) (State, error) { + out := state14{store: store} + s, err := datacap14.ConstructState(store, governor, bitwidth) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state14 struct { + datacap14.State + store adt.Store +} + +func (s *state14) Governor() (address.Address, error) { + return s.State.Governor, nil +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +func (s *state14) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachClient(s.store, actors.Version14, s.verifiedClients, cb) +} + +func (s *state14) verifiedClients() (adt.Map, error) { + return adt14.AsMap(s.store, s.Token.Balances, int(s.Token.HamtBitWidth)) +} + +func (s *state14) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version14, s.verifiedClients, addr) +} + +func (s *state14) ActorKey() string { + return manifest.DatacapKey +} + +func (s *state14) ActorVersion() actorstypes.Version { + return actorstypes.Version14 +} + +func (s *state14) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/venus-shared/actors/builtin/evm/actor.go b/venus-shared/actors/builtin/evm/actor.go index 6875c09d38..56b45d03ba 100644 --- a/venus-shared/actors/builtin/evm/actor.go +++ b/venus-shared/actors/builtin/evm/actor.go @@ -17,10 +17,10 @@ import ( "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/go-state-types/manifest" - builtin13 "github.com/filecoin-project/go-state-types/builtin" + builtin14 "github.com/filecoin-project/go-state-types/builtin" ) -var Methods = builtin13.MethodsEVM +var Methods = builtin14.MethodsEVM // See https://github.com/filecoin-project/builtin-actors/blob/6e781444cee5965278c46ef4ffe1fb1970f18d7d/actors/evm/src/lib.rs#L35-L42 const ( @@ -54,6 +54,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -75,6 +78,9 @@ func MakeState(store adt.Store, av actorstypes.Version, bytecode cid.Cid) (State case actorstypes.Version13: return make13(store, bytecode) + case actorstypes.Version14: + return make14(store, bytecode) + default: return nil, fmt.Errorf("evm actor only valid for actors v10 and above, got %d", av) } diff --git a/venus-shared/actors/builtin/evm/state.v14.go b/venus-shared/actors/builtin/evm/state.v14.go new file mode 100644 index 0000000000..5a007b1090 --- /dev/null +++ b/venus-shared/actors/builtin/evm/state.v14.go @@ -0,0 +1,74 @@ +// FETCHED FROM LOTUS: builtin/evm/state.go.template + +package evm + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + + evm14 "github.com/filecoin-project/go-state-types/builtin/v14/evm" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store, bytecode cid.Cid) (State, error) { + out := state14{store: store} + s, err := evm14.ConstructState(store, bytecode) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state14 struct { + evm14.State + store adt.Store +} + +func (s *state14) Nonce() (uint64, error) { + return s.State.Nonce, nil +} + +func (s *state14) IsAlive() (bool, error) { + return s.State.Tombstone == nil, nil +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +func (s *state14) GetBytecodeCID() (cid.Cid, error) { + return s.State.Bytecode, nil +} + +func (s *state14) GetBytecodeHash() ([32]byte, error) { + return s.State.BytecodeHash, nil +} + +func (s *state14) GetBytecode() ([]byte, error) { + bc, err := s.GetBytecodeCID() + if err != nil { + return nil, err + } + + var byteCode abi.CborBytesTransparent + if err := s.store.Get(s.store.Context(), bc, &byteCode); err != nil { + return nil, err + } + + return byteCode, nil +} diff --git a/venus-shared/actors/builtin/init/actor.go b/venus-shared/actors/builtin/init/actor.go index 0b3ad58b0c..af665234e1 100644 --- a/venus-shared/actors/builtin/init/actor.go +++ b/venus-shared/actors/builtin/init/actor.go @@ -32,12 +32,12 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" - builtin13 "github.com/filecoin-project/go-state-types/builtin" + builtin14 "github.com/filecoin-project/go-state-types/builtin" ) var ( - Address = builtin13.InitActorAddr - Methods = builtin13.MethodsInit + Address = builtin14.InitActorAddr + Methods = builtin14.MethodsInit ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -66,6 +66,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -139,6 +142,9 @@ func MakeState(store adt.Store, av actorstypes.Version, networkName string) (Sta case actorstypes.Version13: return make13(store, networkName) + case actorstypes.Version14: + return make14(store, networkName) + } return nil, fmt.Errorf("unknown actor version %d", av) } @@ -192,5 +198,6 @@ func AllCodes() []cid.Cid { (&state11{}).Code(), (&state12{}).Code(), (&state13{}).Code(), + (&state14{}).Code(), } } diff --git a/venus-shared/actors/builtin/init/state.v14.go b/venus-shared/actors/builtin/init/state.v14.go new file mode 100644 index 0000000000..e5493b0256 --- /dev/null +++ b/venus-shared/actors/builtin/init/state.v14.go @@ -0,0 +1,148 @@ +// FETCHED FROM LOTUS: builtin/init/state.go.template + +package init + +import ( + "crypto/sha256" + "fmt" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/filecoin-project/venus/venus-shared/actors" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + + "github.com/filecoin-project/go-state-types/manifest" + + builtin14 "github.com/filecoin-project/go-state-types/builtin" + init14 "github.com/filecoin-project/go-state-types/builtin/v14/init" + adt14 "github.com/filecoin-project/go-state-types/builtin/v14/util/adt" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store, networkName string) (State, error) { + out := state14{store: store} + + s, err := init14.ConstructState(store, networkName) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state14 struct { + init14.State + store adt.Store +} + +func (s *state14) ResolveAddress(address address.Address) (address.Address, bool, error) { + return s.State.ResolveAddress(s.store, address) +} + +func (s *state14) MapAddressToNewID(address address.Address) (address.Address, error) { + return s.State.MapAddressToNewID(s.store, address) +} + +func (s *state14) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error { + addrs, err := adt14.AsMap(s.store, s.State.AddressMap, builtin14.DefaultHamtBitwidth) + if err != nil { + return err + } + var actorID cbg.CborInt + return addrs.ForEach(&actorID, func(key string) error { + addr, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(abi.ActorID(actorID), addr) + }) +} + +func (s *state14) NetworkName() (string, error) { + return string(s.State.NetworkName), nil +} + +func (s *state14) SetNetworkName(name string) error { + s.State.NetworkName = name + return nil +} + +func (s *state14) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + +func (s *state14) Remove(addrs ...address.Address) (err error) { + m, err := adt14.AsMap(s.store, s.State.AddressMap, builtin14.DefaultHamtBitwidth) + if err != nil { + return err + } + for _, addr := range addrs { + if err = m.Delete(abi.AddrKey(addr)); err != nil { + return fmt.Errorf("failed to delete entry for address: %s; err: %w", addr, err) + } + } + amr, err := m.Root() + if err != nil { + return fmt.Errorf("failed to get address map root: %w", err) + } + s.State.AddressMap = amr + return nil +} + +func (s *state14) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +func (s *state14) AddressMap() (adt.Map, error) { + return adt14.AsMap(s.store, s.State.AddressMap, builtin14.DefaultHamtBitwidth) +} + +func (s *state14) AddressMapBitWidth() int { + return builtin14.DefaultHamtBitwidth +} + +func (s *state14) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state14) ActorKey() string { + return manifest.InitKey +} + +func (s *state14) ActorVersion() actorstypes.Version { + return actorstypes.Version14 +} + +func (s *state14) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/venus-shared/actors/builtin/market/actor.go b/venus-shared/actors/builtin/market/actor.go index 4ff8571274..54a64b44a5 100644 --- a/venus-shared/actors/builtin/market/actor.go +++ b/venus-shared/actors/builtin/market/actor.go @@ -74,6 +74,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -147,6 +150,9 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) { case actorstypes.Version13: return make13(store) + case actorstypes.Version14: + return make14(store) + } return nil, fmt.Errorf("unknown actor version %d", av) } @@ -248,6 +254,9 @@ func DecodePublishStorageDealsReturn(b []byte, nv network.Version) (PublishStora case actorstypes.Version13: return decodePublishStorageDealsReturn13(b) + case actorstypes.Version14: + return decodePublishStorageDealsReturn14(b) + } return nil, fmt.Errorf("unknown actor version %d", av) } @@ -256,6 +265,7 @@ type DealProposal = markettypes.DealProposal type DealLabel = markettypes.DealLabel type DealState interface { + SectorNumber() abi.SectorNumber // 0 if not yet included in proven sector (0 is also a valid sector number) SectorStartEpoch() abi.ChainEpoch // -1 if not yet included in proven sector LastUpdatedEpoch() abi.ChainEpoch // -1 if deal state never updated SlashEpoch() abi.ChainEpoch // -1 if deal never slashed @@ -297,6 +307,10 @@ type ProposalIDState struct { type emptyDealState struct{} +func (e *emptyDealState) SectorNumber() abi.SectorNumber { + return 0 +} + func (e *emptyDealState) SectorStartEpoch() abi.ChainEpoch { return -1 } @@ -369,5 +383,6 @@ func AllCodes() []cid.Cid { (&state11{}).Code(), (&state12{}).Code(), (&state13{}).Code(), + (&state14{}).Code(), } } diff --git a/venus-shared/actors/builtin/market/actor.go.template b/venus-shared/actors/builtin/market/actor.go.template index b1073535f9..d2897eb668 100644 --- a/venus-shared/actors/builtin/market/actor.go.template +++ b/venus-shared/actors/builtin/market/actor.go.template @@ -145,6 +145,7 @@ type DealProposal = markettypes.DealProposal type DealLabel = markettypes.DealLabel type DealState interface { + SectorNumber() abi.SectorNumber // 0 if not yet included in proven sector (0 is also a valid sector number) SectorStartEpoch() abi.ChainEpoch // -1 if not yet included in proven sector LastUpdatedEpoch() abi.ChainEpoch // -1 if deal state never updated SlashEpoch() abi.ChainEpoch // -1 if deal never slashed @@ -187,6 +188,10 @@ type ProposalIDState struct { type emptyDealState struct{} +func (e *emptyDealState) SectorNumber() abi.SectorNumber { + return 0 +} + func (e *emptyDealState) SectorStartEpoch() abi.ChainEpoch { return -1 } diff --git a/venus-shared/actors/builtin/market/state.sep.go.template b/venus-shared/actors/builtin/market/state.sep.go.template index 98785b5de3..40ec98dd69 100644 --- a/venus-shared/actors/builtin/market/state.sep.go.template +++ b/venus-shared/actors/builtin/market/state.sep.go.template @@ -213,6 +213,14 @@ type dealStateV{{.v}} struct { ds{{.v}} market{{.v}}.DealState } +func (d dealStateV{{.v}}) SectorNumber() abi.SectorNumber { +{{if (le .v 12)}} + return 0 +{{else}} + return d.ds{{.v}}.SectorNumber +{{end}} +} + func (d dealStateV{{.v}}) SectorStartEpoch() abi.ChainEpoch { return d.ds{{.v}}.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v0.go b/venus-shared/actors/builtin/market/state.v0.go index f50e0c6bf8..d508b92b70 100644 --- a/venus-shared/actors/builtin/market/state.v0.go +++ b/venus-shared/actors/builtin/market/state.v0.go @@ -192,6 +192,12 @@ type dealStateV0 struct { ds0 market0.DealState } +func (d dealStateV0) SectorNumber() abi.SectorNumber { + + return 0 + +} + func (d dealStateV0) SectorStartEpoch() abi.ChainEpoch { return d.ds0.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v10.go b/venus-shared/actors/builtin/market/state.v10.go index 98b6e600b6..ce8903bbc1 100644 --- a/venus-shared/actors/builtin/market/state.v10.go +++ b/venus-shared/actors/builtin/market/state.v10.go @@ -193,6 +193,12 @@ type dealStateV10 struct { ds10 market10.DealState } +func (d dealStateV10) SectorNumber() abi.SectorNumber { + + return 0 + +} + func (d dealStateV10) SectorStartEpoch() abi.ChainEpoch { return d.ds10.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v11.go b/venus-shared/actors/builtin/market/state.v11.go index fbee2f346d..4b2d734447 100644 --- a/venus-shared/actors/builtin/market/state.v11.go +++ b/venus-shared/actors/builtin/market/state.v11.go @@ -193,6 +193,12 @@ type dealStateV11 struct { ds11 market11.DealState } +func (d dealStateV11) SectorNumber() abi.SectorNumber { + + return 0 + +} + func (d dealStateV11) SectorStartEpoch() abi.ChainEpoch { return d.ds11.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v12.go b/venus-shared/actors/builtin/market/state.v12.go index 0dcfa38699..0689b3d080 100644 --- a/venus-shared/actors/builtin/market/state.v12.go +++ b/venus-shared/actors/builtin/market/state.v12.go @@ -193,6 +193,12 @@ type dealStateV12 struct { ds12 market12.DealState } +func (d dealStateV12) SectorNumber() abi.SectorNumber { + + return 0 + +} + func (d dealStateV12) SectorStartEpoch() abi.ChainEpoch { return d.ds12.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v13.go b/venus-shared/actors/builtin/market/state.v13.go index c70b8f7eee..176553958e 100644 --- a/venus-shared/actors/builtin/market/state.v13.go +++ b/venus-shared/actors/builtin/market/state.v13.go @@ -193,6 +193,12 @@ type dealStateV13 struct { ds13 market13.DealState } +func (d dealStateV13) SectorNumber() abi.SectorNumber { + + return d.ds13.SectorNumber + +} + func (d dealStateV13) SectorStartEpoch() abi.ChainEpoch { return d.ds13.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v14.go b/venus-shared/actors/builtin/market/state.v14.go new file mode 100644 index 0000000000..bbb69dc56b --- /dev/null +++ b/venus-shared/actors/builtin/market/state.v14.go @@ -0,0 +1,413 @@ +// FETCHED FROM LOTUS: builtin/market/state.go.template + +package market + +import ( + "bytes" + "fmt" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + + "github.com/filecoin-project/go-bitfield" + rlepluslazy "github.com/filecoin-project/go-bitfield/rle" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/filecoin-project/go-state-types/manifest" + "github.com/filecoin-project/venus/venus-shared/actors" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + verifregtypes "github.com/filecoin-project/venus/venus-shared/actors/builtin/verifreg" + "github.com/filecoin-project/venus/venus-shared/actors/types" + + market14 "github.com/filecoin-project/go-state-types/builtin/v14/market" + adt14 "github.com/filecoin-project/go-state-types/builtin/v14/util/adt" + markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market" + + "github.com/filecoin-project/go-state-types/builtin" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store) (State, error) { + out := state14{store: store} + + s, err := market14.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state14 struct { + market14.State + store adt.Store +} + +func (s *state14) TotalLocked() (abi.TokenAmount, error) { + fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral) + fml = types.BigAdd(fml, s.TotalClientStorageFee) + return fml, nil +} + +func (s *state14) BalancesChanged(otherState State) (bool, error) { + otherState14, ok := otherState.(*state14) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.EscrowTable.Equals(otherState14.State.EscrowTable) || !s.State.LockedTable.Equals(otherState14.State.LockedTable), nil +} + +func (s *state14) StatesChanged(otherState State) (bool, error) { + otherState14, ok := otherState.(*state14) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.States.Equals(otherState14.State.States), nil +} + +func (s *state14) States() (DealStates, error) { + stateArray, err := adt14.AsArray(s.store, s.State.States, market14.StatesAmtBitwidth) + if err != nil { + return nil, err + } + return &dealStates14{stateArray}, nil +} + +func (s *state14) ProposalsChanged(otherState State) (bool, error) { + otherState14, ok := otherState.(*state14) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.Proposals.Equals(otherState14.State.Proposals), nil +} + +func (s *state14) Proposals() (DealProposals, error) { + proposalArray, err := adt14.AsArray(s.store, s.State.Proposals, market14.ProposalsAmtBitwidth) + if err != nil { + return nil, err + } + return &dealProposals14{proposalArray}, nil +} + +func (s *state14) EscrowTable() (BalanceTable, error) { + bt, err := adt14.AsBalanceTable(s.store, s.State.EscrowTable) + if err != nil { + return nil, err + } + return &balanceTable14{bt}, nil +} + +func (s *state14) LockedTable() (BalanceTable, error) { + bt, err := adt14.AsBalanceTable(s.store, s.State.LockedTable) + if err != nil { + return nil, err + } + return &balanceTable14{bt}, nil +} + +func (s *state14) VerifyDealsForActivation( + minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, +) (weight, verifiedWeight abi.DealWeight, err error) { + w, vw, _, err := market14.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) + return w, vw, err +} + +func (s *state14) NextID() (abi.DealID, error) { + return s.State.NextID, nil +} + +type balanceTable14 struct { + *adt14.BalanceTable +} + +func (bt *balanceTable14) ForEach(cb func(address.Address, abi.TokenAmount) error) error { + asMap := (*adt14.Map)(bt.BalanceTable) + var ta abi.TokenAmount + return asMap.ForEach(&ta, func(key string) error { + a, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(a, ta) + }) +} + +type dealStates14 struct { + adt.Array +} + +func (s *dealStates14) Get(dealID abi.DealID) (DealState, bool, error) { + var deal14 market14.DealState + found, err := s.Array.Get(uint64(dealID), &deal14) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + deal := fromV14DealState(deal14) + return deal, true, nil +} + +func (s *dealStates14) ForEach(cb func(dealID abi.DealID, ds DealState) error) error { + var ds14 market14.DealState + return s.Array.ForEach(&ds14, func(idx int64) error { + return cb(abi.DealID(idx), fromV14DealState(ds14)) + }) +} + +func (s *dealStates14) decode(val *cbg.Deferred) (DealState, error) { + var ds14 market14.DealState + if err := ds14.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + ds := fromV14DealState(ds14) + return ds, nil +} + +func (s *dealStates14) array() adt.Array { + return s.Array +} + +type dealStateV14 struct { + ds14 market14.DealState +} + +func (d dealStateV14) SectorNumber() abi.SectorNumber { + + return d.ds14.SectorNumber + +} + +func (d dealStateV14) SectorStartEpoch() abi.ChainEpoch { + return d.ds14.SectorStartEpoch +} + +func (d dealStateV14) LastUpdatedEpoch() abi.ChainEpoch { + return d.ds14.LastUpdatedEpoch +} + +func (d dealStateV14) SlashEpoch() abi.ChainEpoch { + return d.ds14.SlashEpoch +} + +func (d dealStateV14) Equals(other DealState) bool { + if ov14, ok := other.(dealStateV14); ok { + return d.ds14 == ov14.ds14 + } + + if d.SectorStartEpoch() != other.SectorStartEpoch() { + return false + } + if d.LastUpdatedEpoch() != other.LastUpdatedEpoch() { + return false + } + if d.SlashEpoch() != other.SlashEpoch() { + return false + } + + return true +} + +var _ DealState = (*dealStateV14)(nil) + +func fromV14DealState(v14 market14.DealState) DealState { + return dealStateV14{v14} +} + +type dealProposals14 struct { + adt.Array +} + +func (s *dealProposals14) Get(dealID abi.DealID) (*DealProposal, bool, error) { + var proposal14 market14.DealProposal + found, err := s.Array.Get(uint64(dealID), &proposal14) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + + proposal, err := fromV14DealProposal(proposal14) + if err != nil { + return nil, true, fmt.Errorf("decoding proposal: %w", err) + } + + return &proposal, true, nil +} + +func (s *dealProposals14) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { + var dp14 market14.DealProposal + return s.Array.ForEach(&dp14, func(idx int64) error { + dp, err := fromV14DealProposal(dp14) + if err != nil { + return fmt.Errorf("decoding proposal: %w", err) + } + + return cb(abi.DealID(idx), dp) + }) +} + +func (s *dealProposals14) decode(val *cbg.Deferred) (*DealProposal, error) { + var dp14 market14.DealProposal + if err := dp14.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + + dp, err := fromV14DealProposal(dp14) + if err != nil { + return nil, err + } + + return &dp, nil +} + +func (s *dealProposals14) array() adt.Array { + return s.Array +} + +func fromV14DealProposal(v14 market14.DealProposal) (DealProposal, error) { + + label, err := fromV14Label(v14.Label) + + if err != nil { + return DealProposal{}, fmt.Errorf("error setting deal label: %w", err) + } + + return DealProposal{ + PieceCID: v14.PieceCID, + PieceSize: v14.PieceSize, + VerifiedDeal: v14.VerifiedDeal, + Client: v14.Client, + Provider: v14.Provider, + + Label: label, + + StartEpoch: v14.StartEpoch, + EndEpoch: v14.EndEpoch, + StoragePricePerEpoch: v14.StoragePricePerEpoch, + + ProviderCollateral: v14.ProviderCollateral, + ClientCollateral: v14.ClientCollateral, + }, nil +} + +func fromV14Label(v14 market14.DealLabel) (DealLabel, error) { + if v14.IsString() { + str, err := v14.ToString() + if err != nil { + return markettypes.EmptyDealLabel, fmt.Errorf("failed to convert string label to string: %w", err) + } + return markettypes.NewLabelFromString(str) + } + + bs, err := v14.ToBytes() + if err != nil { + return markettypes.EmptyDealLabel, fmt.Errorf("failed to convert bytes label to bytes: %w", err) + } + return markettypes.NewLabelFromBytes(bs) +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +var _ PublishStorageDealsReturn = (*publishStorageDealsReturn14)(nil) + +func decodePublishStorageDealsReturn14(b []byte) (PublishStorageDealsReturn, error) { + var retval market14.PublishStorageDealsReturn + if err := retval.UnmarshalCBOR(bytes.NewReader(b)); err != nil { + return nil, fmt.Errorf("failed to unmarshal PublishStorageDealsReturn: %w", err) + } + + return &publishStorageDealsReturn14{retval}, nil +} + +type publishStorageDealsReturn14 struct { + market14.PublishStorageDealsReturn +} + +func (r *publishStorageDealsReturn14) IsDealValid(index uint64) (bool, int, error) { + + set, err := r.ValidDeals.IsSet(index) + if err != nil || !set { + return false, -1, err + } + maskBf, err := bitfield.NewFromIter(&rlepluslazy.RunSliceIterator{ + Runs: []rlepluslazy.Run{rlepluslazy.Run{Val: true, Len: index}}}) + if err != nil { + return false, -1, err + } + before, err := bitfield.IntersectBitField(maskBf, r.ValidDeals) + if err != nil { + return false, -1, err + } + outIdx, err := before.Count() + if err != nil { + return false, -1, err + } + return set, int(outIdx), nil + +} + +func (r *publishStorageDealsReturn14) DealIDs() ([]abi.DealID, error) { + return r.IDs, nil +} + +func (s *state14) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtypes.AllocationId, error) { + + allocations, err := adt14.AsMap(s.store, s.PendingDealAllocationIds, builtin.DefaultHamtBitwidth) + if err != nil { + return verifregtypes.NoAllocationID, fmt.Errorf("failed to load allocation id for %d: %w", dealId, err) + } + + var allocationId cbg.CborInt + found, err := allocations.Get(abi.UIntKey(uint64(dealId)), &allocationId) + if err != nil { + return verifregtypes.NoAllocationID, fmt.Errorf("failed to load allocation id for %d: %w", dealId, err) + } + if !found { + return verifregtypes.NoAllocationID, nil + } + + return verifregtypes.AllocationId(allocationId), nil + +} + +func (s *state14) ActorKey() string { + return manifest.MarketKey +} + +func (s *state14) ActorVersion() actorstypes.Version { + return actorstypes.Version14 +} + +func (s *state14) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/venus-shared/actors/builtin/market/state.v2.go b/venus-shared/actors/builtin/market/state.v2.go index 8663f746c4..6a76643767 100644 --- a/venus-shared/actors/builtin/market/state.v2.go +++ b/venus-shared/actors/builtin/market/state.v2.go @@ -192,6 +192,12 @@ type dealStateV2 struct { ds2 market2.DealState } +func (d dealStateV2) SectorNumber() abi.SectorNumber { + + return 0 + +} + func (d dealStateV2) SectorStartEpoch() abi.ChainEpoch { return d.ds2.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v3.go b/venus-shared/actors/builtin/market/state.v3.go index 8252adf7f6..54f0d0b3c0 100644 --- a/venus-shared/actors/builtin/market/state.v3.go +++ b/venus-shared/actors/builtin/market/state.v3.go @@ -187,6 +187,12 @@ type dealStateV3 struct { ds3 market3.DealState } +func (d dealStateV3) SectorNumber() abi.SectorNumber { + + return 0 + +} + func (d dealStateV3) SectorStartEpoch() abi.ChainEpoch { return d.ds3.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v4.go b/venus-shared/actors/builtin/market/state.v4.go index afb08f75e8..64287434b2 100644 --- a/venus-shared/actors/builtin/market/state.v4.go +++ b/venus-shared/actors/builtin/market/state.v4.go @@ -187,6 +187,12 @@ type dealStateV4 struct { ds4 market4.DealState } +func (d dealStateV4) SectorNumber() abi.SectorNumber { + + return 0 + +} + func (d dealStateV4) SectorStartEpoch() abi.ChainEpoch { return d.ds4.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v5.go b/venus-shared/actors/builtin/market/state.v5.go index ce9bb3374f..4d1e00fda3 100644 --- a/venus-shared/actors/builtin/market/state.v5.go +++ b/venus-shared/actors/builtin/market/state.v5.go @@ -187,6 +187,12 @@ type dealStateV5 struct { ds5 market5.DealState } +func (d dealStateV5) SectorNumber() abi.SectorNumber { + + return 0 + +} + func (d dealStateV5) SectorStartEpoch() abi.ChainEpoch { return d.ds5.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v6.go b/venus-shared/actors/builtin/market/state.v6.go index ae54986408..4812c1375f 100644 --- a/venus-shared/actors/builtin/market/state.v6.go +++ b/venus-shared/actors/builtin/market/state.v6.go @@ -190,6 +190,12 @@ type dealStateV6 struct { ds6 market6.DealState } +func (d dealStateV6) SectorNumber() abi.SectorNumber { + + return 0 + +} + func (d dealStateV6) SectorStartEpoch() abi.ChainEpoch { return d.ds6.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v7.go b/venus-shared/actors/builtin/market/state.v7.go index 749237b3ac..a0233eac79 100644 --- a/venus-shared/actors/builtin/market/state.v7.go +++ b/venus-shared/actors/builtin/market/state.v7.go @@ -190,6 +190,12 @@ type dealStateV7 struct { ds7 market7.DealState } +func (d dealStateV7) SectorNumber() abi.SectorNumber { + + return 0 + +} + func (d dealStateV7) SectorStartEpoch() abi.ChainEpoch { return d.ds7.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v8.go b/venus-shared/actors/builtin/market/state.v8.go index 78f9942c76..cbf7db90bb 100644 --- a/venus-shared/actors/builtin/market/state.v8.go +++ b/venus-shared/actors/builtin/market/state.v8.go @@ -191,6 +191,12 @@ type dealStateV8 struct { ds8 market8.DealState } +func (d dealStateV8) SectorNumber() abi.SectorNumber { + + return 0 + +} + func (d dealStateV8) SectorStartEpoch() abi.ChainEpoch { return d.ds8.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/market/state.v9.go b/venus-shared/actors/builtin/market/state.v9.go index f45e5d0df0..9ff0aa2726 100644 --- a/venus-shared/actors/builtin/market/state.v9.go +++ b/venus-shared/actors/builtin/market/state.v9.go @@ -193,6 +193,12 @@ type dealStateV9 struct { ds9 market9.DealState } +func (d dealStateV9) SectorNumber() abi.SectorNumber { + + return 0 + +} + func (d dealStateV9) SectorStartEpoch() abi.ChainEpoch { return d.ds9.SectorStartEpoch } diff --git a/venus-shared/actors/builtin/miner/actor.go b/venus-shared/actors/builtin/miner/actor.go index 21ada6398e..9bd6ce5ccb 100644 --- a/venus-shared/actors/builtin/miner/actor.go +++ b/venus-shared/actors/builtin/miner/actor.go @@ -65,6 +65,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -138,6 +141,9 @@ func MakeState(store adt.Store, av actors.Version) (State, error) { case actors.Version13: return make13(store) + case actors.Version14: + return make14(store) + } return nil, fmt.Errorf("unknown actor version %d", av) } @@ -229,7 +235,7 @@ type Partition interface { UnprovenSectors() (bitfield.BitField, error) } -type SectorOnChainInfo = minertypes.SectorOnChainInfo +type SectorOnChainInfo = minertypes13.SectorOnChainInfo func PreferredSealProofTypeFromWindowPoStType(nver network.Version, proof abi.RegisteredPoStProof, configWantSynthetic bool) (abi.RegisteredSealProof, error) { // We added support for the new proofs in network version 7, and removed support for the old @@ -332,6 +338,7 @@ type ProveCommitSectors3Params = minertypes13.ProveCommitSectors3Params type SectorActivationManifest = minertypes13.SectorActivationManifest type ProveReplicaUpdates3Params = minertypes13.ProveReplicaUpdates3Params type SectorUpdateManifest = minertypes13.SectorUpdateManifest +type SectorOnChainInfoFlags = minertypes13.SectorOnChainInfoFlags var QAPowerMax = minertypes.QAPowerMax @@ -400,5 +407,6 @@ func AllCodes() []cid.Cid { (&state11{}).Code(), (&state12{}).Code(), (&state13{}).Code(), + (&state14{}).Code(), } } diff --git a/venus-shared/actors/builtin/miner/actor.go.template b/venus-shared/actors/builtin/miner/actor.go.template index d59cfd9bd2..e0e924473a 100644 --- a/venus-shared/actors/builtin/miner/actor.go.template +++ b/venus-shared/actors/builtin/miner/actor.go.template @@ -155,7 +155,7 @@ type Partition interface { UnprovenSectors() (bitfield.BitField, error) } -type SectorOnChainInfo = minertypes.SectorOnChainInfo +type SectorOnChainInfo = minertypes13.SectorOnChainInfo func PreferredSealProofTypeFromWindowPoStType(nver network.Version, proof abi.RegisteredPoStProof, configWantSynthetic bool) (abi.RegisteredSealProof, error) { // We added support for the new proofs in network version 7, and removed support for the old @@ -258,6 +258,7 @@ type ProveCommitSectors3Params = minertypes13.ProveCommitSectors3Params type SectorActivationManifest = minertypes13.SectorActivationManifest type ProveReplicaUpdates3Params = minertypes13.ProveReplicaUpdates3Params type SectorUpdateManifest = minertypes13.SectorUpdateManifest +type SectorOnChainInfoFlags = minertypes13.SectorOnChainInfoFlags var QAPowerMax = minertypes.QAPowerMax diff --git a/venus-shared/actors/builtin/miner/state.sep.go.template b/venus-shared/actors/builtin/miner/state.sep.go.template index 5a57d98a22..ecaa729e65 100644 --- a/venus-shared/actors/builtin/miner/state.sep.go.template +++ b/venus-shared/actors/builtin/miner/state.sep.go.template @@ -584,7 +584,12 @@ func fromV{{.v}}SectorOnChainInfo(v{{.v}} miner{{.v}}.SectorOnChainInfo) SectorO ExpectedStoragePledge: v{{.v}}.ExpectedStoragePledge, {{if (ge .v 7)}} SectorKeyCID: v{{.v}}.SectorKeyCID, - {{end}} + {{end}} + {{if (ge .v 12)}} + PowerBaseEpoch: v{{.v}}.PowerBaseEpoch, + ReplacedDayReward: v{{.v}}.ReplacedDayReward, + Flags: SectorOnChainInfoFlags(v{{.v}}.Flags), + {{end}} } return info } diff --git a/venus-shared/actors/builtin/miner/state.v12.go b/venus-shared/actors/builtin/miner/state.v12.go index 0042965c92..91f6dc4ca1 100644 --- a/venus-shared/actors/builtin/miner/state.v12.go +++ b/venus-shared/actors/builtin/miner/state.v12.go @@ -546,6 +546,10 @@ func fromV12SectorOnChainInfo(v12 miner12.SectorOnChainInfo) SectorOnChainInfo { ExpectedStoragePledge: v12.ExpectedStoragePledge, SectorKeyCID: v12.SectorKeyCID, + + PowerBaseEpoch: v12.PowerBaseEpoch, + ReplacedDayReward: v12.ReplacedDayReward, + Flags: SectorOnChainInfoFlags(v12.Flags), } return info } diff --git a/venus-shared/actors/builtin/miner/state.v13.go b/venus-shared/actors/builtin/miner/state.v13.go index debce530c1..bc70cd0f87 100644 --- a/venus-shared/actors/builtin/miner/state.v13.go +++ b/venus-shared/actors/builtin/miner/state.v13.go @@ -546,6 +546,10 @@ func fromV13SectorOnChainInfo(v13 miner13.SectorOnChainInfo) SectorOnChainInfo { ExpectedStoragePledge: v13.ExpectedStoragePledge, SectorKeyCID: v13.SectorKeyCID, + + PowerBaseEpoch: v13.PowerBaseEpoch, + ReplacedDayReward: v13.ReplacedDayReward, + Flags: SectorOnChainInfoFlags(v13.Flags), } return info } diff --git a/venus-shared/actors/builtin/miner/state.v14.go b/venus-shared/actors/builtin/miner/state.v14.go new file mode 100644 index 0000000000..8811cec3cc --- /dev/null +++ b/venus-shared/actors/builtin/miner/state.v14.go @@ -0,0 +1,596 @@ +// FETCHED FROM LOTUS: builtin/miner/state.go.template + +package miner + +import ( + "bytes" + "errors" + "fmt" + + "github.com/filecoin-project/go-bitfield" + rle "github.com/filecoin-project/go-bitfield/rle" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/dline" + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/filecoin-project/go-state-types/manifest" + "github.com/filecoin-project/venus/venus-shared/actors" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + + builtin14 "github.com/filecoin-project/go-state-types/builtin" + miner14 "github.com/filecoin-project/go-state-types/builtin/v14/miner" + adt14 "github.com/filecoin-project/go-state-types/builtin/v14/util/adt" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store) (State, error) { + out := state14{store: store} + out.State = miner14.State{} + return &out, nil +} + +type state14 struct { + miner14.State + store adt.Store +} + +type deadline14 struct { + miner14.Deadline + store adt.Store +} + +type partition14 struct { + miner14.Partition + store adt.Store +} + +func (s *state14) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("failed to get available balance: %v", r) + available = abi.NewTokenAmount(0) + } + }() + // this panics if the miner doesn't have enough funds to cover their locked pledge + available, err = s.GetAvailableBalance(bal) + return available, err +} + +func (s *state14) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) { + return s.CheckVestedFunds(s.store, epoch) +} + +func (s *state14) LockedFunds() (LockedFunds, error) { + return LockedFunds{ + VestingFunds: s.State.LockedFunds, + InitialPledgeRequirement: s.State.InitialPledge, + PreCommitDeposits: s.State.PreCommitDeposits, + }, nil +} + +func (s *state14) FeeDebt() (abi.TokenAmount, error) { + return s.State.FeeDebt, nil +} + +func (s *state14) InitialPledge() (abi.TokenAmount, error) { + return s.State.InitialPledge, nil +} + +func (s *state14) PreCommitDeposits() (abi.TokenAmount, error) { + return s.State.PreCommitDeposits, nil +} + +// Returns nil, nil if sector is not found +func (s *state14) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) { + info, ok, err := s.State.GetSector(s.store, num) + if !ok || err != nil { + return nil, err + } + + ret := fromV14SectorOnChainInfo(*info) + return &ret, nil +} + +func (s *state14) FindSector(num abi.SectorNumber) (*SectorLocation, error) { + dlIdx, partIdx, err := s.State.FindSector(s.store, num) + if err != nil { + return nil, err + } + return &SectorLocation{ + Deadline: dlIdx, + Partition: partIdx, + }, nil +} + +func (s *state14) NumLiveSectors() (uint64, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return 0, err + } + var total uint64 + if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner14.Deadline) error { + total += dl.LiveSectors + return nil + }); err != nil { + return 0, err + } + return total, nil +} + +// GetSectorExpiration returns the effective expiration of the given sector. +// +// If the sector does not expire early, the Early expiration field is 0. +func (s *state14) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return nil, err + } + // NOTE: this can be optimized significantly. + // 1. If the sector is non-faulty, it will expire on-time (can be + // learned from the sector info). + // 2. If it's faulty, it will expire early within the first 42 entries + // of the expiration queue. + + stopErr := errors.New("stop") + out := SectorExpiration{} + err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner14.Deadline) error { + partitions, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + quant := s.State.QuantSpecForDeadline(dlIdx) + var part miner14.Partition + return partitions.ForEach(&part, func(partIdx int64) error { + if found, err := part.Sectors.IsSet(uint64(num)); err != nil { + return err + } else if !found { + return nil + } + if found, err := part.Terminated.IsSet(uint64(num)); err != nil { + return err + } else if found { + // already terminated + return stopErr + } + + q, err := miner14.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant, miner14.PartitionExpirationAmtBitwidth) + if err != nil { + return err + } + var exp miner14.ExpirationSet + return q.ForEach(&exp, func(epoch int64) error { + if early, err := exp.EarlySectors.IsSet(uint64(num)); err != nil { + return err + } else if early { + out.Early = abi.ChainEpoch(epoch) + return nil + } + if onTime, err := exp.OnTimeSectors.IsSet(uint64(num)); err != nil { + return err + } else if onTime { + out.OnTime = abi.ChainEpoch(epoch) + return stopErr + } + return nil + }) + }) + }) + if err == stopErr { + err = nil + } + if err != nil { + return nil, err + } + if out.Early == 0 && out.OnTime == 0 { + return nil, fmt.Errorf("failed to find sector %d", num) + } + return &out, nil +} + +func (s *state14) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) { + info, ok, err := s.State.GetPrecommittedSector(s.store, num) + if !ok || err != nil { + return nil, err + } + + ret := fromV14SectorPreCommitOnChainInfo(*info) + + return &ret, nil +} + +func (s *state14) ForEachPrecommittedSector(cb func(SectorPreCommitOnChainInfo) error) error { + precommitted, err := adt14.AsMap(s.store, s.State.PreCommittedSectors, builtin14.DefaultHamtBitwidth) + if err != nil { + return err + } + + var info miner14.SectorPreCommitOnChainInfo + if err := precommitted.ForEach(&info, func(_ string) error { + return cb(fromV14SectorPreCommitOnChainInfo(info)) + }); err != nil { + return err + } + + return nil +} + +func (s *state14) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) { + sectors, err := miner14.LoadSectors(s.store, s.State.Sectors) + if err != nil { + return nil, err + } + + // If no sector numbers are specified, load all. + if snos == nil { + infos := make([]*SectorOnChainInfo, 0, sectors.Length()) + var info14 miner14.SectorOnChainInfo + if err := sectors.ForEach(&info14, func(_ int64) error { + info := fromV14SectorOnChainInfo(info14) + infos = append(infos, &info) + return nil + }); err != nil { + return nil, err + } + return infos, nil + } + + // Otherwise, load selected. + infos14, err := sectors.Load(*snos) + if err != nil { + return nil, err + } + infos := make([]*SectorOnChainInfo, len(infos14)) + for i, info14 := range infos14 { + info := fromV14SectorOnChainInfo(*info14) + infos[i] = &info + } + return infos, nil +} + +func (s *state14) loadAllocatedSectorNumbers() (bitfield.BitField, error) { + var allocatedSectors bitfield.BitField + err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors) + return allocatedSectors, err +} + +func (s *state14) IsAllocated(num abi.SectorNumber) (bool, error) { + allocatedSectors, err := s.loadAllocatedSectorNumbers() + if err != nil { + return false, err + } + + return allocatedSectors.IsSet(uint64(num)) +} + +func (s *state14) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + +func (s *state14) UnallocatedSectorNumbers(count int) ([]abi.SectorNumber, error) { + allocatedSectors, err := s.loadAllocatedSectorNumbers() + if err != nil { + return nil, err + } + + allocatedRuns, err := allocatedSectors.RunIterator() + if err != nil { + return nil, err + } + + unallocatedRuns, err := rle.Subtract( + &rle.RunSliceIterator{Runs: []rle.Run{{Val: true, Len: abi.MaxSectorNumber}}}, + allocatedRuns, + ) + if err != nil { + return nil, err + } + + iter, err := rle.BitsFromRuns(unallocatedRuns) + if err != nil { + return nil, err + } + + sectors := make([]abi.SectorNumber, 0, count) + for iter.HasNext() && len(sectors) < count { + nextNo, err := iter.Next() + if err != nil { + return nil, err + } + sectors = append(sectors, abi.SectorNumber(nextNo)) + } + + return sectors, nil +} + +func (s *state14) GetAllocatedSectors() (*bitfield.BitField, error) { + var allocatedSectors bitfield.BitField + if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil { + return nil, err + } + + return &allocatedSectors, nil +} + +func (s *state14) LoadDeadline(idx uint64) (Deadline, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return nil, err + } + dl, err := dls.LoadDeadline(s.store, idx) + if err != nil { + return nil, err + } + return &deadline14{*dl, s.store}, nil +} + +func (s *state14) ForEachDeadline(cb func(uint64, Deadline) error) error { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + return dls.ForEach(s.store, func(i uint64, dl *miner14.Deadline) error { + return cb(i, &deadline14{*dl, s.store}) + }) +} + +func (s *state14) NumDeadlines() (uint64, error) { + return miner14.WPoStPeriodDeadlines, nil +} + +func (s *state14) DeadlinesChanged(other State) (bool, error) { + other14, ok := other.(*state14) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + + return !s.State.Deadlines.Equals(other14.Deadlines), nil +} + +func (s *state14) MinerInfoChanged(other State) (bool, error) { + other0, ok := other.(*state14) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.Info.Equals(other0.State.Info), nil +} + +func (s *state14) Info() (MinerInfo, error) { + info, err := s.State.GetInfo(s.store) + if err != nil { + return MinerInfo{}, err + } + + mi := MinerInfo{ + Owner: info.Owner, + Worker: info.Worker, + ControlAddresses: info.ControlAddresses, + + PendingWorkerKey: (*WorkerKeyChange)(info.PendingWorkerKey), + + PeerId: info.PeerId, + Multiaddrs: info.Multiaddrs, + WindowPoStProofType: info.WindowPoStProofType, + SectorSize: info.SectorSize, + WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, + ConsensusFaultElapsed: info.ConsensusFaultElapsed, + + Beneficiary: info.Beneficiary, + BeneficiaryTerm: BeneficiaryTerm(info.BeneficiaryTerm), + PendingBeneficiaryTerm: (*PendingBeneficiaryChange)(info.PendingBeneficiaryTerm), + } + + return mi, nil +} + +func (s *state14) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) { + return s.State.RecordedDeadlineInfo(epoch), nil +} + +func (s *state14) DeadlineCronActive() (bool, error) { + return s.State.DeadlineCronActive, nil +} + +func (s *state14) sectors() (adt.Array, error) { + return adt14.AsArray(s.store, s.Sectors, miner14.SectorsAmtBitwidth) +} + +func (s *state14) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) { + var si miner14.SectorOnChainInfo + err := si.UnmarshalCBOR(bytes.NewReader(val.Raw)) + if err != nil { + return SectorOnChainInfo{}, err + } + + return fromV14SectorOnChainInfo(si), nil +} + +func (s *state14) precommits() (adt.Map, error) { + return adt14.AsMap(s.store, s.PreCommittedSectors, builtin14.DefaultHamtBitwidth) +} + +func (s *state14) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) { + var sp miner14.SectorPreCommitOnChainInfo + err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw)) + if err != nil { + return SectorPreCommitOnChainInfo{}, err + } + + return fromV14SectorPreCommitOnChainInfo(sp), nil +} + +func (s *state14) EraseAllUnproven() error { + + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + + err = dls.ForEach(s.store, func(dindx uint64, dl *miner14.Deadline) error { + ps, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + + var part miner14.Partition + err = ps.ForEach(&part, func(pindx int64) error { + _ = part.ActivateUnproven() + err = ps.Set(uint64(pindx), &part) + return nil + }) + + if err != nil { + return err + } + + dl.Partitions, err = ps.Root() + if err != nil { + return err + } + + return dls.UpdateDeadline(s.store, dindx, dl) + }) + if err != nil { + return err + } + + return s.State.SaveDeadlines(s.store, dls) + +} + +func (d *deadline14) LoadPartition(idx uint64) (Partition, error) { + p, err := d.Deadline.LoadPartition(d.store, idx) + if err != nil { + return nil, err + } + return &partition14{*p, d.store}, nil +} + +func (d *deadline14) ForEachPartition(cb func(uint64, Partition) error) error { + ps, err := d.Deadline.PartitionsArray(d.store) + if err != nil { + return err + } + var part miner14.Partition + return ps.ForEach(&part, func(i int64) error { + return cb(uint64(i), &partition14{part, d.store}) + }) +} + +func (d *deadline14) PartitionsChanged(other Deadline) (bool, error) { + other14, ok := other.(*deadline14) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + + return !d.Deadline.Partitions.Equals(other14.Deadline.Partitions), nil +} + +func (d *deadline14) PartitionsPoSted() (bitfield.BitField, error) { + return d.Deadline.PartitionsPoSted, nil +} + +func (d *deadline14) DisputableProofCount() (uint64, error) { + + ops, err := d.OptimisticProofsSnapshotArray(d.store) + if err != nil { + return 0, err + } + + return ops.Length(), nil + +} + +func (p *partition14) AllSectors() (bitfield.BitField, error) { + return p.Partition.Sectors, nil +} + +func (p *partition14) FaultySectors() (bitfield.BitField, error) { + return p.Partition.Faults, nil +} + +func (p *partition14) RecoveringSectors() (bitfield.BitField, error) { + return p.Partition.Recoveries, nil +} + +func (p *partition14) UnprovenSectors() (bitfield.BitField, error) { + return p.Partition.Unproven, nil +} + +func fromV14SectorOnChainInfo(v14 miner14.SectorOnChainInfo) SectorOnChainInfo { + info := SectorOnChainInfo{ + SectorNumber: v14.SectorNumber, + SealProof: v14.SealProof, + SealedCID: v14.SealedCID, + DealIDs: v14.DealIDs, + Activation: v14.Activation, + Expiration: v14.Expiration, + DealWeight: v14.DealWeight, + VerifiedDealWeight: v14.VerifiedDealWeight, + InitialPledge: v14.InitialPledge, + ExpectedDayReward: v14.ExpectedDayReward, + ExpectedStoragePledge: v14.ExpectedStoragePledge, + + SectorKeyCID: v14.SectorKeyCID, + + PowerBaseEpoch: v14.PowerBaseEpoch, + ReplacedDayReward: v14.ReplacedDayReward, + Flags: SectorOnChainInfoFlags(v14.Flags), + } + return info +} + +func fromV14SectorPreCommitOnChainInfo(v14 miner14.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { + ret := SectorPreCommitOnChainInfo{ + Info: SectorPreCommitInfo{ + SealProof: v14.Info.SealProof, + SectorNumber: v14.Info.SectorNumber, + SealedCID: v14.Info.SealedCID, + SealRandEpoch: v14.Info.SealRandEpoch, + DealIDs: v14.Info.DealIDs, + Expiration: v14.Info.Expiration, + UnsealedCid: nil, + }, + PreCommitDeposit: v14.PreCommitDeposit, + PreCommitEpoch: v14.PreCommitEpoch, + } + + ret.Info.UnsealedCid = v14.Info.UnsealedCid + + return ret +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +func (s *state14) ActorKey() string { + return manifest.MinerKey +} + +func (s *state14) ActorVersion() actorstypes.Version { + return actorstypes.Version14 +} + +func (s *state14) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/venus-shared/actors/builtin/miner/utils.go b/venus-shared/actors/builtin/miner/utils.go index 14b4976143..afab0cb83b 100644 --- a/venus-shared/actors/builtin/miner/utils.go +++ b/venus-shared/actors/builtin/miner/utils.go @@ -10,7 +10,16 @@ import ( "github.com/filecoin-project/go-state-types/network" ) +type SealProofVariant int + +const ( + SealProofVariant_Standard SealProofVariant = iota + SealProofVariant_Synthetic + SealProofVariant_NonInteractive +) + var MinSyntheticPoRepVersion = network.Version21 +var MinNonInteractivePoRepVersion = network.Version23 func AllPartSectors(mas State, sget func(Partition) (bitfield.BitField, error)) (bitfield.BitField, error) { var parts []bitfield.BitField @@ -35,7 +44,18 @@ func AllPartSectors(mas State, sget func(Partition) (bitfield.BitField, error)) // SealProofTypeFromSectorSize returns preferred seal proof type for creating // new miner actors and new sectors -func SealProofTypeFromSectorSize(ssize abi.SectorSize, nv network.Version, synthetic bool) (abi.RegisteredSealProof, error) { +func SealProofTypeFromSectorSize(ssize abi.SectorSize, nv network.Version, variant SealProofVariant) (abi.RegisteredSealProof, error) { + switch variant { + case SealProofVariant_Synthetic: + if nv < MinSyntheticPoRepVersion { + return 0, fmt.Errorf("synthetic proofs are not supported on network version %d", nv) + } + case SealProofVariant_NonInteractive: + if nv < MinNonInteractivePoRepVersion { + return 0, fmt.Errorf("non-interactive proofs are not supported on network version %d", nv) + } + } + switch { case nv < network.Version7: switch ssize { @@ -69,11 +89,13 @@ func SealProofTypeFromSectorSize(ssize abi.SectorSize, nv network.Version, synth return 0, fmt.Errorf("unsupported sector size for miner: %v", ssize) } - if nv >= MinSyntheticPoRepVersion && synthetic { + switch variant { + case SealProofVariant_Synthetic: return toSynthetic(v) - } else { - return v, nil + case SealProofVariant_NonInteractive: + return toNonInteractive(v) } + return v, nil } return 0, fmt.Errorf("unsupported network version") @@ -96,6 +118,23 @@ func toSynthetic(in abi.RegisteredSealProof) (abi.RegisteredSealProof, error) { } } +func toNonInteractive(in abi.RegisteredSealProof) (abi.RegisteredSealProof, error) { + switch in { + case abi.RegisteredSealProof_StackedDrg2KiBV1_1: + return abi.RegisteredSealProof_StackedDrg2KiBV1_2_Feat_NiPoRep, nil + case abi.RegisteredSealProof_StackedDrg8MiBV1_1: + return abi.RegisteredSealProof_StackedDrg8MiBV1_2_Feat_NiPoRep, nil + case abi.RegisteredSealProof_StackedDrg512MiBV1_1: + return abi.RegisteredSealProof_StackedDrg512MiBV1_2_Feat_NiPoRep, nil + case abi.RegisteredSealProof_StackedDrg32GiBV1_1: + return abi.RegisteredSealProof_StackedDrg32GiBV1_2_Feat_NiPoRep, nil + case abi.RegisteredSealProof_StackedDrg64GiBV1_1: + return abi.RegisteredSealProof_StackedDrg64GiBV1_2_Feat_NiPoRep, nil + default: + return 0, fmt.Errorf("unsupported conversion to non-interactive: %v", in) + } +} + // WindowPoStProofTypeFromSectorSize returns preferred post proof type for creating // new miner actors and new sectors func WindowPoStProofTypeFromSectorSize(ssize abi.SectorSize, nv network.Version) (abi.RegisteredPoStProof, error) { diff --git a/venus-shared/actors/builtin/multisig/actor.go b/venus-shared/actors/builtin/multisig/actor.go index e5af442637..b9ef64771a 100644 --- a/venus-shared/actors/builtin/multisig/actor.go +++ b/venus-shared/actors/builtin/multisig/actor.go @@ -15,7 +15,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" - msig13 "github.com/filecoin-project/go-state-types/builtin/v13/multisig" + msig14 "github.com/filecoin-project/go-state-types/builtin/v14/multisig" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" @@ -65,6 +65,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -138,6 +141,9 @@ func MakeState(store adt.Store, av actorstypes.Version, signers []address.Addres case actorstypes.Version13: return make13(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + case actorstypes.Version14: + return make14(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + } return nil, fmt.Errorf("unknown actor version %d", av) } @@ -164,7 +170,7 @@ type State interface { GetState() interface{} } -type Transaction = msig13.Transaction +type Transaction = msig14.Transaction var Methods = builtintypes.MethodsMultisig @@ -209,6 +215,9 @@ func Message(version actorstypes.Version, from address.Address) MessageBuilder { case actorstypes.Version13: return message13{message0{from}} + + case actorstypes.Version14: + return message14{message0{from}} default: panic(fmt.Sprintf("unsupported actors version: %d", version)) } @@ -232,13 +241,13 @@ type MessageBuilder interface { } // this type is the same between v0 and v2 -type ProposalHashData = msig13.ProposalHashData -type ProposeReturn = msig13.ProposeReturn -type ProposeParams = msig13.ProposeParams -type ApproveReturn = msig13.ApproveReturn +type ProposalHashData = msig14.ProposalHashData +type ProposeReturn = msig14.ProposeReturn +type ProposeParams = msig14.ProposeParams +type ApproveReturn = msig14.ApproveReturn func txnParams(id uint64, data *ProposalHashData) ([]byte, error) { - params := msig13.TxnIDParams{ID: msig13.TxnID(id)} + params := msig14.TxnIDParams{ID: msig14.TxnID(id)} if data != nil { if data.Requester.Protocol() != address.ID { return nil, fmt.Errorf("proposer address must be an ID address, was %s", data.Requester) @@ -275,5 +284,6 @@ func AllCodes() []cid.Cid { (&state11{}).Code(), (&state12{}).Code(), (&state13{}).Code(), + (&state14{}).Code(), } } diff --git a/venus-shared/actors/builtin/multisig/message.v10.go b/venus-shared/actors/builtin/multisig/message.v10.go index 4a9ed5ad60..61fa78e409 100644 --- a/venus-shared/actors/builtin/multisig/message.v10.go +++ b/venus-shared/actors/builtin/multisig/message.v10.go @@ -10,7 +10,7 @@ import ( actorstypes "github.com/filecoin-project/go-state-types/actors" multisig10 "github.com/filecoin-project/go-state-types/builtin/v10/multisig" - init13 "github.com/filecoin-project/go-state-types/builtin/v13/init" + init14 "github.com/filecoin-project/go-state-types/builtin/v14/init" "github.com/filecoin-project/go-state-types/manifest" builtintypes "github.com/filecoin-project/go-state-types/builtin" @@ -60,7 +60,7 @@ func (m message10) Create( } // new actors are created by invoking 'exec' on the init actor with the constructor params - execParams := &init13.ExecParams{ + execParams := &init14.ExecParams{ CodeCID: code, ConstructorParams: enc, } diff --git a/venus-shared/actors/builtin/multisig/message.v11.go b/venus-shared/actors/builtin/multisig/message.v11.go index 9e3519c635..f4005de308 100644 --- a/venus-shared/actors/builtin/multisig/message.v11.go +++ b/venus-shared/actors/builtin/multisig/message.v11.go @@ -10,7 +10,7 @@ import ( actorstypes "github.com/filecoin-project/go-state-types/actors" multisig11 "github.com/filecoin-project/go-state-types/builtin/v11/multisig" - init13 "github.com/filecoin-project/go-state-types/builtin/v13/init" + init14 "github.com/filecoin-project/go-state-types/builtin/v14/init" "github.com/filecoin-project/go-state-types/manifest" builtintypes "github.com/filecoin-project/go-state-types/builtin" @@ -60,7 +60,7 @@ func (m message11) Create( } // new actors are created by invoking 'exec' on the init actor with the constructor params - execParams := &init13.ExecParams{ + execParams := &init14.ExecParams{ CodeCID: code, ConstructorParams: enc, } diff --git a/venus-shared/actors/builtin/multisig/message.v12.go b/venus-shared/actors/builtin/multisig/message.v12.go index 3ed46fc340..d3f93960c1 100644 --- a/venus-shared/actors/builtin/multisig/message.v12.go +++ b/venus-shared/actors/builtin/multisig/message.v12.go @@ -10,7 +10,7 @@ import ( actorstypes "github.com/filecoin-project/go-state-types/actors" multisig12 "github.com/filecoin-project/go-state-types/builtin/v12/multisig" - init13 "github.com/filecoin-project/go-state-types/builtin/v13/init" + init14 "github.com/filecoin-project/go-state-types/builtin/v14/init" "github.com/filecoin-project/go-state-types/manifest" builtintypes "github.com/filecoin-project/go-state-types/builtin" @@ -60,7 +60,7 @@ func (m message12) Create( } // new actors are created by invoking 'exec' on the init actor with the constructor params - execParams := &init13.ExecParams{ + execParams := &init14.ExecParams{ CodeCID: code, ConstructorParams: enc, } diff --git a/venus-shared/actors/builtin/multisig/message.v13.go b/venus-shared/actors/builtin/multisig/message.v13.go index 0025a3b176..a6fe1ab3ed 100644 --- a/venus-shared/actors/builtin/multisig/message.v13.go +++ b/venus-shared/actors/builtin/multisig/message.v13.go @@ -9,8 +9,8 @@ import ( "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" - init13 "github.com/filecoin-project/go-state-types/builtin/v13/init" multisig13 "github.com/filecoin-project/go-state-types/builtin/v13/multisig" + init14 "github.com/filecoin-project/go-state-types/builtin/v14/init" "github.com/filecoin-project/go-state-types/manifest" builtintypes "github.com/filecoin-project/go-state-types/builtin" @@ -60,7 +60,7 @@ func (m message13) Create( } // new actors are created by invoking 'exec' on the init actor with the constructor params - execParams := &init13.ExecParams{ + execParams := &init14.ExecParams{ CodeCID: code, ConstructorParams: enc, } diff --git a/venus-shared/actors/builtin/multisig/message.v14.go b/venus-shared/actors/builtin/multisig/message.v14.go new file mode 100644 index 0000000000..528b5009be --- /dev/null +++ b/venus-shared/actors/builtin/multisig/message.v14.go @@ -0,0 +1,80 @@ +// FETCHED FROM LOTUS: builtin/multisig/message.go.template + +package multisig + +import ( + "fmt" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + init14 "github.com/filecoin-project/go-state-types/builtin/v14/init" + multisig14 "github.com/filecoin-project/go-state-types/builtin/v14/multisig" + "github.com/filecoin-project/go-state-types/manifest" + + builtintypes "github.com/filecoin-project/go-state-types/builtin" + "github.com/filecoin-project/venus/venus-shared/actors" + init_ "github.com/filecoin-project/venus/venus-shared/actors/builtin/init" + "github.com/filecoin-project/venus/venus-shared/actors/types" +) + +type message14 struct{ message0 } + +func (m message14) Create( + signers []address.Address, threshold uint64, + unlockStart, unlockDuration abi.ChainEpoch, + initialAmount abi.TokenAmount, +) (*types.Message, error) { + + lenAddrs := uint64(len(signers)) + + if lenAddrs < threshold { + return nil, fmt.Errorf("cannot require signing of more addresses than provided for multisig") + } + + if threshold == 0 { + threshold = lenAddrs + } + + if m.from == address.Undef { + return nil, fmt.Errorf("must provide source address") + } + + // Set up constructor parameters for multisig + msigParams := &multisig14.ConstructorParams{ + Signers: signers, + NumApprovalsThreshold: threshold, + UnlockDuration: unlockDuration, + StartEpoch: unlockStart, + } + + enc, actErr := actors.SerializeParams(msigParams) + if actErr != nil { + return nil, actErr + } + + code, ok := actors.GetActorCodeID(actorstypes.Version14, manifest.MultisigKey) + if !ok { + return nil, fmt.Errorf("failed to get multisig code ID") + } + + // new actors are created by invoking 'exec' on the init actor with the constructor params + execParams := &init14.ExecParams{ + CodeCID: code, + ConstructorParams: enc, + } + + enc, actErr = actors.SerializeParams(execParams) + if actErr != nil { + return nil, actErr + } + + return &types.Message{ + To: init_.Address, + From: m.from, + Method: builtintypes.MethodsInit.Exec, + Params: enc, + Value: initialAmount, + }, nil +} diff --git a/venus-shared/actors/builtin/multisig/message.v8.go b/venus-shared/actors/builtin/multisig/message.v8.go index 48a60a13cf..1a981d3c5a 100644 --- a/venus-shared/actors/builtin/multisig/message.v8.go +++ b/venus-shared/actors/builtin/multisig/message.v8.go @@ -9,7 +9,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" - init13 "github.com/filecoin-project/go-state-types/builtin/v13/init" + init14 "github.com/filecoin-project/go-state-types/builtin/v14/init" multisig8 "github.com/filecoin-project/go-state-types/builtin/v8/multisig" "github.com/filecoin-project/go-state-types/manifest" @@ -60,7 +60,7 @@ func (m message8) Create( } // new actors are created by invoking 'exec' on the init actor with the constructor params - execParams := &init13.ExecParams{ + execParams := &init14.ExecParams{ CodeCID: code, ConstructorParams: enc, } diff --git a/venus-shared/actors/builtin/multisig/message.v9.go b/venus-shared/actors/builtin/multisig/message.v9.go index e2434e6561..9195a9b9fe 100644 --- a/venus-shared/actors/builtin/multisig/message.v9.go +++ b/venus-shared/actors/builtin/multisig/message.v9.go @@ -9,7 +9,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" - init13 "github.com/filecoin-project/go-state-types/builtin/v13/init" + init14 "github.com/filecoin-project/go-state-types/builtin/v14/init" multisig9 "github.com/filecoin-project/go-state-types/builtin/v9/multisig" "github.com/filecoin-project/go-state-types/manifest" @@ -60,7 +60,7 @@ func (m message9) Create( } // new actors are created by invoking 'exec' on the init actor with the constructor params - execParams := &init13.ExecParams{ + execParams := &init14.ExecParams{ CodeCID: code, ConstructorParams: enc, } diff --git a/venus-shared/actors/builtin/multisig/state.v14.go b/venus-shared/actors/builtin/multisig/state.v14.go new file mode 100644 index 0000000000..4248ffb007 --- /dev/null +++ b/venus-shared/actors/builtin/multisig/state.v14.go @@ -0,0 +1,140 @@ +// FETCHED FROM LOTUS: builtin/multisig/state.go.template + +package multisig + +import ( + "bytes" + "encoding/binary" + "fmt" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + + "github.com/filecoin-project/go-state-types/manifest" + "github.com/filecoin-project/venus/venus-shared/actors" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + + builtin14 "github.com/filecoin-project/go-state-types/builtin" + msig14 "github.com/filecoin-project/go-state-types/builtin/v14/multisig" + adt14 "github.com/filecoin-project/go-state-types/builtin/v14/util/adt" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state14{store: store} + out.State = msig14.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + + em, err := adt14.StoreEmptyMap(store, builtin14.DefaultHamtBitwidth) + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + + return &out, nil +} + +type state14 struct { + msig14.State + store adt.Store +} + +func (s *state14) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) { + return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil +} + +func (s *state14) StartEpoch() (abi.ChainEpoch, error) { + return s.State.StartEpoch, nil +} + +func (s *state14) UnlockDuration() (abi.ChainEpoch, error) { + return s.State.UnlockDuration, nil +} + +func (s *state14) InitialBalance() (abi.TokenAmount, error) { + return s.State.InitialBalance, nil +} + +func (s *state14) Threshold() (uint64, error) { + return s.State.NumApprovalsThreshold, nil +} + +func (s *state14) Signers() ([]address.Address, error) { + return s.State.Signers, nil +} + +func (s *state14) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error { + arr, err := adt14.AsMap(s.store, s.State.PendingTxns, builtin14.DefaultHamtBitwidth) + if err != nil { + return err + } + var out msig14.Transaction + return arr.ForEach(&out, func(key string) error { + txid, n := binary.Varint([]byte(key)) + if n <= 0 { + return fmt.Errorf("invalid pending transaction key: %v", key) + } + return cb(txid, (Transaction)(out)) //nolint:unconvert + }) +} + +func (s *state14) PendingTxnChanged(other State) (bool, error) { + other14, ok := other.(*state14) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.PendingTxns.Equals(other14.PendingTxns), nil +} + +func (s *state14) transactions() (adt.Map, error) { + return adt14.AsMap(s.store, s.PendingTxns, builtin14.DefaultHamtBitwidth) +} + +func (s *state14) decodeTransaction(val *cbg.Deferred) (Transaction, error) { + var tx msig14.Transaction + if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return Transaction{}, err + } + return Transaction(tx), nil +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +func (s *state14) ActorKey() string { + return manifest.MultisigKey +} + +func (s *state14) ActorVersion() actorstypes.Version { + return actorstypes.Version14 +} + +func (s *state14) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/venus-shared/actors/builtin/paych/actor.go b/venus-shared/actors/builtin/paych/actor.go index 1a86c3102d..f22b8315d4 100644 --- a/venus-shared/actors/builtin/paych/actor.go +++ b/venus-shared/actors/builtin/paych/actor.go @@ -65,6 +65,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -188,6 +191,9 @@ func Message(version actorstypes.Version, from address.Address) MessageBuilder { case actorstypes.Version13: return message13{from} + case actorstypes.Version14: + return message14{from} + default: panic(fmt.Sprintf("unsupported actors version: %d", version)) } @@ -231,5 +237,6 @@ func AllCodes() []cid.Cid { (&state11{}).Code(), (&state12{}).Code(), (&state13{}).Code(), + (&state14{}).Code(), } } diff --git a/venus-shared/actors/builtin/paych/message.v14.go b/venus-shared/actors/builtin/paych/message.v14.go new file mode 100644 index 0000000000..685e124042 --- /dev/null +++ b/venus-shared/actors/builtin/paych/message.v14.go @@ -0,0 +1,113 @@ +// FETCHED FROM LOTUS: builtin/paych/message.go.template + +package paych + +import ( + "fmt" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + paychtypes "github.com/filecoin-project/go-state-types/builtin/v8/paych" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + builtin14 "github.com/filecoin-project/go-state-types/builtin" + init14 "github.com/filecoin-project/go-state-types/builtin/v14/init" + paych14 "github.com/filecoin-project/go-state-types/builtin/v14/paych" + + "github.com/filecoin-project/venus/venus-shared/actors" + init_ "github.com/filecoin-project/venus/venus-shared/actors/builtin/init" + "github.com/filecoin-project/venus/venus-shared/actors/types" +) + +type message14 struct{ from address.Address } + +func (m message14) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { + + actorCodeID, ok := actors.GetActorCodeID(actorstypes.Version14, "paymentchannel") + if !ok { + return nil, fmt.Errorf("error getting actor paymentchannel code id for actor version %d", 14) + } + + params, aerr := actors.SerializeParams(&paych14.ConstructorParams{From: m.from, To: to}) + if aerr != nil { + return nil, aerr + } + enc, aerr := actors.SerializeParams(&init14.ExecParams{ + CodeCID: actorCodeID, + ConstructorParams: params, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: init_.Address, + From: m.from, + Value: initialAmount, + Method: builtin14.MethodsInit.Exec, + Params: enc, + }, nil +} + +func (m message14) Update(paych address.Address, sv *paychtypes.SignedVoucher, secret []byte) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych14.UpdateChannelStateParams{ + + Sv: toV14SignedVoucher(*sv), + + Secret: secret, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin14.MethodsPaych.UpdateChannelState, + Params: params, + }, nil +} + +func toV14SignedVoucher(sv paychtypes.SignedVoucher) paych14.SignedVoucher { + merges := make([]paych14.Merge, len(sv.Merges)) + for i := range sv.Merges { + merges[i] = paych14.Merge{ + Lane: sv.Merges[i].Lane, + Nonce: sv.Merges[i].Nonce, + } + } + + return paych14.SignedVoucher{ + ChannelAddr: sv.ChannelAddr, + TimeLockMin: sv.TimeLockMin, + TimeLockMax: sv.TimeLockMax, + SecretHash: sv.SecretHash, + Extra: (*paych14.ModVerifyParams)(sv.Extra), + Lane: sv.Lane, + Nonce: sv.Nonce, + Amount: sv.Amount, + MinSettleHeight: sv.MinSettleHeight, + Merges: merges, + Signature: sv.Signature, + } +} + +func (m message14) Settle(paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin14.MethodsPaych.Settle, + }, nil +} + +func (m message14) Collect(paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin14.MethodsPaych.Collect, + }, nil +} diff --git a/venus-shared/actors/builtin/paych/state.v14.go b/venus-shared/actors/builtin/paych/state.v14.go new file mode 100644 index 0000000000..6443214e04 --- /dev/null +++ b/venus-shared/actors/builtin/paych/state.v14.go @@ -0,0 +1,138 @@ +// FETCHED FROM LOTUS: builtin/paych/state.go.template + +package paych + +import ( + "fmt" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + "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" + + "github.com/filecoin-project/go-state-types/manifest" + "github.com/filecoin-project/venus/venus-shared/actors" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + + paych14 "github.com/filecoin-project/go-state-types/builtin/v14/paych" + adt14 "github.com/filecoin-project/go-state-types/builtin/v14/util/adt" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store) (State, error) { + out := state14{store: store} + out.State = paych14.State{} + return &out, nil +} + +type state14 struct { + paych14.State + store adt.Store + lsAmt *adt14.Array +} + +// Channel owner, who has funded the actor +func (s *state14) From() (address.Address, error) { + return s.State.From, nil +} + +// Recipient of payouts from channel +func (s *state14) To() (address.Address, error) { + return s.State.To, nil +} + +// Height at which the channel can be `Collected` +func (s *state14) SettlingAt() (abi.ChainEpoch, error) { + return s.State.SettlingAt, nil +} + +// Amount successfully redeemed through the payment channel, paid out on `Collect()` +func (s *state14) ToSend() (abi.TokenAmount, error) { + return s.State.ToSend, nil +} + +func (s *state14) getOrLoadLsAmt() (*adt14.Array, error) { + if s.lsAmt != nil { + return s.lsAmt, nil + } + + // Get the lane state from the chain + lsamt, err := adt14.AsArray(s.store, s.State.LaneStates, paych14.LaneStatesAmtBitwidth) + if err != nil { + return nil, err + } + + s.lsAmt = lsamt + return lsamt, nil +} + +// Get total number of lanes +func (s *state14) LaneCount() (uint64, error) { + lsamt, err := s.getOrLoadLsAmt() + if err != nil { + return 0, err + } + return lsamt.Length(), nil +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +// Iterate lane states +func (s *state14) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { + // Get the lane state from the chain + lsamt, err := s.getOrLoadLsAmt() + if err != nil { + return err + } + + // Note: we use a map instead of an array to store laneStates because the + // client sets the lane ID (the index) and potentially they could use a + // very large index. + var ls paych14.LaneState + return lsamt.ForEach(&ls, func(i int64) error { + return cb(uint64(i), &laneState14{ls}) + }) +} + +type laneState14 struct { + paych14.LaneState +} + +func (ls *laneState14) Redeemed() (big.Int, error) { + return ls.LaneState.Redeemed, nil +} + +func (ls *laneState14) Nonce() (uint64, error) { + return ls.LaneState.Nonce, nil +} + +func (s *state14) ActorKey() string { + return manifest.PaychKey +} + +func (s *state14) ActorVersion() actorstypes.Version { + return actorstypes.Version14 +} + +func (s *state14) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/venus-shared/actors/builtin/power/actor.go b/venus-shared/actors/builtin/power/actor.go index f8b6114bf5..b42fc8ad56 100644 --- a/venus-shared/actors/builtin/power/actor.go +++ b/venus-shared/actors/builtin/power/actor.go @@ -34,12 +34,12 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" - builtin13 "github.com/filecoin-project/go-state-types/builtin" + builtin14 "github.com/filecoin-project/go-state-types/builtin" ) var ( - Address = builtin13.StoragePowerActorAddr - Methods = builtin13.MethodsPower + Address = builtin14.StoragePowerActorAddr + Methods = builtin14.MethodsPower ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -68,6 +68,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -141,6 +144,9 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) { case actorstypes.Version13: return make13(store) + case actorstypes.Version14: + return make14(store) + } return nil, fmt.Errorf("unknown actor version %d", av) } @@ -208,5 +214,6 @@ func AllCodes() []cid.Cid { (&state11{}).Code(), (&state12{}).Code(), (&state13{}).Code(), + (&state14{}).Code(), } } diff --git a/venus-shared/actors/builtin/power/state.v14.go b/venus-shared/actors/builtin/power/state.v14.go new file mode 100644 index 0000000000..7aad113843 --- /dev/null +++ b/venus-shared/actors/builtin/power/state.v14.go @@ -0,0 +1,210 @@ +// FETCHED FROM LOTUS: builtin/power/state.go.template + +package power + +import ( + "bytes" + "fmt" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + + "github.com/filecoin-project/go-state-types/manifest" + "github.com/filecoin-project/venus/venus-shared/actors" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + "github.com/filecoin-project/venus/venus-shared/actors/builtin" + + builtin14 "github.com/filecoin-project/go-state-types/builtin" + power14 "github.com/filecoin-project/go-state-types/builtin/v14/power" + adt14 "github.com/filecoin-project/go-state-types/builtin/v14/util/adt" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store) (State, error) { + out := state14{store: store} + + s, err := power14.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state14 struct { + power14.State + store adt.Store +} + +func (s *state14) TotalLocked() (abi.TokenAmount, error) { + return s.TotalPledgeCollateral, nil +} + +func (s *state14) TotalPower() (Claim, error) { + return Claim{ + RawBytePower: s.TotalRawBytePower, + QualityAdjPower: s.TotalQualityAdjPower, + }, nil +} + +// Committed power to the network. Includes miners below the minimum threshold. +func (s *state14) TotalCommitted() (Claim, error) { + return Claim{ + RawBytePower: s.TotalBytesCommitted, + QualityAdjPower: s.TotalQABytesCommitted, + }, nil +} + +func (s *state14) MinerPower(addr address.Address) (Claim, bool, error) { + claims, err := s.claims() + if err != nil { + return Claim{}, false, err + } + var claim power14.Claim + ok, err := claims.Get(abi.AddrKey(addr), &claim) + if err != nil { + return Claim{}, false, err + } + return Claim{ + RawBytePower: claim.RawBytePower, + QualityAdjPower: claim.QualityAdjPower, + }, ok, nil +} + +func (s *state14) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) { + return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a) +} + +func (s *state14) TotalPowerSmoothed() (builtin.FilterEstimate, error) { + return builtin.FilterEstimate(s.State.ThisEpochQAPowerSmoothed), nil +} + +func (s *state14) MinerCounts() (uint64, uint64, error) { + return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil +} + +func (s *state14) ListAllMiners() ([]address.Address, error) { + claims, err := s.claims() + if err != nil { + return nil, err + } + + var miners []address.Address + err = claims.ForEach(nil, func(k string) error { + a, err := address.NewFromBytes([]byte(k)) + if err != nil { + return err + } + miners = append(miners, a) + return nil + }) + if err != nil { + return nil, err + } + + return miners, nil +} + +func (s *state14) ForEachClaim(cb func(miner address.Address, claim Claim) error) error { + claims, err := s.claims() + if err != nil { + return err + } + + var claim power14.Claim + return claims.ForEach(&claim, func(k string) error { + a, err := address.NewFromBytes([]byte(k)) + if err != nil { + return err + } + return cb(a, Claim{ + RawBytePower: claim.RawBytePower, + QualityAdjPower: claim.QualityAdjPower, + }) + }) +} + +func (s *state14) ClaimsChanged(other State) (bool, error) { + other14, ok := other.(*state14) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.Claims.Equals(other14.State.Claims), nil +} + +func (s *state14) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state14) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state14) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state14) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +func (s *state14) claims() (adt.Map, error) { + return adt14.AsMap(s.store, s.Claims, builtin14.DefaultHamtBitwidth) +} + +func (s *state14) decodeClaim(val *cbg.Deferred) (Claim, error) { + var ci power14.Claim + if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return Claim{}, err + } + return fromV14Claim(ci), nil +} + +func fromV14Claim(v14 power14.Claim) Claim { + return Claim{ + RawBytePower: v14.RawBytePower, + QualityAdjPower: v14.QualityAdjPower, + } +} + +func (s *state14) ActorKey() string { + return manifest.PowerKey +} + +func (s *state14) ActorVersion() actorstypes.Version { + return actorstypes.Version14 +} + +func (s *state14) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/venus-shared/actors/builtin/registry.go b/venus-shared/actors/builtin/registry.go index f0c211f4d7..6aacf9b935 100644 --- a/venus-shared/actors/builtin/registry.go +++ b/venus-shared/actors/builtin/registry.go @@ -114,6 +114,25 @@ import ( evm13 "github.com/filecoin-project/go-state-types/builtin/v13/evm" placeholder13 "github.com/filecoin-project/go-state-types/builtin/v13/placeholder" + account14 "github.com/filecoin-project/go-state-types/builtin/v14/account" + cron14 "github.com/filecoin-project/go-state-types/builtin/v14/cron" + _init14 "github.com/filecoin-project/go-state-types/builtin/v14/init" + market14 "github.com/filecoin-project/go-state-types/builtin/v14/market" + miner14 "github.com/filecoin-project/go-state-types/builtin/v14/miner" + multisig14 "github.com/filecoin-project/go-state-types/builtin/v14/multisig" + paych14 "github.com/filecoin-project/go-state-types/builtin/v14/paych" + power14 "github.com/filecoin-project/go-state-types/builtin/v14/power" + reward14 "github.com/filecoin-project/go-state-types/builtin/v14/reward" + system14 "github.com/filecoin-project/go-state-types/builtin/v14/system" + verifreg14 "github.com/filecoin-project/go-state-types/builtin/v14/verifreg" + + datacap14 "github.com/filecoin-project/go-state-types/builtin/v14/datacap" + + eam14 "github.com/filecoin-project/go-state-types/builtin/v14/eam" + ethaccount14 "github.com/filecoin-project/go-state-types/builtin/v14/ethaccount" + evm14 "github.com/filecoin-project/go-state-types/builtin/v14/evm" + placeholder14 "github.com/filecoin-project/go-state-types/builtin/v14/placeholder" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/manifest" @@ -754,6 +773,110 @@ func MakeRegistry(av actorstypes.Version) []RegistryEntry { } } + case actorstypes.Version14: + for key, codeID := range codeIDs { + switch key { + case manifest.AccountKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: account14.Methods, + state: new(account14.State), + }) + case manifest.CronKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: cron14.Methods, + state: new(cron14.State), + }) + case manifest.InitKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: _init14.Methods, + state: new(_init14.State), + }) + case manifest.MarketKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: market14.Methods, + state: new(market14.State), + }) + case manifest.MinerKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: miner14.Methods, + state: new(miner14.State), + }) + case manifest.MultisigKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: multisig14.Methods, + state: new(multisig14.State), + }) + case manifest.PaychKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: paych14.Methods, + state: new(paych14.State), + }) + case manifest.PowerKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: power14.Methods, + state: new(power14.State), + }) + case manifest.RewardKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: reward14.Methods, + state: new(reward14.State), + }) + case manifest.SystemKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: system14.Methods, + state: new(system14.State), + }) + case manifest.VerifregKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: verifreg14.Methods, + state: new(verifreg14.State), + }) + case manifest.DatacapKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: datacap14.Methods, + state: new(datacap14.State), + }) + + case manifest.EvmKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: evm14.Methods, + state: new(evm14.State), + }) + case manifest.EamKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: eam14.Methods, + state: nil, + }) + case manifest.PlaceholderKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: placeholder14.Methods, + state: nil, + }) + case manifest.EthAccountKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: ethaccount14.Methods, + state: nil, + }) + + } + } + default: panic("expected version v8 and up only, use specs-actors for v0-7") } diff --git a/venus-shared/actors/builtin/reward/actor.go b/venus-shared/actors/builtin/reward/actor.go index 0e47f169fc..3c90b97813 100644 --- a/venus-shared/actors/builtin/reward/actor.go +++ b/venus-shared/actors/builtin/reward/actor.go @@ -27,7 +27,7 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" - builtin13 "github.com/filecoin-project/go-state-types/builtin" + builtin14 "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/manifest" "github.com/filecoin-project/venus/venus-shared/actors/adt" @@ -36,8 +36,8 @@ import ( ) var ( - Address = builtin13.RewardActorAddr - Methods = builtin13.MethodsReward + Address = builtin14.RewardActorAddr + Methods = builtin14.MethodsReward ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -66,6 +66,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -139,6 +142,9 @@ func MakeState(store adt.Store, av actorstypes.Version, currRealizedPower abi.St case actorstypes.Version13: return make13(store, currRealizedPower) + case actorstypes.Version14: + return make14(store, currRealizedPower) + } return nil, fmt.Errorf("unknown actor version %d", av) } @@ -184,5 +190,6 @@ func AllCodes() []cid.Cid { (&state11{}).Code(), (&state12{}).Code(), (&state13{}).Code(), + (&state14{}).Code(), } } diff --git a/venus-shared/actors/builtin/reward/state.v14.go b/venus-shared/actors/builtin/reward/state.v14.go new file mode 100644 index 0000000000..1d5725b3a8 --- /dev/null +++ b/venus-shared/actors/builtin/reward/state.v14.go @@ -0,0 +1,122 @@ +// FETCHED FROM LOTUS: builtin/reward/state.go.template + +package reward + +import ( + "fmt" + + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-state-types/manifest" + "github.com/filecoin-project/venus/venus-shared/actors" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + "github.com/filecoin-project/venus/venus-shared/actors/builtin" + + miner14 "github.com/filecoin-project/go-state-types/builtin/v14/miner" + reward14 "github.com/filecoin-project/go-state-types/builtin/v14/reward" + smoothing14 "github.com/filecoin-project/go-state-types/builtin/v14/util/smoothing" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state14{store: store} + out.State = *reward14.ConstructState(currRealizedPower) + return &out, nil +} + +type state14 struct { + reward14.State + store adt.Store +} + +func (s *state14) ThisEpochReward() (abi.TokenAmount, error) { + return s.State.ThisEpochReward, nil +} + +func (s *state14) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) { + + return builtin.FilterEstimate{ + PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate, + VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate, + }, nil + +} + +func (s *state14) ThisEpochBaselinePower() (abi.StoragePower, error) { + return s.State.ThisEpochBaselinePower, nil +} + +func (s *state14) TotalStoragePowerReward() (abi.TokenAmount, error) { + return s.State.TotalStoragePowerReward, nil +} + +func (s *state14) EffectiveBaselinePower() (abi.StoragePower, error) { + return s.State.EffectiveBaselinePower, nil +} + +func (s *state14) EffectiveNetworkTime() (abi.ChainEpoch, error) { + return s.State.EffectiveNetworkTime, nil +} + +func (s *state14) CumsumBaseline() (reward14.Spacetime, error) { + return s.State.CumsumBaseline, nil +} + +func (s *state14) CumsumRealized() (reward14.Spacetime, error) { + return s.State.CumsumRealized, nil +} + +func (s *state14) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) { + return miner14.InitialPledgeForPower( + qaPower, + s.State.ThisEpochBaselinePower, + s.State.ThisEpochRewardSmoothed, + smoothing14.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + circSupply, + ), nil +} + +func (s *state14) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) { + return miner14.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed, + smoothing14.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + sectorWeight), nil +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +func (s *state14) ActorKey() string { + return manifest.RewardKey +} + +func (s *state14) ActorVersion() actorstypes.Version { + return actorstypes.Version14 +} + +func (s *state14) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/venus-shared/actors/builtin/system/actor.go b/venus-shared/actors/builtin/system/actor.go index f46d11eaf5..14ccec8ae3 100644 --- a/venus-shared/actors/builtin/system/actor.go +++ b/venus-shared/actors/builtin/system/actor.go @@ -26,11 +26,11 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" - builtin13 "github.com/filecoin-project/go-state-types/builtin" + builtin14 "github.com/filecoin-project/go-state-types/builtin" ) var ( - Address = builtin13.SystemActorAddr + Address = builtin14.SystemActorAddr ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -59,6 +59,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -132,6 +135,9 @@ func MakeState(store adt.Store, av actorstypes.Version, builtinActors cid.Cid) ( case actorstypes.Version13: return make13(store, builtinActors) + case actorstypes.Version14: + return make14(store, builtinActors) + } return nil, fmt.Errorf("unknown actor version %d", av) } @@ -161,5 +167,6 @@ func AllCodes() []cid.Cid { (&state11{}).Code(), (&state12{}).Code(), (&state13{}).Code(), + (&state14{}).Code(), } } diff --git a/venus-shared/actors/builtin/system/state.v14.go b/venus-shared/actors/builtin/system/state.v14.go new file mode 100644 index 0000000000..c4fd069a10 --- /dev/null +++ b/venus-shared/actors/builtin/system/state.v14.go @@ -0,0 +1,75 @@ +// FETCHED FROM LOTUS: builtin/system/state.go.template + +package system + +import ( + "fmt" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/venus/venus-shared/actors" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + + system14 "github.com/filecoin-project/go-state-types/builtin/v14/system" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store, builtinActors cid.Cid) (State, error) { + out := state14{store: store} + out.State = system14.State{ + BuiltinActors: builtinActors, + } + return &out, nil +} + +type state14 struct { + system14.State + store adt.Store +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +func (s *state14) GetBuiltinActors() cid.Cid { + + return s.State.BuiltinActors + +} + +func (s *state14) SetBuiltinActors(c cid.Cid) error { + + s.State.BuiltinActors = c + return nil + +} + +func (s *state14) ActorKey() string { + return manifest.SystemKey +} + +func (s *state14) ActorVersion() actorstypes.Version { + return actorstypes.Version14 +} + +func (s *state14) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/venus-shared/actors/builtin/verifreg/actor.go b/venus-shared/actors/builtin/verifreg/actor.go index d2591deba7..b308d71fa7 100644 --- a/venus-shared/actors/builtin/verifreg/actor.go +++ b/venus-shared/actors/builtin/verifreg/actor.go @@ -28,7 +28,7 @@ import ( builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" - builtin13 "github.com/filecoin-project/go-state-types/builtin" + builtin14 "github.com/filecoin-project/go-state-types/builtin" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" "github.com/filecoin-project/venus/venus-shared/actors" @@ -37,8 +37,8 @@ import ( ) var ( - Address = builtin13.VerifiedRegistryActorAddr - Methods = builtin13.MethodsVerifiedRegistry + Address = builtin14.VerifiedRegistryActorAddr + Methods = builtin14.MethodsVerifiedRegistry ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -67,6 +67,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version13: return load13(store, act.Head) + case actorstypes.Version14: + return load14(store, act.Head) + } } @@ -140,6 +143,9 @@ func MakeState(store adt.Store, av actorstypes.Version, rootKeyAddress address.A case actorstypes.Version13: return make13(store, rootKeyAddress) + case actorstypes.Version14: + return make14(store, rootKeyAddress) + } return nil, fmt.Errorf("unknown actor version %d", av) } @@ -182,6 +188,7 @@ func AllCodes() []cid.Cid { (&state11{}).Code(), (&state12{}).Code(), (&state13{}).Code(), + (&state14{}).Code(), } } diff --git a/venus-shared/actors/builtin/verifreg/state.v14.go b/venus-shared/actors/builtin/verifreg/state.v14.go new file mode 100644 index 0000000000..aeb00602ae --- /dev/null +++ b/venus-shared/actors/builtin/verifreg/state.v14.go @@ -0,0 +1,199 @@ +// FETCHED FROM LOTUS: builtin/verifreg/state.go.template + +package verifreg + +import ( + "fmt" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/filecoin-project/go-state-types/manifest" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/venus/venus-shared/actors" + "github.com/filecoin-project/venus/venus-shared/actors/adt" + + builtin14 "github.com/filecoin-project/go-state-types/builtin" + adt14 "github.com/filecoin-project/go-state-types/builtin/v14/util/adt" + verifreg14 "github.com/filecoin-project/go-state-types/builtin/v14/verifreg" + + "github.com/filecoin-project/go-state-types/big" + + verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" +) + +var _ State = (*state14)(nil) + +func load14(store adt.Store, root cid.Cid) (State, error) { + out := state14{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make14(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state14{store: store} + + s, err := verifreg14.ConstructState(store, rootKeyAddress) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state14 struct { + verifreg14.State + store adt.Store +} + +func (s *state14) RootKey() (address.Address, error) { + return s.State.RootKey, nil +} + +func (s *state14) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { + + return false, big.Zero(), fmt.Errorf("unsupported in actors v14") + +} + +func (s *state14) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version14, s.verifiers, addr) +} + +func (s *state14) RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error) { + return getRemoveDataCapProposalID(s.store, actors.Version14, s.removeDataCapProposalIDs, verifier, client) +} + +func (s *state14) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, actors.Version14, s.verifiers, cb) +} + +func (s *state14) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { + + return fmt.Errorf("unsupported in actors v14") + +} + +func (s *state14) verifiedClients() (adt.Map, error) { + + return nil, fmt.Errorf("unsupported in actors v14") + +} + +func (s *state14) verifiers() (adt.Map, error) { + return adt14.AsMap(s.store, s.Verifiers, builtin14.DefaultHamtBitwidth) +} + +func (s *state14) removeDataCapProposalIDs() (adt.Map, error) { + return adt14.AsMap(s.store, s.RemoveDataCapProposalIDs, builtin14.DefaultHamtBitwidth) +} + +func (s *state14) GetState() interface{} { + return &s.State +} + +func (s *state14) GetAllocation(clientIdAddr address.Address, allocationId verifreg9.AllocationId) (*Allocation, bool, error) { + + alloc, ok, err := s.FindAllocation(s.store, clientIdAddr, verifreg14.AllocationId(allocationId)) + return (*Allocation)(alloc), ok, err +} + +func (s *state14) GetAllocations(clientIdAddr address.Address) (map[AllocationId]Allocation, error) { + + v14Map, err := s.LoadAllocationsToMap(s.store, clientIdAddr) + + retMap := make(map[AllocationId]Allocation, len(v14Map)) + for k, v := range v14Map { + retMap[AllocationId(k)] = Allocation(v) + } + + return retMap, err + +} + +func (s *state14) GetAllAllocations() (map[AllocationId]Allocation, error) { + + v14Map, err := s.State.GetAllAllocations(s.store) + + retMap := make(map[AllocationId]Allocation, len(v14Map)) + for k, v := range v14Map { + retMap[AllocationId(k)] = Allocation(v) + } + + return retMap, err + +} + +func (s *state14) GetClaim(providerIdAddr address.Address, claimId verifreg9.ClaimId) (*Claim, bool, error) { + + claim, ok, err := s.FindClaim(s.store, providerIdAddr, verifreg14.ClaimId(claimId)) + return (*Claim)(claim), ok, err + +} + +func (s *state14) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, error) { + + v14Map, err := s.LoadClaimsToMap(s.store, providerIdAddr) + + retMap := make(map[ClaimId]Claim, len(v14Map)) + for k, v := range v14Map { + retMap[ClaimId(k)] = Claim(v) + } + + return retMap, err + +} + +func (s *state14) GetAllClaims() (map[ClaimId]Claim, error) { + + v14Map, err := s.State.GetAllClaims(s.store) + + retMap := make(map[ClaimId]Claim, len(v14Map)) + for k, v := range v14Map { + retMap[ClaimId(k)] = Claim(v) + } + + return retMap, err + +} + +func (s *state14) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) { + + v14Map, err := s.LoadClaimsToMap(s.store, providerIdAddr) + + retMap := make(map[abi.SectorNumber][]ClaimId) + for k, v := range v14Map { + claims, ok := retMap[v.Sector] + if !ok { + retMap[v.Sector] = []ClaimId{ClaimId(k)} + } else { + retMap[v.Sector] = append(claims, ClaimId(k)) + } + } + + return retMap, err + +} + +func (s *state14) ActorKey() string { + return manifest.VerifregKey +} + +func (s *state14) ActorVersion() actorstypes.Version { + return actorstypes.Version14 +} + +func (s *state14) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/venus-shared/actors/builtin_actors.go b/venus-shared/actors/builtin_actors.go index 3b6083f891..097cd15ae7 100644 --- a/venus-shared/actors/builtin_actors.go +++ b/venus-shared/actors/builtin_actors.go @@ -12,11 +12,11 @@ import ( "strconv" "strings" - "github.com/DataDog/zstd" actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" "github.com/ipld/go-car" + "github.com/klauspost/compress/zstd" "github.com/filecoin-project/venus/venus-shared/actors/adt" blockstoreutil "github.com/filecoin-project/venus/venus-shared/blockstore" @@ -193,8 +193,11 @@ func readEmbeddedBuiltinActorsMetadata(bundle string) ([]*BuiltinActorsMetadata, } defer fi.Close() //nolint - uncompressed := zstd.NewReader(fi) - defer uncompressed.Close() //nolint + uncompressed, err := zstd.NewReader(fi) + if err != nil { + return nil, err + } + defer uncompressed.Close() var bundles []*BuiltinActorsMetadata @@ -288,8 +291,11 @@ func GetEmbeddedBuiltinActorsBundle(version actorstypes.Version, networkBundleNa } defer fi.Close() //nolint - uncompressed := zstd.NewReader(fi) - defer uncompressed.Close() //nolint + uncompressed, err := zstd.NewReader(fi) + if err != nil { + return nil, false + } + defer uncompressed.Close() tarReader := tar.NewReader(uncompressed) targetFileName := fmt.Sprintf("builtin-actors-%s.car", networkBundleName) diff --git a/venus-shared/actors/builtin_actors_gen.go b/venus-shared/actors/builtin_actors_gen.go index 280fb1dcdc..a5ed6d8fd8 100644 --- a/venus-shared/actors/builtin_actors_gen.go +++ b/venus-shared/actors/builtin_actors_gen.go @@ -139,6 +139,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "system": mustParseCid("bafk2bzaceacjmlxrvydlud77ilpzbscez46yedx6zjsj6olxsdeuv6d4x4cwe"), "verifiedregistry": mustParseCid("bafk2bzacebs5muoq7ft2wgqojhjio7a4vltbyprqkmlr43ojlzbil4nwvj3jg"), }, +}, { + Network: "butterflynet", + Version: 14, + + ManifestCid: mustParseCid("bafy2bzacecmkqezl3a5klkzz7z4ou4jwqk4zzd3nvz727l4qh44ngsxtxdblu"), + Actors: map[string]cid.Cid{ + "account": mustParseCid("bafk2bzaceazutruyfvvqxgp5qoneq36uv6yethps2bonil5psy2vivl5j2hks"), + "cron": mustParseCid("bafk2bzacecsiz2nzjieposnkz2kqvjjnqyu5zwk6ccm4dbptx26v3qirm6zni"), + "datacap": mustParseCid("bafk2bzaceaavii766hmiawhw2fjvtoy5kvbukou3zejf6gtwu7xi4jxt4uidk"), + "eam": mustParseCid("bafk2bzacebkzhnamn5ohtsvn76opprsi3ao3ujgytjr3c6kdcvhmhg4ze5xxm"), + "ethaccount": mustParseCid("bafk2bzacebvvri25rmgt6yy5qtdrikcsestk6z52aebynwd53s2rm2l3ukn7g"), + "evm": mustParseCid("bafk2bzacebta2jkyxknvwnr6ldcimmwpzenhtdwqbuifzk6g2wktzqf3vj33a"), + "init": mustParseCid("bafk2bzaceblybzwnn55uiivbsjae6l7haz5iocexnynfcz2yjg5spciimxdme"), + "multisig": mustParseCid("bafk2bzaceb54rbdcfdcdtzwbohshn64opgsqf5vhqh3xqb37iignsm3plrtpa"), + "paymentchannel": mustParseCid("bafk2bzacebyyn42ie7jekdytacqpqfll7xctsfpza3tb2sonzsjdeltxqgmdo"), + "placeholder": mustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": mustParseCid("bafk2bzaceczaoglexx6w3m744s4emfmjkeizpl4ofdkh4xzhevjtd6zift5iu"), + "storagemarket": mustParseCid("bafk2bzaceceaqmhkxuerleq2dpju35mcsdiklpkisglzlj5xkf32hbyqn7sam"), + "storageminer": mustParseCid("bafk2bzacebkiqu5pclx5zze4ugcsn3lvumihyathpcrjfq36b3hgmd7jqe2bk"), + "storagepower": mustParseCid("bafk2bzacebcxydq2iampltz5zoo3oojka45hjkd62vz46xtpl6qilhkkjdeaq"), + "system": mustParseCid("bafk2bzacebbrs3dzgxwj43ztup7twz25xkbhhtmcbjjbscjvpsrpbwux3b32g"), + "verifiedregistry": mustParseCid("bafk2bzacebj3znhdpxqjgvztrv3petqwdkvrefg4j6lrp3n7wfrkdoan4os42"), + }, }, { Network: "calibrationnet", Version: 8, @@ -268,6 +291,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "system": mustParseCid("bafk2bzacedjnrb5glewazsxpcx6rwiuhl4kwrfcqolyprn6rrjtlzmthlhdq6"), "verifiedregistry": mustParseCid("bafk2bzacebj2zdquagzy2xxn7up574oemg3w7ed3fe4aujkyhgdwj57voesn2"), }, +}, { + Network: "calibrationnet", + Version: 14, + + ManifestCid: mustParseCid("bafy2bzacebq3hncszqpojglh2dkwekybq4zn6qpc4gceqbx36wndps5qehtau"), + Actors: map[string]cid.Cid{ + "account": mustParseCid("bafk2bzaced5ecfm56dvtw26q56j4d32yoccyd7ggxn3qdki2enxpqqav45ths"), + "cron": mustParseCid("bafk2bzacedpbtttpyvtjncqoyobr63mhqqtlrygbnudhxyp2vha56f626dkfs"), + "datacap": mustParseCid("bafk2bzacecded3lcvo7ndsk66samyecw2trnhrgzi7jxsary3sqgopxlk6rku"), + "eam": mustParseCid("bafk2bzacecsda4uw7dcu76a27gnrrdcm73tgms7wrte6jbou63vloktkqc5ne"), + "ethaccount": mustParseCid("bafk2bzacebu2lcxfmohomjj3umslnylwugf5gssywdq3575tjarta7o227dls"), + "evm": mustParseCid("bafk2bzacea4xnekruhfmdnzvzeo6cbf7jsfgco6x5wje2ckwc2ui2ojzcrlgu"), + "init": mustParseCid("bafk2bzacedfmsdlewihdcrkdepnfata26nj7akbvexzs3chicujhjf2uxsazc"), + "multisig": mustParseCid("bafk2bzacedwx4svscsp6wqqu2vlcunjihvvm4u2jnsqjkwutjhir7dwtl7z6m"), + "paymentchannel": mustParseCid("bafk2bzacedbit7oo6lryhbo64uikvtjtfcth6oxwy3eebxerenu2h7rj44n24"), + "placeholder": mustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": mustParseCid("bafk2bzaced5rlycj7fzpscfc7p3wwxarngwqylqshj7te3uffey5tevunz4we"), + "storagemarket": mustParseCid("bafk2bzaceatwbyrec2nnwggxc2alpqve7rl52fmbhqflebuxmmnvg3qckjb7c"), + "storageminer": mustParseCid("bafk2bzacecr7ozkdz7l2pq3ig5qxae2ysivbnojhsn4gw3o57ov4mhksma7me"), + "storagepower": mustParseCid("bafk2bzacedgeolvjtnw7fkji5kqmx322abv6uls2v34fuml6nw36dvfcw4mtu"), + "system": mustParseCid("bafk2bzacederl6tlpieldsn6mkndqwd4wj5orfoqgab6p2klswfn3cjagxwla"), + "verifiedregistry": mustParseCid("bafk2bzaceczw2kp6gjjdcjbso7mewp7guik7gr525pal6dotdja2lrct6ok3c"), + }, }, { Network: "caterpillarnet", Version: 8, @@ -406,6 +452,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "system": mustParseCid("bafk2bzacecc5oavxivfnvirx2g7megpdf6lugooyoc2wijloju247xzjcdezy"), "verifiedregistry": mustParseCid("bafk2bzacebnkdt42mpf5emypo6iroux3hszfh5yt54v2mmnnura3ketholly4"), }, +}, { + Network: "caterpillarnet", + Version: 14, + + ManifestCid: mustParseCid("bafy2bzacecr6g2co4zkdvrsbz2z7wh44o6hrl3rpbgnlhe52772hhjs43vxge"), + Actors: map[string]cid.Cid{ + "account": mustParseCid("bafk2bzacecaoykugysdikvzptp5jc6qzhfxv3tsy7eggoabfk34jc6ozr3nju"), + "cron": mustParseCid("bafk2bzacede6xljkkb6qww47hdho2dfs75bfxjwmxspldwclekd2ntdvcapj6"), + "datacap": mustParseCid("bafk2bzacedjwq3frxklkkejk4payjpjwgdj352izzcmymtzib6xzgrrtczeuw"), + "eam": mustParseCid("bafk2bzaceana2fkgcjhtr56rrqngvilybjpavfgfwf3kuqed6qxa4lfdjmkac"), + "ethaccount": mustParseCid("bafk2bzacedg7tcqwoykjd57dkettxxato4yufxlyzy6hgsggc7jhf6v7zqgas"), + "evm": mustParseCid("bafk2bzacedwqu6pi4csjod4c5677pgsr6g4ekhqnqgdnsiodyqczmcsj3sspk"), + "init": mustParseCid("bafk2bzaceakukvex4wjcrmwp5msp4d2dhe4qlftqxgolxx5sbtshah3fxoepy"), + "multisig": mustParseCid("bafk2bzaceamp2c2qfgnl7z6vz5majhcm64ml72kbg5kea4xgdnfcyqanynfks"), + "paymentchannel": mustParseCid("bafk2bzacebs44wqfedfx3o23q7tkza5cm3q54gevreqzetsei2bvhsmqdwz3i"), + "placeholder": mustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": mustParseCid("bafk2bzacedyckhwkkmcoc2n6byzw6vxi3lqyp3zjs3b7flfqj2wybprwxkw2m"), + "storagemarket": mustParseCid("bafk2bzacebx7ky74ry222rvi56wav3dbal4rqooeuafiakg7r6ksxh2uahbju"), + "storageminer": mustParseCid("bafk2bzacecwfsmi6xxbwkddunjt2zs6qn2g4hvrwury7g36vqvafmok7gs642"), + "storagepower": mustParseCid("bafk2bzacecqcvllpsttt3nqcso4ng2z4cjjn5sr36is7yze74ihqnol2dst2u"), + "system": mustParseCid("bafk2bzacea75k6agtdmjxdfnwbctzstc6pozdblpdevc5ixjevvuzcqwwuzrc"), + "verifiedregistry": mustParseCid("bafk2bzacedxwgmgffeapq4nffplapb5mixkrm2vosmc2i3fxcye5dookiqubu"), + }, }, { Network: "devnet", Version: 8, @@ -535,6 +604,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "system": mustParseCid("bafk2bzaceaxg6k5vuozxlemfi5hv663m6jcawzu5puboo4znj73i36e3tsovs"), "verifiedregistry": mustParseCid("bafk2bzacea2czkb4vt2iiiwdb6e57qfwqse4mk2pcyvwjmdl5ojbnla57oh2u"), }, +}, { + Network: "devnet", + Version: 14, + + ManifestCid: mustParseCid("bafy2bzacebwn7ymtozv5yz3x5hnxl4bds2grlgsk5kncyxjak3hqyhslb534m"), + Actors: map[string]cid.Cid{ + "account": mustParseCid("bafk2bzacecqyi3xhyrze7hlo73zzyzz5jw5e6eqqyesmnbef4xr7br5amqsm2"), + "cron": mustParseCid("bafk2bzacebmeovn3fehscsm2ejcd2vejgqmuqidzx3ytlvp4osa6fes3w73yy"), + "datacap": mustParseCid("bafk2bzaceasqdluegec5qllzjhu66jsyvb74dix6wjztpiaxvha74in7h4eek"), + "eam": mustParseCid("bafk2bzaced4shnjesuxk44ufllcywjbaixerx6hkcyj5rqqopjuic725fymx2"), + "ethaccount": mustParseCid("bafk2bzacebbw6hg766y4ouycqlr3llur7sxkgj7hnu7jq4xlwtycp3ovpqjee"), + "evm": mustParseCid("bafk2bzaceafzevk77d6zhjbrw7grm5p3es2pzuklpvcthedjv6ejh7alvxqoc"), + "init": mustParseCid("bafk2bzacebaywpmwlfhhog6vey3dkz25hjrlwnhacsjryq3ujymyttolglats"), + "multisig": mustParseCid("bafk2bzacedm52r4h7upic7ynukzwjkadefbjeq7w7ozdonsbdumgoabk7xass"), + "paymentchannel": mustParseCid("bafk2bzacecsvfy77loubouoyqwl2ke574zpg3x5f2qon6ougjzfjna6eadwxg"), + "placeholder": mustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": mustParseCid("bafk2bzacecvc7v5d2krwxqeyklfg2xb5qc3kalu66265smcbmwepjmj643uqu"), + "storagemarket": mustParseCid("bafk2bzacecegzksfqu35xlcc6ymxae3vqpkntbajx4jtahugszvb77fnr37ii"), + "storageminer": mustParseCid("bafk2bzacedoimzimltyfzbabwuam2bqw32nqwo2twjq73q7mklwtvqi2evsw2"), + "storagepower": mustParseCid("bafk2bzacebszcfmepyvssrg2tbbqgpqm2cnrl5ub4n6cfy7eie2wwseyloxvs"), + "system": mustParseCid("bafk2bzacea4rh5i36ucj23zb4mid4tw5ym2wqlfap4ejjaynvobengeuby4ja"), + "verifiedregistry": mustParseCid("bafk2bzaceapbsihfuk3munfpcoevtxlwuenxeiiv7dp7v3t2yjs26hcpypexi"), + }, }, { Network: "hyperspace", Version: 8, @@ -687,6 +779,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "system": mustParseCid("bafk2bzacecyf523quuq2kdjfdvyty446z2ounmamtgtgeqnr3ynlu5cqrlt6e"), "verifiedregistry": mustParseCid("bafk2bzacedkxehp7y7iyukbcje3wbpqcvufisos6exatkanyrbotoecdkrbta"), }, +}, { + Network: "mainnet", + Version: 14, + + ManifestCid: mustParseCid("bafy2bzacecbueuzsropvqawsri27owo7isa5gp2qtluhrfsto2qg7wpgxnkba"), + Actors: map[string]cid.Cid{ + "account": mustParseCid("bafk2bzacebr7ik7lng7vysm754mu5x7sakphwm4soqi6zwbox4ukpd6ndwvqy"), + "cron": mustParseCid("bafk2bzacecwn6eiwa7ysimmk6i57i5whj4cqzwijx3xdlxwb5canmweaez6xc"), + "datacap": mustParseCid("bafk2bzacecidw7ajvtjhmygqs2yxhmuybyvtwp25dxpblvdxxo7u4gqfzirjg"), + "eam": mustParseCid("bafk2bzaced2cxnfwngpcubg63h7zk4y5hjwwuhfjxrh43xozax2u6u2woweju"), + "ethaccount": mustParseCid("bafk2bzacechu4u7asol5mpcsr6fo6jeaeltvayj5bllupyiux7tcynsxby7ko"), + "evm": mustParseCid("bafk2bzacedupohbgwrcw5ztbbsvrpqyybnokr4ylegmk7hrbt3ueeykua6zxw"), + "init": mustParseCid("bafk2bzacecbbcshenkb6z2v4irsudv7tyklfgphhizhghix6ke5gpl4r5f2b6"), + "multisig": mustParseCid("bafk2bzaceajcmsngu3f2chk2y7nanlen5xlftzatytzm6hxwiiw5i5nz36bfc"), + "paymentchannel": mustParseCid("bafk2bzaceavslp27u3f4zwjq45rlg6assj6cqod7r5f6wfwkptlpi6j4qkmne"), + "placeholder": mustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": mustParseCid("bafk2bzacedvfnjittwrkhoar6n5xrykowg2e6rpur4poh2m572f7m7evyx4lc"), + "storagemarket": mustParseCid("bafk2bzaceaju5wobednmornvdqcyi6khkvdttkru4dqduqicrdmohlwfddwhg"), + "storageminer": mustParseCid("bafk2bzacea3f43rxzemmakjpktq2ukayngean3oo2de5cdxlg2wsyn53wmepc"), + "storagepower": mustParseCid("bafk2bzacedo6scxizooytn53wjwg2ooiawnj4fsoylcadnp7mhgzluuckjl42"), + "system": mustParseCid("bafk2bzacecak4ow7tmauku42s3u2yydonk4hx6ov6ov542hy7lcbji3nhrrhs"), + "verifiedregistry": mustParseCid("bafk2bzacebvyzjzmvmjvpypphqsumpy6rzxuugnehgum7grc6sv3yqxzrshb4"), + }, }, { Network: "testing", Version: 8, @@ -816,6 +931,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "system": mustParseCid("bafk2bzaceby6aiiosnrtb5kzlmrvd4k3o27oo3idmbd6llydz2uqibbp23pzq"), "verifiedregistry": mustParseCid("bafk2bzaceadw6mxuyb6ipaq3fhekk7u5osyyiis3c4wbkvysy2ut6qfsua5zs"), }, +}, { + Network: "testing", + Version: 14, + + ManifestCid: mustParseCid("bafy2bzacebgc3zha33w7wggshqjeeomjnxfsqdezpt6e5w4tcqnfp42hvhqyy"), + Actors: map[string]cid.Cid{ + "account": mustParseCid("bafk2bzacedz5ko33xyknznoj5mcwnijhggapvn7hzmec3ix3vlqjg6uuwownm"), + "cron": mustParseCid("bafk2bzacebifywvakusxpvnzn33qneqm46g3trnqvuvaw5cgslfg5cl7prtwa"), + "datacap": mustParseCid("bafk2bzacedx4zxq5ae6qbucm6elokqhhmlwbtas7mbqm6rnigwkmorrtfzo66"), + "eam": mustParseCid("bafk2bzaceavilsrvq7kdyqelapjabixsgmhf6caufc4hdyviccmerf3sawzdk"), + "ethaccount": mustParseCid("bafk2bzaceavutdrzkspoiz6a5m46m2qzqbsmdb33s62xnkpevuwjrhxm6trn2"), + "evm": mustParseCid("bafk2bzacedovnz466nuqdp5pzs6sztcqofsy5zet7k2gybnbelpwuxpmfphwo"), + "init": mustParseCid("bafk2bzaceajnftptl2tdbrudshriqcg3caw5mqublmd6i5dm3qug3j5qo7g4q"), + "multisig": mustParseCid("bafk2bzacebagezdbubvu4g3norwxaomzpk3mxyzfal3rsvvppdbt46y6h74yc"), + "paymentchannel": mustParseCid("bafk2bzacebmtufrtdxo757c6c5ndmsk3wlnzzuzqp4yzbtltqjutnlgh7awus"), + "placeholder": mustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": mustParseCid("bafk2bzacebtnflocubjjrtvzba4tmrn32tlx2klfgmjreqeo234lqdzu4ovna"), + "storagemarket": mustParseCid("bafk2bzacec6tovj5vh6lyor3m67uhahhldrixnqg7e5246pce5gcwkqwmbvxo"), + "storageminer": mustParseCid("bafk2bzacedcwqwswnkbb22eoajke4t72qvxrp3rpqaotymbqsnlqkz5ovde6m"), + "storagepower": mustParseCid("bafk2bzacea4c3h6gnhgfcjf6lxhzcmp5qq7kgrcym7wv4vcnmd4whegpjdwuq"), + "system": mustParseCid("bafk2bzacechwe3ehay6h7x7tecaajgsxrvvmzcdul6omejfvzf4mpbzkuryhm"), + "verifiedregistry": mustParseCid("bafk2bzacec66mmy7sj6qy5urqplwhbem7wbjrzna7mxh6qbdljdawhu3g5rao"), + }, }, { Network: "testing-fake-proofs", Version: 8, @@ -945,6 +1083,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "system": mustParseCid("bafk2bzaceby6aiiosnrtb5kzlmrvd4k3o27oo3idmbd6llydz2uqibbp23pzq"), "verifiedregistry": mustParseCid("bafk2bzaceadw6mxuyb6ipaq3fhekk7u5osyyiis3c4wbkvysy2ut6qfsua5zs"), }, +}, { + Network: "testing-fake-proofs", + Version: 14, + + ManifestCid: mustParseCid("bafy2bzacebca2c7r6m47fv5ojbzfgqxw74zxyzphlkxigj75q7vobbe6vm4x4"), + Actors: map[string]cid.Cid{ + "account": mustParseCid("bafk2bzacedz5ko33xyknznoj5mcwnijhggapvn7hzmec3ix3vlqjg6uuwownm"), + "cron": mustParseCid("bafk2bzacebifywvakusxpvnzn33qneqm46g3trnqvuvaw5cgslfg5cl7prtwa"), + "datacap": mustParseCid("bafk2bzacedx4zxq5ae6qbucm6elokqhhmlwbtas7mbqm6rnigwkmorrtfzo66"), + "eam": mustParseCid("bafk2bzaceavilsrvq7kdyqelapjabixsgmhf6caufc4hdyviccmerf3sawzdk"), + "ethaccount": mustParseCid("bafk2bzaceavutdrzkspoiz6a5m46m2qzqbsmdb33s62xnkpevuwjrhxm6trn2"), + "evm": mustParseCid("bafk2bzacedovnz466nuqdp5pzs6sztcqofsy5zet7k2gybnbelpwuxpmfphwo"), + "init": mustParseCid("bafk2bzaceajnftptl2tdbrudshriqcg3caw5mqublmd6i5dm3qug3j5qo7g4q"), + "multisig": mustParseCid("bafk2bzacecaioywepaxgtrpkmr7k2bjlwcpj6mu3r7ctk77a3sqwrb72wn4ra"), + "paymentchannel": mustParseCid("bafk2bzacebmtufrtdxo757c6c5ndmsk3wlnzzuzqp4yzbtltqjutnlgh7awus"), + "placeholder": mustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": mustParseCid("bafk2bzacebtnflocubjjrtvzba4tmrn32tlx2klfgmjreqeo234lqdzu4ovna"), + "storagemarket": mustParseCid("bafk2bzacec6tovj5vh6lyor3m67uhahhldrixnqg7e5246pce5gcwkqwmbvxo"), + "storageminer": mustParseCid("bafk2bzacecgckzurejgtbw2xfmys5talfq5sloia2mrjcdsl5xolbwkolkrss"), + "storagepower": mustParseCid("bafk2bzacea4c3h6gnhgfcjf6lxhzcmp5qq7kgrcym7wv4vcnmd4whegpjdwuq"), + "system": mustParseCid("bafk2bzacechwe3ehay6h7x7tecaajgsxrvvmzcdul6omejfvzf4mpbzkuryhm"), + "verifiedregistry": mustParseCid("bafk2bzacec66mmy7sj6qy5urqplwhbem7wbjrzna7mxh6qbdljdawhu3g5rao"), + }, }} func mustParseCid(c string) cid.Cid { diff --git a/venus-shared/actors/policy/policy.go b/venus-shared/actors/policy/policy.go index 518730589b..154c529f4e 100644 --- a/venus-shared/actors/policy/policy.go +++ b/venus-shared/actors/policy/policy.go @@ -85,18 +85,23 @@ import ( miner13 "github.com/filecoin-project/go-state-types/builtin/v13/miner" verifreg13 "github.com/filecoin-project/go-state-types/builtin/v13/verifreg" - paych13 "github.com/filecoin-project/go-state-types/builtin/v13/paych" + builtin14 "github.com/filecoin-project/go-state-types/builtin" + market14 "github.com/filecoin-project/go-state-types/builtin/v14/market" + miner14 "github.com/filecoin-project/go-state-types/builtin/v14/miner" + verifreg14 "github.com/filecoin-project/go-state-types/builtin/v14/verifreg" + + paych14 "github.com/filecoin-project/go-state-types/builtin/v14/paych" ) const ( - ChainFinality = miner13.ChainFinality + ChainFinality = miner14.ChainFinality SealRandomnessLookback = ChainFinality - PaychSettleDelay = paych13.SettleDelay - MaxPreCommitRandomnessLookback = builtin13.EpochsInDay + SealRandomnessLookback + PaychSettleDelay = paych14.SettleDelay + MaxPreCommitRandomnessLookback = builtin14.EpochsInDay + SealRandomnessLookback ) var ( - MarketDefaultAllocationTermBuffer = market13.MarketDefaultAllocationTermBuffer + MarketDefaultAllocationTermBuffer = market14.MarketDefaultAllocationTermBuffer ) // SetSupportedProofTypes sets supported proof types, across all actor versions. @@ -213,11 +218,13 @@ func SetPreCommitChallengeDelay(delay abi.ChainEpoch) { miner13.PreCommitChallengeDelay = delay + miner14.PreCommitChallengeDelay = delay + } // TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay. func GetPreCommitChallengeDelay() abi.ChainEpoch { - return miner13.PreCommitChallengeDelay + return miner14.PreCommitChallengeDelay } // SetConsensusMinerMinPower sets the minimum power of an individual miner must @@ -275,6 +282,10 @@ func SetConsensusMinerMinPower(p abi.StoragePower) { policy.ConsensusMinerMinPower = p } + for _, policy := range builtin14.PoStProofPolicies { + policy.ConsensusMinerMinPower = p + } + } // SetMinVerifiedDealSize sets the minimum size of a verified deal. This should @@ -307,6 +318,8 @@ func SetMinVerifiedDealSize(size abi.StoragePower) { verifreg13.MinVerifiedDealSize = size + verifreg14.MinVerifiedDealSize = size + } func GetMaxProveCommitDuration(ver actorstypes.Version, t abi.RegisteredSealProof) (abi.ChainEpoch, error) { @@ -364,6 +377,10 @@ func GetMaxProveCommitDuration(ver actorstypes.Version, t abi.RegisteredSealProo return miner13.MaxProveCommitDuration[t], nil + case actorstypes.Version14: + + return miner14.MaxProveCommitDuration[t], nil + default: return 0, fmt.Errorf("unsupported actors version") } @@ -434,6 +451,11 @@ func SetProviderCollateralSupplyTarget(num, denom big.Int) { Denominator: denom, } + market14.ProviderCollateralSupplyTarget = builtin14.BigFrac{ + Numerator: num, + Denominator: denom, + } + } func DealProviderCollateralBounds( @@ -512,13 +534,18 @@ func DealProviderCollateralBounds( min, max := market13.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) return min, max, nil + case actorstypes.Version14: + + min, max := market14.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + return min, max, nil + default: return big.Zero(), big.Zero(), fmt.Errorf("unsupported actors version") } } func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) { - return market13.DealDurationBounds(pieceSize) + return market14.DealDurationBounds(pieceSize) } // Sets the challenge window and scales the proving period to match (such that @@ -608,6 +635,13 @@ func SetWPoStChallengeWindow(period abi.ChainEpoch) { // scale it if we're scaling the challenge period. miner13.WPoStDisputeWindow = period * 30 + miner14.WPoStChallengeWindow = period + miner14.WPoStProvingPeriod = period * abi.ChainEpoch(miner14.WPoStPeriodDeadlines) + + // by default, this is 2x finality which is 30 periods. + // scale it if we're scaling the challenge period. + miner14.WPoStDisputeWindow = period * 30 + } func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { @@ -665,6 +699,9 @@ func GetMaxSectorExpirationExtension(nv network.Version) (abi.ChainEpoch, error) case actorstypes.Version13: return miner13.MaxSectorExpirationExtension, nil + case actorstypes.Version14: + return miner14.MaxSectorExpirationExtension, nil + default: return 0, fmt.Errorf("unsupported network version") } @@ -672,11 +709,11 @@ func GetMaxSectorExpirationExtension(nv network.Version) (abi.ChainEpoch, error) } func GetMinSectorExpiration() abi.ChainEpoch { - return miner13.MinSectorExpiration + return miner14.MinSectorExpiration } func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, error) { - sectorsPerPart, err := builtin13.PoStProofWindowPoStPartitionSectors(p) + sectorsPerPart, err := builtin14.PoStProofWindowPoStPartitionSectors(p) if err != nil { return 0, err } @@ -685,7 +722,7 @@ func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, e return 0, err } - return min(miner13.PoStedPartitionsMax, int(uint64(maxSectors)/sectorsPerPart)), nil + return min(miner14.PoStedPartitionsMax, int(uint64(maxSectors)/sectorsPerPart)), nil } func GetDefaultAggregationProof() abi.RegisteredAggregationProof { @@ -697,7 +734,7 @@ func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) return builtin4.SealProofPoliciesV0[proof].SectorMaxLifetime } - return builtin13.SealProofPoliciesV11[proof].SectorMaxLifetime + return builtin14.SealProofPoliciesV11[proof].SectorMaxLifetime } func GetAddressedSectorsMax(nwVer network.Version) (int, error) { @@ -746,6 +783,9 @@ func GetAddressedSectorsMax(nwVer network.Version) (int, error) { case actorstypes.Version13: return miner13.AddressedSectorsMax, nil + case actorstypes.Version14: + return miner14.AddressedSectorsMax, nil + default: return 0, fmt.Errorf("unsupported network version") } @@ -811,6 +851,10 @@ func GetDeclarationsMax(nwVer network.Version) (int, error) { return miner13.DeclarationsMax, nil + case actorstypes.Version14: + + return miner14.DeclarationsMax, nil + default: return 0, fmt.Errorf("unsupported network version") } @@ -875,6 +919,10 @@ func AggregateProveCommitNetworkFee(nwVer network.Version, aggregateSize int, ba return miner13.AggregateProveCommitNetworkFee(aggregateSize, baseFee), nil + case actorstypes.Version14: + + return miner14.AggregateProveCommitNetworkFee(aggregateSize, baseFee), nil + default: return big.Zero(), fmt.Errorf("unsupported network version") } @@ -939,6 +987,10 @@ func AggregatePreCommitNetworkFee(nwVer network.Version, aggregateSize int, base return miner13.AggregatePreCommitNetworkFee(aggregateSize, baseFee), nil + case actorstypes.Version14: + + return miner14.AggregatePreCommitNetworkFee(aggregateSize, baseFee), nil + default: return big.Zero(), fmt.Errorf("unsupported network version") } diff --git a/venus-shared/actors/types/actor.go b/venus-shared/actors/types/actor.go index 128862abf8..6aeeb962f4 100644 --- a/venus-shared/actors/types/actor.go +++ b/venus-shared/actors/types/actor.go @@ -46,8 +46,8 @@ type ActorV5 struct { Head cid.Cid Nonce uint64 Balance BigInt - // Deterministic Address - Address *address.Address + // The f4 address of the actor, if any. + DelegatedAddress *address.Address } type Actor = ActorV5 diff --git a/venus-shared/actors/types/cbor_gen.go b/venus-shared/actors/types/cbor_gen.go index 921ecc9bca..c8857e9a03 100644 --- a/venus-shared/actors/types/cbor_gen.go +++ b/venus-shared/actors/types/cbor_gen.go @@ -483,8 +483,8 @@ func (t *ActorV5) MarshalCBOR(w io.Writer) error { return err } - // t.Address (address.Address) (struct) - if err := t.Address.MarshalCBOR(cw); err != nil { + // t.DelegatedAddress (address.Address) (struct) + if err := t.DelegatedAddress.MarshalCBOR(cw); err != nil { return err } return nil @@ -560,7 +560,7 @@ func (t *ActorV5) UnmarshalCBOR(r io.Reader) (err error) { } } - // t.Address (address.Address) (struct) + // t.DelegatedAddress (address.Address) (struct) { @@ -572,9 +572,9 @@ func (t *ActorV5) UnmarshalCBOR(r io.Reader) (err error) { if err := cr.UnreadByte(); err != nil { return err } - t.Address = new(address.Address) - if err := t.Address.UnmarshalCBOR(cr); err != nil { - return xerrors.Errorf("unmarshaling t.Address pointer: %w", err) + t.DelegatedAddress = new(address.Address) + if err := t.DelegatedAddress.UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.DelegatedAddress pointer: %w", err) } } diff --git a/venus-shared/actors/types/eth.go b/venus-shared/actors/types/eth.go index 448527f13a..13aeba9d9e 100644 --- a/venus-shared/actors/types/eth.go +++ b/venus-shared/actors/types/eth.go @@ -25,11 +25,18 @@ import ( var ErrInvalidAddress = errors.New("invalid Filecoin Eth address") +// Research into Filecoin chain behaviour suggests that probabilistic finality +// generally approaches the intended stability guarantee at, or near, 30 epochs. +// Although a strictly "finalized" safe recommendation remains 900 epochs. +// See https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0089.md +const SafeEpochDelay = abi.ChainEpoch(30) + // mainnet var Eip155ChainID = 314 func SetEip155ChainID(val int) { Eip155ChainID = val + initEthLegacy155TxSignature() } type EthUint64 uint64 @@ -203,7 +210,7 @@ func init() { } } -func NewEthBlock(hasTransactions bool) EthBlock { +func NewEthBlock(hasTransactions bool, tipsetLen int) EthBlock { b := EthBlock{ Sha3Uncles: EmptyUncleHash, // Sha3Uncles set to a hardcoded value which is used by some clients to determine if has no uncles., StateRoot: EmptyEthHash, @@ -214,7 +221,7 @@ func NewEthBlock(hasTransactions bool) EthBlock { Extradata: []byte{}, MixHash: EmptyEthHash, Nonce: EmptyEthNonce, - GasLimit: EthUint64(constants.BlockGasLimit), // TODO we map Ethereum blocks to Filecoin tipsets; this is inconsistent. + GasLimit: EthUint64(constants.BlockGasLimit * uint64(tipsetLen)), Uncles: []EthHash{}, Transactions: []interface{}{}, } @@ -1038,12 +1045,6 @@ type EthTrace struct { TraceAddress []int `json:"traceAddress"` Action any `json:"action"` Result any `json:"result"` - - Parent *EthTrace `json:"-"` - - // if a subtrace makes a call to GetBytecode, we store a pointer to that subtrace here - // which we then lookup when checking for delegatecall (InvokeContractDelegate) - LastByteCode *EthTrace `json:"-"` } type EthTraceBlock struct { @@ -1062,6 +1063,14 @@ type EthTraceReplayBlockTransaction struct { VMTrace *string `json:"vmTrace"` } +type EthTraceTransaction struct { + *EthTrace + BlockHash EthHash `json:"blockHash"` + BlockNumber int64 `json:"blockNumber"` + TransactionHash EthHash `json:"transactionHash"` + TransactionPosition int `json:"transactionPosition"` +} + type EthCallTraceAction struct { CallType string `json:"callType"` From EthAddress `json:"from"` diff --git a/venus-shared/actors/types/eth_1559_transactions.go b/venus-shared/actors/types/eth_1559_transactions.go new file mode 100644 index 0000000000..7a7dbaafcb --- /dev/null +++ b/venus-shared/actors/types/eth_1559_transactions.go @@ -0,0 +1,339 @@ +package types + +import ( + "fmt" + + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/big" + typescrypto "github.com/filecoin-project/go-state-types/crypto" +) + +var _ EthTransaction = (*Eth1559TxArgs)(nil) + +type Eth1559TxArgs struct { + ChainID int `json:"chainId"` + Nonce int `json:"nonce"` + To *EthAddress `json:"to"` + Value big.Int `json:"value"` + MaxFeePerGas big.Int `json:"maxFeePerGas"` + MaxPriorityFeePerGas big.Int `json:"maxPriorityFeePerGas"` + GasLimit int `json:"gasLimit"` + Input []byte `json:"input"` + V big.Int `json:"v"` + R big.Int `json:"r"` + S big.Int `json:"s"` +} + +func (tx *Eth1559TxArgs) ToUnsignedFilecoinMessage(from address.Address) (*Message, error) { + if tx.ChainID != Eip155ChainID { + return nil, fmt.Errorf("invalid chain id: %d", tx.ChainID) + } + mi, err := getFilecoinMethodInfo(tx.To, tx.Input) + if err != nil { + return nil, xerrors.Errorf("failed to get method info: %w", err) + } + + return &Message{ + Version: 0, + To: mi.to, + From: from, + Nonce: uint64(tx.Nonce), + Value: tx.Value, + GasLimit: int64(tx.GasLimit), + GasFeeCap: tx.MaxFeePerGas, + GasPremium: tx.MaxPriorityFeePerGas, + Method: mi.method, + Params: mi.params, + }, nil +} + +func (tx *Eth1559TxArgs) ToRlpUnsignedMsg() ([]byte, error) { + encoded, err := toRlpUnsignedMsg(tx) + if err != nil { + return nil, err + } + return append([]byte{EIP1559TxType}, encoded...), nil +} + +func (tx *Eth1559TxArgs) TxHash() (EthHash, error) { + rlp, err := tx.ToRlpSignedMsg() + if err != nil { + return EmptyEthHash, err + } + + return EthHashFromTxBytes(rlp), nil +} + +func (tx *Eth1559TxArgs) ToRlpSignedMsg() ([]byte, error) { + encoded, err := toRlpSignedMsg(tx, tx.V, tx.R, tx.S) + if err != nil { + return nil, err + } + return append([]byte{EIP1559TxType}, encoded...), nil +} + +func (tx *Eth1559TxArgs) Signature() (*typescrypto.Signature, error) { + r := tx.R.Int.Bytes() + s := tx.S.Int.Bytes() + v := tx.V.Int.Bytes() + + sig := append([]byte{}, padLeadingZeros(r, 32)...) + sig = append(sig, padLeadingZeros(s, 32)...) + if len(v) == 0 { + sig = append(sig, 0) + } else { + sig = append(sig, v[0]) + } + + if len(sig) != 65 { + return nil, xerrors.Errorf("signature is not 65 bytes") + } + return &typescrypto.Signature{ + Type: typescrypto.SigTypeDelegated, Data: sig, + }, nil +} + +func (tx *Eth1559TxArgs) Sender() (address.Address, error) { + return sender(tx) +} + +func (tx *Eth1559TxArgs) Type() int { + return EIP1559TxType +} + +func (tx *Eth1559TxArgs) ToVerifiableSignature(sig []byte) ([]byte, error) { + return sig, nil +} + +func (tx *Eth1559TxArgs) ToEthTx(smsg *SignedMessage) (EthTx, error) { + from, err := EthAddressFromFilecoinAddress(smsg.Message.From) + if err != nil { + return EthTx{}, xerrors.Errorf("sender was not an eth account") + } + hash, err := tx.TxHash() + if err != nil { + return EthTx{}, err + } + gasFeeCap := EthBigInt(tx.MaxFeePerGas) + gasPremium := EthBigInt(tx.MaxPriorityFeePerGas) + + ethTx := EthTx{ + ChainID: EthUint64(Eip155ChainID), + Type: EIP1559TxType, + Nonce: EthUint64(tx.Nonce), + Hash: hash, + To: tx.To, + Value: EthBigInt(tx.Value), + Input: tx.Input, + Gas: EthUint64(tx.GasLimit), + MaxFeePerGas: &gasFeeCap, + MaxPriorityFeePerGas: &gasPremium, + From: from, + R: EthBigInt(tx.R), + S: EthBigInt(tx.S), + V: EthBigInt(tx.V), + } + + return ethTx, nil +} + +func (tx *Eth1559TxArgs) InitialiseSignature(sig typescrypto.Signature) error { + if sig.Type != typescrypto.SigTypeDelegated { + return xerrors.Errorf("RecoverSignature only supports Delegated signature") + } + + if len(sig.Data) != EthEIP1559TxSignatureLen { + return xerrors.Errorf("signature should be 65 bytes long, but got %d bytes", len(sig.Data)) + } + + r_, err := parseBigInt(sig.Data[0:32]) + if err != nil { + return xerrors.Errorf("cannot parse r into EthBigInt") + } + + s_, err := parseBigInt(sig.Data[32:64]) + if err != nil { + return xerrors.Errorf("cannot parse s into EthBigInt") + } + + v_, err := parseBigInt([]byte{sig.Data[64]}) + if err != nil { + return xerrors.Errorf("cannot parse v into EthBigInt") + } + + tx.R = r_ + tx.S = s_ + tx.V = v_ + + return nil +} + +func (tx *Eth1559TxArgs) packTxFields() ([]interface{}, error) { + chainID, err := formatInt(tx.ChainID) + if err != nil { + return nil, err + } + + nonce, err := formatInt(tx.Nonce) + if err != nil { + return nil, err + } + + maxPriorityFeePerGas, err := formatBigInt(tx.MaxPriorityFeePerGas) + if err != nil { + return nil, err + } + + maxFeePerGas, err := formatBigInt(tx.MaxFeePerGas) + if err != nil { + return nil, err + } + + gasLimit, err := formatInt(tx.GasLimit) + if err != nil { + return nil, err + } + + value, err := formatBigInt(tx.Value) + if err != nil { + return nil, err + } + + res := []interface{}{ + chainID, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + formatEthAddr(tx.To), + value, + tx.Input, + []interface{}{}, // access list + } + return res, nil +} + +func parseEip1559Tx(data []byte) (*Eth1559TxArgs, error) { + if data[0] != EIP1559TxType { + return nil, xerrors.Errorf("not an EIP-1559 transaction: first byte is not %d", EIP1559TxType) + } + + d, err := DecodeRLP(data[1:]) + if err != nil { + return nil, err + } + decoded, ok := d.([]interface{}) + if !ok { + return nil, xerrors.Errorf("not an EIP-1559 transaction: decoded data is not a list") + } + + if len(decoded) != 12 { + return nil, xerrors.Errorf("not an EIP-1559 transaction: should have 12 elements in the rlp list") + } + + chainID, err := parseInt(decoded[0]) + if err != nil { + return nil, err + } + + nonce, err := parseInt(decoded[1]) + if err != nil { + return nil, err + } + + maxPriorityFeePerGas, err := parseBigInt(decoded[2]) + if err != nil { + return nil, err + } + + maxFeePerGas, err := parseBigInt(decoded[3]) + if err != nil { + return nil, err + } + + gasLimit, err := parseInt(decoded[4]) + if err != nil { + return nil, err + } + + to, err := parseEthAddr(decoded[5]) + if err != nil { + return nil, err + } + + value, err := parseBigInt(decoded[6]) + if err != nil { + return nil, err + } + + input, err := parseBytes(decoded[7]) + if err != nil { + return nil, err + } + + accessList, ok := decoded[8].([]interface{}) + if !ok || (ok && len(accessList) != 0) { + return nil, xerrors.Errorf("access list should be an empty list") + } + + r, err := parseBigInt(decoded[10]) + if err != nil { + return nil, err + } + + s, err := parseBigInt(decoded[11]) + if err != nil { + return nil, err + } + + v, err := parseBigInt(decoded[9]) + if err != nil { + return nil, err + } + + // EIP-1559 and EIP-2930 transactions only support 0 or 1 for v + // Legacy and EIP-155 transactions support other values + // https://github.com/ethers-io/ethers.js/blob/56fabe987bb8c1e4891fdf1e5d3fe8a4c0471751/packages/transactions/src.ts/index.ts#L333 + if !v.Equals(big.NewInt(0)) && !v.Equals(big.NewInt(1)) { + return nil, xerrors.Errorf("EIP-1559 transactions only support 0 or 1 for v") + } + + args := Eth1559TxArgs{ + ChainID: chainID, + Nonce: nonce, + To: to, + MaxPriorityFeePerGas: maxPriorityFeePerGas, + MaxFeePerGas: maxFeePerGas, + GasLimit: gasLimit, + Value: value, + Input: input, + V: v, + R: r, + S: s, + } + return &args, nil +} + +func Eth1559TxArgsFromUnsignedFilecoinMessage(msg *Message) (*Eth1559TxArgs, error) { + if msg.Version != 0 { + return nil, fmt.Errorf("unsupported msg version: %d", msg.Version) + } + + params, to, err := getEthParamsAndRecipient(msg) + if err != nil { + return nil, fmt.Errorf("failed to get eth params and recipient: %w", err) + } + + return &Eth1559TxArgs{ + ChainID: Eip155ChainID, + Nonce: int(msg.Nonce), + To: to, + Value: msg.Value, + Input: params, + MaxFeePerGas: msg.GasFeeCap, + MaxPriorityFeePerGas: msg.GasPremium, + GasLimit: int(msg.GasLimit), + }, nil +} diff --git a/venus-shared/types/eth_transactions_test.go b/venus-shared/actors/types/eth_1559_transactions_test.go similarity index 98% rename from venus-shared/types/eth_transactions_test.go rename to venus-shared/actors/types/eth_1559_transactions_test.go index 82cf8c6412..92ebd48a0b 100644 --- a/venus-shared/types/eth_transactions_test.go +++ b/venus-shared/actors/types/eth_1559_transactions_test.go @@ -27,10 +27,10 @@ type TxTestcase struct { TxJSON string NosigTx string Input EthBytes - Output EthTxArgs + Output Eth1559TxArgs } -func TestTxArgs(t *testing.T) { +func TestEIP1559TxArgs(t *testing.T) { testcases, err := prepareTxTestcases() require.Nil(t, err) require.NotEmpty(t, testcases) @@ -39,31 +39,31 @@ func TestTxArgs(t *testing.T) { comment := fmt.Sprintf("case %d: \n%s\n%s", i, tc.TxJSON, hex.EncodeToString(tc.Input)) // parse txargs - txArgs, err := ParseEthTxArgs(tc.Input) - require.NoErrorf(t, err, comment) + txArgs, err := parseEip1559Tx(tc.Input) + require.NoError(t, err, comment) msgRecovered, err := txArgs.ToRlpUnsignedMsg() - require.NoErrorf(t, err, comment) + require.NoError(t, err, comment) require.Equal(t, tc.NosigTx, "0x"+hex.EncodeToString(msgRecovered), comment) // verify signatures from, err := txArgs.Sender() - require.NoErrorf(t, err, comment) + require.NoError(t, err, comment) - smsg, err := txArgs.ToSignedMessage() - require.NoErrorf(t, err, comment) + smsg, err := ToSignedFilecoinMessage(txArgs) + require.NoError(t, err, comment) err = crypto.Verify(&smsg.Signature, from, msgRecovered) - require.NoErrorf(t, err, comment) + require.NoError(t, err, comment) // verify data - require.Equal(t, tc.Output.ChainID, txArgs.ChainID) - require.Equal(t, tc.Output.Nonce, txArgs.Nonce) - require.Equal(t, tc.Output.To, txArgs.To) + require.Equal(t, tc.Output.ChainID, txArgs.ChainID, comment) + require.Equal(t, tc.Output.Nonce, txArgs.Nonce, comment) + require.Equal(t, tc.Output.To, txArgs.To, comment) } } -func TestSignatures(t *testing.T) { +func TestEIP1559Signatures(t *testing.T) { testcases := []struct { RawTx string ExpectedR string @@ -73,29 +73,29 @@ func TestSignatures(t *testing.T) { }{ { "0x02f8598401df5e76028301d69083086a5e835532dd808080c080a0457e33227ac7ceee2ef121755e26b872b6fb04221993f9939349bb7b0a3e1595a02d8ef379e1d2a9e30fa61c92623cc9ed72d80cf6a48cfea341cb916bcc0a81bc", - `"0x457e33227ac7ceee2ef121755e26b872b6fb04221993f9939349bb7b0a3e1595"`, - `"0x2d8ef379e1d2a9e30fa61c92623cc9ed72d80cf6a48cfea341cb916bcc0a81bc"`, - `"0x0"`, + "0x457e33227ac7ceee2ef121755e26b872b6fb04221993f9939349bb7b0a3e1595", + "0x2d8ef379e1d2a9e30fa61c92623cc9ed72d80cf6a48cfea341cb916bcc0a81bc", + "0x0", false, }, { "0x02f8598401df5e76038301d69083086a5e835532dd808080c001a012a232866dcb0671eb0ddc01fb9c01d6ef384ec892bb29691ed0d2d293052ddfa052a6ae38c6139930db21a00eee2a4caced9a6500991b823d64ec664d003bc4b1", - `"0x12a232866dcb0671eb0ddc01fb9c01d6ef384ec892bb29691ed0d2d293052ddf"`, - `"0x52a6ae38c6139930db21a00eee2a4caced9a6500991b823d64ec664d003bc4b1"`, - `"0x1"`, + "0x12a232866dcb0671eb0ddc01fb9c01d6ef384ec892bb29691ed0d2d293052ddf", + "0x52a6ae38c6139930db21a00eee2a4caced9a6500991b823d64ec664d003bc4b1", + "0x1", false, }, { "0x00", - `""`, - `""`, - `""`, + "", + "", + "", true, }, } for _, tc := range testcases { - tx, err := ParseEthTxArgs(mustDecodeHex(tc.RawTx)) + tx, err := parseEip1559Tx(mustDecodeHex(tc.RawTx)) if tc.ExpectErr { require.Error(t, err) continue @@ -105,21 +105,11 @@ func TestSignatures(t *testing.T) { sig, err := tx.Signature() require.Nil(t, err) - r, s, v, err := RecoverSignature(*sig) - require.Nil(t, err) - - marshaledR, err := r.MarshalJSON() - require.Nil(t, err) - - marshaledS, err := s.MarshalJSON() - require.Nil(t, err) - - marshaledV, err := v.MarshalJSON() - require.Nil(t, err) + require.NoError(t, tx.InitialiseSignature(*sig)) - require.Equal(t, tc.ExpectedR, string(marshaledR)) - require.Equal(t, tc.ExpectedS, string(marshaledS)) - require.Equal(t, tc.ExpectedV, string(marshaledV)) + require.Equal(t, tc.ExpectedR, "0x"+tx.R.Text(16)) + require.Equal(t, tc.ExpectedS, "0x"+tx.S.Text(16)) + require.Equal(t, tc.ExpectedV, "0x"+tx.V.Text(16)) } } @@ -150,6 +140,7 @@ func TestTransformParams(t *testing.T) { require.Equal(t, mustDecodeHex("0x1122334455"), evmParams.Initcode) } + func TestEcRecover(t *testing.T) { rHex := "0x479ff7fa64cf8bf641eb81635d1e8a698530d2f219951d234539e6d074819529" sHex := "0x4b6146d27be50cdbb2853ba9a42f207af8d730272f1ebe9c9a78aeef1d6aa924" @@ -233,7 +224,7 @@ func prepareTxTestcases() ([]TxTestcase, error) { res := []TxTestcase{} for _, tc := range testcases { - tx := EthTxArgs{} + tx := Eth1559TxArgs{} err := json.Unmarshal([]byte(tc.Output), &tx) if err != nil { return nil, err diff --git a/venus-shared/actors/types/eth_legacy_155_transactions.go b/venus-shared/actors/types/eth_legacy_155_transactions.go new file mode 100644 index 0000000000..bd85a84634 --- /dev/null +++ b/venus-shared/actors/types/eth_legacy_155_transactions.go @@ -0,0 +1,300 @@ +package types + +import ( + "fmt" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/big" + typescrypto "github.com/filecoin-project/go-state-types/crypto" +) + +var _ EthTransaction = (*EthLegacy155TxArgs)(nil) + +// EthLegacy155TxArgs is a legacy Ethereum transaction that uses the EIP-155 chain replay protection mechanism +// by incorporating the chainId in the signature. +// See how the `V` value in the signature is derived from the chainId at +// https://github.com/ethereum/go-ethereum/blob/86a1f0c39494c8f5caddf6bd9fbddd4bdfa944fd/core/types/transaction_signing.go#L424 +// For EthLegacy155TxArgs, the digest that is used to create a signed transaction includes the `ChainID` but the serialised RLP transaction +// does not include the `ChainID` as an explicit field. Instead, the `ChainID` is included in the V value of the signature as mentioned above. +type EthLegacy155TxArgs struct { + legacyTx *EthLegacyHomesteadTxArgs +} + +func NewEthLegacy155TxArgs(tx *EthLegacyHomesteadTxArgs) *EthLegacy155TxArgs { + return &EthLegacy155TxArgs{legacyTx: tx} +} + +func (tx *EthLegacy155TxArgs) GetLegacyTx() *EthLegacyHomesteadTxArgs { + return tx.legacyTx +} + +func (tx *EthLegacy155TxArgs) ToEthTx(smsg *SignedMessage) (EthTx, error) { + from, err := EthAddressFromFilecoinAddress(smsg.Message.From) + if err != nil { + return EthTx{}, fmt.Errorf("sender was not an eth account") + } + hash, err := tx.TxHash() + if err != nil { + return EthTx{}, fmt.Errorf("failed to get tx hash: %w", err) + } + + gasPrice := EthBigInt(tx.legacyTx.GasPrice) + ethTx := EthTx{ + ChainID: EthUint64(Eip155ChainID), + Type: EthLegacyTxType, + Nonce: EthUint64(tx.legacyTx.Nonce), + Hash: hash, + To: tx.legacyTx.To, + Value: EthBigInt(tx.legacyTx.Value), + Input: tx.legacyTx.Input, + Gas: EthUint64(tx.legacyTx.GasLimit), + GasPrice: &gasPrice, + From: from, + R: EthBigInt(tx.legacyTx.R), + S: EthBigInt(tx.legacyTx.S), + V: EthBigInt(tx.legacyTx.V), + } + + return ethTx, nil +} + +func (tx *EthLegacy155TxArgs) ToUnsignedFilecoinMessage(from address.Address) (*Message, error) { + if err := validateEIP155ChainId(tx.legacyTx.V); err != nil { + return nil, fmt.Errorf("failed to validate EIP155 chain id: %w", err) + } + return tx.legacyTx.ToUnsignedFilecoinMessage(from) +} + +func (tx *EthLegacy155TxArgs) ToRlpUnsignedMsg() ([]byte, error) { + return toRlpUnsignedMsg(tx) +} + +func (tx *EthLegacy155TxArgs) TxHash() (EthHash, error) { + encoded, err := tx.ToRawTxBytesSigned() + if err != nil { + return EthHash{}, fmt.Errorf("failed to encode rlp signed msg: %w", err) + } + + return EthHashFromTxBytes(encoded), nil +} + +func (tx *EthLegacy155TxArgs) ToRawTxBytesSigned() ([]byte, error) { + packed1, err := tx.packTxFields() + if err != nil { + return nil, err + } + + packed1 = packed1[:len(packed1)-3] // remove chainID, r and s as they are only used for signature verification + + packed2, err := packSigFields(tx.legacyTx.V, tx.legacyTx.R, tx.legacyTx.S) + if err != nil { + return nil, err + } + + encoded, err := EncodeRLP(append(packed1, packed2...)) + if err != nil { + return nil, fmt.Errorf("failed to encode rlp signed msg: %w", err) + } + return encoded, nil +} + +func (tx *EthLegacy155TxArgs) ToRlpSignedMsg() ([]byte, error) { + return toRlpSignedMsg(tx, tx.legacyTx.V, tx.legacyTx.R, tx.legacyTx.S) +} + +func (tx *EthLegacy155TxArgs) Signature() (*typescrypto.Signature, error) { + if err := validateEIP155ChainId(tx.legacyTx.V); err != nil { + return nil, fmt.Errorf("failed to validate EIP155 chain id: %w", err) + } + r := tx.legacyTx.R.Int.Bytes() + s := tx.legacyTx.S.Int.Bytes() + v := tx.legacyTx.V.Int.Bytes() + + sig := append([]byte{}, padLeadingZeros(r, 32)...) + sig = append(sig, padLeadingZeros(s, 32)...) + sig = append(sig, v...) + + // pre-pend a one byte marker so nodes know that this is a legacy transaction + sig = append([]byte{EthLegacy155TxSignaturePrefix}, sig...) + + if len(sig) != EthLegacy155TxSignatureLen0 && len(sig) != EthLegacy155TxSignatureLen1 { + return nil, fmt.Errorf("signature is not %d OR %d bytes; it is %d bytes", EthLegacy155TxSignatureLen0, EthLegacy155TxSignatureLen1, + len(sig)) + } + + return &typescrypto.Signature{ + Type: typescrypto.SigTypeDelegated, Data: sig, + }, nil +} + +func (tx *EthLegacy155TxArgs) Sender() (address.Address, error) { + if err := validateEIP155ChainId(tx.legacyTx.V); err != nil { + return address.Address{}, fmt.Errorf("failed to validate EIP155 chain id: %w", err) + } + return sender(tx) +} + +func (tx *EthLegacy155TxArgs) Type() int { + return EthLegacyTxType +} + +var big8 = big.NewInt(8) + +func (tx *EthLegacy155TxArgs) ToVerifiableSignature(sig []byte) ([]byte, error) { + if len(sig) != EthLegacy155TxSignatureLen0 && len(sig) != EthLegacy155TxSignatureLen1 { + return nil, fmt.Errorf("signature should be %d or %d bytes long but got %d bytes", + EthLegacy155TxSignatureLen0, EthLegacy155TxSignatureLen1, len(sig)) + } + if sig[0] != EthLegacy155TxSignaturePrefix { + return nil, fmt.Errorf("expected signature prefix 0x%x, but got 0x%x", EthLegacy155TxSignaturePrefix, sig[0]) + } + + // Remove the prefix byte as it's only used for legacy transaction identification + sig = sig[1:] + + // Extract the 'v' value from the signature + vValue := big.NewFromGo(big.NewInt(0).SetBytes(sig[64:])) + + if err := validateEIP155ChainId(vValue); err != nil { + return nil, fmt.Errorf("failed to validate EIP155 chain id: %w", err) + } + + // See https://github.com/ethereum/go-ethereum/blob/86a1f0c39494c8f5caddf6bd9fbddd4bdfa944fd/core/types/transaction_signing.go#L424 + chainIDMul := big.Mul(big.NewIntUnsigned(uint64(Eip155ChainID)), big.NewInt(2)) + vValue = big.Sub(vValue, chainIDMul) + vValue = big.Sub(vValue, big8) + + // Adjust 'v' value for compatibility with new transactions: 27 -> 0, 28 -> 1 + if vValue.Equals(big.NewInt(27)) { + sig[64] = 0 + } else if vValue.Equals(big.NewInt(28)) { + sig[64] = 1 + } else { + return nil, fmt.Errorf("invalid 'v' value: expected 27 or 28, got %d", vValue.Int64()) + } + + return sig[0:65], nil +} + +func (tx *EthLegacy155TxArgs) InitialiseSignature(sig typescrypto.Signature) error { + if sig.Type != typescrypto.SigTypeDelegated { + return fmt.Errorf("RecoverSignature only supports Delegated signature") + } + + if len(sig.Data) != EthLegacy155TxSignatureLen0 && len(sig.Data) != EthLegacy155TxSignatureLen1 { + return fmt.Errorf("signature should be %d or %d bytes long, but got %d bytes", EthLegacy155TxSignatureLen0, + EthLegacy155TxSignatureLen1, len(sig.Data)) + } + + if sig.Data[0] != EthLegacy155TxSignaturePrefix { + return fmt.Errorf("expected signature prefix 0x01, but got 0x%x", sig.Data[0]) + } + + // ignore the first byte of the signature as it's only used for legacy transaction identification + r_, err := parseBigInt(sig.Data[1:33]) + if err != nil { + return fmt.Errorf("cannot parse r into EthBigInt: %w", err) + } + + s_, err := parseBigInt(sig.Data[33:65]) + if err != nil { + return fmt.Errorf("cannot parse s into EthBigInt: %w", err) + } + + v_, err := parseBigInt(sig.Data[65:]) + if err != nil { + return fmt.Errorf("cannot parse v into EthBigInt: %w", err) + } + + if err := validateEIP155ChainId(v_); err != nil { + return fmt.Errorf("failed to validate EIP155 chain id: %w", err) + } + + tx.legacyTx.R = r_ + tx.legacyTx.S = s_ + tx.legacyTx.V = v_ + return nil +} + +func (tx *EthLegacy155TxArgs) packTxFields() ([]interface{}, error) { + nonce, err := formatInt(tx.legacyTx.Nonce) + if err != nil { + return nil, err + } + + // format gas price + gasPrice, err := formatBigInt(tx.legacyTx.GasPrice) + if err != nil { + return nil, err + } + + gasLimit, err := formatInt(tx.legacyTx.GasLimit) + if err != nil { + return nil, err + } + + value, err := formatBigInt(tx.legacyTx.Value) + if err != nil { + return nil, err + } + + chainIDBigInt := big.NewIntUnsigned(uint64(Eip155ChainID)) + chainID, err := formatBigInt(chainIDBigInt) + if err != nil { + return nil, err + } + + r, err := formatInt(0) + if err != nil { + return nil, err + } + + s, err := formatInt(0) + if err != nil { + return nil, err + } + + res := []interface{}{ + nonce, + gasPrice, + gasLimit, + formatEthAddr(tx.legacyTx.To), + value, + tx.legacyTx.Input, + chainID, + r, s, + } + return res, nil +} + +func validateEIP155ChainId(v big.Int) error { + chainID := deriveEIP155ChainId(v) + if !chainID.Equals(big.NewIntUnsigned(uint64(Eip155ChainID))) { + return fmt.Errorf("invalid chain id, expected %d, got %s", Eip155ChainID, chainID.String()) + } + return nil +} + +// deriveEIP155ChainId derives the chain id from the given v parameter +func deriveEIP155ChainId(v big.Int) big.Int { + if big.BitLen(v) <= 64 { + vUint64 := v.Uint64() + if vUint64 == 27 || vUint64 == 28 { + return big.NewInt(0) + } + return big.NewIntUnsigned((vUint64 - 35) / 2) + } + + v = big.Sub(v, big.NewInt(35)) + return big.Div(v, big.NewInt(2)) +} + +func calcEIP155TxSignatureLen(chain uint64, v int) int { + chainID := big.NewIntUnsigned(chain) + vVal := big.Add(big.Mul(chainID, big.NewInt(2)), big.NewInt(int64(v))) + vLen := len(vVal.Int.Bytes()) + + // EthLegacyHomesteadTxSignatureLen includes the 1 byte legacy tx marker prefix and also 1 byte for the V value. + // So we subtract 1 to not double count the length of the v value + return EthLegacyHomesteadTxSignatureLen + vLen - 1 +} diff --git a/venus-shared/actors/types/eth_legacy_155_transactions_test.go b/venus-shared/actors/types/eth_legacy_155_transactions_test.go new file mode 100644 index 0000000000..443009b05a --- /dev/null +++ b/venus-shared/actors/types/eth_legacy_155_transactions_test.go @@ -0,0 +1,188 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-state-types/big" + builtintypes "github.com/filecoin-project/go-state-types/builtin" +) + +func TestEIP155Tx(t *testing.T) { + txStr := "f86680843b9aca00835dc1ba94c2dca9a18d4a4057921d1bcb22da05e68e46b1d06480820297a0f91ee69c4603c4f21131467ee9e06ad4a96d0a29fa8064db61f3adaea0eb6e92a07181e306bb8f773d94cc3b75e9835de00c004e072e6630c0c46971d38706bb01" + + bz := mustDecodeHex(txStr) + + tx, err := parseLegacyTx(bz) + require.NoError(t, err) + + eth155Tx, ok := tx.(*EthLegacy155TxArgs) + require.True(t, ok) + + // Verify nonce + require.EqualValues(t, 0, eth155Tx.legacyTx.Nonce) + + // Verify recipient address + expectedToAddr, err := ParseEthAddress("0xc2dca9a18d4a4057921d1bcb22da05e68e46b1d0") + require.NoError(t, err) + require.EqualValues(t, expectedToAddr, *eth155Tx.legacyTx.To) + + // Verify sender address + expectedFromAddr, err := ParseEthAddress("0xA2BBB73aC59b256415e91A820b224dbAF2C268FA") + require.NoError(t, err) + sender, err := eth155Tx.Sender() + require.NoError(t, err) + expectedFromFilecoinAddr, err := expectedFromAddr.ToFilecoinAddress() + require.NoError(t, err) + require.EqualValues(t, expectedFromFilecoinAddr, sender) + + // Verify transaction value + expectedValue, ok := big.NewInt(0).SetString("100", 10) + require.True(t, ok) + require.True(t, eth155Tx.legacyTx.Value.Cmp(expectedValue) == 0) + + // Verify gas limit and gas price + expectedGasPrice, ok := big.NewInt(0).SetString("1000000000", 10) + require.True(t, ok) + require.EqualValues(t, 6144442, eth155Tx.legacyTx.GasLimit) + require.True(t, eth155Tx.legacyTx.GasPrice.Cmp(expectedGasPrice) == 0) + + require.Empty(t, eth155Tx.legacyTx.Input) + + // Verify signature values (v, r, s) + expectedV, ok := big.NewInt(0).SetString("0297", 16) + require.True(t, ok) + require.True(t, eth155Tx.legacyTx.V.Cmp(expectedV) == 0) + + expectedR, ok := big.NewInt(0).SetString("f91ee69c4603c4f21131467ee9e06ad4a96d0a29fa8064db61f3adaea0eb6e92", 16) + require.True(t, ok) + require.True(t, eth155Tx.legacyTx.R.Cmp(expectedR) == 0) + + expectedS, ok := big.NewInt(0).SetString("7181e306bb8f773d94cc3b75e9835de00c004e072e6630c0c46971d38706bb01", 16) + require.True(t, ok) + require.True(t, eth155Tx.legacyTx.S.Cmp(expectedS) == 0) + + // Convert to signed Filecoin message and verify fields + smsg, err := ToSignedFilecoinMessage(eth155Tx) + require.NoError(t, err) + + require.EqualValues(t, smsg.Message.From, sender) + + expectedToFilecoinAddr, err := eth155Tx.legacyTx.To.ToFilecoinAddress() + require.NoError(t, err) + require.EqualValues(t, smsg.Message.To, expectedToFilecoinAddr) + require.EqualValues(t, smsg.Message.Value, eth155Tx.legacyTx.Value) + require.EqualValues(t, smsg.Message.GasLimit, eth155Tx.legacyTx.GasLimit) + require.EqualValues(t, smsg.Message.GasFeeCap, eth155Tx.legacyTx.GasPrice) + require.EqualValues(t, smsg.Message.GasPremium, eth155Tx.legacyTx.GasPrice) + require.EqualValues(t, smsg.Message.Nonce, eth155Tx.legacyTx.Nonce) + require.Empty(t, smsg.Message.Params) + require.EqualValues(t, smsg.Message.Method, builtintypes.MethodsEVM.InvokeContract) + + // Convert signed Filecoin message back to Ethereum transaction and verify equality + ethTx, err := EthTransactionFromSignedFilecoinMessage(smsg) + require.NoError(t, err) + convertedLegacyTx, ok := ethTx.(*EthLegacy155TxArgs) + require.True(t, ok) + eth155Tx.legacyTx.Input = nil + require.EqualValues(t, convertedLegacyTx, eth155Tx) + + // Verify EthTx fields + ethTxVal, err := eth155Tx.ToEthTx(smsg) + require.NoError(t, err) + expectedHash, err := eth155Tx.TxHash() + require.NoError(t, err) + require.EqualValues(t, ethTxVal.Hash, expectedHash) + require.Nil(t, ethTxVal.MaxFeePerGas) + require.Nil(t, ethTxVal.MaxPriorityFeePerGas) + require.EqualValues(t, ethTxVal.Gas, eth155Tx.legacyTx.GasLimit) + require.EqualValues(t, ethTxVal.Value, eth155Tx.legacyTx.Value) + require.EqualValues(t, ethTxVal.Nonce, eth155Tx.legacyTx.Nonce) + require.EqualValues(t, ethTxVal.To, eth155Tx.legacyTx.To) + require.EqualValues(t, ethTxVal.From, expectedFromAddr) +} + +func TestDeriveEIP155ChainId(t *testing.T) { + tests := []struct { + name string + v big.Int + expectedChainID big.Int + }{ + { + name: "V equals 27", + v: big.NewInt(27), + expectedChainID: big.NewInt(0), + }, + { + name: "V equals 28", + v: big.NewInt(28), + expectedChainID: big.NewInt(0), + }, + { + name: "V small chain ID", + v: big.NewInt(37), // (37 - 35) / 2 = 1 + expectedChainID: big.NewInt(1), + }, + { + name: "V large chain ID", + v: big.NewInt(1001), // (1001 - 35) / 2 = 483 + expectedChainID: big.NewInt(483), + }, + { + name: "V very large chain ID", + v: big.NewInt(1 << 20), // (1048576 - 35) / 2 = 524770 + expectedChainID: big.NewInt(524270), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := deriveEIP155ChainId(tt.v) + require.True(t, result.Equals(tt.expectedChainID), "Expected %s, got %s for V=%s", tt.expectedChainID.String(), result.String(), tt.v.String()) + }) + } +} + +func TestCalcEIP155TxSignatureLen(t *testing.T) { + tests := []struct { + name string + chainID uint64 + expected int + }{ + { + name: "ChainID that fits in 1 byte", + chainID: 0x01, + expected: EthLegacyHomesteadTxSignatureLen + 1 - 1, + }, + { + name: "ChainID that fits in 2 bytes", + chainID: 0x0100, + expected: EthLegacyHomesteadTxSignatureLen + 2 - 1, + }, + { + name: "ChainID that fits in 3 bytes", + chainID: 0x010000, + expected: EthLegacyHomesteadTxSignatureLen + 3 - 1, + }, + { + name: "ChainID that fits in 4 bytes", + chainID: 0x01000000, + expected: EthLegacyHomesteadTxSignatureLen + 4 - 1, + }, + { + name: "ChainID that fits in 6 bytes", + chainID: 0x010000000000, + expected: EthLegacyHomesteadTxSignatureLen + 6 - 1, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := calcEIP155TxSignatureLen(tt.chainID, 1) + if result != tt.expected { + t.Errorf("calcEIP155TxSignatureLen(%d) = %d, want %d", tt.chainID, result, tt.expected) + } + }) + } +} diff --git a/venus-shared/actors/types/eth_legacy_homestead_transactions.go b/venus-shared/actors/types/eth_legacy_homestead_transactions.go new file mode 100644 index 0000000000..ef96b52674 --- /dev/null +++ b/venus-shared/actors/types/eth_legacy_homestead_transactions.go @@ -0,0 +1,226 @@ +package types + +import ( + "fmt" + + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/big" + typescrypto "github.com/filecoin-project/go-state-types/crypto" +) + +var _ EthTransaction = (*EthLegacyHomesteadTxArgs)(nil) + +type EthLegacyHomesteadTxArgs struct { + Nonce int `json:"nonce"` + GasPrice big.Int `json:"gasPrice"` + GasLimit int `json:"gasLimit"` + To *EthAddress `json:"to"` + Value big.Int `json:"value"` + Input []byte `json:"input"` + V big.Int `json:"v"` + R big.Int `json:"r"` + S big.Int `json:"s"` +} + +func (tx *EthLegacyHomesteadTxArgs) ToEthTx(smsg *SignedMessage) (EthTx, error) { + from, err := EthAddressFromFilecoinAddress(smsg.Message.From) + if err != nil { + return EthTx{}, fmt.Errorf("sender was not an eth account") + } + hash, err := tx.TxHash() + if err != nil { + return EthTx{}, fmt.Errorf("failed to get tx hash: %w", err) + } + + gasPrice := EthBigInt(tx.GasPrice) + ethTx := EthTx{ + ChainID: EthLegacyHomesteadTxChainID, + Type: EthLegacyTxType, + Nonce: EthUint64(tx.Nonce), + Hash: hash, + To: tx.To, + Value: EthBigInt(tx.Value), + Input: tx.Input, + Gas: EthUint64(tx.GasLimit), + GasPrice: &gasPrice, + From: from, + R: EthBigInt(tx.R), + S: EthBigInt(tx.S), + V: EthBigInt(tx.V), + } + + return ethTx, nil +} + +func (tx *EthLegacyHomesteadTxArgs) ToUnsignedFilecoinMessage(from address.Address) (*Message, error) { + mi, err := getFilecoinMethodInfo(tx.To, tx.Input) + if err != nil { + return nil, xerrors.Errorf("failed to get method info: %w", err) + } + + return &Message{ + Version: 0, + To: mi.to, + From: from, + Nonce: uint64(tx.Nonce), + Value: tx.Value, + GasLimit: int64(tx.GasLimit), + GasFeeCap: tx.GasPrice, + GasPremium: tx.GasPrice, + Method: mi.method, + Params: mi.params, + }, nil +} + +func (tx *EthLegacyHomesteadTxArgs) ToVerifiableSignature(sig []byte) ([]byte, error) { + if len(sig) != EthLegacyHomesteadTxSignatureLen { + return nil, fmt.Errorf("signature should be %d bytes long (1 byte metadata, %d bytes sig data), but got %d bytes", + EthLegacyHomesteadTxSignatureLen, EthLegacyHomesteadTxSignatureLen-1, len(sig)) + } + if sig[0] != EthLegacyHomesteadTxSignaturePrefix { + return nil, fmt.Errorf("expected signature prefix 0x%x, but got 0x%x", EthLegacyHomesteadTxSignaturePrefix, sig[0]) + } + + // Remove the prefix byte as it's only used for legacy transaction identification + sig = sig[1:] + + // Extract the 'v' value from the signature, which is the last byte in Ethereum signatures + vValue := big.NewFromGo(big.NewInt(0).SetBytes(sig[64:])) + + // Adjust 'v' value for compatibility with new transactions: 27 -> 0, 28 -> 1 + if vValue.Equals(big.NewInt(27)) { + sig[64] = 0 + } else if vValue.Equals(big.NewInt(28)) { + sig[64] = 1 + } else { + return nil, fmt.Errorf("invalid 'v' value: expected 27 or 28, got %d", vValue.Int64()) + } + + return sig, nil +} + +func (tx *EthLegacyHomesteadTxArgs) ToRlpUnsignedMsg() ([]byte, error) { + return toRlpUnsignedMsg(tx) +} + +func (tx *EthLegacyHomesteadTxArgs) TxHash() (EthHash, error) { + rlp, err := tx.ToRlpSignedMsg() + if err != nil { + return EthHash{}, err + } + return EthHashFromTxBytes(rlp), nil +} + +func (tx *EthLegacyHomesteadTxArgs) ToRlpSignedMsg() ([]byte, error) { + return toRlpSignedMsg(tx, tx.V, tx.R, tx.S) +} + +func (tx *EthLegacyHomesteadTxArgs) Signature() (*typescrypto.Signature, error) { + // throw an error if the v value is not 27 or 28 + if !tx.V.Equals(big.NewInt(27)) && !tx.V.Equals(big.NewInt(28)) { + return nil, fmt.Errorf("legacy homestead transactions only support 27 or 28 for v") + } + r := tx.R.Int.Bytes() + s := tx.S.Int.Bytes() + v := tx.V.Int.Bytes() + + sig := append([]byte{}, padLeadingZeros(r, 32)...) + sig = append(sig, padLeadingZeros(s, 32)...) + if len(v) == 0 { + sig = append(sig, 0) + } else { + sig = append(sig, v[0]) + } + // pre-pend a one byte marker so nodes know that this is a legacy transaction + sig = append([]byte{EthLegacyHomesteadTxSignaturePrefix}, sig...) + + if len(sig) != EthLegacyHomesteadTxSignatureLen { + return nil, fmt.Errorf("signature is not %d bytes", EthLegacyHomesteadTxSignatureLen) + } + + return &typescrypto.Signature{ + Type: typescrypto.SigTypeDelegated, Data: sig, + }, nil +} + +func (tx *EthLegacyHomesteadTxArgs) Sender() (address.Address, error) { + return sender(tx) +} + +func (tx *EthLegacyHomesteadTxArgs) Type() int { + return EthLegacyTxType +} + +func (tx *EthLegacyHomesteadTxArgs) InitialiseSignature(sig typescrypto.Signature) error { + if sig.Type != typescrypto.SigTypeDelegated { + return fmt.Errorf("RecoverSignature only supports Delegated signature") + } + + if len(sig.Data) != EthLegacyHomesteadTxSignatureLen { + return fmt.Errorf("signature should be %d bytes long, but got %d bytes", EthLegacyHomesteadTxSignatureLen, len(sig.Data)) + } + + if sig.Data[0] != EthLegacyHomesteadTxSignaturePrefix { + return fmt.Errorf("expected signature prefix 0x01, but got 0x%x", sig.Data[0]) + } + + // ignore the first byte of the signature as it's only used for legacy transaction identification + r_, err := parseBigInt(sig.Data[1:33]) + if err != nil { + return fmt.Errorf("cannot parse r into EthBigInt: %w", err) + } + + s_, err := parseBigInt(sig.Data[33:65]) + if err != nil { + return fmt.Errorf("cannot parse s into EthBigInt: %w", err) + } + + v_, err := parseBigInt([]byte{sig.Data[65]}) + if err != nil { + return fmt.Errorf("cannot parse v into EthBigInt: %w", err) + } + + if !v_.Equals(big.NewInt(27)) && !v_.Equals(big.NewInt(28)) { + return fmt.Errorf("legacy homestead transactions only support 27 or 28 for v") + } + + tx.R = r_ + tx.S = s_ + tx.V = v_ + return nil +} + +func (tx *EthLegacyHomesteadTxArgs) packTxFields() ([]interface{}, error) { + nonce, err := formatInt(tx.Nonce) + if err != nil { + return nil, err + } + + // format gas price + gasPrice, err := formatBigInt(tx.GasPrice) + if err != nil { + return nil, err + } + + gasLimit, err := formatInt(tx.GasLimit) + if err != nil { + return nil, err + } + + value, err := formatBigInt(tx.Value) + if err != nil { + return nil, err + } + + res := []interface{}{ + nonce, + gasPrice, + gasLimit, + formatEthAddr(tx.To), + value, + tx.Input, + } + return res, nil +} diff --git a/venus-shared/actors/types/eth_legacy_homestead_transactions_test.go b/venus-shared/actors/types/eth_legacy_homestead_transactions_test.go new file mode 100644 index 0000000000..3134f0aab2 --- /dev/null +++ b/venus-shared/actors/types/eth_legacy_homestead_transactions_test.go @@ -0,0 +1,299 @@ +package types + +import ( + "encoding/hex" + "strings" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-state-types/big" + builtintypes "github.com/filecoin-project/go-state-types/builtin" + + "github.com/filecoin-project/venus/pkg/crypto" +) + +func TestEthLegacyHomesteadTxArgs(t *testing.T) { + testcases := []struct { + RawTx string + ExpectedNonce uint64 + ExpectedTo string + ExpectedInput string + ExpectedGasPrice big.Int + ExpectedGasLimit int + ExpectErr bool + }{ + { + "0xf882800182540894095e7baea6a6c7c4c2dfeb977efac326af552d8780a3deadbeef0000000101010010101010101010101010101aaabbbbbbcccccccddddddddd1ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a01fffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + 0x0, + "0x095e7baea6a6c7c4c2dfeb977efac326af552d87", + "0xdeadbeef0000000101010010101010101010101010101aaabbbbbbcccccccddddddddd", + big.NewInt(1), + 0x5408, + false, + }, + { + "0xf85f030182520794b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa07778cde41a8a37f6a087622b38bc201bd3e7df06dce067569d4def1b53dba98c", + 0x3, + "0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x", + big.NewInt(1), + 0x5207, + false, + }, + } + + for i, tc := range testcases { + // parse txargs + tx, err := parseLegacyTx(mustDecodeHex(tc.RawTx)) + require.NoError(t, err) + + msgRecovered, err := tx.ToRlpUnsignedMsg() + require.NoError(t, err) + + // verify signatures + from, err := tx.Sender() + require.NoError(t, err) + + smsg, err := ToSignedFilecoinMessage(tx) + require.NoError(t, err) + + sig := smsg.Signature.Data[:] + sig = sig[1:] + vValue := big.NewInt(0).SetBytes(sig[64:]) + vValue_ := big.Sub(big.NewFromGo(vValue), big.NewInt(27)) + sig[64] = byte(vValue_.Uint64()) + smsg.Signature.Data = sig + + err = crypto.Verify(&smsg.Signature, from, msgRecovered) + require.NoError(t, err) + + txArgs := tx.(*EthLegacyHomesteadTxArgs) + // verify data + require.EqualValues(t, tc.ExpectedNonce, txArgs.Nonce, i) + + expectedTo, err := ParseEthAddress(tc.ExpectedTo) + require.NoError(t, err) + require.EqualValues(t, expectedTo, *txArgs.To, i) + require.EqualValues(t, tc.ExpectedInput, "0x"+hex.EncodeToString(txArgs.Input)) + require.EqualValues(t, tc.ExpectedGasPrice, txArgs.GasPrice) + require.EqualValues(t, tc.ExpectedGasLimit, txArgs.GasLimit) + } +} + +func TestLegacyHomesteadSignatures(t *testing.T) { + testcases := []struct { + RawTx string + ExpectedR string + ExpectedS string + ExpectedV string + ExpectErr bool + ExpectErrMsg string + ExpectVMismatch bool + }{ + { + "0xf882800182540894095e7baea6a6c7c4c2dfeb977efac326af552d8780a3deadbeef0000000101010010101010101010101010101aaabbbbbbcccccccddddddddd1ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a01fffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "0x1fffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "0x1b", + false, + "", + false, + }, + { + "0xf85f030182520794b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa07778cde41a8a37f6a087622b38bc201bd3e7df06dce067569d4def1b53dba98c", + "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "0x7778cde41a8a37f6a087622b38bc201bd3e7df06dce067569d4def1b53dba98c", + "0x1b", + false, + "", + false, + }, + { + "0xf882800182540894095e7baea6a6c7c4c2dfeb977efac326af552d8780a3deadbeef0000000101010010101010101010101010101aaabbbbbbcccccccddddddddd1ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a01fffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "0x1fffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "0x1c", + false, + "", + true, + }, + { + "0xf882800182540894095e7baea6a6c7c4c2dfeb977efac326af552d8780a3deadbeef0000000101010010101010101010101010101aaabbbbbbcccccccddddddddd1ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a01fffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "0x1fffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "0x1f", + false, + "", + true, + }, + { + "0x00", + "", + "", + "", + true, + "not a legacy eth transaction", + false, + }, + } + + for i, tc := range testcases { + tx, err := parseLegacyTx(mustDecodeHex(tc.RawTx)) + if tc.ExpectErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.ExpectErrMsg) + continue + } + require.Nil(t, err) + + sig, err := tx.Signature() + require.Nil(t, err) + + require.NoError(t, tx.InitialiseSignature(*sig)) + + txArgs := tx.(*EthLegacyHomesteadTxArgs) + + require.Equal(t, tc.ExpectedR, "0x"+txArgs.R.Text(16), i) + require.Equal(t, tc.ExpectedS, "0x"+txArgs.S.Text(16), i) + + if tc.ExpectVMismatch { + require.NotEqual(t, tc.ExpectedV, "0x"+txArgs.V.Text(16), i) + } else { + require.Equal(t, tc.ExpectedV, "0x"+txArgs.V.Text(16), i) + } + } +} + +// https://etherscan.io/getRawTx?tx=0xc55e2b90168af6972193c1f86fa4d7d7b31a29c156665d15b9cd48618b5177ef +// https://tools.deth.net/tx-decoder +func TestEtherScanLegacyRLP(t *testing.T) { + rlp := "0xf8718301efc58506fc23ac008305161594104994f45d9d697ca104e5704a7b77d7fec3537c890821878651a4d70000801ba051222d91a379452395d0abaff981af4cfcc242f25cfaf947dea8245a477731f9a03a997c910b4701cca5d933fb26064ee5af7fe3236ff0ef2b58aa50b25aff8ca5" + bz := mustDecodeHex(rlp) + + tx, err := parseLegacyTx(bz) + require.NoError(t, err) + + ethLegacyTx, ok := tx.(*EthLegacyHomesteadTxArgs) + require.True(t, ok) + + // Verify nonce + require.EqualValues(t, 0x1efc5, ethLegacyTx.Nonce) + + // Verify recipient address + expectedToAddr, err := ParseEthAddress("0x104994f45d9d697ca104e5704a7b77d7fec3537c") + require.NoError(t, err) + require.EqualValues(t, expectedToAddr, *ethLegacyTx.To) + + // Verify sender address + expectedFromAddr, err := ParseEthAddress("0x32Be343B94f860124dC4fEe278FDCBD38C102D88") + require.NoError(t, err) + sender, err := ethLegacyTx.Sender() + require.NoError(t, err) + expectedFromFilecoinAddr, err := expectedFromAddr.ToFilecoinAddress() + require.NoError(t, err) + require.EqualValues(t, expectedFromFilecoinAddr, sender) + + // Verify transaction value + expectedValue, ok := big.NewInt(0).SetString("821878651a4d70000", 16) + require.True(t, ok) + require.True(t, ethLegacyTx.Value.Cmp(expectedValue) == 0) + + // Verify gas limit and gas price + expectedGasPrice, ok := big.NewInt(0).SetString("6fc23ac00", 16) + require.True(t, ok) + require.EqualValues(t, 0x51615, ethLegacyTx.GasLimit) + require.True(t, ethLegacyTx.GasPrice.Cmp(expectedGasPrice) == 0) + + require.Empty(t, ethLegacyTx.Input) + + // Verify signature values (v, r, s) + expectedV, ok := big.NewInt(0).SetString("1b", 16) + require.True(t, ok) + require.True(t, ethLegacyTx.V.Cmp(expectedV) == 0) + + expectedR, ok := big.NewInt(0).SetString("51222d91a379452395d0abaff981af4cfcc242f25cfaf947dea8245a477731f9", 16) + require.True(t, ok) + require.True(t, ethLegacyTx.R.Cmp(expectedR) == 0) + + expectedS, ok := big.NewInt(0).SetString("3a997c910b4701cca5d933fb26064ee5af7fe3236ff0ef2b58aa50b25aff8ca5", 16) + require.True(t, ok) + require.True(t, ethLegacyTx.S.Cmp(expectedS) == 0) + + // Convert to signed Filecoin message and verify fields + smsg, err := ToSignedFilecoinMessage(ethLegacyTx) + require.NoError(t, err) + + require.EqualValues(t, smsg.Message.From, sender) + + expectedToFilecoinAddr, err := ethLegacyTx.To.ToFilecoinAddress() + require.NoError(t, err) + require.EqualValues(t, smsg.Message.To, expectedToFilecoinAddr) + require.EqualValues(t, smsg.Message.Value, ethLegacyTx.Value) + require.EqualValues(t, smsg.Message.GasLimit, ethLegacyTx.GasLimit) + require.EqualValues(t, smsg.Message.GasFeeCap, ethLegacyTx.GasPrice) + require.EqualValues(t, smsg.Message.GasPremium, ethLegacyTx.GasPrice) + require.EqualValues(t, smsg.Message.Nonce, ethLegacyTx.Nonce) + require.Empty(t, smsg.Message.Params) + require.EqualValues(t, smsg.Message.Method, builtintypes.MethodsEVM.InvokeContract) + + // Convert signed Filecoin message back to Ethereum transaction and verify equality + ethTx, err := EthTransactionFromSignedFilecoinMessage(smsg) + require.NoError(t, err) + convertedLegacyTx, ok := ethTx.(*EthLegacyHomesteadTxArgs) + require.True(t, ok) + ethLegacyTx.Input = nil + require.EqualValues(t, convertedLegacyTx, ethLegacyTx) + + // Verify EthTx fields + ethTxVal, err := ethLegacyTx.ToEthTx(smsg) + require.NoError(t, err) + expectedHash, err := ethLegacyTx.TxHash() + require.NoError(t, err) + require.EqualValues(t, ethTxVal.Hash, expectedHash) + require.Nil(t, ethTxVal.MaxFeePerGas) + require.Nil(t, ethTxVal.MaxPriorityFeePerGas) + require.EqualValues(t, ethTxVal.Gas, ethLegacyTx.GasLimit) + require.EqualValues(t, ethTxVal.Value, ethLegacyTx.Value) + require.EqualValues(t, ethTxVal.Nonce, ethLegacyTx.Nonce) + require.EqualValues(t, ethTxVal.To, ethLegacyTx.To) + require.EqualValues(t, ethTxVal.From, expectedFromAddr) +} + +func TestFailurePaths(t *testing.T) { + // Test case for invalid RLP + invalidRLP := "0x08718301efc58506fc23ac008305161594104994f45d9d697ca104e5704a7b77d7fec3537c890821878651a4d70000801ba051222d91a379452395d0abaff981af4cfcc242f25cfaf947dea8245a477731f9a03a997c910b4701cca5d933fb26064ee5af7fe3236ff0ef2b58aa50b25aff8ca5" + decoded, err := hex.DecodeString(strings.TrimPrefix(invalidRLP, "0x")) + require.NoError(t, err) + + _, err = parseLegacyTx(decoded) + require.Error(t, err, "Expected error for invalid RLP") + + // Test case for mangled signature + mangledSignatureRLP := "0xf8718301efc58506fc23ac008305161594104994f45d9d697ca104e5704a7b77d7fec3537c890821878651a4d70000801ba051222d91a379452395d0abaff981af4cfcc242f25cfaf947dea8245a477731f9a03a997c910b4701cca5d933fb26064ee5af7fe3236ff0ef2b58aa50b25aff8ca5" + decodedSig, err := hex.DecodeString(strings.TrimPrefix(mangledSignatureRLP, "0x")) + require.NoError(t, err) + + tx, err := parseLegacyTx(decodedSig) + require.NoError(t, err) + + ethLegacyTx, ok := tx.(*EthLegacyHomesteadTxArgs) + require.True(t, ok) + + // Mangle R value + ethLegacyTx.R = big.Add(ethLegacyTx.R, big.NewInt(1)) + + expectedFromAddr, err := ParseEthAddress("0x32Be343B94f860124dC4fEe278FDCBD38C102D88") + require.NoError(t, err) + expectedFromFilecoinAddr, err := expectedFromAddr.ToFilecoinAddress() + require.NoError(t, err) + + senderAddr, err := ethLegacyTx.Sender() + require.NoError(t, err) + require.NotEqual(t, senderAddr, expectedFromFilecoinAddr, "Expected sender address to not match after mangling R value") + + // Mangle V value + ethLegacyTx.V = big.NewInt(1) + _, err = ethLegacyTx.Sender() + require.Error(t, err, "Expected error when V value is not 27 or 28") +} diff --git a/venus-shared/types/eth_test.go b/venus-shared/actors/types/eth_test.go similarity index 100% rename from venus-shared/types/eth_test.go rename to venus-shared/actors/types/eth_test.go diff --git a/venus-shared/actors/types/eth_transactions.go b/venus-shared/actors/types/eth_transactions.go index e57b5f215e..94b9c47fa1 100644 --- a/venus-shared/actors/types/eth_transactions.go +++ b/venus-shared/actors/types/eth_transactions.go @@ -3,21 +3,68 @@ package types import ( "bytes" "encoding/binary" + "errors" "fmt" mathbig "math/big" - cbg "github.com/whyrusleeping/cbor-gen" - "golang.org/x/crypto/sha3" - "github.com/filecoin-project/go-address" gocrypto "github.com/filecoin-project/go-crypto" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" builtintypes "github.com/filecoin-project/go-state-types/builtin" typescrypto "github.com/filecoin-project/go-state-types/crypto" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/crypto/sha3" +) + +const ( + EthLegacyTxType = 0x00 + EIP1559TxType = 0x02 +) + +const ( + EthEIP1559TxSignatureLen = 65 + EthLegacyHomesteadTxSignatureLen = 66 + EthLegacyHomesteadTxSignaturePrefix = 0x01 + EthLegacy155TxSignaturePrefix = 0x02 + EthLegacyHomesteadTxChainID = 0x00 ) -const Eip1559TxType = 2 +var ( + EthLegacy155TxSignatureLen0 int + EthLegacy155TxSignatureLen1 int +) + +func init() { + initEthLegacy155TxSignature() +} + +func initEthLegacy155TxSignature() { + EthLegacy155TxSignatureLen0 = calcEIP155TxSignatureLen(uint64(Eip155ChainID), 35) + EthLegacy155TxSignatureLen1 = calcEIP155TxSignatureLen(uint64(Eip155ChainID), 36) +} + +// EthTransaction defines the interface for Ethereum-like transactions. +// It provides methods to convert transactions to various formats, +// retrieve transaction details, and manipulate transaction signatures. +type EthTransaction interface { + Type() int + Sender() (address.Address, error) + Signature() (*typescrypto.Signature, error) + InitialiseSignature(sig typescrypto.Signature) error + ToUnsignedFilecoinMessage(from address.Address) (*Message, error) + ToRlpUnsignedMsg() ([]byte, error) + ToRlpSignedMsg() ([]byte, error) + TxHash() (EthHash, error) + ToVerifiableSignature(sig []byte) ([]byte, error) + ToEthTx(*SignedMessage) (EthTx, error) +} + +// EthTx represents an Ethereum transaction structure, encapsulating fields that align with the standard Ethereum transaction components. +// This structure can represent both EIP-1559 transactions and legacy Homestead transactions: +// - In EIP-1559 transactions, the `GasPrice` field is set to nil/empty. +// - In legacy Homestead transactions, the `GasPrice` field is populated to specify the fee per unit of gas, while the `MaxFeePerGas` and `MaxPriorityFeePerGas` fields are set to nil/empty. +// Additionally, both the `ChainID` and the `Type` fields are set to 0 in legacy Homestead transactions to differentiate them from EIP-1559 transactions. type EthTx struct { ChainID EthUint64 `json:"chainId"` @@ -32,169 +79,122 @@ type EthTx struct { Type EthUint64 `json:"type"` Input EthBytes `json:"input"` Gas EthUint64 `json:"gas"` - MaxFeePerGas EthBigInt `json:"maxFeePerGas"` - MaxPriorityFeePerGas EthBigInt `json:"maxPriorityFeePerGas"` + MaxFeePerGas *EthBigInt `json:"maxFeePerGas,omitempty"` + MaxPriorityFeePerGas *EthBigInt `json:"maxPriorityFeePerGas,omitempty"` + GasPrice *EthBigInt `json:"gasPrice,omitempty"` AccessList []EthHash `json:"accessList"` V EthBigInt `json:"v"` R EthBigInt `json:"r"` S EthBigInt `json:"s"` } -type EthTxArgs struct { - ChainID int `json:"chainId"` - Nonce int `json:"nonce"` - To *EthAddress `json:"to"` - Value big.Int `json:"value"` - MaxFeePerGas big.Int `json:"maxFeePerGas"` - MaxPriorityFeePerGas big.Int `json:"maxPriorityFeePerGas"` - GasLimit int `json:"gasLimit"` - Input []byte `json:"input"` - V big.Int `json:"v"` - R big.Int `json:"r"` - S big.Int `json:"s"` +func (tx *EthTx) GasFeeCap() (EthBigInt, error) { + if tx.GasPrice == nil && tx.MaxFeePerGas == nil { + return EthBigInt{}, fmt.Errorf("gas fee cap is not set") + } + if tx.MaxFeePerGas != nil { + return *tx.MaxFeePerGas, nil + } + return *tx.GasPrice, nil } -// EthTxFromSignedEthMessage does NOT populate: -// - BlockHash -// - BlockNumber -// - TransactionIndex -// - From -// - Hash -func EthTxFromSignedEthMessage(smsg *SignedMessage) (EthTx, error) { - if smsg.Signature.Type != typescrypto.SigTypeDelegated { - return EthTx{}, fmt.Errorf("signature is not delegated type, is type: %d", smsg.Signature.Type) +func (tx *EthTx) GasPremium() (EthBigInt, error) { + if tx.GasPrice == nil && tx.MaxPriorityFeePerGas == nil { + return EthBigInt{}, fmt.Errorf("gas premium is not set") } - txArgs, err := EthTxArgsFromUnsignedEthMessage(&smsg.Message) - if err != nil { - return EthTx{}, fmt.Errorf("failed to convert the unsigned message: %w", err) + if tx.MaxPriorityFeePerGas != nil { + return *tx.MaxPriorityFeePerGas, nil } - r, s, v, err := RecoverSignature(smsg.Signature) - if err != nil { - return EthTx{}, fmt.Errorf("failed to recover signature: %w", err) - } - - return EthTx{ - Nonce: EthUint64(txArgs.Nonce), - ChainID: EthUint64(txArgs.ChainID), - To: txArgs.To, - Value: EthBigInt(txArgs.Value), - Type: Eip1559TxType, - Gas: EthUint64(txArgs.GasLimit), - MaxFeePerGas: EthBigInt(txArgs.MaxFeePerGas), - MaxPriorityFeePerGas: EthBigInt(txArgs.MaxPriorityFeePerGas), - AccessList: []EthHash{}, - V: v, - R: r, - S: s, - Input: txArgs.Input, - }, nil + return *tx.GasPrice, nil } -func EthTxArgsFromUnsignedEthMessage(msg *Message) (EthTxArgs, error) { - var ( - to *EthAddress - params []byte - err error - ) - - if msg.Version != 0 { - return EthTxArgs{}, fmt.Errorf("unsupported msg version: %d", msg.Version) +func EthTransactionFromSignedFilecoinMessage(smsg *SignedMessage) (EthTransaction, error) { + if smsg == nil { + return nil, errors.New("signed message is nil") } - if len(msg.Params) > 0 { - paramsReader := bytes.NewReader(msg.Params) - params, err = cbg.ReadByteArray(paramsReader, uint64(len(msg.Params))) - if err != nil { - return EthTxArgs{}, fmt.Errorf("failed to read params byte array: %w", err) - } - if paramsReader.Len() != 0 { - return EthTxArgs{}, fmt.Errorf("extra data found in params") - } - if len(params) == 0 { - return EthTxArgs{}, fmt.Errorf("non-empty params encode empty byte array") - } + // Ensure the signature type is delegated. + if smsg.Signature.Type != typescrypto.SigTypeDelegated { + return nil, fmt.Errorf("signature is not delegated type, is type: %d", smsg.Signature.Type) } - if msg.To == builtintypes.EthereumAddressManagerActorAddr { - if msg.Method != builtintypes.MethodsEAM.CreateExternal { - return EthTxArgs{}, fmt.Errorf("unsupported EAM method") - } - } else if msg.Method == builtintypes.MethodsEVM.InvokeContract { - addr, err := EthAddressFromFilecoinAddress(msg.To) - if err != nil { - return EthTxArgs{}, err - } - to = &addr - } else { - return EthTxArgs{}, - fmt.Errorf("invalid methodnum %d: only allowed method is InvokeContract(%d)", - msg.Method, builtintypes.MethodsEVM.InvokeContract) - } - - return EthTxArgs{ - ChainID: Eip155ChainID, - Nonce: int(msg.Nonce), - To: to, - Value: msg.Value, - Input: params, - MaxFeePerGas: msg.GasFeeCap, - MaxPriorityFeePerGas: msg.GasPremium, - GasLimit: int(msg.GasLimit), - }, nil -} + // Convert Filecoin address to Ethereum address. + _, err := EthAddressFromFilecoinAddress(smsg.Message.From) + if err != nil { + return nil, fmt.Errorf("sender was not an eth account") + } -func (tx *EthTxArgs) ToUnsignedMessage(from address.Address) (*Message, error) { - if tx.ChainID != Eip155ChainID { - return nil, fmt.Errorf("unsupported chain id: %d", tx.ChainID) + // Extract Ethereum parameters and recipient from the message. + params, to, err := getEthParamsAndRecipient(&smsg.Message) + if err != nil { + return nil, fmt.Errorf("failed to parse input params and recipient: %w", err) } - var err error - var params []byte - if len(tx.Input) > 0 { - buf := new(bytes.Buffer) - if err = cbg.WriteByteArray(buf, tx.Input); err != nil { - return nil, fmt.Errorf("failed to write input args: %w", err) - } - params = buf.Bytes() + // Check for supported message version. + if smsg.Message.Version != 0 { + return nil, fmt.Errorf("unsupported msg version: %d", smsg.Message.Version) } - var to address.Address - var method abi.MethodNum - // nil indicates the EAM, only CreateExternal is allowed - if tx.To == nil { - method = builtintypes.MethodsEAM.CreateExternal - to = builtintypes.EthereumAddressManagerActorAddr - } else { - method = builtintypes.MethodsEVM.InvokeContract - to, err = tx.To.ToFilecoinAddress() - if err != nil { - return nil, fmt.Errorf("failed to convert To into filecoin addr: %w", err) + // Determine the type of transaction based on the signature length + switch len(smsg.Signature.Data) { + case EthEIP1559TxSignatureLen: + tx := Eth1559TxArgs{ + ChainID: Eip155ChainID, + Nonce: int(smsg.Message.Nonce), + To: to, + Value: smsg.Message.Value, + Input: params, + MaxFeePerGas: smsg.Message.GasFeeCap, + MaxPriorityFeePerGas: smsg.Message.GasPremium, + GasLimit: int(smsg.Message.GasLimit), + } + if err := tx.InitialiseSignature(smsg.Signature); err != nil { + return nil, fmt.Errorf("failed to initialise signature: %w", err) + } + return &tx, nil + + case EthLegacyHomesteadTxSignatureLen, EthLegacy155TxSignatureLen0, EthLegacy155TxSignatureLen1: + legacyTx := &EthLegacyHomesteadTxArgs{ + Nonce: int(smsg.Message.Nonce), + To: to, + Value: smsg.Message.Value, + Input: params, + GasPrice: smsg.Message.GasFeeCap, + GasLimit: int(smsg.Message.GasLimit), + } + // Process based on the first byte of the signature + switch smsg.Signature.Data[0] { + case EthLegacyHomesteadTxSignaturePrefix: + if err := legacyTx.InitialiseSignature(smsg.Signature); err != nil { + return nil, fmt.Errorf("failed to initialise signature: %w", err) + } + return legacyTx, nil + case EthLegacy155TxSignaturePrefix: + tx := &EthLegacy155TxArgs{ + legacyTx: legacyTx, + } + if err := tx.InitialiseSignature(smsg.Signature); err != nil { + return nil, fmt.Errorf("failed to initialise signature: %w", err) + } + return tx, nil + default: + return nil, fmt.Errorf("unsupported legacy transaction; first byte of signature is %d", smsg.Signature.Data[0]) } - } - return &Message{ - Version: 0, - To: to, - From: from, - Nonce: uint64(tx.Nonce), - Value: tx.Value, - GasLimit: int64(tx.GasLimit), - GasFeeCap: tx.MaxFeePerGas, - GasPremium: tx.MaxPriorityFeePerGas, - Method: method, - Params: params, - }, nil + default: + return nil, fmt.Errorf("unsupported signature length") + } } -func (tx *EthTxArgs) ToSignedMessage() (*SignedMessage, error) { +func ToSignedFilecoinMessage(tx EthTransaction) (*SignedMessage, error) { from, err := tx.Sender() if err != nil { return nil, fmt.Errorf("failed to calculate sender: %w", err) } - unsignedMsg, err := tx.ToUnsignedMessage(from) + unsignedMsg, err := tx.ToUnsignedFilecoinMessage(from) if err != nil { return nil, fmt.Errorf("failed to convert to unsigned msg: %w", err) } @@ -210,443 +210,386 @@ func (tx *EthTxArgs) ToSignedMessage() (*SignedMessage, error) { }, nil } -func (tx *EthTxArgs) HashedOriginalRlpMsg() ([]byte, error) { - msg, err := tx.ToRlpUnsignedMsg() - if err != nil { - return nil, err - } - - hasher := sha3.NewLegacyKeccak256() - hasher.Write(msg) - hash := hasher.Sum(nil) - return hash, nil -} - -func (tx *EthTxArgs) ToRlpUnsignedMsg() ([]byte, error) { - packed, err := tx.packTxFields() - if err != nil { - return nil, err +func ParseEthTransaction(data []byte) (EthTransaction, error) { + if len(data) == 0 { + return nil, fmt.Errorf("empty data") } - encoded, err := EncodeRLP(packed) - if err != nil { - return nil, err + switch data[0] { + case 1: + // EIP-2930 + return nil, fmt.Errorf("EIP-2930 transaction is not supported") + case EIP1559TxType: + // EIP-1559 + return parseEip1559Tx(data) + default: + if data[0] > 0x7f { + tx, err := parseLegacyTx(data) + if err != nil { + return nil, fmt.Errorf("failed to parse legacy transaction: %w", err) + } + return tx, nil + } } - return append([]byte{0x02}, encoded...), nil -} -func (tx *EthTx) ToEthTxArgs() EthTxArgs { - return EthTxArgs{ - ChainID: int(tx.ChainID), - Nonce: int(tx.Nonce), - To: tx.To, - Value: big.Int(tx.Value), - MaxFeePerGas: big.Int(tx.MaxFeePerGas), - MaxPriorityFeePerGas: big.Int(tx.MaxPriorityFeePerGas), - GasLimit: int(tx.Gas), - Input: tx.Input, - V: big.Int(tx.V), - R: big.Int(tx.R), - S: big.Int(tx.S), - } + return nil, fmt.Errorf("unsupported transaction type") } -func (tx *EthTx) TxHash() (EthHash, error) { - ethTxArgs := tx.ToEthTxArgs() - return (ðTxArgs).TxHash() +type methodInfo struct { + to address.Address + method abi.MethodNum + params []byte } -func (tx *EthTxArgs) TxHash() (EthHash, error) { - rlp, err := tx.ToRlpSignedMsg() - if err != nil { - return EmptyEthHash, err +func getFilecoinMethodInfo(recipient *EthAddress, input []byte) (*methodInfo, error) { + var params []byte + if len(input) > 0 { + buf := new(bytes.Buffer) + if err := cbg.WriteByteArray(buf, input); err != nil { + return nil, fmt.Errorf("failed to write input args: %w", err) + } + params = buf.Bytes() } - return EthHashFromTxBytes(rlp), nil -} - -func (tx *EthTxArgs) ToRlpSignedMsg() ([]byte, error) { - packed1, err := tx.packTxFields() - if err != nil { - return nil, err - } + var to address.Address + var method abi.MethodNum - packed2, err := tx.packSigFields() - if err != nil { - return nil, err + if recipient == nil { + // If recipient is nil, use Ethereum Address Manager Actor and CreateExternal method + method = builtintypes.MethodsEAM.CreateExternal + to = builtintypes.EthereumAddressManagerActorAddr + } else { + // Otherwise, use InvokeContract method and convert EthAddress to Filecoin address + method = builtintypes.MethodsEVM.InvokeContract + var err error + to, err = recipient.ToFilecoinAddress() + if err != nil { + return nil, fmt.Errorf("failed to convert EthAddress to Filecoin address: %w", err) + } } - encoded, err := EncodeRLP(append(packed1, packed2...)) - if err != nil { - return nil, err - } - return append([]byte{0x02}, encoded...), nil + return &methodInfo{ + to: to, + method: method, + params: params, + }, nil } -func (tx *EthTxArgs) packTxFields() ([]interface{}, error) { - chainID, err := formatInt(tx.ChainID) - if err != nil { - return nil, err - } - - nonce, err := formatInt(tx.Nonce) +func packSigFields(v, r, s big.Int) ([]interface{}, error) { + rr, err := formatBigInt(r) if err != nil { return nil, err } - maxPriorityFeePerGas, err := formatBigInt(tx.MaxPriorityFeePerGas) + ss, err := formatBigInt(s) if err != nil { return nil, err } - maxFeePerGas, err := formatBigInt(tx.MaxFeePerGas) + vv, err := formatBigInt(v) if err != nil { return nil, err } - gasLimit, err := formatInt(tx.GasLimit) - if err != nil { - return nil, err - } + res := []interface{}{vv, rr, ss} + return res, nil +} - value, err := formatBigInt(tx.Value) - if err != nil { - return nil, err +func padLeadingZeros(data []byte, length int) []byte { + if len(data) >= length { + return data } + zeros := make([]byte, length-len(data)) + return append(zeros, data...) +} - res := []interface{}{ - chainID, - nonce, - maxPriorityFeePerGas, - maxFeePerGas, - gasLimit, - formatEthAddr(tx.To), - value, - tx.Input, - []interface{}{}, // access list +func removeLeadingZeros(data []byte) []byte { + firstNonZeroIndex := len(data) + for i, b := range data { + if b > 0 { + firstNonZeroIndex = i + break + } } - return res, nil + return data[firstNonZeroIndex:] } -func (tx *EthTxArgs) packSigFields() ([]interface{}, error) { - r, err := formatBigInt(tx.R) +func formatInt(val int) ([]byte, error) { + buf := new(bytes.Buffer) + err := binary.Write(buf, binary.BigEndian, int64(val)) if err != nil { return nil, err } + return removeLeadingZeros(buf.Bytes()), nil +} - s, err := formatBigInt(tx.S) - if err != nil { - return nil, err +func formatEthAddr(addr *EthAddress) []byte { + if addr == nil { + return nil } + return addr[:] +} - v, err := formatBigInt(tx.V) +func formatBigInt(val big.Int) ([]byte, error) { + b, err := val.Bytes() if err != nil { return nil, err } - - res := []interface{}{v, r, s} - return res, nil + return removeLeadingZeros(b), nil } -func (tx *EthTxArgs) Signature() (*typescrypto.Signature, error) { - r := tx.R.Int.Bytes() - s := tx.S.Int.Bytes() - v := tx.V.Int.Bytes() - - sig := append([]byte{}, padLeadingZeros(r, 32)...) - sig = append(sig, padLeadingZeros(s, 32)...) - if len(v) == 0 { - sig = append(sig, 0) - } else { - sig = append(sig, v[0]) +func parseInt(v interface{}) (int, error) { + data, ok := v.([]byte) + if !ok { + return 0, fmt.Errorf("cannot parse interface to int: input is not a byte array") } - - if len(sig) != 65 { - return nil, fmt.Errorf("signature is not 65 bytes") + if len(data) == 0 { + return 0, nil } - return &typescrypto.Signature{ - Type: typescrypto.SigTypeDelegated, Data: sig, - }, nil -} - -func (tx *EthTxArgs) Sender() (address.Address, error) { - msg, err := tx.ToRlpUnsignedMsg() - if err != nil { - return address.Undef, err + if len(data) > 8 { + return 0, fmt.Errorf("cannot parse interface to int: length is more than 8 bytes") } - - hasher := sha3.NewLegacyKeccak256() - hasher.Write(msg) - hash := hasher.Sum(nil) - - sig, err := tx.Signature() - if err != nil { - return address.Undef, err + var value int64 + r := bytes.NewReader(append(make([]byte, 8-len(data)), data...)) + if err := binary.Read(r, binary.BigEndian, &value); err != nil { + return 0, fmt.Errorf("cannot parse interface to EthUint64: %w", err) } + return int(value), nil +} - pubk, err := gocrypto.EcRecover(hash, sig.Data) - if err != nil { - return address.Undef, err +func parseBigInt(v interface{}) (big.Int, error) { + data, ok := v.([]byte) + if !ok { + return big.Zero(), fmt.Errorf("cannot parse interface to big.Int: input is not a byte array") } - - ethAddr, err := EthAddressFromPubKey(pubk) - if err != nil { - return address.Undef, err + if len(data) == 0 { + return big.Zero(), nil } + var b mathbig.Int + b.SetBytes(data) + return big.NewFromGo(&b), nil +} - ea, err := CastEthAddress(ethAddr) - if err != nil { - return address.Undef, err +func parseBytes(v interface{}) ([]byte, error) { + val, ok := v.([]byte) + if !ok { + return nil, fmt.Errorf("cannot parse interface into bytes: input is not a byte array") } - - return ea.ToFilecoinAddress() + return val, nil } -func RecoverSignature(sig typescrypto.Signature) (EthBigInt, EthBigInt, EthBigInt, error) { - if sig.Type != typescrypto.SigTypeDelegated { - return EthBigIntZero, EthBigIntZero, EthBigIntZero, fmt.Errorf("RecoverSignature only supports Delegated signature") +func parseEthAddr(v interface{}) (*EthAddress, error) { + b, err := parseBytes(v) + if err != nil { + return nil, err } - - if len(sig.Data) != 65 { - return EthBigIntZero, EthBigIntZero, EthBigIntZero, fmt.Errorf("signature should be 65 bytes long, but got %d bytes", len(sig.Data)) + if len(b) == 0 { + return nil, nil } - - r, err := parseBigInt(sig.Data[0:32]) + addr, err := CastEthAddress(b) if err != nil { - return EthBigIntZero, EthBigIntZero, EthBigIntZero, fmt.Errorf("cannot parse r into EthBigInt") + return nil, err } + return &addr, nil +} - s, err := parseBigInt(sig.Data[32:64]) - if err != nil { - return EthBigIntZero, EthBigIntZero, EthBigIntZero, fmt.Errorf("cannot parse s into EthBigInt") +func getEthParamsAndRecipient(msg *Message) (params []byte, to *EthAddress, err error) { + if len(msg.Params) > 0 { + paramsReader := bytes.NewReader(msg.Params) + var err error + params, err = cbg.ReadByteArray(paramsReader, uint64(len(msg.Params))) + if err != nil { + return nil, nil, fmt.Errorf("failed to read params byte array: %w", err) + } + if paramsReader.Len() != 0 { + return nil, nil, fmt.Errorf("extra data found in params") + } + if len(params) == 0 { + return nil, nil, fmt.Errorf("non-empty params encode empty byte array") + } } - v, err := parseBigInt([]byte{sig.Data[64]}) - if err != nil { - return EthBigIntZero, EthBigIntZero, EthBigIntZero, fmt.Errorf("cannot parse v into EthBigInt") + if msg.To == builtintypes.EthereumAddressManagerActorAddr { + if msg.Method != builtintypes.MethodsEAM.CreateExternal { + return nil, nil, fmt.Errorf("unsupported EAM method") + } + } else if msg.Method == builtintypes.MethodsEVM.InvokeContract { + addr, err := EthAddressFromFilecoinAddress(msg.To) + if err != nil { + return nil, nil, err + } + to = &addr + } else { + return nil, nil, + fmt.Errorf("invalid methodnum %d: only allowed method is InvokeContract(%d) or CreateExternal(%d)", + msg.Method, builtintypes.MethodsEVM.InvokeContract, builtintypes.MethodsEAM.CreateExternal) } - return EthBigInt(r), EthBigInt(s), EthBigInt(v), nil + return params, to, nil } -func parseEip1559Tx(data []byte) (*EthTxArgs, error) { - if data[0] != 2 { - return nil, fmt.Errorf("not an EIP-1559 transaction: first byte is not 2") +func parseLegacyTx(data []byte) (EthTransaction, error) { + if data[0] <= 0x7f { + return nil, fmt.Errorf("not a legacy eth transaction") } - d, err := DecodeRLP(data[1:]) + d, err := DecodeRLP(data) if err != nil { return nil, err } decoded, ok := d.([]interface{}) if !ok { - return nil, fmt.Errorf("not an EIP-1559 transaction: decoded data is not a list") - } - - if len(decoded) != 12 { - return nil, fmt.Errorf("not an EIP-1559 transaction: should have 12 elements in the rlp list") - } - - chainID, err := parseInt(decoded[0]) - if err != nil { - return nil, err - } - - nonce, err := parseInt(decoded[1]) - if err != nil { - return nil, err + return nil, fmt.Errorf("not a Legacy transaction: decoded data is not a list") } - maxPriorityFeePerGas, err := parseBigInt(decoded[2]) - if err != nil { - return nil, err + if len(decoded) != 9 { + return nil, fmt.Errorf("not a Legacy transaction: should have 9 elements in the rlp list") } - maxFeePerGas, err := parseBigInt(decoded[3]) + nonce, err := parseInt(decoded[0]) if err != nil { return nil, err } - gasLimit, err := parseInt(decoded[4]) + gasPrice, err := parseBigInt(decoded[1]) if err != nil { return nil, err } - to, err := parseEthAddr(decoded[5]) + gasLimit, err := parseInt(decoded[2]) if err != nil { return nil, err } - value, err := parseBigInt(decoded[6]) + to, err := parseEthAddr(decoded[3]) if err != nil { return nil, err } - input, err := parseBytes(decoded[7]) + value, err := parseBigInt(decoded[4]) if err != nil { return nil, err } - accessList, ok := decoded[8].([]interface{}) - if !ok || (ok && len(accessList) != 0) { - return nil, fmt.Errorf("access list should be an empty list") + input, ok := decoded[5].([]byte) + if !ok { + return nil, fmt.Errorf("input is not a byte slice") } - r, err := parseBigInt(decoded[10]) + v, err := parseBigInt(decoded[6]) if err != nil { return nil, err } - s, err := parseBigInt(decoded[11]) + r, err := parseBigInt(decoded[7]) if err != nil { return nil, err } - v, err := parseBigInt(decoded[9]) + s, err := parseBigInt(decoded[8]) if err != nil { return nil, err } - // EIP-1559 and EIP-2930 transactions only support 0 or 1 for v - // Legacy and EIP-155 transactions support other values - // https://github.com/ethers-io/ethers.js/blob/56fabe987bb8c1e4891fdf1e5d3fe8a4c0471751/packages/transactions/src.ts/index.ts#L333 - if !v.Equals(big.NewInt(0)) && !v.Equals(big.NewInt(1)) { - return nil, fmt.Errorf("EIP-1559 transactions only support 0 or 1 for v") + tx := &EthLegacyHomesteadTxArgs{ + Nonce: nonce, + GasPrice: gasPrice, + GasLimit: gasLimit, + To: to, + Value: value, + Input: input, + V: v, + R: r, + S: s, } - args := EthTxArgs{ - ChainID: chainID, - Nonce: nonce, - To: to, - MaxPriorityFeePerGas: maxPriorityFeePerGas, - MaxFeePerGas: maxFeePerGas, - GasLimit: gasLimit, - Value: value, - Input: input, - R: r, - S: s, - V: v, - } - return &args, nil -} - -func ParseEthTxArgs(data []byte) (*EthTxArgs, error) { - if len(data) == 0 { - return nil, fmt.Errorf("empty data") - } - - if data[0] > 0x7f { - // legacy transaction - return nil, fmt.Errorf("legacy transaction is not supported") + chainID := deriveEIP155ChainId(v) + if chainID.Equals(big.NewInt(0)) { + // This is a legacy Homestead transaction + if !v.Equals(big.NewInt(27)) && !v.Equals(big.NewInt(28)) { + return nil, fmt.Errorf("legacy homestead transactions only support 27 or 28 for v, got %d", v.Uint64()) + } + return tx, nil } - if data[0] == 1 { - // EIP-2930 - return nil, fmt.Errorf("EIP-2930 transaction is not supported") + // This is a EIP-155 transaction -> ensure chainID protection + if err := validateEIP155ChainId(v); err != nil { + return nil, fmt.Errorf("failed to validate EIP155 chain id: %w", err) } - if data[0] == Eip1559TxType { - // EIP-1559 - return parseEip1559Tx(data) - } - - return nil, fmt.Errorf("unsupported transaction type") + return &EthLegacy155TxArgs{ + legacyTx: tx, + }, nil } -func padLeadingZeros(data []byte, length int) []byte { - if len(data) >= length { - return data - } - zeros := make([]byte, length-len(data)) - return append(zeros, data...) +type RlpPackable interface { + packTxFields() ([]interface{}, error) } -func removeLeadingZeros(data []byte) []byte { - firstNonZeroIndex := len(data) - for i, b := range data { - if b > 0 { - firstNonZeroIndex = i - break - } +func toRlpUnsignedMsg(tx RlpPackable) ([]byte, error) { + packedFields, err := tx.packTxFields() + if err != nil { + return nil, err } - return data[firstNonZeroIndex:] -} - -func formatInt(val int) ([]byte, error) { - buf := new(bytes.Buffer) - err := binary.Write(buf, binary.BigEndian, int64(val)) + encoded, err := EncodeRLP(packedFields) if err != nil { return nil, err } - return removeLeadingZeros(buf.Bytes()), nil + return encoded, nil } -func formatEthAddr(addr *EthAddress) []byte { - if addr == nil { - return nil +func toRlpSignedMsg(tx RlpPackable, V, R, S big.Int) ([]byte, error) { + packed1, err := tx.packTxFields() + if err != nil { + return nil, err } - return addr[:] -} -func formatBigInt(val big.Int) ([]byte, error) { - b, err := val.Bytes() + packed2, err := packSigFields(V, R, S) if err != nil { return nil, err } - return removeLeadingZeros(b), nil -} -func parseInt(v interface{}) (int, error) { - data, ok := v.([]byte) - if !ok { - return 0, fmt.Errorf("cannot parse interface to int: input is not a byte array") - } - if len(data) == 0 { - return 0, nil - } - if len(data) > 8 { - return 0, fmt.Errorf("cannot parse interface to int: length is more than 8 bytes") - } - var value int64 - r := bytes.NewReader(append(make([]byte, 8-len(data)), data...)) - if err := binary.Read(r, binary.BigEndian, &value); err != nil { - return 0, fmt.Errorf("cannot parse interface to EthUint64: %w", err) + encoded, err := EncodeRLP(append(packed1, packed2...)) + if err != nil { + return nil, fmt.Errorf("failed to encode rlp signed msg: %w", err) } - return int(value), nil + return encoded, nil } -func parseBigInt(v interface{}) (big.Int, error) { - data, ok := v.([]byte) - if !ok { - return big.Zero(), fmt.Errorf("cannot parse interface to big.Int: input is not a byte array") +func sender(tx EthTransaction) (address.Address, error) { + msg, err := tx.ToRlpUnsignedMsg() + if err != nil { + return address.Undef, fmt.Errorf("failed to get rlp unsigned msg: %w", err) } - if len(data) == 0 { - return big.Zero(), nil + + hasher := sha3.NewLegacyKeccak256() + hasher.Write(msg) + hash := hasher.Sum(nil) + + sig, err := tx.Signature() + if err != nil { + return address.Undef, fmt.Errorf("failed to get signature: %w", err) } - var b mathbig.Int - b.SetBytes(data) - return big.NewFromGo(&b), nil -} -func parseBytes(v interface{}) ([]byte, error) { - val, ok := v.([]byte) - if !ok { - return nil, fmt.Errorf("cannot parse interface into bytes: input is not a byte array") + sigData, err := tx.ToVerifiableSignature(sig.Data) + if err != nil { + return address.Undef, fmt.Errorf("failed to get verifiable signature: %w", err) } - return val, nil -} -func parseEthAddr(v interface{}) (*EthAddress, error) { - b, err := parseBytes(v) + pubk, err := gocrypto.EcRecover(hash, sigData) if err != nil { - return nil, err + return address.Undef, fmt.Errorf("failed to recover pubkey: %w", err) } - if len(b) == 0 { - return nil, nil + + ethAddr, err := EthAddressFromPubKey(pubk) + if err != nil { + return address.Undef, fmt.Errorf("failed to get eth address from pubkey: %w", err) } - addr, err := CastEthAddress(b) + + ea, err := CastEthAddress(ethAddr) if err != nil { - return nil, err + return address.Undef, fmt.Errorf("failed to cast eth address: %w", err) } - return &addr, nil + + return ea.ToFilecoinAddress() } diff --git a/venus-shared/actors/types/eth_transactions_test.go b/venus-shared/actors/types/eth_transactions_test.go new file mode 100644 index 0000000000..63f574d153 --- /dev/null +++ b/venus-shared/actors/types/eth_transactions_test.go @@ -0,0 +1,165 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/big" + builtintypes "github.com/filecoin-project/go-state-types/builtin" + "github.com/filecoin-project/go-state-types/crypto" +) + +func TestEthTransactionFromSignedFilecoinMessage(t *testing.T) { + eip1559sig := make([]byte, 65) + eip1559sig[0] = 1 + + legacySig := make([]byte, 66) + legacySig[0] = 1 + legacySig[65] = 27 + + pubKeyHex := "0x04cfecc0520d906cbfea387759246e89d85e2998843e56ad1c41de247ce10b3e4c453aa73c8de13c178d94461b6fa3f8b6f74406ce43d2fbab6992d0b283394242" + pubk := mustDecodeHex(pubKeyHex) + addrHash, err := EthAddressFromPubKey(pubk) + require.NoError(t, err) + from, err := address.NewDelegatedAddress(builtintypes.EthereumAddressManagerActorID, addrHash) + require.NoError(t, err) + + fromEth, err := EthAddressFromFilecoinAddress(from) + require.NoError(t, err) + + to, err := address.NewIDAddress(1) + require.NoError(t, err) + + toEth, err := EthAddressFromFilecoinAddress(to) + require.NoError(t, err) + + tcs := map[string]struct { + msg *SignedMessage + expectedErr string + validateFunc func(t *testing.T, smsg *SignedMessage, tx EthTransaction) + }{ + "empty": { + expectedErr: "signed message is nil", + }, + "invalid-signature": { + msg: &SignedMessage{ + Message: Message{ + To: builtintypes.EthereumAddressManagerActorAddr, + From: from, + Method: builtintypes.MethodsEAM.CreateExternal, + }, + Signature: crypto.Signature{ + Type: crypto.SigTypeDelegated, + Data: []byte{1}, + }, + }, + expectedErr: "unsupported signature length", + }, + "valid-eip1559": { + msg: &SignedMessage{ + Message: Message{ + From: from, + To: to, + Value: big.NewInt(10), + GasFeeCap: big.NewInt(11), + GasPremium: big.NewInt(12), + GasLimit: 13, + Nonce: 14, + Method: builtintypes.MethodsEVM.InvokeContract, + }, + Signature: crypto.Signature{ + Type: crypto.SigTypeDelegated, + Data: eip1559sig, + }, + }, + validateFunc: func(t *testing.T, smsg *SignedMessage, tx EthTransaction) { + eip1559tx := tx.(*Eth1559TxArgs) + require.Equal(t, big.NewInt(10), eip1559tx.Value) + require.Equal(t, big.NewInt(11), eip1559tx.MaxFeePerGas) + require.Equal(t, big.NewInt(12), eip1559tx.MaxPriorityFeePerGas) + require.EqualValues(t, uint64(13), eip1559tx.GasLimit) + require.EqualValues(t, uint64(14), eip1559tx.Nonce) + require.EqualValues(t, toEth, *eip1559tx.To) + require.EqualValues(t, 314, eip1559tx.ChainID) + require.Empty(t, eip1559tx.Input) + + ethTx, err := tx.ToEthTx(smsg) + require.NoError(t, err) + require.EqualValues(t, 314, ethTx.ChainID) + require.EqualValues(t, 14, ethTx.Nonce) + hash, err := eip1559tx.TxHash() + require.NoError(t, err) + require.EqualValues(t, hash, ethTx.Hash) + require.EqualValues(t, fromEth, ethTx.From) + require.EqualValues(t, toEth, *ethTx.To) + require.EqualValues(t, big.NewInt(10), ethTx.Value) + require.EqualValues(t, 13, ethTx.Gas) + require.EqualValues(t, big.NewInt(11), *ethTx.MaxFeePerGas) + require.EqualValues(t, big.NewInt(12), *ethTx.MaxPriorityFeePerGas) + require.Nil(t, ethTx.GasPrice) + require.Empty(t, ethTx.AccessList) + }, + }, + "valid-legacy": { + msg: &SignedMessage{ + Message: Message{ + From: from, + To: to, + Value: big.NewInt(10), + GasFeeCap: big.NewInt(11), + GasPremium: big.NewInt(12), + GasLimit: 13, + Nonce: 14, + Method: builtintypes.MethodsEVM.InvokeContract, + }, + Signature: crypto.Signature{ + Type: crypto.SigTypeDelegated, + Data: legacySig, + }, + }, + validateFunc: func(t *testing.T, smsg *SignedMessage, tx EthTransaction) { + legacyTx := tx.(*EthLegacyHomesteadTxArgs) + require.Equal(t, big.NewInt(10), legacyTx.Value) + require.EqualValues(t, uint64(13), legacyTx.GasLimit) + require.EqualValues(t, uint64(14), legacyTx.Nonce) + require.EqualValues(t, toEth, *legacyTx.To) + require.EqualValues(t, big.NewInt(11), legacyTx.GasPrice) + require.Empty(t, legacyTx.Input) + + ethTx, err := tx.ToEthTx(smsg) + require.NoError(t, err) + require.EqualValues(t, 0, ethTx.ChainID) + require.EqualValues(t, 14, ethTx.Nonce) + hash, err := legacyTx.TxHash() + require.NoError(t, err) + require.EqualValues(t, big.NewInt(11), *ethTx.GasPrice) + require.EqualValues(t, hash, ethTx.Hash) + require.EqualValues(t, fromEth, ethTx.From) + require.EqualValues(t, toEth, *ethTx.To) + require.EqualValues(t, big.NewInt(10), ethTx.Value) + require.EqualValues(t, 13, ethTx.Gas) + require.Nil(t, ethTx.MaxFeePerGas) + require.Nil(t, ethTx.MaxPriorityFeePerGas) + require.Empty(t, ethTx.AccessList) + require.EqualValues(t, big.NewInt(27), ethTx.V) + }, + }, + } + + for name, tc := range tcs { + t.Run(name, func(t *testing.T) { + tx, err := EthTransactionFromSignedFilecoinMessage(tc.msg) + if tc.expectedErr != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expectedErr) + } else { + require.NoError(t, err) + } + if tc.validateFunc != nil { + tc.validateFunc(t, tc.msg, tx) + } + }) + } +} diff --git a/venus-shared/actors/types/message.go b/venus-shared/actors/types/message.go index e7535bda1f..4b30b2af68 100644 --- a/venus-shared/actors/types/message.go +++ b/venus-shared/actors/types/message.go @@ -241,7 +241,7 @@ func (m *Message) RequiredFunds() abi.TokenAmount { func (m *Message) SigningBytes(sigType crypto.SigType) ([]byte, error) { if sigType == crypto.SigTypeDelegated { - txArgs, err := EthTxArgsFromUnsignedEthMessage(m) + txArgs, err := Eth1559TxArgsFromUnsignedFilecoinMessage(m) if err != nil { return nil, fmt.Errorf("failed to reconstruct eth transaction: %w", err) } diff --git a/venus-shared/actors/types/rlp_test.go b/venus-shared/actors/types/rlp_test.go index 7396dee83e..3492719a46 100644 --- a/venus-shared/actors/types/rlp_test.go +++ b/venus-shared/actors/types/rlp_test.go @@ -11,11 +11,6 @@ import ( "github.com/filecoin-project/go-address" ) -type TestCase struct { - Input interface{} - Output interface{} -} - func TestEncode(t *testing.T) { testcases := []TestCase{ {[]byte(""), mustDecodeHex("0x80")}, @@ -197,7 +192,7 @@ func TestDecodeError(t *testing.T) { func TestDecode1(t *testing.T) { b := mustDecodeHex("0x02f8758401df5e7680832c8411832c8411830767f89452963ef50e27e06d72d59fcb4f3c2a687be3cfef880de0b6b3a764000080c080a094b11866f453ad85a980e0e8a2fc98cbaeb4409618c7734a7e12ae2f66fd405da042dbfb1b37af102023830ceeee0e703ffba0b8b3afeb8fe59f405eca9ed61072") - decoded, err := ParseEthTxArgs(b) + decoded, err := parseEip1559Tx(b) require.NoError(t, err) sender, err := decoded.Sender() diff --git a/venus-shared/actors/version.go b/venus-shared/actors/version.go index c793ecfb42..6244ef360a 100644 --- a/venus-shared/actors/version.go +++ b/venus-shared/actors/version.go @@ -16,9 +16,9 @@ const ({{range .actorVersions}} /* inline-gen start */ -var LatestVersion = 13 +var LatestVersion = 14 -var Versions = []int{0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} +var Versions = []int{0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14} const ( Version0 Version = 0 @@ -34,6 +34,7 @@ const ( Version11 Version = 11 Version12 Version = 12 Version13 Version = 13 + Version14 Version = 14 ) /* inline-gen end */ diff --git a/venus-shared/api/chain/v0/chain.go b/venus-shared/api/chain/v0/chain.go index 16edc9f61f..5534e29406 100644 --- a/venus-shared/api/chain/v0/chain.go +++ b/venus-shared/api/chain/v0/chain.go @@ -131,7 +131,7 @@ type IMinerState interface { StateListMessages(ctx context.Context, match *types.MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) //perm:read StateMinerSectorAllocated(ctx context.Context, maddr address.Address, s abi.SectorNumber, tsk types.TipSetKey) (bool, error) //perm:read StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (types.SectorPreCommitOnChainInfo, error) //perm:read - StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*types.SectorOnChainInfo, error) //perm:read + StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorOnChainInfo, error) //perm:read StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorLocation, error) //perm:read StateMinerSectorSize(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (abi.SectorSize, error) //perm:read StateMinerInfo(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (types.MinerInfo, error) //perm:read @@ -139,12 +139,12 @@ type IMinerState interface { StateMinerRecoveries(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (bitfield.BitField, error) //perm:read StateMinerFaults(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (bitfield.BitField, error) //perm:read // StateAllMinerFaults returns all non-expired Faults that occur within lookback epochs of the given tipset - StateAllMinerFaults(ctx context.Context, lookback abi.ChainEpoch, ts types.TipSetKey) ([]*types.Fault, error) //perm:read - StateMinerProvingDeadline(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*dline.Info, error) //perm:read - StateMinerPartitions(ctx context.Context, maddr address.Address, dlIdx uint64, tsk types.TipSetKey) ([]types.Partition, error) //perm:read - StateMinerDeadlines(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]types.Deadline, error) //perm:read - StateMinerSectors(ctx context.Context, maddr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*types.SectorOnChainInfo, error) //perm:read - StateMarketStorageDeal(ctx context.Context, dealID abi.DealID, tsk types.TipSetKey) (*types.MarketDeal, error) //perm:read + StateAllMinerFaults(ctx context.Context, lookback abi.ChainEpoch, ts types.TipSetKey) ([]*types.Fault, error) //perm:read + StateMinerProvingDeadline(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*dline.Info, error) //perm:read + StateMinerPartitions(ctx context.Context, maddr address.Address, dlIdx uint64, tsk types.TipSetKey) ([]types.Partition, error) //perm:read + StateMinerDeadlines(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]types.Deadline, error) //perm:read + StateMinerSectors(ctx context.Context, maddr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) //perm:read + StateMarketStorageDeal(ctx context.Context, dealID abi.DealID, tsk types.TipSetKey) (*types.MarketDeal, error) //perm:read // StateGetAllocationForPendingDeal returns the allocation for a given deal ID of a pending deal. Returns nil if // pending allocation is not found. StateGetAllocationForPendingDeal(ctx context.Context, dealID abi.DealID, tsk types.TipSetKey) (*types.Allocation, error) //perm:read @@ -161,7 +161,7 @@ type IMinerState interface { StateVMCirculatingSupplyInternal(ctx context.Context, tsk types.TipSetKey) (types.CirculatingSupply, error) //perm:read StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) //perm:read StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (map[string]*types.MarketDeal, error) //perm:read - StateMinerActiveSectors(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]*types.SectorOnChainInfo, error) //perm:read + StateMinerActiveSectors(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) //perm:read StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) //perm:read StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) //perm:read StateListActors(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) //perm:read diff --git a/venus-shared/api/chain/v0/method.md b/venus-shared/api/chain/v0/method.md index bb2b328d08..22c1ac6abc 100644 --- a/venus-shared/api/chain/v0/method.md +++ b/venus-shared/api/chain/v0/method.md @@ -266,7 +266,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } ``` @@ -1003,7 +1003,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } ``` @@ -1168,7 +1168,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } ``` @@ -1221,7 +1221,7 @@ Perms: read Inputs: ```json [ - 22 + 23 ] ``` @@ -1236,7 +1236,7 @@ Perms: read Inputs: ```json [ - 22 + 23 ] ``` @@ -1349,7 +1349,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } }, "GasCharges": [ @@ -1389,7 +1389,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } }, "GasCharges": [ @@ -1552,7 +1552,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } }, "GasCharges": [ @@ -1592,7 +1592,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } }, "GasCharges": [ @@ -1660,7 +1660,8 @@ Response: "UpgradeThunderHeight": 10101, "UpgradeWatermelonHeight": 10101, "UpgradeDragonHeight": 10101, - "UpgradePhoenixHeight": 10101 + "UpgradePhoenixHeight": 10101, + "UpgradeWaffleHeight": 10101 }, "Eip155ChainID": 123 } @@ -1778,7 +1779,7 @@ Inputs: ] ``` -Response: `22` +Response: `23` ### StateReplay @@ -1870,7 +1871,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } }, "GasCharges": [ @@ -1910,7 +1911,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } }, "GasCharges": [ @@ -3136,7 +3137,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } } ``` @@ -3549,6 +3550,7 @@ Response: "ClientCollateral": "0" }, "State": { + "SectorNumber": 9, "SectorStartEpoch": 10101, "LastUpdatedEpoch": 10101, "SlashEpoch": 10101 @@ -3596,6 +3598,7 @@ Response: "ClientCollateral": "0" }, "State": { + "SectorNumber": 9, "SectorStartEpoch": 10101, "LastUpdatedEpoch": 10101, "SlashEpoch": 10101 @@ -3642,12 +3645,12 @@ Response: "InitialPledge": "0", "ExpectedDayReward": "0", "ExpectedStoragePledge": "0", - "ReplacedSectorAge": 10101, + "PowerBaseEpoch": 10101, "ReplacedDayReward": "0", "SectorKeyCID": { "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" }, - "SimpleQAPower": true + "Flags": 0 } ] ``` @@ -4131,12 +4134,12 @@ Response: "InitialPledge": "0", "ExpectedDayReward": "0", "ExpectedStoragePledge": "0", - "ReplacedSectorAge": 10101, + "PowerBaseEpoch": 10101, "ReplacedDayReward": "0", "SectorKeyCID": { "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" }, - "SimpleQAPower": true + "Flags": 0 } ] ``` @@ -4263,12 +4266,12 @@ Response: "InitialPledge": "0", "ExpectedDayReward": "0", "ExpectedStoragePledge": "0", - "ReplacedSectorAge": 10101, + "PowerBaseEpoch": 10101, "ReplacedDayReward": "0", "SectorKeyCID": { "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" }, - "SimpleQAPower": true + "Flags": 0 } ``` diff --git a/venus-shared/api/chain/v0/mock/mock_fullnode.go b/venus-shared/api/chain/v0/mock/mock_fullnode.go index cd5fe6076c..2532426a2f 100644 --- a/venus-shared/api/chain/v0/mock/mock_fullnode.go +++ b/venus-shared/api/chain/v0/mock/mock_fullnode.go @@ -13,13 +13,14 @@ import ( bitfield "github.com/filecoin-project/go-bitfield" abi "github.com/filecoin-project/go-state-types/abi" big "github.com/filecoin-project/go-state-types/big" + miner "github.com/filecoin-project/go-state-types/builtin/v13/miner" paych "github.com/filecoin-project/go-state-types/builtin/v8/paych" - miner "github.com/filecoin-project/go-state-types/builtin/v9/miner" + miner0 "github.com/filecoin-project/go-state-types/builtin/v9/miner" verifreg "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" crypto "github.com/filecoin-project/go-state-types/crypto" dline "github.com/filecoin-project/go-state-types/dline" network "github.com/filecoin-project/go-state-types/network" - miner0 "github.com/filecoin-project/venus/venus-shared/actors/builtin/miner" + miner1 "github.com/filecoin-project/venus/venus-shared/actors/builtin/miner" types "github.com/filecoin-project/venus/venus-shared/actors/types" types0 "github.com/filecoin-project/venus/venus-shared/types" gomock "github.com/golang/mock/gomock" @@ -2029,7 +2030,7 @@ func (mr *MockFullNodeMockRecorder) StateMinerInfo(arg0, arg1, arg2 interface{}) } // StateMinerInitialPledgeCollateral mocks base method. -func (m *MockFullNode) StateMinerInitialPledgeCollateral(arg0 context.Context, arg1 address.Address, arg2 miner.SectorPreCommitInfo, arg3 types0.TipSetKey) (big.Int, error) { +func (m *MockFullNode) StateMinerInitialPledgeCollateral(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 types0.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerInitialPledgeCollateral", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(big.Int) @@ -2074,7 +2075,7 @@ func (mr *MockFullNodeMockRecorder) StateMinerPower(arg0, arg1, arg2 interface{} } // StateMinerPreCommitDepositForPower mocks base method. -func (m *MockFullNode) StateMinerPreCommitDepositForPower(arg0 context.Context, arg1 address.Address, arg2 miner.SectorPreCommitInfo, arg3 types0.TipSetKey) (big.Int, error) { +func (m *MockFullNode) StateMinerPreCommitDepositForPower(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 types0.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerPreCommitDepositForPower", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(big.Int) @@ -2284,10 +2285,10 @@ func (mr *MockFullNodeMockRecorder) StateSearchMsgLimited(arg0, arg1, arg2 inter } // StateSectorExpiration mocks base method. -func (m *MockFullNode) StateSectorExpiration(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types0.TipSetKey) (*miner0.SectorExpiration, error) { +func (m *MockFullNode) StateSectorExpiration(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types0.TipSetKey) (*miner1.SectorExpiration, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorExpiration", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*miner0.SectorExpiration) + ret0, _ := ret[0].(*miner1.SectorExpiration) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2314,10 +2315,10 @@ func (mr *MockFullNodeMockRecorder) StateSectorGetInfo(arg0, arg1, arg2, arg3 in } // StateSectorPartition mocks base method. -func (m *MockFullNode) StateSectorPartition(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types0.TipSetKey) (*miner0.SectorLocation, error) { +func (m *MockFullNode) StateSectorPartition(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types0.TipSetKey) (*miner1.SectorLocation, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorPartition", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*miner0.SectorLocation) + ret0, _ := ret[0].(*miner1.SectorLocation) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2329,10 +2330,10 @@ func (mr *MockFullNodeMockRecorder) StateSectorPartition(arg0, arg1, arg2, arg3 } // StateSectorPreCommitInfo mocks base method. -func (m *MockFullNode) StateSectorPreCommitInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types0.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { +func (m *MockFullNode) StateSectorPreCommitInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types0.TipSetKey) (miner0.SectorPreCommitOnChainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorPreCommitInfo", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(miner.SectorPreCommitOnChainInfo) + ret0, _ := ret[0].(miner0.SectorPreCommitOnChainInfo) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/venus-shared/api/chain/v0/proxy_gen.go b/venus-shared/api/chain/v0/proxy_gen.go index f295109c4d..c1b6dd85d4 100644 --- a/venus-shared/api/chain/v0/proxy_gen.go +++ b/venus-shared/api/chain/v0/proxy_gen.go @@ -85,46 +85,46 @@ func (s *IBeaconStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (* type IMinerStateStruct struct { Internal struct { - StateAllMinerFaults func(ctx context.Context, lookback abi.ChainEpoch, ts types.TipSetKey) ([]*types.Fault, error) `perm:"read"` - StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"` - StateCirculatingSupply func(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) `perm:"read"` - StateDealProviderCollateralBounds func(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (types.DealCollateralBounds, error) `perm:"read"` - StateDecodeParams func(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error) `perm:"read"` - StateGetAllocation func(ctx context.Context, clientAddr address.Address, allocationID types.AllocationId, tsk types.TipSetKey) (*types.Allocation, error) `perm:"read"` - StateGetAllocationForPendingDeal func(ctx context.Context, dealID abi.DealID, tsk types.TipSetKey) (*types.Allocation, error) `perm:"read"` - StateGetAllocations func(ctx context.Context, clientAddr address.Address, tsk types.TipSetKey) (map[types.AllocationId]types.Allocation, error) `perm:"read"` - StateGetClaim func(ctx context.Context, providerAddr address.Address, claimID types.ClaimId, tsk types.TipSetKey) (*types.Claim, error) `perm:"read"` - StateGetClaims func(ctx context.Context, providerAddr address.Address, tsk types.TipSetKey) (map[types.ClaimId]types.Claim, error) `perm:"read"` - StateListActors func(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) `perm:"read"` - StateListMessages func(ctx context.Context, match *types.MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"` - StateListMiners func(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) `perm:"read"` - StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) `perm:"read"` - StateMarketBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.MarketBalance, error) `perm:"read"` - StateMarketDeals func(ctx context.Context, tsk types.TipSetKey) (map[string]*types.MarketDeal, error) `perm:"read"` - StateMarketStorageDeal func(ctx context.Context, dealID abi.DealID, tsk types.TipSetKey) (*types.MarketDeal, error) `perm:"read"` - StateMinerActiveSectors func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]*types.SectorOnChainInfo, error) `perm:"read"` - StateMinerAvailableBalance func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (big.Int, error) `perm:"read"` - StateMinerDeadlines func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]types.Deadline, error) `perm:"read"` - StateMinerFaults func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (bitfield.BitField, error) `perm:"read"` - StateMinerInfo func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (types.MinerInfo, error) `perm:"read"` - StateMinerInitialPledgeCollateral func(ctx context.Context, maddr address.Address, pci types.SectorPreCommitInfo, tsk types.TipSetKey) (big.Int, error) `perm:"read"` - StateMinerPartitions func(ctx context.Context, maddr address.Address, dlIdx uint64, tsk types.TipSetKey) ([]types.Partition, error) `perm:"read"` - StateMinerPower func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.MinerPower, error) `perm:"read"` - StateMinerPreCommitDepositForPower func(ctx context.Context, maddr address.Address, pci types.SectorPreCommitInfo, tsk types.TipSetKey) (big.Int, error) `perm:"read"` - StateMinerProvingDeadline func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*dline.Info, error) `perm:"read"` - StateMinerRecoveries func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (bitfield.BitField, error) `perm:"read"` - StateMinerSectorAllocated func(ctx context.Context, maddr address.Address, s abi.SectorNumber, tsk types.TipSetKey) (bool, error) `perm:"read"` - StateMinerSectorCount func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.MinerSectors, error) `perm:"read"` - StateMinerSectorSize func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (abi.SectorSize, error) `perm:"read"` - StateMinerSectors func(ctx context.Context, maddr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*types.SectorOnChainInfo, error) `perm:"read"` - StateMinerWorkerAddress func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (address.Address, error) `perm:"read"` - StateReadState func(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.ActorState, error) `perm:"read"` - StateSectorExpiration func(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorExpiration, error) `perm:"read"` - StateSectorGetInfo func(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*types.SectorOnChainInfo, error) `perm:"read"` - StateSectorPartition func(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorLocation, error) `perm:"read"` - StateSectorPreCommitInfo func(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (types.SectorPreCommitOnChainInfo, error) `perm:"read"` - StateVMCirculatingSupplyInternal func(ctx context.Context, tsk types.TipSetKey) (types.CirculatingSupply, error) `perm:"read"` - StateVerifiedClientStatus func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` + StateAllMinerFaults func(ctx context.Context, lookback abi.ChainEpoch, ts types.TipSetKey) ([]*types.Fault, error) `perm:"read"` + StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"` + StateCirculatingSupply func(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) `perm:"read"` + StateDealProviderCollateralBounds func(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (types.DealCollateralBounds, error) `perm:"read"` + StateDecodeParams func(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error) `perm:"read"` + StateGetAllocation func(ctx context.Context, clientAddr address.Address, allocationID types.AllocationId, tsk types.TipSetKey) (*types.Allocation, error) `perm:"read"` + StateGetAllocationForPendingDeal func(ctx context.Context, dealID abi.DealID, tsk types.TipSetKey) (*types.Allocation, error) `perm:"read"` + StateGetAllocations func(ctx context.Context, clientAddr address.Address, tsk types.TipSetKey) (map[types.AllocationId]types.Allocation, error) `perm:"read"` + StateGetClaim func(ctx context.Context, providerAddr address.Address, claimID types.ClaimId, tsk types.TipSetKey) (*types.Claim, error) `perm:"read"` + StateGetClaims func(ctx context.Context, providerAddr address.Address, tsk types.TipSetKey) (map[types.ClaimId]types.Claim, error) `perm:"read"` + StateListActors func(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) `perm:"read"` + StateListMessages func(ctx context.Context, match *types.MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"` + StateListMiners func(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) `perm:"read"` + StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) `perm:"read"` + StateMarketBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.MarketBalance, error) `perm:"read"` + StateMarketDeals func(ctx context.Context, tsk types.TipSetKey) (map[string]*types.MarketDeal, error) `perm:"read"` + StateMarketStorageDeal func(ctx context.Context, dealID abi.DealID, tsk types.TipSetKey) (*types.MarketDeal, error) `perm:"read"` + StateMinerActiveSectors func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) `perm:"read"` + StateMinerAvailableBalance func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (big.Int, error) `perm:"read"` + StateMinerDeadlines func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]types.Deadline, error) `perm:"read"` + StateMinerFaults func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (bitfield.BitField, error) `perm:"read"` + StateMinerInfo func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (types.MinerInfo, error) `perm:"read"` + StateMinerInitialPledgeCollateral func(ctx context.Context, maddr address.Address, pci types.SectorPreCommitInfo, tsk types.TipSetKey) (big.Int, error) `perm:"read"` + StateMinerPartitions func(ctx context.Context, maddr address.Address, dlIdx uint64, tsk types.TipSetKey) ([]types.Partition, error) `perm:"read"` + StateMinerPower func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.MinerPower, error) `perm:"read"` + StateMinerPreCommitDepositForPower func(ctx context.Context, maddr address.Address, pci types.SectorPreCommitInfo, tsk types.TipSetKey) (big.Int, error) `perm:"read"` + StateMinerProvingDeadline func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*dline.Info, error) `perm:"read"` + StateMinerRecoveries func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (bitfield.BitField, error) `perm:"read"` + StateMinerSectorAllocated func(ctx context.Context, maddr address.Address, s abi.SectorNumber, tsk types.TipSetKey) (bool, error) `perm:"read"` + StateMinerSectorCount func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.MinerSectors, error) `perm:"read"` + StateMinerSectorSize func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (abi.SectorSize, error) `perm:"read"` + StateMinerSectors func(ctx context.Context, maddr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) `perm:"read"` + StateMinerWorkerAddress func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (address.Address, error) `perm:"read"` + StateReadState func(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.ActorState, error) `perm:"read"` + StateSectorExpiration func(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorExpiration, error) `perm:"read"` + StateSectorGetInfo func(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorOnChainInfo, error) `perm:"read"` + StateSectorPartition func(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorLocation, error) `perm:"read"` + StateSectorPreCommitInfo func(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (types.SectorPreCommitOnChainInfo, error) `perm:"read"` + StateVMCirculatingSupplyInternal func(ctx context.Context, tsk types.TipSetKey) (types.CirculatingSupply, error) `perm:"read"` + StateVerifiedClientStatus func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` } } @@ -179,7 +179,7 @@ func (s *IMinerStateStruct) StateMarketDeals(p0 context.Context, p1 types.TipSet func (s *IMinerStateStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*types.MarketDeal, error) { return s.Internal.StateMarketStorageDeal(p0, p1, p2) } -func (s *IMinerStateStruct) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*types.SectorOnChainInfo, error) { +func (s *IMinerStateStruct) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) { return s.Internal.StateMinerActiveSectors(p0, p1, p2) } func (s *IMinerStateStruct) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (big.Int, error) { @@ -221,7 +221,7 @@ func (s *IMinerStateStruct) StateMinerSectorCount(p0 context.Context, p1 address func (s *IMinerStateStruct) StateMinerSectorSize(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (abi.SectorSize, error) { return s.Internal.StateMinerSectorSize(p0, p1, p2) } -func (s *IMinerStateStruct) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*types.SectorOnChainInfo, error) { +func (s *IMinerStateStruct) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) { return s.Internal.StateMinerSectors(p0, p1, p2, p3) } func (s *IMinerStateStruct) StateMinerWorkerAddress(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { @@ -233,7 +233,7 @@ func (s *IMinerStateStruct) StateReadState(p0 context.Context, p1 address.Addres func (s *IMinerStateStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) { return s.Internal.StateSectorExpiration(p0, p1, p2, p3) } -func (s *IMinerStateStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*types.SectorOnChainInfo, error) { +func (s *IMinerStateStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorOnChainInfo, error) { return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) } func (s *IMinerStateStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) { diff --git a/venus-shared/api/chain/v1/chain.go b/venus-shared/api/chain/v1/chain.go index 0fe3cf6d95..f2b4907218 100644 --- a/venus-shared/api/chain/v1/chain.go +++ b/venus-shared/api/chain/v1/chain.go @@ -170,7 +170,7 @@ type IMinerState interface { // numbers were compacted, and the sector number was marked as allocated in order to reduce size of the allocated // sectors bitfield, or that the sector was precommitted, but the precommit has expired. StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*types.SectorPreCommitOnChainInfo, error) //perm:read - StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*types.SectorOnChainInfo, error) //perm:read + StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorOnChainInfo, error) //perm:read StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorLocation, error) //perm:read StateMinerSectorSize(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (abi.SectorSize, error) //perm:read StateMinerInfo(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (types.MinerInfo, error) //perm:read @@ -181,7 +181,7 @@ type IMinerState interface { StateMinerProvingDeadline(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*dline.Info, error) //perm:read StateMinerPartitions(ctx context.Context, maddr address.Address, dlIdx uint64, tsk types.TipSetKey) ([]types.Partition, error) //perm:read StateMinerDeadlines(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]types.Deadline, error) //perm:read - StateMinerSectors(ctx context.Context, maddr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*types.SectorOnChainInfo, error) //perm:read + StateMinerSectors(ctx context.Context, maddr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) //perm:read StateMarketStorageDeal(ctx context.Context, dealID abi.DealID, tsk types.TipSetKey) (*types.MarketDeal, error) //perm:read // StateGetAllocationForPendingDeal returns the allocation for a given deal ID of a pending deal. Returns nil if // pending allocation is not found. @@ -207,7 +207,7 @@ type IMinerState interface { StateVMCirculatingSupplyInternal(ctx context.Context, tsk types.TipSetKey) (types.CirculatingSupply, error) //perm:read StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) //perm:read StateMarketDeals(ctx context.Context, tsk types.TipSetKey) (map[string]*types.MarketDeal, error) //perm:read - StateMinerActiveSectors(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]*types.SectorOnChainInfo, error) //perm:read + StateMinerActiveSectors(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) //perm:read StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) //perm:read // StateLookupRobustAddress returns the public key address of the given ID address for non-account addresses (multisig, miners etc) StateLookupRobustAddress(context.Context, address.Address, types.TipSetKey) (address.Address, error) //perm:read diff --git a/venus-shared/api/chain/v1/eth.go b/venus-shared/api/chain/v1/eth.go index c551c81307..8636ae4702 100644 --- a/venus-shared/api/chain/v1/eth.go +++ b/venus-shared/api/chain/v1/eth.go @@ -85,6 +85,8 @@ type IETH interface { EthTraceBlock(ctx context.Context, blkNum string) ([]*types.EthTraceBlock, error) //perm:read // Replays all transactions in a block returning the requested traces for each transaction EthTraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*types.EthTraceReplayBlockTransaction, error) //perm:read + // Implmements OpenEthereum-compatible API method trace_transaction + EthTraceTransaction(ctx context.Context, txHash string) ([]*types.EthTraceTransaction, error) //perm:read } type IETHEvent interface { diff --git a/venus-shared/api/chain/v1/method.md b/venus-shared/api/chain/v1/method.md index 9959d34303..b58a4b090a 100644 --- a/venus-shared/api/chain/v1/method.md +++ b/venus-shared/api/chain/v1/method.md @@ -99,6 +99,7 @@ curl http://:/rpc/v1 -X POST -H "Content-Type: application/json" -H " * [EthSyncing](#ethsyncing) * [EthTraceBlock](#ethtraceblock) * [EthTraceReplayBlockTransactions](#ethtracereplayblocktransactions) + * [EthTraceTransaction](#ethtracetransaction) * [FilecoinAddressToEthAddress](#filecoinaddresstoethaddress) * [NetListening](#netlistening) * [NetVersion](#netversion) @@ -324,7 +325,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } ``` @@ -1179,7 +1180,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } ``` @@ -1344,7 +1345,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } ``` @@ -1397,7 +1398,7 @@ Perms: read Inputs: ```json [ - 22 + 23 ] ``` @@ -1412,7 +1413,7 @@ Perms: read Inputs: ```json [ - 22 + 23 ] ``` @@ -1525,7 +1526,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } }, "GasCharges": [ @@ -1565,7 +1566,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } }, "GasCharges": [ @@ -1728,7 +1729,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } }, "GasCharges": [ @@ -1768,7 +1769,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } }, "GasCharges": [ @@ -1859,7 +1860,8 @@ Response: "UpgradeThunderHeight": 10101, "UpgradeWatermelonHeight": 10101, "UpgradeDragonHeight": 10101, - "UpgradePhoenixHeight": 10101 + "UpgradePhoenixHeight": 10101, + "UpgradeWaffleHeight": 10101 }, "Eip155ChainID": 123 } @@ -1987,7 +1989,7 @@ Inputs: ] ``` -Response: `22` +Response: `23` ### StateReplay @@ -2079,7 +2081,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } }, "GasCharges": [ @@ -2119,7 +2121,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } }, "GasCharges": [ @@ -2745,6 +2747,7 @@ Response: "gas": "0x5", "maxFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0", + "gasPrice": "0x0", "accessList": [ "0x0707070707070707070707070707070707070707070707070707070707070707" ], @@ -2784,6 +2787,7 @@ Response: "gas": "0x5", "maxFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0", + "gasPrice": "0x0", "accessList": [ "0x0707070707070707070707070707070707070707070707070707070707070707" ], @@ -2822,6 +2826,7 @@ Response: "gas": "0x5", "maxFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0", + "gasPrice": "0x0", "accessList": [ "0x0707070707070707070707070707070707070707070707070707070707070707" ], @@ -2861,6 +2866,7 @@ Response: "gas": "0x5", "maxFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0", + "gasPrice": "0x0", "accessList": [ "0x0707070707070707070707070707070707070707070707070707070707070707" ], @@ -3114,6 +3120,39 @@ Response: ] ``` +### EthTraceTransaction +Implmements OpenEthereum-compatible API method trace_transaction + + +Perms: read + +Inputs: +```json +[ + "string value" +] +``` + +Response: +```json +[ + { + "type": "string value", + "error": "string value", + "subtraces": 123, + "traceAddress": [ + 123 + ], + "action": {}, + "result": {}, + "blockHash": "0x0707070707070707070707070707070707070707070707070707070707070707", + "blockNumber": 9, + "transactionHash": "0x0707070707070707070707070707070707070707070707070707070707070707", + "transactionPosition": 123 + } +] +``` + ### FilecoinAddressToEthAddress FilecoinAddressToEthAddress converts an f410 or f0 Filecoin Address to an EthAddress @@ -4393,7 +4432,7 @@ Response: }, "Nonce": 42, "Balance": "0", - "Address": "f01234" + "DelegatedAddress": "f01234" } } ``` @@ -4944,6 +4983,7 @@ Response: "ClientCollateral": "0" }, "State": { + "SectorNumber": 9, "SectorStartEpoch": 10101, "LastUpdatedEpoch": 10101, "SlashEpoch": 10101 @@ -4991,6 +5031,7 @@ Response: "ClientCollateral": "0" }, "State": { + "SectorNumber": 9, "SectorStartEpoch": 10101, "LastUpdatedEpoch": 10101, "SlashEpoch": 10101 @@ -5037,12 +5078,12 @@ Response: "InitialPledge": "0", "ExpectedDayReward": "0", "ExpectedStoragePledge": "0", - "ReplacedSectorAge": 10101, + "PowerBaseEpoch": 10101, "ReplacedDayReward": "0", "SectorKeyCID": { "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" }, - "SimpleQAPower": true + "Flags": 0 } ] ``` @@ -5555,12 +5596,12 @@ Response: "InitialPledge": "0", "ExpectedDayReward": "0", "ExpectedStoragePledge": "0", - "ReplacedSectorAge": 10101, + "PowerBaseEpoch": 10101, "ReplacedDayReward": "0", "SectorKeyCID": { "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" }, - "SimpleQAPower": true + "Flags": 0 } ] ``` @@ -5686,12 +5727,12 @@ Response: "InitialPledge": "0", "ExpectedDayReward": "0", "ExpectedStoragePledge": "0", - "ReplacedSectorAge": 10101, + "PowerBaseEpoch": 10101, "ReplacedDayReward": "0", "SectorKeyCID": { "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" }, - "SimpleQAPower": true + "Flags": 0 } ``` diff --git a/venus-shared/api/chain/v1/mock/mock_fullnode.go b/venus-shared/api/chain/v1/mock/mock_fullnode.go index 9c3dc33966..9789fd75fc 100644 --- a/venus-shared/api/chain/v1/mock/mock_fullnode.go +++ b/venus-shared/api/chain/v1/mock/mock_fullnode.go @@ -15,13 +15,14 @@ import ( jsonrpc "github.com/filecoin-project/go-jsonrpc" abi "github.com/filecoin-project/go-state-types/abi" big "github.com/filecoin-project/go-state-types/big" + miner "github.com/filecoin-project/go-state-types/builtin/v13/miner" paych "github.com/filecoin-project/go-state-types/builtin/v8/paych" - miner "github.com/filecoin-project/go-state-types/builtin/v9/miner" + miner0 "github.com/filecoin-project/go-state-types/builtin/v9/miner" verifreg "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" crypto "github.com/filecoin-project/go-state-types/crypto" dline "github.com/filecoin-project/go-state-types/dline" network "github.com/filecoin-project/go-state-types/network" - miner0 "github.com/filecoin-project/venus/venus-shared/actors/builtin/miner" + miner1 "github.com/filecoin-project/venus/venus-shared/actors/builtin/miner" types "github.com/filecoin-project/venus/venus-shared/actors/types" types0 "github.com/filecoin-project/venus/venus-shared/types" gomock "github.com/golang/mock/gomock" @@ -1010,6 +1011,21 @@ func (mr *MockFullNodeMockRecorder) EthTraceReplayBlockTransactions(arg0, arg1, return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthTraceReplayBlockTransactions", reflect.TypeOf((*MockFullNode)(nil).EthTraceReplayBlockTransactions), arg0, arg1, arg2) } +// EthTraceTransaction mocks base method. +func (m *MockFullNode) EthTraceTransaction(arg0 context.Context, arg1 string) ([]*types.EthTraceTransaction, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EthTraceTransaction", arg0, arg1) + ret0, _ := ret[0].([]*types.EthTraceTransaction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// EthTraceTransaction indicates an expected call of EthTraceTransaction. +func (mr *MockFullNodeMockRecorder) EthTraceTransaction(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthTraceTransaction", reflect.TypeOf((*MockFullNode)(nil).EthTraceTransaction), arg0, arg1) +} + // EthUninstallFilter mocks base method. func (m *MockFullNode) EthUninstallFilter(arg0 context.Context, arg1 types.EthFilterID) (bool, error) { m.ctrl.T.Helper() @@ -2871,7 +2887,7 @@ func (mr *MockFullNodeMockRecorder) StateMinerInfo(arg0, arg1, arg2 interface{}) } // StateMinerInitialPledgeCollateral mocks base method. -func (m *MockFullNode) StateMinerInitialPledgeCollateral(arg0 context.Context, arg1 address.Address, arg2 miner.SectorPreCommitInfo, arg3 types0.TipSetKey) (big.Int, error) { +func (m *MockFullNode) StateMinerInitialPledgeCollateral(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 types0.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerInitialPledgeCollateral", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(big.Int) @@ -2916,7 +2932,7 @@ func (mr *MockFullNodeMockRecorder) StateMinerPower(arg0, arg1, arg2 interface{} } // StateMinerPreCommitDepositForPower mocks base method. -func (m *MockFullNode) StateMinerPreCommitDepositForPower(arg0 context.Context, arg1 address.Address, arg2 miner.SectorPreCommitInfo, arg3 types0.TipSetKey) (big.Int, error) { +func (m *MockFullNode) StateMinerPreCommitDepositForPower(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 types0.TipSetKey) (big.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateMinerPreCommitDepositForPower", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(big.Int) @@ -3111,10 +3127,10 @@ func (mr *MockFullNodeMockRecorder) StateSearchMsg(arg0, arg1, arg2, arg3, arg4 } // StateSectorExpiration mocks base method. -func (m *MockFullNode) StateSectorExpiration(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types0.TipSetKey) (*miner0.SectorExpiration, error) { +func (m *MockFullNode) StateSectorExpiration(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types0.TipSetKey) (*miner1.SectorExpiration, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorExpiration", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*miner0.SectorExpiration) + ret0, _ := ret[0].(*miner1.SectorExpiration) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3141,10 +3157,10 @@ func (mr *MockFullNodeMockRecorder) StateSectorGetInfo(arg0, arg1, arg2, arg3 in } // StateSectorPartition mocks base method. -func (m *MockFullNode) StateSectorPartition(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types0.TipSetKey) (*miner0.SectorLocation, error) { +func (m *MockFullNode) StateSectorPartition(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types0.TipSetKey) (*miner1.SectorLocation, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorPartition", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*miner0.SectorLocation) + ret0, _ := ret[0].(*miner1.SectorLocation) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3156,10 +3172,10 @@ func (mr *MockFullNodeMockRecorder) StateSectorPartition(arg0, arg1, arg2, arg3 } // StateSectorPreCommitInfo mocks base method. -func (m *MockFullNode) StateSectorPreCommitInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types0.TipSetKey) (*miner.SectorPreCommitOnChainInfo, error) { +func (m *MockFullNode) StateSectorPreCommitInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types0.TipSetKey) (*miner0.SectorPreCommitOnChainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateSectorPreCommitInfo", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*miner.SectorPreCommitOnChainInfo) + ret0, _ := ret[0].(*miner0.SectorPreCommitOnChainInfo) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/venus-shared/api/chain/v1/proxy_gen.go b/venus-shared/api/chain/v1/proxy_gen.go index 8fca6f1c53..fa51eafe83 100644 --- a/venus-shared/api/chain/v1/proxy_gen.go +++ b/venus-shared/api/chain/v1/proxy_gen.go @@ -101,7 +101,7 @@ type IMinerStateStruct struct { StateMarketBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.MarketBalance, error) `perm:"read"` StateMarketDeals func(ctx context.Context, tsk types.TipSetKey) (map[string]*types.MarketDeal, error) `perm:"read"` StateMarketStorageDeal func(ctx context.Context, dealID abi.DealID, tsk types.TipSetKey) (*types.MarketDeal, error) `perm:"read"` - StateMinerActiveSectors func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]*types.SectorOnChainInfo, error) `perm:"read"` + StateMinerActiveSectors func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) `perm:"read"` StateMinerAllocated func(context.Context, address.Address, types.TipSetKey) (*bitfield.BitField, error) `perm:"read"` StateMinerAvailableBalance func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (big.Int, error) `perm:"read"` StateMinerDeadlines func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) ([]types.Deadline, error) `perm:"read"` @@ -116,11 +116,11 @@ type IMinerStateStruct struct { StateMinerSectorAllocated func(ctx context.Context, maddr address.Address, s abi.SectorNumber, tsk types.TipSetKey) (bool, error) `perm:"read"` StateMinerSectorCount func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.MinerSectors, error) `perm:"read"` StateMinerSectorSize func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (abi.SectorSize, error) `perm:"read"` - StateMinerSectors func(ctx context.Context, maddr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*types.SectorOnChainInfo, error) `perm:"read"` + StateMinerSectors func(ctx context.Context, maddr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) `perm:"read"` StateMinerWorkerAddress func(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (address.Address, error) `perm:"read"` StateReadState func(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.ActorState, error) `perm:"read"` StateSectorExpiration func(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorExpiration, error) `perm:"read"` - StateSectorGetInfo func(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*types.SectorOnChainInfo, error) `perm:"read"` + StateSectorGetInfo func(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorOnChainInfo, error) `perm:"read"` StateSectorPartition func(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tsk types.TipSetKey) (*lminer.SectorLocation, error) `perm:"read"` StateSectorPreCommitInfo func(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*types.SectorPreCommitOnChainInfo, error) `perm:"read"` StateVMCirculatingSupplyInternal func(ctx context.Context, tsk types.TipSetKey) (types.CirculatingSupply, error) `perm:"read"` @@ -197,7 +197,7 @@ func (s *IMinerStateStruct) StateMarketDeals(p0 context.Context, p1 types.TipSet func (s *IMinerStateStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*types.MarketDeal, error) { return s.Internal.StateMarketStorageDeal(p0, p1, p2) } -func (s *IMinerStateStruct) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*types.SectorOnChainInfo, error) { +func (s *IMinerStateStruct) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) { return s.Internal.StateMinerActiveSectors(p0, p1, p2) } func (s *IMinerStateStruct) StateMinerAllocated(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*bitfield.BitField, error) { @@ -242,7 +242,7 @@ func (s *IMinerStateStruct) StateMinerSectorCount(p0 context.Context, p1 address func (s *IMinerStateStruct) StateMinerSectorSize(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (abi.SectorSize, error) { return s.Internal.StateMinerSectorSize(p0, p1, p2) } -func (s *IMinerStateStruct) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*types.SectorOnChainInfo, error) { +func (s *IMinerStateStruct) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*lminer.SectorOnChainInfo, error) { return s.Internal.StateMinerSectors(p0, p1, p2, p3) } func (s *IMinerStateStruct) StateMinerWorkerAddress(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { @@ -254,7 +254,7 @@ func (s *IMinerStateStruct) StateReadState(p0 context.Context, p1 address.Addres func (s *IMinerStateStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) { return s.Internal.StateSectorExpiration(p0, p1, p2, p3) } -func (s *IMinerStateStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*types.SectorOnChainInfo, error) { +func (s *IMinerStateStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorOnChainInfo, error) { return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) } func (s *IMinerStateStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) { @@ -893,6 +893,7 @@ type IETHStruct struct { EthSyncing func(ctx context.Context) (types.EthSyncingResult, error) `perm:"read"` EthTraceBlock func(ctx context.Context, blkNum string) ([]*types.EthTraceBlock, error) `perm:"read"` EthTraceReplayBlockTransactions func(ctx context.Context, blkNum string, traceTypes []string) ([]*types.EthTraceReplayBlockTransaction, error) `perm:"read"` + EthTraceTransaction func(ctx context.Context, txHash string) ([]*types.EthTraceTransaction, error) `perm:"read"` FilecoinAddressToEthAddress func(ctx context.Context, filecoinAddress address.Address) (types.EthAddress, error) `perm:"read"` NetListening func(ctx context.Context) (bool, error) `perm:"read"` NetVersion func(ctx context.Context) (string, error) `perm:"read"` @@ -990,6 +991,9 @@ func (s *IETHStruct) EthTraceBlock(p0 context.Context, p1 string) ([]*types.EthT func (s *IETHStruct) EthTraceReplayBlockTransactions(p0 context.Context, p1 string, p2 []string) ([]*types.EthTraceReplayBlockTransaction, error) { return s.Internal.EthTraceReplayBlockTransactions(p0, p1, p2) } +func (s *IETHStruct) EthTraceTransaction(p0 context.Context, p1 string) ([]*types.EthTraceTransaction, error) { + return s.Internal.EthTraceTransaction(p0, p1) +} func (s *IETHStruct) FilecoinAddressToEthAddress(p0 context.Context, p1 address.Address) (types.EthAddress, error) { return s.Internal.FilecoinAddressToEthAddress(p0, p1) } diff --git a/venus-shared/api/f3/api.go b/venus-shared/api/f3/api.go new file mode 100644 index 0000000000..9fd60f8998 --- /dev/null +++ b/venus-shared/api/f3/api.go @@ -0,0 +1,22 @@ +package f3 + +import ( + "context" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-f3/certs" +) + +type F3 interface { + // F3Participate should be called by a miner node to participate in signing F3 consensus. + // The address should be of type ID + // The returned channel will never be closed by the F3 + // If it is closed without the context being cancelled, the caller should retry. + // The values returned on the channel will inform the caller about participation + // Empty strings will be sent if participation succeeded, non-empty strings explain possible errors. + F3Participate(ctx context.Context, minerID address.Address) (<-chan string, error) //perm:admin + // F3GetCertificate returns a finality certificate at given instance number + F3GetCertificate(ctx context.Context, instance uint64) (*certs.FinalityCertificate, error) //perm:read + // F3GetLatestCertificate returns the latest finality certificate + F3GetLatestCertificate(ctx context.Context) (*certs.FinalityCertificate, error) //perm:read +} diff --git a/venus-shared/api/f3/client_gen.go b/venus-shared/api/f3/client_gen.go new file mode 100644 index 0000000000..acbad0a4d4 --- /dev/null +++ b/venus-shared/api/f3/client_gen.go @@ -0,0 +1,54 @@ +// Code generated by github.com/filecoin-project/venus/venus-devtool/api-gen. DO NOT EDIT. +package f3 + +import ( + "context" + "fmt" + "net/http" + + "github.com/filecoin-project/go-jsonrpc" + + "github.com/filecoin-project/venus/venus-shared/api" +) + +const MajorVersion = 0 +const APINamespace = "f3.F3" +const MethodNamespace = "F3" + +// NewF3RPC creates a new httpparse jsonrpc remotecli. +func NewF3RPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (F3, jsonrpc.ClientCloser, error) { + endpoint, err := api.Endpoint(addr, MajorVersion) + if err != nil { + return nil, nil, fmt.Errorf("invalid addr %s: %w", addr, err) + } + + if requestHeader == nil { + requestHeader = http.Header{} + } + requestHeader.Set(api.VenusAPINamespaceHeader, APINamespace) + + var res F3Struct + closer, err := jsonrpc.NewMergeClient(ctx, endpoint, MethodNamespace, api.GetInternalStructs(&res), requestHeader, opts...) + + return &res, closer, err +} + +// DialF3RPC is a more convinient way of building client, as it resolves any format (url, multiaddr) of addr string. +func DialF3RPC(ctx context.Context, addr string, token string, requestHeader http.Header, opts ...jsonrpc.Option) (F3, jsonrpc.ClientCloser, error) { + ainfo := api.NewAPIInfo(addr, token) + endpoint, err := ainfo.DialArgs(api.VerString(MajorVersion)) + if err != nil { + return nil, nil, fmt.Errorf("get dial args: %w", err) + } + + if requestHeader == nil { + requestHeader = http.Header{} + } + requestHeader.Set(api.VenusAPINamespaceHeader, APINamespace) + ainfo.SetAuthHeader(requestHeader) + + var res F3Struct + closer, err := jsonrpc.NewMergeClient(ctx, endpoint, MethodNamespace, api.GetInternalStructs(&res), requestHeader, opts...) + + return &res, closer, err +} diff --git a/venus-shared/api/f3/method.md b/venus-shared/api/f3/method.md new file mode 100644 index 0000000000..b559084bb7 --- /dev/null +++ b/venus-shared/api/f3/method.md @@ -0,0 +1,156 @@ +# Sample code of curl + +```bash +# corresponding to the value of Inputs Tag of each API +curl http://:/rpc/v0 -X POST -H "Content-Type: application/json" -H "Authorization: Bearer " -d '{"method": "F3.", "params": , "id": 0}' +``` +# Groups + +* [F3](#f3) + * [F3GetCertificate](#f3getcertificate) + * [F3GetLatestCertificate](#f3getlatestcertificate) + * [F3Participate](#f3participate) + +## F3 + +### F3GetCertificate +F3GetCertificate returns a finality certificate at given instance number + + +Perms: read + +Inputs: +```json +[ + 42 +] +``` + +Response: +```json +{ + "GPBFTInstance": 0, + "ECChain": null, + "SupplementalData": { + "Commitments": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "PowerTable": null + }, + "Signers": [ + 0 + ], + "Signature": null, + "PowerTableDelta": null +} +``` + +### F3GetLatestCertificate +F3GetLatestCertificate returns the latest finality certificate + + +Perms: read + +Inputs: `[]` + +Response: +```json +{ + "GPBFTInstance": 0, + "ECChain": null, + "SupplementalData": { + "Commitments": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "PowerTable": null + }, + "Signers": [ + 0 + ], + "Signature": null, + "PowerTableDelta": null +} +``` + +### F3Participate +F3Participate should be called by a miner node to participate in signing F3 consensus. +The address should be of type ID +The returned channel will never be closed by the F3 +If it is closed without the context being cancelled, the caller should retry. +The values returned on the channel will inform the caller about participation +Empty strings will be sent if participation succeeded, non-empty strings explain possible errors. + + +Perms: admin + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `"string value"` + diff --git a/venus-shared/api/f3/mock/mock_f3.go b/venus-shared/api/f3/mock/mock_f3.go new file mode 100644 index 0000000000..5edda7eea6 --- /dev/null +++ b/venus-shared/api/f3/mock/mock_f3.go @@ -0,0 +1,82 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/filecoin-project/venus/venus-shared/api/f3 (interfaces: F3) + +// Package mock is a generated GoMock package. +package mock + +import ( + context "context" + reflect "reflect" + + address "github.com/filecoin-project/go-address" + certs "github.com/filecoin-project/go-f3/certs" + gomock "github.com/golang/mock/gomock" +) + +// MockF3 is a mock of F3 interface. +type MockF3 struct { + ctrl *gomock.Controller + recorder *MockF3MockRecorder +} + +// MockF3MockRecorder is the mock recorder for MockF3. +type MockF3MockRecorder struct { + mock *MockF3 +} + +// NewMockF3 creates a new mock instance. +func NewMockF3(ctrl *gomock.Controller) *MockF3 { + mock := &MockF3{ctrl: ctrl} + mock.recorder = &MockF3MockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockF3) EXPECT() *MockF3MockRecorder { + return m.recorder +} + +// F3GetCertificate mocks base method. +func (m *MockF3) F3GetCertificate(arg0 context.Context, arg1 uint64) (*certs.FinalityCertificate, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "F3GetCertificate", arg0, arg1) + ret0, _ := ret[0].(*certs.FinalityCertificate) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// F3GetCertificate indicates an expected call of F3GetCertificate. +func (mr *MockF3MockRecorder) F3GetCertificate(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F3GetCertificate", reflect.TypeOf((*MockF3)(nil).F3GetCertificate), arg0, arg1) +} + +// F3GetLatestCertificate mocks base method. +func (m *MockF3) F3GetLatestCertificate(arg0 context.Context) (*certs.FinalityCertificate, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "F3GetLatestCertificate", arg0) + ret0, _ := ret[0].(*certs.FinalityCertificate) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// F3GetLatestCertificate indicates an expected call of F3GetLatestCertificate. +func (mr *MockF3MockRecorder) F3GetLatestCertificate(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F3GetLatestCertificate", reflect.TypeOf((*MockF3)(nil).F3GetLatestCertificate), arg0) +} + +// F3Participate mocks base method. +func (m *MockF3) F3Participate(arg0 context.Context, arg1 address.Address) (<-chan string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "F3Participate", arg0, arg1) + ret0, _ := ret[0].(<-chan string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// F3Participate indicates an expected call of F3Participate. +func (mr *MockF3MockRecorder) F3Participate(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F3Participate", reflect.TypeOf((*MockF3)(nil).F3Participate), arg0, arg1) +} diff --git a/venus-shared/api/f3/proxy_gen.go b/venus-shared/api/f3/proxy_gen.go new file mode 100644 index 0000000000..1932c96239 --- /dev/null +++ b/venus-shared/api/f3/proxy_gen.go @@ -0,0 +1,27 @@ +// Code generated by github.com/filecoin-project/venus/venus-devtool/api-gen. DO NOT EDIT. +package f3 + +import ( + "context" + + address "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-f3/certs" +) + +type F3Struct struct { + Internal struct { + F3GetCertificate func(ctx context.Context, instance uint64) (*certs.FinalityCertificate, error) `perm:"read"` + F3GetLatestCertificate func(ctx context.Context) (*certs.FinalityCertificate, error) `perm:"read"` + F3Participate func(ctx context.Context, minerID address.Address) (<-chan string, error) `perm:"admin"` + } +} + +func (s *F3Struct) F3GetCertificate(p0 context.Context, p1 uint64) (*certs.FinalityCertificate, error) { + return s.Internal.F3GetCertificate(p0, p1) +} +func (s *F3Struct) F3GetLatestCertificate(p0 context.Context) (*certs.FinalityCertificate, error) { + return s.Internal.F3GetLatestCertificate(p0) +} +func (s *F3Struct) F3Participate(p0 context.Context, p1 address.Address) (<-chan string, error) { + return s.Internal.F3Participate(p0, p1) +} diff --git a/venus-shared/api/gateway/v1/method.md b/venus-shared/api/gateway/v1/method.md index 6a1fc0161d..2fc313a689 100644 --- a/venus-shared/api/gateway/v1/method.md +++ b/venus-shared/api/gateway/v1/method.md @@ -205,7 +205,7 @@ Inputs: ], "Bw==", 10101, - 22 + 23 ] ``` diff --git a/venus-shared/api/gateway/v2/method.md b/venus-shared/api/gateway/v2/method.md index 7312b2d60d..8fb9193b0d 100644 --- a/venus-shared/api/gateway/v2/method.md +++ b/venus-shared/api/gateway/v2/method.md @@ -174,7 +174,7 @@ Inputs: ], "Bw==", 10101, - 22 + 23 ] ``` diff --git a/venus-shared/api/market/v0/method.md b/venus-shared/api/market/v0/method.md index 2e26bf15e3..8719245b73 100644 --- a/venus-shared/api/market/v0/method.md +++ b/venus-shared/api/market/v0/method.md @@ -1693,6 +1693,7 @@ Response: "ClientCollateral": "0" }, "State": { + "SectorNumber": 9, "SectorStartEpoch": 10101, "LastUpdatedEpoch": 10101, "SlashEpoch": 10101 diff --git a/venus-shared/api/market/v1/method.md b/venus-shared/api/market/v1/method.md index 7a4395485d..e33af96d03 100644 --- a/venus-shared/api/market/v1/method.md +++ b/venus-shared/api/market/v1/method.md @@ -1904,6 +1904,7 @@ Response: "ClientCollateral": "0" }, "State": { + "SectorNumber": 9, "SectorStartEpoch": 10101, "LastUpdatedEpoch": 10101, "SlashEpoch": 10101 diff --git a/venus-shared/compatible-checks/actor-sources.txt b/venus-shared/compatible-checks/actor-sources.txt index d6354ef186..5a74732f8a 100644 --- a/venus-shared/compatible-checks/actor-sources.txt +++ b/venus-shared/compatible-checks/actor-sources.txt @@ -14,6 +14,7 @@ SOURCES IN chain/actors: builtin/account/v11.go builtin/account/v12.go builtin/account/v13.go + builtin/account/v14.go builtin/account/v2.go builtin/account/v3.go builtin/account/v4.go @@ -29,6 +30,7 @@ SOURCES IN chain/actors: builtin/cron/v11.go builtin/cron/v12.go builtin/cron/v13.go + builtin/cron/v14.go builtin/cron/v2.go builtin/cron/v3.go builtin/cron/v4.go @@ -43,12 +45,14 @@ SOURCES IN chain/actors: builtin/datacap/v11.go builtin/datacap/v12.go builtin/datacap/v13.go + builtin/datacap/v14.go builtin/datacap/v9.go builtin/evm/evm.go builtin/evm/v10.go builtin/evm/v11.go builtin/evm/v12.go builtin/evm/v13.go + builtin/evm/v14.go builtin/init/diff.go builtin/init/init.go builtin/init/v0.go @@ -56,6 +60,7 @@ SOURCES IN chain/actors: builtin/init/v11.go builtin/init/v12.go builtin/init/v13.go + builtin/init/v14.go builtin/init/v2.go builtin/init/v3.go builtin/init/v4.go @@ -71,6 +76,7 @@ SOURCES IN chain/actors: builtin/market/v11.go builtin/market/v12.go builtin/market/v13.go + builtin/market/v14.go builtin/market/v2.go builtin/market/v3.go builtin/market/v4.go @@ -88,6 +94,7 @@ SOURCES IN chain/actors: builtin/miner/v11.go builtin/miner/v12.go builtin/miner/v13.go + builtin/miner/v14.go builtin/miner/v2.go builtin/miner/v3.go builtin/miner/v4.go @@ -102,6 +109,7 @@ SOURCES IN chain/actors: builtin/multisig/message11.go builtin/multisig/message12.go builtin/multisig/message13.go + builtin/multisig/message14.go builtin/multisig/message2.go builtin/multisig/message3.go builtin/multisig/message4.go @@ -116,6 +124,7 @@ SOURCES IN chain/actors: builtin/multisig/v11.go builtin/multisig/v12.go builtin/multisig/v13.go + builtin/multisig/v14.go builtin/multisig/v2.go builtin/multisig/v3.go builtin/multisig/v4.go @@ -129,6 +138,7 @@ SOURCES IN chain/actors: builtin/paych/message11.go builtin/paych/message12.go builtin/paych/message13.go + builtin/paych/message14.go builtin/paych/message2.go builtin/paych/message3.go builtin/paych/message4.go @@ -144,6 +154,7 @@ SOURCES IN chain/actors: builtin/paych/v11.go builtin/paych/v12.go builtin/paych/v13.go + builtin/paych/v14.go builtin/paych/v2.go builtin/paych/v3.go builtin/paych/v4.go @@ -159,6 +170,7 @@ SOURCES IN chain/actors: builtin/power/v11.go builtin/power/v12.go builtin/power/v13.go + builtin/power/v14.go builtin/power/v2.go builtin/power/v3.go builtin/power/v4.go @@ -174,6 +186,7 @@ SOURCES IN chain/actors: builtin/reward/v11.go builtin/reward/v12.go builtin/reward/v13.go + builtin/reward/v14.go builtin/reward/v2.go builtin/reward/v3.go builtin/reward/v4.go @@ -188,6 +201,7 @@ SOURCES IN chain/actors: builtin/system/v11.go builtin/system/v12.go builtin/system/v13.go + builtin/system/v14.go builtin/system/v2.go builtin/system/v3.go builtin/system/v4.go @@ -202,6 +216,7 @@ SOURCES IN chain/actors: builtin/verifreg/v11.go builtin/verifreg/v12.go builtin/verifreg/v13.go + builtin/verifreg/v14.go builtin/verifreg/v2.go builtin/verifreg/v3.go builtin/verifreg/v4.go diff --git a/venus-shared/compatible-checks/api-checksum.txt b/venus-shared/compatible-checks/api-checksum.txt index 4662972e58..001c909329 100644 --- a/venus-shared/compatible-checks/api-checksum.txt +++ b/venus-shared/compatible-checks/api-checksum.txt @@ -25,33 +25,6 @@ v0api.FullNode: ChainSetHead: In=2, Out=1, CheckSum=cdfe593ac791e823186abb77bfad49a0 ChainStatObj: In=3, Out=2, CheckSum=9db2a0d97998daaf9c15e7c3d6ffe82d ChainTipSetWeight: In=2, Out=2, CheckSum=22ac180fa0c583b4036666bfc155fd63 - ClientCalcCommP: In=2, Out=2, CheckSum=f83c6f3b9d823d22dfcd13e5aee9fb6b - ClientCancelDataTransfer: In=4, Out=1, CheckSum=c07b9f21141607983053047579f2a8b3 - ClientCancelRetrievalDeal: In=2, Out=1, CheckSum=d289f4c3758ed7d6ab991b2cf569c969 - ClientDataTransferUpdates: In=1, Out=2, CheckSum=2d33b419e4b215c06ab0e8b66b5f8430 - ClientDealPieceCID: In=2, Out=2, CheckSum=93537a844ba6b74ec1ce82c887359a75 - ClientDealSize: In=2, Out=2, CheckSum=cca1dd5f58136af28546bdbdef2f948a - ClientFindData: In=3, Out=2, CheckSum=232da9eb987d92a76b37572c8f44bf53 - ClientGenCar: In=3, Out=1, CheckSum=b8a0c89fc2c7c16464ac968865e9c156 - ClientGetDealInfo: In=2, Out=2, CheckSum=e67f0e7b88aff099976b0f275b601c9c - ClientGetDealStatus: In=2, Out=2, CheckSum=1297eb9ae9a9ed209cfcb5899910f415 - ClientGetDealUpdates: In=1, Out=2, CheckSum=459cb2faa373d8dcf4cf8e33a2854366 - ClientGetRetrievalUpdates: In=1, Out=2, CheckSum=9390e4328ba9fe6c034341d574fd6f3d - ClientHasLocal: In=2, Out=2, CheckSum=7fe71bcffa1b110db106e0104e98a32f - ClientImport: In=2, Out=2, CheckSum=8c5886f6f2eb7b5db886d639c62e5808 - ClientListDataTransfers: In=1, Out=2, CheckSum=aa113d3aaf47f5b34fc947d26d58d001 - ClientListDeals: In=1, Out=2, CheckSum=fddf5a2bf3dd94a5aec97248ff7db918 - ClientListImports: In=1, Out=2, CheckSum=1966c3c721d57e0a728d3b51ba3a61d4 - ClientListRetrievals: In=1, Out=2, CheckSum=d5485e62b97cf31e1880d54808968895 - ClientMinerQueryOffer: In=4, Out=2, CheckSum=f57fabb5f04c1086302b43bd5087b9e2 - ClientQueryAsk: In=3, Out=2, CheckSum=929f732f0ba36128dc6e0250bee150e8 - ClientRemoveImport: In=2, Out=1, CheckSum=a3fcb78bf5bac553baac584941c1771f - ClientRestartDataTransfer: In=4, Out=1, CheckSum=c07b9f21141607983053047579f2a8b3 - ClientRetrieve: In=3, Out=1, CheckSum=3b17e80e3a84f40959f87bff6359a49d - ClientRetrieveTryRestartInsufficientFunds: In=2, Out=1, CheckSum=98613e8d41d3a2e52b37f97908560bd9 - ClientRetrieveWithEvents: In=3, Out=2, CheckSum=56e4fa49192938527c1f089b446f0860 - ClientStartDeal: In=2, Out=2, CheckSum=85256e9ef86dbb8ebeb76097c3eea078 - ClientStatelessDeal: In=2, Out=2, CheckSum=85256e9ef86dbb8ebeb76097c3eea078 Closing: In=1, Out=2, CheckSum=3e0dae65a2378c12be14cee8a60a3bfe CreateBackup: In=2, Out=1, CheckSum=7b0679c2c73ab9606a7da21c5251ad19 Discover: In=1, Out=2, CheckSum=09640e20c6d71c3e96c7a56c8698acc9 @@ -171,7 +144,7 @@ v0api.FullNode: StateMarketDeals: In=2, Out=2, CheckSum=46b5eef922e8252939bf00e1e80ae89e StateMarketParticipants: In=2, Out=2, CheckSum=acc9019d0b6e389743c6f992350f407c StateMarketStorageDeal: In=3, Out=2, CheckSum=94af302d39beba9f0ce7648f4118b6aa - StateMinerActiveSectors: In=3, Out=2, CheckSum=a6cc03c30ff0302d5dcd3002e55585b7 + StateMinerActiveSectors: In=3, Out=2, CheckSum=6dc03bd9f54d60f68a2dd9790a6490a3 StateMinerAvailableBalance: In=3, Out=2, CheckSum=a05010da3c73edfba49c3b5d28a216cd StateMinerDeadlines: In=3, Out=2, CheckSum=5b128c75ba4953740906520cca96b962 StateMinerFaults: In=3, Out=2, CheckSum=9d26d848f93597964f751b43edd3d476 @@ -184,7 +157,7 @@ v0api.FullNode: StateMinerRecoveries: In=3, Out=2, CheckSum=9d26d848f93597964f751b43edd3d476 StateMinerSectorAllocated: In=4, Out=2, CheckSum=2accd56a9e9196fa1ca85a1d60e19fc2 StateMinerSectorCount: In=3, Out=2, CheckSum=573483cbcf3ccdd38063b9ce16453dc2 - StateMinerSectors: In=4, Out=2, CheckSum=532dd2620e4430f0ae9113b75104e12f + StateMinerSectors: In=4, Out=2, CheckSum=21ce897ae50cf7ea1fdd83d4dc1caa38 StateNetworkName: In=1, Out=2, CheckSum=afb82130640a26dcd9d7010f31c69572 StateNetworkVersion: In=2, Out=2, CheckSum=47de92e3b59793ade53abd96c347bace StateReadState: In=3, Out=2, CheckSum=f53f39943eea93d5f3dd64f1389e4c64 @@ -192,7 +165,7 @@ v0api.FullNode: StateSearchMsg: In=2, Out=2, CheckSum=e4186ab56a9d2e3c99174110e3f697dc StateSearchMsgLimited: In=3, Out=2, CheckSum=8990ed018d033c44ebb38c0d077bc6d0 StateSectorExpiration: In=4, Out=2, CheckSum=bb669c8b66b6f74c681b4345c9e4cc8f - StateSectorGetInfo: In=4, Out=2, CheckSum=8d176fd8a2054079b0017f795f9a4d56 + StateSectorGetInfo: In=4, Out=2, CheckSum=20fcd228b7cf923e013b24313230e256 StateSectorPartition: In=4, Out=2, CheckSum=e3743df55a360243a32ac64ce1282c53 StateSectorPreCommitInfo: In=4, Out=2, CheckSum=f0961d63ab3679dafcf6563a83126d56 StateVMCirculatingSupplyInternal: In=2, Out=2, CheckSum=05c2114e08be095cece55db19e214d2c @@ -256,34 +229,6 @@ api.FullNode: ChainSetHead: In=2, Out=1, CheckSum=cdfe593ac791e823186abb77bfad49a0 ChainStatObj: In=3, Out=2, CheckSum=9db2a0d97998daaf9c15e7c3d6ffe82d ChainTipSetWeight: In=2, Out=2, CheckSum=22ac180fa0c583b4036666bfc155fd63 - ClientCalcCommP: In=2, Out=2, CheckSum=f83c6f3b9d823d22dfcd13e5aee9fb6b - ClientCancelDataTransfer: In=4, Out=1, CheckSum=c07b9f21141607983053047579f2a8b3 - ClientCancelRetrievalDeal: In=2, Out=1, CheckSum=d289f4c3758ed7d6ab991b2cf569c969 - ClientDataTransferUpdates: In=1, Out=2, CheckSum=2d33b419e4b215c06ab0e8b66b5f8430 - ClientDealPieceCID: In=2, Out=2, CheckSum=93537a844ba6b74ec1ce82c887359a75 - ClientDealSize: In=2, Out=2, CheckSum=cca1dd5f58136af28546bdbdef2f948a - ClientExport: In=3, Out=1, CheckSum=77c3a3632e06654aee2dade7aa467433 - ClientFindData: In=3, Out=2, CheckSum=232da9eb987d92a76b37572c8f44bf53 - ClientGenCar: In=3, Out=1, CheckSum=b8a0c89fc2c7c16464ac968865e9c156 - ClientGetDealInfo: In=2, Out=2, CheckSum=e67f0e7b88aff099976b0f275b601c9c - ClientGetDealStatus: In=2, Out=2, CheckSum=1297eb9ae9a9ed209cfcb5899910f415 - ClientGetDealUpdates: In=1, Out=2, CheckSum=459cb2faa373d8dcf4cf8e33a2854366 - ClientGetRetrievalUpdates: In=1, Out=2, CheckSum=9390e4328ba9fe6c034341d574fd6f3d - ClientHasLocal: In=2, Out=2, CheckSum=7fe71bcffa1b110db106e0104e98a32f - ClientImport: In=2, Out=2, CheckSum=8c5886f6f2eb7b5db886d639c62e5808 - ClientListDataTransfers: In=1, Out=2, CheckSum=aa113d3aaf47f5b34fc947d26d58d001 - ClientListDeals: In=1, Out=2, CheckSum=fddf5a2bf3dd94a5aec97248ff7db918 - ClientListImports: In=1, Out=2, CheckSum=1966c3c721d57e0a728d3b51ba3a61d4 - ClientListRetrievals: In=1, Out=2, CheckSum=d5485e62b97cf31e1880d54808968895 - ClientMinerQueryOffer: In=4, Out=2, CheckSum=f57fabb5f04c1086302b43bd5087b9e2 - ClientQueryAsk: In=3, Out=2, CheckSum=c6a0b229078419aa2fbb69f747bd6e89 - ClientRemoveImport: In=2, Out=1, CheckSum=a3fcb78bf5bac553baac584941c1771f - ClientRestartDataTransfer: In=4, Out=1, CheckSum=c07b9f21141607983053047579f2a8b3 - ClientRetrieve: In=2, Out=2, CheckSum=b941d6f05cbec209e2f347b6826717e1 - ClientRetrieveTryRestartInsufficientFunds: In=2, Out=1, CheckSum=98613e8d41d3a2e52b37f97908560bd9 - ClientRetrieveWait: In=2, Out=1, CheckSum=d289f4c3758ed7d6ab991b2cf569c969 - ClientStartDeal: In=2, Out=2, CheckSum=85256e9ef86dbb8ebeb76097c3eea078 - ClientStatelessDeal: In=2, Out=2, CheckSum=85256e9ef86dbb8ebeb76097c3eea078 Closing: In=1, Out=2, CheckSum=3e0dae65a2378c12be14cee8a60a3bfe CreateBackup: In=2, Out=1, CheckSum=7b0679c2c73ab9606a7da21c5251ad19 Discover: In=1, Out=2, CheckSum=09640e20c6d71c3e96c7a56c8698acc9 @@ -324,8 +269,12 @@ api.FullNode: EthSyncing: In=1, Out=2, CheckSum=2c17cf64e376c0e9d0d56053d33c0722 EthTraceBlock: In=2, Out=2, CheckSum=87ad85d70d0a285fae530a47eee79d13 EthTraceReplayBlockTransactions: In=3, Out=2, CheckSum=ec2c86340cf2a777bc64bab8d10e3fdb + EthTraceTransaction: In=2, Out=2, CheckSum=5baa667f39dbbb1355663613b6e9cf3b EthUninstallFilter: In=2, Out=2, CheckSum=eaa6a477ffaae115413457bbdb11e339 EthUnsubscribe: In=2, Out=2, CheckSum=eaa6a477ffaae115413457bbdb11e339 + F3GetCertificate: In=2, Out=2, CheckSum=eda9046b5f1856a3214558c306707d88 + F3GetLatestCertificate: In=1, Out=2, CheckSum=de551a11a224677fff1d64e2014932e6 + F3Participate: In=2, Out=2, CheckSum=6d724f07a798cb19cb8cf779845b81ed FilecoinAddressToEthAddress: In=2, Out=2, CheckSum=13a0b5ce8f82604e17803a00c4086c4c GasEstimateFeeCap: In=4, Out=2, CheckSum=0fcac02de1d21c9ac6e10696a6499eba GasEstimateGasLimit: In=3, Out=2, CheckSum=4d1bd57eef0ee90d4c2e89f097d0604d @@ -419,8 +368,6 @@ api.FullNode: PaychVoucherCreate: In=4, Out=2, CheckSum=e5113a58d351abf5cadd77b46f690c2d PaychVoucherList: In=2, Out=2, CheckSum=c4a81e1915ceee53e3ecde9f1ae30b4c PaychVoucherSubmit: In=5, Out=2, CheckSum=03f7a7f3a90849ea5da8eedd01643a1c - RaftLeader: In=1, Out=2, CheckSum=1635810444d2b13b381cbefece853ba7 - RaftState: In=1, Out=2, CheckSum=f5cfaa01ba547fa4fe060c9f5bc3e518 Session: In=1, Out=2, CheckSum=cdb04ef6a97114c8f24f456a2e70f1cd Shutdown: In=1, Out=1, CheckSum=c39be30cc5a8826024fcf4d23e7017d6 StartTime: In=1, Out=2, CheckSum=7eaff8e9437521f47c2a8bf1be7a77c8 @@ -460,7 +407,7 @@ api.FullNode: StateMarketDeals: In=2, Out=2, CheckSum=46b5eef922e8252939bf00e1e80ae89e StateMarketParticipants: In=2, Out=2, CheckSum=acc9019d0b6e389743c6f992350f407c StateMarketStorageDeal: In=3, Out=2, CheckSum=94af302d39beba9f0ce7648f4118b6aa - StateMinerActiveSectors: In=3, Out=2, CheckSum=a6cc03c30ff0302d5dcd3002e55585b7 + StateMinerActiveSectors: In=3, Out=2, CheckSum=6dc03bd9f54d60f68a2dd9790a6490a3 StateMinerAllocated: In=3, Out=2, CheckSum=808e4357d56c3d08769a9d7a249ea7c0 StateMinerAvailableBalance: In=3, Out=2, CheckSum=a05010da3c73edfba49c3b5d28a216cd StateMinerDeadlines: In=3, Out=2, CheckSum=5b128c75ba4953740906520cca96b962 @@ -474,14 +421,14 @@ api.FullNode: StateMinerRecoveries: In=3, Out=2, CheckSum=9d26d848f93597964f751b43edd3d476 StateMinerSectorAllocated: In=4, Out=2, CheckSum=2accd56a9e9196fa1ca85a1d60e19fc2 StateMinerSectorCount: In=3, Out=2, CheckSum=573483cbcf3ccdd38063b9ce16453dc2 - StateMinerSectors: In=4, Out=2, CheckSum=532dd2620e4430f0ae9113b75104e12f + StateMinerSectors: In=4, Out=2, CheckSum=21ce897ae50cf7ea1fdd83d4dc1caa38 StateNetworkName: In=1, Out=2, CheckSum=afb82130640a26dcd9d7010f31c69572 StateNetworkVersion: In=2, Out=2, CheckSum=47de92e3b59793ade53abd96c347bace StateReadState: In=3, Out=2, CheckSum=f53f39943eea93d5f3dd64f1389e4c64 StateReplay: In=3, Out=2, CheckSum=ec89143eb01290212c3ce0032f62c5fc StateSearchMsg: In=5, Out=2, CheckSum=05ad20588933ea6ffa941f47b826708a StateSectorExpiration: In=4, Out=2, CheckSum=bb669c8b66b6f74c681b4345c9e4cc8f - StateSectorGetInfo: In=4, Out=2, CheckSum=8d176fd8a2054079b0017f795f9a4d56 + StateSectorGetInfo: In=4, Out=2, CheckSum=20fcd228b7cf923e013b24313230e256 StateSectorPartition: In=4, Out=2, CheckSum=e3743df55a360243a32ac64ce1282c53 StateSectorPreCommitInfo: In=4, Out=2, CheckSum=80eabb64c62e90a2cf0e497107b774ff StateVMCirculatingSupplyInternal: In=2, Out=2, CheckSum=05c2114e08be095cece55db19e214d2c diff --git a/venus-shared/compatible-checks/api-diff.txt b/venus-shared/compatible-checks/api-diff.txt index 94f0bcc00b..4fe1f2aacc 100644 --- a/venus-shared/compatible-checks/api-diff.txt +++ b/venus-shared/compatible-checks/api-diff.txt @@ -6,33 +6,6 @@ github.com/filecoin-project/venus/venus-shared/api/chain/v0.FullNode <> github.c + ChainGetReceipts + ChainList + ChainSyncHandleNewTipSet - - ClientCalcCommP - - ClientCancelDataTransfer - - ClientCancelRetrievalDeal - - ClientDataTransferUpdates - - ClientDealPieceCID - - ClientDealSize - - ClientFindData - - ClientGenCar - - ClientGetDealInfo - - ClientGetDealStatus - - ClientGetDealUpdates - - ClientGetRetrievalUpdates - - ClientHasLocal - - ClientImport - - ClientListDataTransfers - - ClientListDeals - - ClientListImports - - ClientListRetrievals - - ClientMinerQueryOffer - - ClientQueryAsk - - ClientRemoveImport - - ClientRestartDataTransfer - - ClientRetrieve - - ClientRetrieveTryRestartInsufficientFunds - - ClientRetrieveWithEvents - - ClientStartDeal - - ClientStatelessDeal - Closing + Concurrent - CreateBackup @@ -127,40 +100,14 @@ github.com/filecoin-project/venus/venus-shared/api/chain/v1.FullNode <> github.c + ChainList - ChainPrune + ChainSyncHandleNewTipSet - - ClientCalcCommP - - ClientCancelDataTransfer - - ClientCancelRetrievalDeal - - ClientDataTransferUpdates - - ClientDealPieceCID - - ClientDealSize - - ClientExport - - ClientFindData - - ClientGenCar - - ClientGetDealInfo - - ClientGetDealStatus - - ClientGetDealUpdates - - ClientGetRetrievalUpdates - - ClientHasLocal - - ClientImport - - ClientListDataTransfers - - ClientListDeals - - ClientListImports - - ClientListRetrievals - - ClientMinerQueryOffer - - ClientQueryAsk - - ClientRemoveImport - - ClientRestartDataTransfer - - ClientRetrieve - - ClientRetrieveTryRestartInsufficientFunds - - ClientRetrieveWait - - ClientStartDeal - - ClientStatelessDeal - Closing + Concurrent - CreateBackup - Discover - > EthTraceBlock {[func(context.Context, string) ([]*types.EthTraceBlock, error) <> func(context.Context, string) ([]*ethtypes.EthTraceBlock, error)] base=func out type: #0 input; nested={[[]*types.EthTraceBlock <> []*ethtypes.EthTraceBlock] base=slice element; nested={[*types.EthTraceBlock <> *ethtypes.EthTraceBlock] base=pointed type; nested={[types.EthTraceBlock <> ethtypes.EthTraceBlock] base=struct field; nested={[types.EthTraceBlock <> ethtypes.EthTraceBlock] base=exported field type: #0 field named EthTrace; nested={[*types.EthTrace <> *ethtypes.EthTrace] base=pointed type; nested={[types.EthTrace <> ethtypes.EthTrace] base=struct field; nested={[types.EthTrace <> ethtypes.EthTrace] base=exported fields count: 8 != 6; nested=nil}}}}}}}} - > EthTraceReplayBlockTransactions {[func(context.Context, string, []string) ([]*types.EthTraceReplayBlockTransaction, error) <> func(context.Context, string, []string) ([]*ethtypes.EthTraceReplayBlockTransaction, error)] base=func out type: #0 input; nested={[[]*types.EthTraceReplayBlockTransaction <> []*ethtypes.EthTraceReplayBlockTransaction] base=slice element; nested={[*types.EthTraceReplayBlockTransaction <> *ethtypes.EthTraceReplayBlockTransaction] base=pointed type; nested={[types.EthTraceReplayBlockTransaction <> ethtypes.EthTraceReplayBlockTransaction] base=struct field; nested={[types.EthTraceReplayBlockTransaction <> ethtypes.EthTraceReplayBlockTransaction] base=exported field type: #2 field named Trace; nested={[[]*types.EthTrace <> []*ethtypes.EthTrace] base=slice element; nested={[*types.EthTrace <> *ethtypes.EthTrace] base=pointed type; nested={[types.EthTrace <> ethtypes.EthTrace] base=struct field; nested={[types.EthTrace <> ethtypes.EthTrace] base=exported fields count: 8 != 6; nested=nil}}}}}}}}} + > EthTraceReplayBlockTransactions {[func(context.Context, string, []string) ([]*types.EthTraceReplayBlockTransaction, error) <> func(context.Context, string, []string) ([]*ethtypes.EthTraceReplayBlockTransaction, error)] base=func out type: #0 input; nested={[[]*types.EthTraceReplayBlockTransaction <> []*ethtypes.EthTraceReplayBlockTransaction] base=slice element; nested={[*types.EthTraceReplayBlockTransaction <> *ethtypes.EthTraceReplayBlockTransaction] base=pointed type; nested={[types.EthTraceReplayBlockTransaction <> ethtypes.EthTraceReplayBlockTransaction] base=struct field; nested={[types.EthTraceReplayBlockTransaction <> ethtypes.EthTraceReplayBlockTransaction] base=exported field name: #4 field, VMTrace != VmTrace; nested=nil}}}}} + - F3GetCertificate + - F3GetLatestCertificate + - F3Participate + GasBatchEstimateMessageGas > GasEstimateMessageGas {[func(context.Context, *types.Message, *types.MessageSendSpec, types.TipSetKey) (*types.Message, error) <> func(context.Context, *types.Message, *api.MessageSendSpec, types.TipSetKey) (*types.Message, error)] base=func in type: #2 input; nested={[*types.MessageSendSpec <> *api.MessageSendSpec] base=pointed type; nested={[types.MessageSendSpec <> api.MessageSendSpec] base=struct field; nested={[types.MessageSendSpec <> api.MessageSendSpec] base=exported field name: #1 field, GasOverEstimation != MsgUuid; nested=nil}}}} + GetActor @@ -210,8 +157,6 @@ github.com/filecoin-project/venus/venus-shared/api/chain/v1.FullNode <> github.c - NetSetLimit - NetStat + ProtocolParameters - - RaftLeader - - RaftState + ResolveToKeyAddr - Session + SetConcurrent diff --git a/venus-shared/types/api_types.go b/venus-shared/types/api_types.go index a67c2adb53..b06353e5c3 100644 --- a/venus-shared/types/api_types.go +++ b/venus-shared/types/api_types.go @@ -172,13 +172,15 @@ type Deadline struct { var MarketBalanceNil = MarketBalance{} type MarketDealState struct { - SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector - LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated - SlashEpoch abi.ChainEpoch // -1 if deal never slashed + SectorNumber abi.SectorNumber // 0 if not yet included in proven sector (0 is also a valid sector number). + SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector + LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated + SlashEpoch abi.ChainEpoch // -1 if deal never slashed } func MakeDealState(mds market.DealState) MarketDealState { return MarketDealState{ + SectorNumber: mds.SectorNumber(), SectorStartEpoch: mds.SectorStartEpoch(), LastUpdatedEpoch: mds.LastUpdatedEpoch(), SlashEpoch: mds.SlashEpoch(), @@ -189,6 +191,10 @@ type mstate struct { s MarketDealState } +func (m mstate) SectorNumber() abi.SectorNumber { + return m.s.SectorNumber +} + func (m mstate) SectorStartEpoch() abi.ChainEpoch { return m.s.SectorStartEpoch } @@ -471,6 +477,7 @@ type ForkUpgradeParams struct { UpgradeWatermelonHeight abi.ChainEpoch UpgradeDragonHeight abi.ChainEpoch UpgradePhoenixHeight abi.ChainEpoch + UpgradeWaffleHeight abi.ChainEpoch } type NodeStatus struct { diff --git a/venus-shared/types/eth.go b/venus-shared/types/eth.go index db6b424630..bfeb684566 100644 --- a/venus-shared/types/eth.go +++ b/venus-shared/types/eth.go @@ -9,6 +9,7 @@ const ( EthAddressLength = types.EthAddressLength EthBloomSize = types.EthBloomSize EthHashLength = types.EthHashLength + SafeEpochDelay = types.SafeEpochDelay ) var ( @@ -54,6 +55,7 @@ type ( EthTrace = types.EthTrace EthTraceBlock = types.EthTraceBlock EthTraceReplayBlockTransaction = types.EthTraceReplayBlockTransaction + EthTraceTransaction = types.EthTraceTransaction EthTxReceipt = types.EthTxReceipt EthUint64 = types.EthUint64 ) diff --git a/venus-shared/types/eth_1559_transactions.go b/venus-shared/types/eth_1559_transactions.go new file mode 100755 index 0000000000..4deb19642e --- /dev/null +++ b/venus-shared/types/eth_1559_transactions.go @@ -0,0 +1,14 @@ +// Code generated by github.com/filecoin-project/venus/venus-devtool/state-type-gen. DO NOT EDIT. +package types + +import ( + "github.com/filecoin-project/venus/venus-shared/actors/types" +) + +type ( + Eth1559TxArgs = types.Eth1559TxArgs +) + +var ( + Eth1559TxArgsFromUnsignedFilecoinMessage = types.Eth1559TxArgsFromUnsignedFilecoinMessage +) diff --git a/venus-shared/types/eth_legacy_155_transactions.go b/venus-shared/types/eth_legacy_155_transactions.go new file mode 100755 index 0000000000..1b239e1b0c --- /dev/null +++ b/venus-shared/types/eth_legacy_155_transactions.go @@ -0,0 +1,14 @@ +// Code generated by github.com/filecoin-project/venus/venus-devtool/state-type-gen. DO NOT EDIT. +package types + +import ( + "github.com/filecoin-project/venus/venus-shared/actors/types" +) + +type ( + EthLegacy155TxArgs = types.EthLegacy155TxArgs +) + +var ( + NewEthLegacy155TxArgs = types.NewEthLegacy155TxArgs +) diff --git a/venus-shared/types/eth_legacy_homestead_transactions.go b/venus-shared/types/eth_legacy_homestead_transactions.go new file mode 100755 index 0000000000..3fec0ceb1f --- /dev/null +++ b/venus-shared/types/eth_legacy_homestead_transactions.go @@ -0,0 +1,10 @@ +// Code generated by github.com/filecoin-project/venus/venus-devtool/state-type-gen. DO NOT EDIT. +package types + +import ( + "github.com/filecoin-project/venus/venus-shared/actors/types" +) + +type ( + EthLegacyHomesteadTxArgs = types.EthLegacyHomesteadTxArgs +) diff --git a/venus-shared/types/eth_transactions.go b/venus-shared/types/eth_transactions.go index 098865974f..40eb42fd86 100644 --- a/venus-shared/types/eth_transactions.go +++ b/venus-shared/types/eth_transactions.go @@ -6,17 +6,30 @@ import ( ) const ( - Eip1559TxType = types.Eip1559TxType + EIP1559TxType = types.EIP1559TxType + EthEIP1559TxSignatureLen = types.EthEIP1559TxSignatureLen + EthLegacy155TxSignaturePrefix = types.EthLegacy155TxSignaturePrefix + EthLegacyHomesteadTxChainID = types.EthLegacyHomesteadTxChainID + EthLegacyHomesteadTxSignatureLen = types.EthLegacyHomesteadTxSignatureLen + EthLegacyHomesteadTxSignaturePrefix = types.EthLegacyHomesteadTxSignaturePrefix + EthLegacyTxType = types.EthLegacyTxType ) +var ( + EthLegacy155TxSignatureLen0 = types.EthLegacy155TxSignatureLen0 + EthLegacy155TxSignatureLen1 = types.EthLegacy155TxSignatureLen1 +) + +type ( + EthTransaction = types.EthTransaction + RlpPackable = types.RlpPackable +) type ( - EthTx = types.EthTx - EthTxArgs = types.EthTxArgs + EthTx = types.EthTx ) var ( - EthTxArgsFromUnsignedEthMessage = types.EthTxArgsFromUnsignedEthMessage - EthTxFromSignedEthMessage = types.EthTxFromSignedEthMessage - ParseEthTxArgs = types.ParseEthTxArgs - RecoverSignature = types.RecoverSignature + EthTransactionFromSignedFilecoinMessage = types.EthTransactionFromSignedFilecoinMessage + ParseEthTransaction = types.ParseEthTransaction + ToSignedFilecoinMessage = types.ToSignedFilecoinMessage ) diff --git a/venus-shared/types/rlp_test.go b/venus-shared/types/rlp_test.go deleted file mode 100644 index e2da12e7ed..0000000000 --- a/venus-shared/types/rlp_test.go +++ /dev/null @@ -1,190 +0,0 @@ -package types - -import ( - "encoding/hex" - "fmt" - "strings" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/filecoin-project/go-address" -) - -func TestEncode(t *testing.T) { - testcases := []TestCase{ - {[]byte(""), mustDecodeHex("0x80")}, - {mustDecodeHex("0x01"), mustDecodeHex("0x01")}, - {mustDecodeHex("0xaa"), mustDecodeHex("0x81aa")}, - {mustDecodeHex("0x0402"), mustDecodeHex("0x820402")}, - { - []interface{}{}, - mustDecodeHex("0xc0"), - }, - { - mustDecodeHex("0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"), - mustDecodeHex("0xb83cabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"), - }, - { - mustDecodeHex("0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"), - mustDecodeHex("0xb8aaabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"), - }, - { - []interface{}{ - mustDecodeHex("0xaaaa"), - mustDecodeHex("0xbbbb"), - mustDecodeHex("0xcccc"), - mustDecodeHex("0xdddd"), - }, - mustDecodeHex("0xcc82aaaa82bbbb82cccc82dddd"), - }, - { - []interface{}{ - mustDecodeHex("0xaaaaaaaaaaaaaaaaaaaa"), - mustDecodeHex("0xbbbbbbbbbbbbbbbbbbbb"), - []interface{}{ - mustDecodeHex("0xc1c1c1c1c1c1c1c1c1c1"), - mustDecodeHex("0xc2c2c2c2c2c2c2c2c2c2"), - mustDecodeHex("0xc3c3c3c3c3c3c3c3c3c3"), - }, - mustDecodeHex("0xdddddddddddddddddddd"), - mustDecodeHex("0xeeeeeeeeeeeeeeeeeeee"), - mustDecodeHex("0xffffffffffffffffffff"), - }, - mustDecodeHex("0xf8598aaaaaaaaaaaaaaaaaaaaa8abbbbbbbbbbbbbbbbbbbbe18ac1c1c1c1c1c1c1c1c1c18ac2c2c2c2c2c2c2c2c2c28ac3c3c3c3c3c3c3c3c3c38adddddddddddddddddddd8aeeeeeeeeeeeeeeeeeeee8affffffffffffffffffff"), - }, - } - - for _, tc := range testcases { - result, err := EncodeRLP(tc.Input) - require.Nil(t, err) - - require.Equal(t, tc.Output.([]byte), result) - } -} - -func TestDecodeString(t *testing.T) { - testcases := []TestCase{ - {"0x00", "0x00"}, - {"0x80", "0x"}, - {"0x0f", "0x0f"}, - {"0x81aa", "0xaa"}, - {"0x820400", "0x0400"}, - {"0xb83cabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", - "0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"}, - } - - for _, tc := range testcases { - input, err := hex.DecodeString(strings.Replace(tc.Input.(string), "0x", "", -1)) - require.Nil(t, err) - - output, err := hex.DecodeString(strings.Replace(tc.Output.(string), "0x", "", -1)) - require.Nil(t, err) - - result, err := DecodeRLP(input) - require.Nil(t, err) - require.Equal(t, output, result.([]byte)) - } -} - -func mustDecodeHex(s string) []byte { - d, err := hex.DecodeString(strings.Replace(s, "0x", "", -1)) - if err != nil { - panic(fmt.Errorf("err must be nil: %w", err)) - } - return d -} - -func TestDecodeList(t *testing.T) { - testcases := []TestCase{ - {"0xc0", []interface{}{}}, - {"0xc100", []interface{}{[]byte{0}}}, - {"0xc3000102", []interface{}{[]byte{0}, []byte{1}, []byte{2}}}, - {"0xc4000181aa", []interface{}{[]byte{0}, []byte{1}, []byte{0xaa}}}, - {"0xc6000181aa81ff", []interface{}{[]byte{0}, []byte{1}, []byte{0xaa}, []byte{0xff}}}, - {"0xf8428aabcdabcdabcdabcdabcd8aabcdabcdabcdabcdabcd8aabcdabcdabcdabcdabcd8aabcdabcdabcdabcdabcd8aabcdabcdabcdabcdabcd8aabcdabcdabcdabcdabcd", - []interface{}{ - mustDecodeHex("0xabcdabcdabcdabcdabcd"), - mustDecodeHex("0xabcdabcdabcdabcdabcd"), - mustDecodeHex("0xabcdabcdabcdabcdabcd"), - mustDecodeHex("0xabcdabcdabcdabcdabcd"), - mustDecodeHex("0xabcdabcdabcdabcdabcd"), - mustDecodeHex("0xabcdabcdabcdabcdabcd"), - }, - }, - {"0xf1030185012a05f2008504a817c800825208942b87d1cb599bc2a606db9a0169fcec96af04ad3a880de0b6b3a764000080c0", - []interface{}{ - []byte{3}, - []byte{1}, - mustDecodeHex("0x012a05f200"), - mustDecodeHex("0x04a817c800"), - mustDecodeHex("0x5208"), - mustDecodeHex("0x2b87d1CB599Bc2a606Db9A0169fcEc96Af04ad3a"), - mustDecodeHex("0x0de0b6b3a7640000"), - []byte{}, - []interface{}{}, - }}, - } - - for _, tc := range testcases { - input, err := hex.DecodeString(strings.Replace(tc.Input.(string), "0x", "", -1)) - require.Nil(t, err) - - result, err := DecodeRLP(input) - require.Nil(t, err) - - fmt.Println(result) - r := result.([]interface{}) - require.Equal(t, len(tc.Output.([]interface{})), len(r)) - - for i, v := range r { - require.Equal(t, tc.Output.([]interface{})[i], v) - } - } -} - -func TestDecodeEncodeTx(t *testing.T) { - testcases := [][]byte{ - mustDecodeHex("0xdc82013a0185012a05f2008504a817c8008080872386f26fc1000000c0"), - mustDecodeHex("0xf85f82013a0185012a05f2008504a817c8008080872386f26fc1000000c001a027fa36fb9623e4d71fcdd7f7dce71eb814c9560dcf3908c1719386e2efd122fba05fb4e4227174eeb0ba84747a4fb883c8d4e0fdb129c4b1f42e90282c41480234"), - mustDecodeHex("0xf9061c82013a0185012a05f2008504a817c8008080872386f26fc10000b905bb608060405234801561001057600080fd5b506127106000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610556806100656000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80637bd703e81461004657806390b98a1114610076578063f8b2cb4f146100a6575b600080fd5b610060600480360381019061005b919061030a565b6100d6565b60405161006d9190610350565b60405180910390f35b610090600480360381019061008b9190610397565b6100f4565b60405161009d91906103f2565b60405180910390f35b6100c060048036038101906100bb919061030a565b61025f565b6040516100cd9190610350565b60405180910390f35b600060026100e38361025f565b6100ed919061043c565b9050919050565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156101455760009050610259565b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101939190610496565b92505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101e891906104ca565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161024c9190610350565b60405180910390a3600190505b92915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102d7826102ac565b9050919050565b6102e7816102cc565b81146102f257600080fd5b50565b600081359050610304816102de565b92915050565b6000602082840312156103205761031f6102a7565b5b600061032e848285016102f5565b91505092915050565b6000819050919050565b61034a81610337565b82525050565b60006020820190506103656000830184610341565b92915050565b61037481610337565b811461037f57600080fd5b50565b6000813590506103918161036b565b92915050565b600080604083850312156103ae576103ad6102a7565b5b60006103bc858286016102f5565b92505060206103cd85828601610382565b9150509250929050565b60008115159050919050565b6103ec816103d7565b82525050565b600060208201905061040760008301846103e3565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061044782610337565b915061045283610337565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561048b5761048a61040d565b5b828202905092915050565b60006104a182610337565b91506104ac83610337565b9250828210156104bf576104be61040d565b5b828203905092915050565b60006104d582610337565b91506104e083610337565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156105155761051461040d565b5b82820190509291505056fea26469706673582212208e5b4b874c839967f88008ed2fa42d6c2d9c9b0ae05d1d2c61faa7d229c134e664736f6c634300080d0033c080a0c4e9477f57c6848b2f1ea73a14809c1f44529d20763c947f3ac8ffd3d1629d93a011485a215457579bb13ac7b53bb9d6804763ae6fe5ce8ddd41642cea55c9a09a"), - mustDecodeHex("0xf9063082013a0185012a05f2008504a817c8008094025b594a4f1c4888cafcfaf2bb24ed95507749e0872386f26fc10000b905bb608060405234801561001057600080fd5b506127106000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610556806100656000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80637bd703e81461004657806390b98a1114610076578063f8b2cb4f146100a6575b600080fd5b610060600480360381019061005b919061030a565b6100d6565b60405161006d9190610350565b60405180910390f35b610090600480360381019061008b9190610397565b6100f4565b60405161009d91906103f2565b60405180910390f35b6100c060048036038101906100bb919061030a565b61025f565b6040516100cd9190610350565b60405180910390f35b600060026100e38361025f565b6100ed919061043c565b9050919050565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156101455760009050610259565b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101939190610496565b92505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101e891906104ca565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161024c9190610350565b60405180910390a3600190505b92915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102d7826102ac565b9050919050565b6102e7816102cc565b81146102f257600080fd5b50565b600081359050610304816102de565b92915050565b6000602082840312156103205761031f6102a7565b5b600061032e848285016102f5565b91505092915050565b6000819050919050565b61034a81610337565b82525050565b60006020820190506103656000830184610341565b92915050565b61037481610337565b811461037f57600080fd5b50565b6000813590506103918161036b565b92915050565b600080604083850312156103ae576103ad6102a7565b5b60006103bc858286016102f5565b92505060206103cd85828601610382565b9150509250929050565b60008115159050919050565b6103ec816103d7565b82525050565b600060208201905061040760008301846103e3565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061044782610337565b915061045283610337565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561048b5761048a61040d565b5b828202905092915050565b60006104a182610337565b91506104ac83610337565b9250828210156104bf576104be61040d565b5b828203905092915050565b60006104d582610337565b91506104e083610337565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156105155761051461040d565b5b82820190509291505056fea26469706673582212208e5b4b874c839967f88008ed2fa42d6c2d9c9b0ae05d1d2c61faa7d229c134e664736f6c634300080d0033c080a0fe38720928596f9e9dfbf891d00311638efce3713f03cdd67b212ecbbcf18f29a05993e656c0b35b8a580da6aff7c89b3d3e8b1c6f83a7ce09473c0699a8500b9c"), - } - - for _, tc := range testcases { - decoded, err := DecodeRLP(tc) - require.Nil(t, err) - - encoded, err := EncodeRLP(decoded) - require.Nil(t, err) - require.Equal(t, tc, encoded) - } -} - -func TestDecodeError(t *testing.T) { - testcases := [][]byte{ - mustDecodeHex("0xdc82013a0185012a05f2008504a817c8008080872386f26fc1000000"), - mustDecodeHex("0xdc013a01012a05f2008504a817c8008080872386f26fc1000000"), - mustDecodeHex("0xdc82013a0185012a05f28504a817c08080872386f26fc1000000"), - mustDecodeHex("0xdc82013a0185012a05f504a817c080872386ffc1000000"), - mustDecodeHex("0x013a018505f2008504a817c8008080872386f26fc1000000"), - } - - for _, tc := range testcases { - _, err := DecodeRLP(tc) - require.NotNil(t, err, hex.EncodeToString(tc)) - } -} - -func TestDecode1(t *testing.T) { - b := mustDecodeHex("0x02f8758401df5e7680832c8411832c8411830767f89452963ef50e27e06d72d59fcb4f3c2a687be3cfef880de0b6b3a764000080c080a094b11866f453ad85a980e0e8a2fc98cbaeb4409618c7734a7e12ae2f66fd405da042dbfb1b37af102023830ceeee0e703ffba0b8b3afeb8fe59f405eca9ed61072") - decoded, err := ParseEthTxArgs(b) - require.NoError(t, err) - - sender, err := decoded.Sender() - require.NoError(t, err) - - addr, err := address.NewFromString("f410fkkld55ioe7qg24wvt7fu6pbknb56ht7pt4zamxa") - require.NoError(t, err) - require.Equal(t, sender, addr) -} diff --git a/venus-shared/types/state_types_gen.go b/venus-shared/types/state_types_gen.go index dbf1f2679e..326ad2f826 100755 --- a/venus-shared/types/state_types_gen.go +++ b/venus-shared/types/state_types_gen.go @@ -252,7 +252,7 @@ type ( AllocationRequest = verifreg.AllocationRequest AllocationRequests = verifreg.AllocationRequests AllocationsResponse = verifreg.AllocationsResponse - BatchReturn = verifreg.BatchReturn + VerifregBatchReturn = verifreg.BatchReturn Claim = verifreg.Claim ClaimAllocationsParams = verifreg.ClaimAllocationsParams ClaimAllocationsReturn = verifreg.ClaimAllocationsReturn @@ -262,7 +262,7 @@ type ( DataCap = verifreg.DataCap ExtendClaimTermsParams = verifreg.ExtendClaimTermsParams ExtendClaimTermsReturn = verifreg.ExtendClaimTermsReturn - FailCode = verifreg.FailCode + VerifregFailCode = verifreg.FailCode GetClaimsParams = verifreg.GetClaimsParams GetClaimsReturn = verifreg.GetClaimsReturn ReceiverType = verifreg.ReceiverType diff --git a/venus-shared/utils/method_map.go b/venus-shared/utils/method_map.go index 38adf699e8..06196a4342 100644 --- a/venus-shared/utils/method_map.go +++ b/venus-shared/utils/method_map.go @@ -61,6 +61,7 @@ func loadMethodsMap() { actors = append(actors, actorsWithVersion{av: actorstypes.Version11, actors: builtin.MakeRegistry(actorstypes.Version11)}) actors = append(actors, actorsWithVersion{av: actorstypes.Version12, actors: builtin.MakeRegistry(actorstypes.Version12)}) actors = append(actors, actorsWithVersion{av: actorstypes.Version13, actors: builtin.MakeRegistry(actorstypes.Version13)}) + actors = append(actors, actorsWithVersion{av: actorstypes.Version14, actors: builtin.MakeRegistry(actorstypes.Version14)}) for _, awv := range actors { for _, actor := range awv.actors {