From 014c3e9691015a6ddf809739df9513e7e2887ff0 Mon Sep 17 00:00:00 2001 From: simlecode <69969590+simlecode@users.noreply.github.com> Date: Tue, 7 Feb 2023 10:30:39 +0800 Subject: [PATCH 1/3] refactor: rename ResolveToKeyAddress to ResolveToDeterministicAddress --- app/submodule/chain/account_api.go | 2 +- app/submodule/chain/chaininfo_api.go | 2 +- app/submodule/mining/mining_api.go | 2 +- app/submodule/wallet/wallet_api.go | 2 +- pkg/chain/store.go | 6 +++--- pkg/consensus/block_validator.go | 2 +- pkg/consensusfault/check.go | 2 +- pkg/fvm/fvm.go | 2 +- pkg/messagepool/gas.go | 4 ++-- pkg/messagepool/provider.go | 4 ++-- pkg/paychmgr/mock_test.go | 2 +- pkg/paychmgr/paych.go | 2 +- pkg/paychmgr/state.go | 4 ++-- pkg/state/power_table_view.go | 4 ++-- pkg/state/signer.go | 12 ++++++------ pkg/state/signer_test.go | 2 +- pkg/state/sigval.go | 4 ++-- pkg/state/testing.go | 2 +- pkg/state/view.go | 10 +++++----- pkg/state/view_test.go | 2 +- pkg/statemanger/call.go | 2 +- pkg/statemanger/state_manger.go | 6 +++--- pkg/vm/vm.go | 2 +- pkg/vm/vmcontext/invocation_context.go | 6 +++--- pkg/vm/vmcontext/syscalls.go | 2 +- pkg/vm/vmcontext/syscallsStateView.go | 6 +++--- pkg/vm/vmcontext/types.go | 2 +- 27 files changed, 49 insertions(+), 49 deletions(-) diff --git a/app/submodule/chain/account_api.go b/app/submodule/chain/account_api.go index 0b9f1408d7..a4e8a4ced6 100644 --- a/app/submodule/chain/account_api.go +++ b/app/submodule/chain/account_api.go @@ -27,5 +27,5 @@ func (accountAPI *accountAPI) StateAccountKey(ctx context.Context, addr address. if err != nil { return address.Undef, fmt.Errorf("loading tipset %s: %w", tsk, err) } - return accountAPI.chain.Stmgr.ResolveToKeyAddress(ctx, addr, ts) + return accountAPI.chain.Stmgr.ResolveToDeterministicAddress(ctx, addr, ts) } diff --git a/app/submodule/chain/chaininfo_api.go b/app/submodule/chain/chaininfo_api.go index 01a02a8d11..c09a1a7749 100644 --- a/app/submodule/chain/chaininfo_api.go +++ b/app/submodule/chain/chaininfo_api.go @@ -319,7 +319,7 @@ func (cia *chainInfoAPI) ResolveToKeyAddr(ctx context.Context, addr address.Addr if ts == nil { ts = cia.chain.ChainReader.GetHead() } - return cia.chain.Stmgr.ResolveToKeyAddress(ctx, addr, ts) + return cia.chain.Stmgr.ResolveToDeterministicAddress(ctx, addr, ts) } // ************Drand****************// diff --git a/app/submodule/mining/mining_api.go b/app/submodule/mining/mining_api.go index 1e85505829..8d753feb1f 100644 --- a/app/submodule/mining/mining_api.go +++ b/app/submodule/mining/mining_api.go @@ -123,7 +123,7 @@ func (miningAPI *MiningAPI) MinerGetBaseInfo(ctx context.Context, maddr address. if err != nil { return nil, fmt.Errorf("failed to load latest state: %v", err) } - worker, err := st.ResolveToKeyAddr(ctx, info.Worker) + worker, err := st.ResolveToDeterministicAddress(ctx, info.Worker) if err != nil { return nil, fmt.Errorf("resolving worker address: %v", err) } diff --git a/app/submodule/wallet/wallet_api.go b/app/submodule/wallet/wallet_api.go index 6567344166..79cac43f25 100644 --- a/app/submodule/wallet/wallet_api.go +++ b/app/submodule/wallet/wallet_api.go @@ -114,7 +114,7 @@ func (walletAPI *WalletAPI) WalletDelete(ctx context.Context, addr address.Addre // WalletSign signs the given bytes using the given address. func (walletAPI *WalletAPI) WalletSign(ctx context.Context, k address.Address, msg []byte, meta types.MsgMeta) (*crypto.Signature, error) { - keyAddr, err := walletAPI.walletModule.Chain.Stmgr.ResolveToKeyAddress(ctx, k, nil) + keyAddr, err := walletAPI.walletModule.Chain.Stmgr.ResolveToDeterministicAddress(ctx, k, nil) if err != nil { return nil, fmt.Errorf("ResolveTokeyAddress failed:%v", err) } diff --git a/pkg/chain/store.go b/pkg/chain/store.go index 4e877c7a26..0a326629ea 100644 --- a/pkg/chain/store.go +++ b/pkg/chain/store.go @@ -1374,15 +1374,15 @@ func (store *Store) LookupID(ctx context.Context, ts *types.TipSet, addr address return st.LookupID(addr) } -// ResolveToKeyAddr get key address of specify address. +// ResolveToDeterministicAddress get key address of specify address. // if ths addr is bls/secpk address, return directly, other get the pubkey and generate address -func (store *Store) ResolveToKeyAddr(ctx context.Context, ts *types.TipSet, addr address.Address) (address.Address, error) { +func (store *Store) ResolveToDeterministicAddress(ctx context.Context, ts *types.TipSet, addr address.Address) (address.Address, error) { st, err := store.StateView(ctx, ts) if err != nil { return address.Undef, errors.Wrap(err, "failed to load latest state") } - return st.ResolveToKeyAddr(ctx, addr) + return st.ResolveToDeterministicAddress(ctx, addr) } // StateView return state view at ts epoch diff --git a/pkg/consensus/block_validator.go b/pkg/consensus/block_validator.go index 8b3643a64f..e32c9f9277 100644 --- a/pkg/consensus/block_validator.go +++ b/pkg/consensus/block_validator.go @@ -801,7 +801,7 @@ func (bv *BlockValidator) checkBlockMessages(ctx context.Context, // Verify that all secp message signatures are correct for i, msg := range blksecpMsgs { - signer, err := stateView.ResolveToKeyAddr(ctx, msg.Message.From) + signer, err := stateView.ResolveToDeterministicAddress(ctx, msg.Message.From) if err != nil { return errors.Wrapf(err, "failed to load signer address for %v", signer) } diff --git a/pkg/consensusfault/check.go b/pkg/consensusfault/check.go index 674cf5d105..12829312a0 100644 --- a/pkg/consensusfault/check.go +++ b/pkg/consensusfault/check.go @@ -24,7 +24,7 @@ import ( ) type FaultStateView interface { - ResolveToKeyAddr(ctx context.Context, address address.Address) (address.Address, error) + ResolveToDeterministicAddress(ctx context.Context, address address.Address) (address.Address, error) MinerInfo(ctx context.Context, maddr address.Address, nv network.Version) (*miner.MinerInfo, error) } diff --git a/pkg/fvm/fvm.go b/pkg/fvm/fvm.go index 93038b8552..36b755f494 100644 --- a/pkg/fvm/fvm.go +++ b/pkg/fvm/fvm.go @@ -292,7 +292,7 @@ func (x *FvmExtern) workerKeyAtLookback(ctx context.Context, minerID address.Add if err != nil { return address.Undef, 0, err } - raddr, err := vm.ResolveToKeyAddr(ctx, st, info.Worker, cstWithGas) + raddr, err := vm.ResolveToDeterministicAddress(ctx, st, info.Worker, cstWithGas) if err != nil { return address.Undef, 0, err } diff --git a/pkg/messagepool/gas.go b/pkg/messagepool/gas.go index 68f2f3641a..ca3349da24 100644 --- a/pkg/messagepool/gas.go +++ b/pkg/messagepool/gas.go @@ -202,7 +202,7 @@ func (mp *MessagePool) GasEstimateGasLimit(ctx context.Context, msgIn *types.Mes msg.GasFeeCap = big.NewInt(int64(constants.MinimumBaseFee) + 1) msg.GasPremium = big.NewInt(1) - fromA, err := mp.sm.ResolveToKeyAddress(ctx, msgIn.From, currTS) + fromA, err := mp.sm.ResolveToDeterministicAddress(ctx, msgIn.From, currTS) if err != nil { return -1, fmt.Errorf("getting key address: %w", err) } @@ -364,7 +364,7 @@ func (mp *MessagePool) GasBatchEstimateMessageGas(ctx context.Context, estimateM return nil, fmt.Errorf("getting tipset: %w", err) } - fromA, err := mp.sm.ResolveToKeyAddress(ctx, estimateMessages[0].Msg.From, currTS) + fromA, err := mp.sm.ResolveToDeterministicAddress(ctx, estimateMessages[0].Msg.From, currTS) if err != nil { return nil, fmt.Errorf("getting key address: %w", err) } diff --git a/pkg/messagepool/provider.go b/pkg/messagepool/provider.go index 514609f6aa..9519696984 100644 --- a/pkg/messagepool/provider.go +++ b/pkg/messagepool/provider.go @@ -134,7 +134,7 @@ func (mpp *mpoolProvider) StateAccountKeyAtFinality(ctx context.Context, addr ad return address.Undef, fmt.Errorf("failed to load lookback tipset: %w", err) } } - return mpp.stmgr.ResolveToKeyAddress(ctx, addr, ts) + return mpp.stmgr.ResolveToDeterministicAddress(ctx, addr, ts) } func (mpp *mpoolProvider) StateNetworkVersion(ctx context.Context, height abi.ChainEpoch) network.Version { @@ -142,7 +142,7 @@ func (mpp *mpoolProvider) StateNetworkVersion(ctx context.Context, height abi.Ch } func (mpp *mpoolProvider) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { - return mpp.stmgr.ResolveToKeyAddress(ctx, addr, ts) + return mpp.stmgr.ResolveToDeterministicAddress(ctx, addr, ts) } func (mpp *mpoolProvider) MessagesForBlock(ctx context.Context, h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) { diff --git a/pkg/paychmgr/mock_test.go b/pkg/paychmgr/mock_test.go index 3530645316..3a923cf298 100644 --- a/pkg/paychmgr/mock_test.go +++ b/pkg/paychmgr/mock_test.go @@ -69,7 +69,7 @@ func (sm *mockStateManager) setPaychState(a address.Address, actor *types.Actor, sm.paychState[a] = mockPchState{actor, state} } -func (sm *mockStateManager) ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { +func (sm *mockStateManager) ResolveToDeterministicAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { sm.lk.Lock() defer sm.lk.Unlock() keyAddr, ok := sm.accountState[addr] diff --git a/pkg/paychmgr/paych.go b/pkg/paychmgr/paych.go index e0aae820d5..7540408093 100644 --- a/pkg/paychmgr/paych.go +++ b/pkg/paychmgr/paych.go @@ -209,7 +209,7 @@ func (ca *channelAccessor) checkVoucherValidUnlocked(ctx context.Context, ch add return nil, err } - from, err := ca.api.ResolveToKeyAddress(ctx, f, nil) + from, err := ca.api.ResolveToDeterministicAddress(ctx, f, nil) if err != nil { return nil, err } diff --git a/pkg/paychmgr/state.go b/pkg/paychmgr/state.go index ba78b880fc..c079cccc4e 100644 --- a/pkg/paychmgr/state.go +++ b/pkg/paychmgr/state.go @@ -30,7 +30,7 @@ func (ca *stateAccessor) loadStateChannelInfo(ctx context.Context, ch address.Ad if err != nil { return nil, err } - from, err := ca.sm.ResolveToKeyAddress(ctx, f, nil) + from, err := ca.sm.ResolveToDeterministicAddress(ctx, f, nil) if err != nil { return nil, err } @@ -38,7 +38,7 @@ func (ca *stateAccessor) loadStateChannelInfo(ctx context.Context, ch address.Ad if err != nil { return nil, err } - to, err := ca.sm.ResolveToKeyAddress(ctx, t, nil) + to, err := ca.sm.ResolveToDeterministicAddress(ctx, t, nil) if err != nil { return nil, err } diff --git a/pkg/state/power_table_view.go b/pkg/state/power_table_view.go index 07d73892db..7eed210e80 100644 --- a/pkg/state/power_table_view.go +++ b/pkg/state/power_table_view.go @@ -16,7 +16,7 @@ import ( // immediate parent state. // This type isn't doing much that the state view doesn't already do, consider removing it. type PowerStateView interface { - ResolveToKeyAddr(ctx context.Context, maddr address.Address) (address.Address, error) + ResolveToDeterministicAddress(ctx context.Context, maddr address.Address) (address.Address, error) GetMinerWorkerRaw(ctx context.Context, maddr address.Address) (address.Address, error) MinerInfo(ctx context.Context, maddr address.Address, nv network.Version) (*miner.MinerInfo, error) MinerSectorInfo(ctx context.Context, maddr address.Address, sectorNum abi.SectorNumber) (*miner.SectorOnChainInfo, error) @@ -86,5 +86,5 @@ func (v PowerTableView) WorkerAddr(ctx context.Context, mAddr address.Address, n // SignerAddress returns the public key address associated with the given address. func (v PowerTableView) SignerAddress(ctx context.Context, addr address.Address) (address.Address, error) { - return v.state.ResolveToKeyAddr(ctx, addr) + return v.state.ResolveToDeterministicAddress(ctx, addr) } diff --git a/pkg/state/signer.go b/pkg/state/signer.go index 0dd1c32106..4c673b94df 100644 --- a/pkg/state/signer.go +++ b/pkg/state/signer.go @@ -11,12 +11,12 @@ import ( // todo remove Account view a nd headsignerview type AccountView interface { - ResolveToKeyAddr(ctx context.Context, address address.Address) (address.Address, error) + ResolveToDeterministicAddress(ctx context.Context, address address.Address) (address.Address, error) } type tipSignerView interface { GetHead() *types.TipSet - ResolveToKeyAddr(ctx context.Context, ts *types.TipSet, address address.Address) (address.Address, error) + ResolveToDeterministicAddress(ctx context.Context, ts *types.TipSet, address address.Address) (address.Address, error) } // Signer looks up non-signing addresses before signing @@ -35,7 +35,7 @@ func NewSigner(signerView AccountView, wallet *wallet.Wallet) *Signer { // SignBytes creates a signature for the given data using either the given addr or its associated signing address func (s *Signer) SignBytes(ctx context.Context, data []byte, addr address.Address) (*crypto.Signature, error) { - signingAddr, err := s.signerView.ResolveToKeyAddr(ctx, addr) + signingAddr, err := s.signerView.ResolveToDeterministicAddress(ctx, addr) if err != nil { return nil, err } @@ -44,7 +44,7 @@ func (s *Signer) SignBytes(ctx context.Context, data []byte, addr address.Addres // HasAddress returns whether this signer can sign with the given address func (s *Signer) HasAddress(ctx context.Context, addr address.Address) (bool, error) { - signingAddr, err := s.signerView.ResolveToKeyAddr(ctx, addr) + signingAddr, err := s.signerView.ResolveToDeterministicAddress(ctx, addr) if err != nil { return false, err } @@ -59,7 +59,7 @@ func NewHeadSignView(tipSignerView tipSignerView) *HeadSignView { return &HeadSignView{tipSignerView: tipSignerView} } -func (headSignView *HeadSignView) ResolveToKeyAddr(ctx context.Context, addr address.Address) (address.Address, error) { +func (headSignView *HeadSignView) ResolveToDeterministicAddress(ctx context.Context, addr address.Address) (address.Address, error) { head := headSignView.GetHead() - return headSignView.tipSignerView.ResolveToKeyAddr(ctx, head, addr) // nil will use latest + return headSignView.tipSignerView.ResolveToDeterministicAddress(ctx, head, addr) // nil will use latest } diff --git a/pkg/state/signer_test.go b/pkg/state/signer_test.go index 57f3bda0fb..c543a14467 100644 --- a/pkg/state/signer_test.go +++ b/pkg/state/signer_test.go @@ -15,7 +15,7 @@ import ( type mockAccountView struct { } -func (mac *mockAccountView) ResolveToKeyAddr(_ context.Context, addr address.Address) (address.Address, error) { +func (mac *mockAccountView) ResolveToDeterministicAddress(_ context.Context, addr address.Address) (address.Address, error) { return addr, nil } diff --git a/pkg/state/sigval.go b/pkg/state/sigval.go index 5ea67f6d6c..0076a333eb 100644 --- a/pkg/state/sigval.go +++ b/pkg/state/sigval.go @@ -21,7 +21,7 @@ func NewSignatureValidator(signerView AccountView) *SignatureValidator { // ValidateSignature check the signature is valid or not func (v *SignatureValidator) ValidateSignature(ctx context.Context, data []byte, signer address.Address, sig crypto.Signature) error { - signerAddress, err := v.signerView.ResolveToKeyAddr(ctx, signer) + signerAddress, err := v.signerView.ResolveToDeterministicAddress(ctx, signer) if err != nil { return errors.Wrapf(err, "failed to load signer address for %v", signer) } @@ -44,7 +44,7 @@ func (v *SignatureValidator) ValidateBLSMessageAggregate(ctx context.Context, ms var pubKeys [][]byte var encodedMsgCids [][]byte for _, msg := range msgs { - signerAddress, err := v.signerView.ResolveToKeyAddr(ctx, msg.From) + signerAddress, err := v.signerView.ResolveToDeterministicAddress(ctx, msg.From) if err != nil { return errors.Wrapf(err, "failed to load signer address for %v", msg.From) } diff --git a/pkg/state/testing.go b/pkg/state/testing.go index 5eabe427f2..8459791c7a 100644 --- a/pkg/state/testing.go +++ b/pkg/state/testing.go @@ -146,6 +146,6 @@ func (v *FakeStateView) GetMinerWorkerRaw(ctx context.Context, maddr address.Add return m.Worker, nil } -func (v *FakeStateView) ResolveToKeyAddr(ctx context.Context, addr address.Address) (address.Address, error) { +func (v *FakeStateView) ResolveToDeterministicAddress(ctx context.Context, addr address.Address) (address.Address, error) { return addr, nil } diff --git a/pkg/state/view.go b/pkg/state/view.go index cb5e0628d9..fcfaf864e5 100644 --- a/pkg/state/view.go +++ b/pkg/state/view.go @@ -97,7 +97,7 @@ func (v *View) InitResolveAddress(ctx context.Context, a addr.Address) (addr.Add return rAddr, nil } -// ResolveToKeyAddr returns the public key type of address (`BLS`/`SECP256K1`) of an account actor identified by `addr`. +// GetMinerWorkerRaw returns the public key type of address (`BLS`/`SECP256K1`) of an account actor identified by `addr`. func (v *View) GetMinerWorkerRaw(ctx context.Context, maddr addr.Address) (addr.Address, error) { minerState, err := v.LoadMinerState(ctx, maddr) if err != nil { @@ -108,7 +108,7 @@ func (v *View) GetMinerWorkerRaw(ctx context.Context, maddr addr.Address) (addr. if err != nil { return addr.Undef, err } - return v.ResolveToKeyAddr(ctx, minerInfo.Worker) + return v.ResolveToDeterministicAddress(ctx, minerInfo.Worker) } // MinerInfo returns info about the indicated miner @@ -694,10 +694,10 @@ func (v *View) LoadActor(ctx context.Context, address addr.Address) (*types.Acto return v.loadActor(ctx, address) } -// ResolveToKeyAddress is similar to `vm.ResolveToKeyAddr` but does not allow `Actor` type of addresses. +// ResolveToDeterministicAddress is similar to `vm.ResolveToDeterministicAddress` but does not allow `Actor` type of addresses. // Uses the `TipSet` `ts` to generate the VM state. -// todo: use pkg/vm/vm.go.ResolveToKeyAddr, avoid repetitive implementations -func (v *View) ResolveToKeyAddr(ctx context.Context, address addr.Address) (addr.Address, error) { +// todo: use pkg/vm/vm.go.ResolveToDeterministicAddress, avoid repetitive implementations +func (v *View) ResolveToDeterministicAddress(ctx context.Context, address addr.Address) (addr.Address, error) { if address.Protocol() == addr.BLS || address.Protocol() == addr.SECP256K1 || address.Protocol() == addr.Delegated { return address, nil } diff --git a/pkg/state/view_test.go b/pkg/state/view_test.go index 4eaef6e101..dc520cee6c 100644 --- a/pkg/state/view_test.go +++ b/pkg/state/view_test.go @@ -54,7 +54,7 @@ func TestView(t *testing.T) { minerInfo, err := view.MinerInfo(ctx, m, network.Version17) assert.NoError(t, err) - ownerPkAddress, err := view.ResolveToKeyAddr(ctx, minerInfo.Owner) + ownerPkAddress, err := view.ResolveToDeterministicAddress(ctx, minerInfo.Owner) assert.NoError(t, err) _, find := keyMap[ownerPkAddress] assert.True(t, find) diff --git a/pkg/statemanger/call.go b/pkg/statemanger/call.go index f1e9f6b952..cecdbc1595 100644 --- a/pkg/statemanger/call.go +++ b/pkg/statemanger/call.go @@ -139,7 +139,7 @@ func (s *Stmgr) CallWithGas(ctx context.Context, msg *types.Message, priorMsgs [ } msg.Nonce = fromActor.Nonce - fromKey, err := view.ResolveToKeyAddr(ctx, msg.VMMessage().From) + fromKey, err := view.ResolveToDeterministicAddress(ctx, msg.VMMessage().From) if err != nil { return nil, fmt.Errorf("could not resolve key: %v", err) } diff --git a/pkg/statemanger/state_manger.go b/pkg/statemanger/state_manger.go index 1fb771c415..3d1f1cfbd4 100644 --- a/pkg/statemanger/state_manger.go +++ b/pkg/statemanger/state_manger.go @@ -29,7 +29,7 @@ import ( // stateManagerAPI defines the methods needed from StateManager // todo remove this code and add private interface in market and paychanel package type IStateManager interface { - ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) + ResolveToDeterministicAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) GetPaychState(ctx context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, paych.State, error) Call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*vm.Ret, error) GetMarketState(ctx context.Context, ts *types.TipSet) (market.State, error) @@ -88,7 +88,7 @@ func NewStateManger(cs *chain.Store, } } -func (s *Stmgr) ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { +func (s *Stmgr) ResolveToDeterministicAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { switch addr.Protocol() { case address.BLS, address.SECP256K1, address.Delegated: return addr, nil @@ -101,7 +101,7 @@ func (s *Stmgr) ResolveToKeyAddress(ctx context.Context, addr address.Address, t if err != nil { return address.Undef, err } - return view.ResolveToKeyAddr(ctx, addr) + return view.ResolveToDeterministicAddress(ctx, addr) } func (s *Stmgr) GetPaychState(ctx context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, paych.State, error) { diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index f31459f848..87962daf22 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -60,4 +60,4 @@ type ( TipSetGetter = vmcontext.TipSetGetter ) -var ResolveToKeyAddr = vmcontext.ResolveToKeyAddr +var ResolveToDeterministicAddress = vmcontext.ResolveToDeterministicAddress diff --git a/pkg/vm/vmcontext/invocation_context.go b/pkg/vm/vmcontext/invocation_context.go index 9d6d12f4bc..737cc7f990 100644 --- a/pkg/vm/vmcontext/invocation_context.go +++ b/pkg/vm/vmcontext/invocation_context.go @@ -383,8 +383,8 @@ func (ctx *invocationContext) resolveTarget(target address.Address) (*types.Acto } } -func (ctx *invocationContext) resolveToKeyAddr(addr address.Address) (address.Address, error) { - return ResolveToKeyAddr(ctx.vm.context, ctx.vm.State, addr, ctx.vm.store) +func (ctx *invocationContext) resolveToDeterministicAddress(addr address.Address) (address.Address, error) { + return ResolveToDeterministicAddress(ctx.vm.context, ctx.vm.State, addr, ctx.vm.store) } // implement runtime.InvocationContext for invocationContext @@ -473,7 +473,7 @@ var _ runtime.ExtendedInvocationContext = (*invocationContext)(nil) // Code is adapted from vm.Runtime#NewActorAddress() func (ctx *invocationContext) NewActorAddress() address.Address { buf := new(bytes.Buffer) - origin, err := ctx.resolveToKeyAddr(ctx.topLevel.originatorStableAddress) + origin, err := ctx.resolveToDeterministicAddress(ctx.topLevel.originatorStableAddress) if err != nil { panic(err) } diff --git a/pkg/vm/vmcontext/syscalls.go b/pkg/vm/vmcontext/syscalls.go index 4e1831fd2d..95cbc1250f 100644 --- a/pkg/vm/vmcontext/syscalls.go +++ b/pkg/vm/vmcontext/syscalls.go @@ -28,7 +28,7 @@ import ( ) type SyscallsStateView interface { - ResolveToKeyAddr(ctx context.Context, address address.Address) (address.Address, error) + ResolveToDeterministicAddress(ctx context.Context, address address.Address) (address.Address, error) MinerInfo(ctx context.Context, maddr address.Address, nv network.Version) (*miner.MinerInfo, error) TotalFilCircSupply(height abi.ChainEpoch, st vmState.Tree) (abi.TokenAmount, error) GetNetworkVersion(ctx context.Context, ce abi.ChainEpoch) network.Version diff --git a/pkg/vm/vmcontext/syscallsStateView.go b/pkg/vm/vmcontext/syscallsStateView.go index 3624e2afd1..985076ce13 100644 --- a/pkg/vm/vmcontext/syscallsStateView.go +++ b/pkg/vm/vmcontext/syscallsStateView.go @@ -23,9 +23,9 @@ func newSyscallsStateView(ctx *invocationContext, VM *LegacyVM) *syscallsStateVi return &syscallsStateView{ctx: ctx, LegacyVM: VM} } -// ResolveToKeyAddr returns the public key type of address (`BLS`/`SECP256K1`) of an account actor identified by `addr`. -func (vm *syscallsStateView) ResolveToKeyAddr(ctx context.Context, accountAddr address.Address) (address.Address, error) { - return ResolveToKeyAddr(ctx, vm.State, accountAddr, vm.ctx.gasIpld) +// ResolveToDeterministicAddress returns the public key type of address (`BLS`/`SECP256K1`) of an account actor identified by `addr`. +func (vm *syscallsStateView) ResolveToDeterministicAddress(ctx context.Context, accountAddr address.Address) (address.Address, error) { + return ResolveToDeterministicAddress(ctx, vm.State, accountAddr, vm.ctx.gasIpld) } // MinerInfo get miner info diff --git a/pkg/vm/vmcontext/types.go b/pkg/vm/vmcontext/types.go index 3909e39c70..649a0a7733 100644 --- a/pkg/vm/vmcontext/types.go +++ b/pkg/vm/vmcontext/types.go @@ -113,7 +113,7 @@ type Interface interface { Flush(ctx context.Context) (cid.Cid, error) } -func ResolveToKeyAddr(ctx context.Context, state tree.Tree, addr address.Address, cst cbor.IpldStore) (address.Address, error) { +func ResolveToDeterministicAddress(ctx context.Context, state tree.Tree, addr address.Address, cst cbor.IpldStore) (address.Address, error) { if addr.Protocol() == address.BLS || addr.Protocol() == address.SECP256K1 || addr.Protocol() == address.Delegated { return addr, nil } From 3df8e09a7c601b40fe69935db3b6d0e65abb1a11 Mon Sep 17 00:00:00 2001 From: simlecode <69969590+simlecode@users.noreply.github.com> Date: Tue, 7 Feb 2023 10:48:24 +0800 Subject: [PATCH 2/3] feat: compute a better gas limit for recursive external contract calls --- app/submodule/eth/eth_api.go | 133 ++++++++++++++++++++++++++++++++++- pkg/messagepool/gas.go | 50 +++++++++++++ 2 files changed, 181 insertions(+), 2 deletions(-) diff --git a/app/submodule/eth/eth_api.go b/app/submodule/eth/eth_api.go index 30eb2c1ceb..15e758105f 100644 --- a/app/submodule/eth/eth_api.go +++ b/app/submodule/eth/eth_api.go @@ -15,6 +15,7 @@ import ( builtintypes "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/builtin/v10/eam" "github.com/filecoin-project/go-state-types/builtin/v10/evm" + "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/venus/pkg/chain" "github.com/filecoin-project/venus/pkg/constants" @@ -22,6 +23,8 @@ import ( "github.com/filecoin-project/venus/pkg/ethhashlookup" "github.com/filecoin-project/venus/pkg/events" "github.com/filecoin-project/venus/pkg/fork" + "github.com/filecoin-project/venus/pkg/messagepool" + "github.com/filecoin-project/venus/pkg/statemanger" "github.com/filecoin-project/venus/pkg/vm" "github.com/filecoin-project/venus/pkg/vm/vmcontext" "github.com/filecoin-project/venus/venus-shared/actors" @@ -751,12 +754,138 @@ func (a *ethAPI) EthEstimateGas(ctx context.Context, tx types.EthCall) (types.Et // gas estimation actually run. msg.GasLimit = 0 - msg, err = a.mpool.GasEstimateMessageGas(ctx, msg, nil, types.EmptyTSK) + ts, err := a.chain.ChainHead(ctx) if err != nil { return types.EthUint64(0), err } + msg, err = a.mpool.GasEstimateMessageGas(ctx, msg, nil, ts.Key()) + if err != nil { + return types.EthUint64(0), fmt.Errorf("failed to estimate gas: %w", err) + } + + expectedGas, err := ethGasSearch(ctx, a.em.chainModule.Stmgr, a.em.mpoolModule.MPool, msg, ts) + if err != nil { + log.Errorw("expected gas", "err", err) + } + + return types.EthUint64(expectedGas), nil +} + +// gasSearch does an exponential search to find a gas value to execute the +// message with. It first finds a high gas limit that allows the message to execute +// by doubling the previous gas limit until it succeeds then does a binary +// search till it gets within a range of 1% +func gasSearch( + ctx context.Context, + smgr *statemanger.Stmgr, + msgIn *types.Message, + priorMsgs []types.ChainMsg, + ts *types.TipSet, +) (int64, error) { + msg := *msgIn + + high := msg.GasLimit + low := msg.GasLimit + + canSucceed := func(limit int64) (bool, error) { + msg.GasLimit = limit + + res, err := smgr.CallWithGas(ctx, &msg, priorMsgs, ts) + if err != nil { + return false, fmt.Errorf("CallWithGas failed: %w", err) + } + + if res.Receipt.ExitCode.IsSuccess() { + return true, nil + } + + return false, nil + } + + for { + ok, err := canSucceed(high) + if err != nil { + return -1, fmt.Errorf("searching for high gas limit failed: %w", err) + } + if ok { + break + } + + low = high + high = high * 2 + + if high > constants.BlockGasLimit { + high = constants.BlockGasLimit + break + } + } + + checkThreshold := high / 100 + for (high - low) > checkThreshold { + median := (low + high) / 2 + ok, err := canSucceed(median) + if err != nil { + return -1, fmt.Errorf("searching for optimal gas limit failed: %w", err) + } + + if ok { + high = median + } else { + low = median + } + + checkThreshold = median / 100 + } + + return high, nil +} + +func traceContainsExitCode(et types.ExecutionTrace, ex exitcode.ExitCode) bool { + if et.MsgRct.ExitCode == ex { + return true + } + + for _, et := range et.Subcalls { + if traceContainsExitCode(et, ex) { + return true + } + } + + return false +} + +// ethGasSearch executes a message for gas estimation using the previously estimated gas. +// If the message fails due to an out of gas error then a gas search is performed. +// See gasSearch. +func ethGasSearch( + ctx context.Context, + stmgr *statemanger.Stmgr, + mpool *messagepool.MessagePool, + msgIn *types.Message, + ts *types.TipSet, +) (int64, error) { + msg := *msgIn + currTS := ts + + res, priorMsgs, ts, err := mpool.GasEstimateCallWithGas(ctx, &msg, currTS) + if err != nil { + return -1, fmt.Errorf("gas estimation failed: %w", err) + } + + if res.MsgRct.ExitCode.IsSuccess() { + return msg.GasLimit, nil + } + if traceContainsExitCode(res.ExecutionTrace, exitcode.SysErrOutOfGas) { + ret, err := gasSearch(ctx, stmgr, &msg, priorMsgs, ts) + if err != nil { + return -1, fmt.Errorf("gas estimation search failed: %w", err) + } + + ret = int64(float64(ret) * mpool.GetConfig().GasLimitOverestimation) + return ret, nil + } - return types.EthUint64(msg.GasLimit), nil + return -1, fmt.Errorf("message execution failed: exit %s, reason: %s", res.MsgRct.ExitCode, res.Error) } func (a *ethAPI) EthCall(ctx context.Context, tx types.EthCall, blkParam string) (types.EthBytes, error) { diff --git a/pkg/messagepool/gas.go b/pkg/messagepool/gas.go index ca3349da24..066f12b31b 100644 --- a/pkg/messagepool/gas.go +++ b/pkg/messagepool/gas.go @@ -19,6 +19,7 @@ import ( "github.com/filecoin-project/venus/pkg/constants" "github.com/filecoin-project/venus/pkg/fork" "github.com/filecoin-project/venus/pkg/vm" + "github.com/filecoin-project/venus/pkg/vm/vmcontext" "github.com/filecoin-project/venus/venus-shared/actors/builtin" "github.com/filecoin-project/venus/venus-shared/types" ) @@ -219,6 +220,55 @@ func (mp *MessagePool) GasEstimateGasLimit(ctx context.Context, msgIn *types.Mes return mp.evalMessageGasLimit(ctx, msgIn, priorMsgs, ts) } +// GasEstimateCallWithGas invokes a message "msgIn" on the earliest available tipset with pending +// messages in the message pool. The function returns the result of the message invocation, the +// pending messages, the tipset used for the invocation, and an error if occurred. +// The returned information can be used to make subsequent calls to CallWithGas with the same parameters. +func (mp *MessagePool) GasEstimateCallWithGas( + ctx context.Context, + msgIn *types.Message, + currTS *types.TipSet, +) (*types.InvocResult, []types.ChainMsg, *types.TipSet, error) { + msg := *msgIn + fromA, err := mp.sm.ResolveToDeterministicAddress(ctx, msgIn.From, currTS) + if err != nil { + return nil, []types.ChainMsg{}, nil, fmt.Errorf("getting key address: %w", err) + } + + pending, ts := mp.PendingFor(ctx, fromA) + priorMsgs := make([]types.ChainMsg, 0, len(pending)) + for _, m := range pending { + if m.Message.Nonce == msg.Nonce { + break + } + priorMsgs = append(priorMsgs, m) + } + + // Try calling until we find a height with no migration. + var res *vmcontext.Ret + for { + res, err = mp.sm.CallWithGas(ctx, &msg, priorMsgs, ts) + if err != fork.ErrExpensiveFork { + break + } + ts, err = mp.api.ChainTipSet(ctx, ts.Parents()) + if err != nil { + return nil, []types.ChainMsg{}, nil, fmt.Errorf("getting parent tipset: %w", err) + } + } + if err != nil { + return nil, []types.ChainMsg{}, nil, fmt.Errorf("CallWithGas failed: %w", err) + } + + return &types.InvocResult{ + MsgCid: msg.Cid(), + Msg: &msg, + MsgRct: &res.Receipt, + ExecutionTrace: res.GasTracker.ExecutionTrace, + Duration: res.Duration, + }, priorMsgs, ts, nil +} + func (mp *MessagePool) evalMessageGasLimit(ctx context.Context, msgIn *types.Message, priorMsgs []types.ChainMsg, ts *types.TipSet) (int64, error) { msg := *msgIn msg.GasLimit = constants.BlockGasLimit From 3186d16d9992e9662d376c149adc217a33dd7f2d Mon Sep 17 00:00:00 2001 From: simlecode <69969590+simlecode@users.noreply.github.com> Date: Tue, 7 Feb 2023 13:53:02 +0800 Subject: [PATCH 3/3] chore: fix test --- pkg/migration/migrate_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/migration/migrate_test.go b/pkg/migration/migrate_test.go index 2f471f9864..8debc36bb0 100644 --- a/pkg/migration/migrate_test.go +++ b/pkg/migration/migrate_test.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "testing" + "time" "github.com/filecoin-project/venus/fixtures/networks" "github.com/filecoin-project/venus/pkg/config" @@ -30,9 +31,8 @@ func TestMigration(t *testing.T) { for nt, paramsCfg := range cfgs { cfg := config.NewDefaultConfig() cfg.NetworkParams.NetworkType = nt - repoPath := t.TempDir() - assert.Nil(t, os.RemoveAll(repoPath)) - t.Log(repoPath) + repoPath := filepath.Join(os.TempDir(), fmt.Sprintf("TestMigration%d", time.Now().UnixNano())) + assert.Nil(t, repo.InitFSRepo(repoPath, 0, cfg)) assert.Nil(t, TryToMigrate(repoPath)) @@ -41,6 +41,7 @@ func TestMigration(t *testing.T) { newCfg := fsRepo.Config() assert.Equal(t, paramsCfg.NetworkType, newCfg.NetworkParams.NetworkType) assert.EqualValuesf(t, config.NewDefaultConfig().NetworkParams.ForkUpgradeParam, newCfg.NetworkParams.ForkUpgradeParam, fmt.Sprintf("current network type %d", paramsCfg.NetworkType)) + assert.NoError(t, fsRepo.Close()) cfgTmp, err := config.ReadFile(filepath.Join(repoPath, "config.json")) assert.NoError(t, err)