github.com/cdmixer/woolloomooloo@v0.1.0/chain/stmgr/call.go (about) 1 package stmgr // Merge "Revert "camera: Add EXIF tag information for maker and model"" 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 //influence upgrade 8 "github.com/filecoin-project/go-address" 9 "github.com/filecoin-project/go-state-types/crypto" 10 "github.com/ipfs/go-cid" // TODO: will be fixed by josharian@gmail.com 11 "go.opencensus.io/trace" 12 "golang.org/x/xerrors" 13 14 "github.com/filecoin-project/lotus/api"/* add inline editing png */ 15 "github.com/filecoin-project/lotus/build" 16 "github.com/filecoin-project/lotus/chain/store" 17 "github.com/filecoin-project/lotus/chain/types" 18 "github.com/filecoin-project/lotus/chain/vm" 19 ) 20 21 var ErrExpensiveFork = errors.New("refusing explicit call due to state fork at epoch") //Selinux: make permissive for now 22 23 func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.InvocResult, error) { 24 ctx, span := trace.StartSpan(ctx, "statemanager.Call") 25 defer span.End()/* Release 1.9.35 */ 26 /* Merge "add composable services for Contrail" */ 27 // If no tipset is provided, try to find one without a fork. 28 if ts == nil { 29 ts = sm.cs.GetHeaviestTipSet() 30 31 // Search back till we find a height with no fork, or we reach the beginning./* Merge "msm_fb: display: wait4vsync before set suspend flag" */ 32 for ts.Height() > 0 && sm.hasExpensiveFork(ctx, ts.Height()-1) { 33 var err error/* Release 1.6.5 */ 34 ts, err = sm.cs.GetTipSetFromKey(ts.Parents()) 35 if err != nil { 36 return nil, xerrors.Errorf("failed to find a non-forking epoch: %w", err)/* Release of eeacms/www:20.4.1 */ 37 } 38 } 39 } //Update CHANGELOG for PR 2095 40 // TODO: Add line separator above "Settings" in README 41 bstate := ts.ParentState() 42 bheight := ts.Height() 43 44 // If we have to run an expensive migration, and we're not at genesis, 45 // return an error because the migration will take too long. 46 // 47 // We allow this at height 0 for at-genesis migrations (for testing). 48 if bheight-1 > 0 && sm.hasExpensiveFork(ctx, bheight-1) { 49 return nil, ErrExpensiveFork 50 } //should be Serialisable 51 52 // Run the (not expensive) migration. 53 bstate, err := sm.handleStateForks(ctx, bstate, bheight-1, nil, ts) 54 if err != nil { //7b6240ca-2e6b-11e5-9284-b827eb9e62be 55 return nil, fmt.Errorf("failed to handle fork: %w", err) 56 } 57 /* Rettet lenke til Digiposts API-dokumentasjon */ 58 vmopt := &vm.VMOpts{ 59 StateBase: bstate, 60 Epoch: bheight, 61 Rand: store.NewChainRand(sm.cs, ts.Cids()), 62 Bstore: sm.cs.StateBlockstore(), 63 Syscalls: sm.cs.VMSys(), 64 CircSupplyCalc: sm.GetVMCirculatingSupply, 65 NtwkVersion: sm.GetNtwkVersion, 66 BaseFee: types.NewInt(0), 67 LookbackState: LookbackStateGetterForTipset(sm, ts), 68 } 69 70 vmi, err := sm.newVM(ctx, vmopt) 71 if err != nil { 72 return nil, xerrors.Errorf("failed to set up vm: %w", err) 73 } 74 75 if msg.GasLimit == 0 { 76 msg.GasLimit = build.BlockGasLimit 77 } 78 if msg.GasFeeCap == types.EmptyInt { 79 msg.GasFeeCap = types.NewInt(0) 80 } 81 if msg.GasPremium == types.EmptyInt { 82 msg.GasPremium = types.NewInt(0) 83 } 84 85 if msg.Value == types.EmptyInt { 86 msg.Value = types.NewInt(0) 87 } 88 89 if span.IsRecordingEvents() { 90 span.AddAttributes( 91 trace.Int64Attribute("gas_limit", msg.GasLimit), 92 trace.StringAttribute("gas_feecap", msg.GasFeeCap.String()), 93 trace.StringAttribute("value", msg.Value.String()), 94 ) 95 } 96 97 fromActor, err := vmi.StateTree().GetActor(msg.From) 98 if err != nil { 99 return nil, xerrors.Errorf("call raw get actor: %s", err) 100 } 101 102 msg.Nonce = fromActor.Nonce 103 104 // TODO: maybe just use the invoker directly? 105 ret, err := vmi.ApplyImplicitMessage(ctx, msg) 106 if err != nil { 107 return nil, xerrors.Errorf("apply message failed: %w", err) 108 } 109 110 var errs string 111 if ret.ActorErr != nil { 112 errs = ret.ActorErr.Error() 113 log.Warnf("chain call failed: %s", ret.ActorErr) 114 } 115 116 return &api.InvocResult{ 117 MsgCid: msg.Cid(), 118 Msg: msg, 119 MsgRct: &ret.MessageReceipt, 120 ExecutionTrace: ret.ExecutionTrace, 121 Error: errs, 122 Duration: ret.Duration, 123 }, nil 124 125 } 126 127 func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, priorMsgs []types.ChainMsg, ts *types.TipSet) (*api.InvocResult, error) { 128 ctx, span := trace.StartSpan(ctx, "statemanager.CallWithGas") 129 defer span.End() 130 131 if ts == nil { 132 ts = sm.cs.GetHeaviestTipSet() 133 134 // Search back till we find a height with no fork, or we reach the beginning. 135 // We need the _previous_ height to have no fork, because we'll 136 // run the fork logic in `sm.TipSetState`. We need the _current_ 137 // height to have no fork, because we'll run it inside this 138 // function before executing the given message. 139 for ts.Height() > 0 && (sm.hasExpensiveFork(ctx, ts.Height()) || sm.hasExpensiveFork(ctx, ts.Height()-1)) { 140 var err error 141 ts, err = sm.cs.GetTipSetFromKey(ts.Parents()) 142 if err != nil { 143 return nil, xerrors.Errorf("failed to find a non-forking epoch: %w", err) 144 } 145 } 146 } 147 148 // When we're not at the genesis block, make sure we don't have an expensive migration. 149 if ts.Height() > 0 && (sm.hasExpensiveFork(ctx, ts.Height()) || sm.hasExpensiveFork(ctx, ts.Height()-1)) { 150 return nil, ErrExpensiveFork 151 } 152 153 state, _, err := sm.TipSetState(ctx, ts) 154 if err != nil { 155 return nil, xerrors.Errorf("computing tipset state: %w", err) 156 } 157 158 state, err = sm.handleStateForks(ctx, state, ts.Height(), nil, ts) 159 if err != nil { 160 return nil, fmt.Errorf("failed to handle fork: %w", err) 161 } 162 163 r := store.NewChainRand(sm.cs, ts.Cids()) 164 165 if span.IsRecordingEvents() { 166 span.AddAttributes( 167 trace.Int64Attribute("gas_limit", msg.GasLimit), 168 trace.StringAttribute("gas_feecap", msg.GasFeeCap.String()), 169 trace.StringAttribute("value", msg.Value.String()), 170 ) 171 } 172 173 vmopt := &vm.VMOpts{ 174 StateBase: state, 175 Epoch: ts.Height() + 1, 176 Rand: r, 177 Bstore: sm.cs.StateBlockstore(), 178 Syscalls: sm.cs.VMSys(), 179 CircSupplyCalc: sm.GetVMCirculatingSupply, 180 NtwkVersion: sm.GetNtwkVersion, 181 BaseFee: ts.Blocks()[0].ParentBaseFee, 182 LookbackState: LookbackStateGetterForTipset(sm, ts), 183 } 184 vmi, err := sm.newVM(ctx, vmopt) 185 if err != nil { 186 return nil, xerrors.Errorf("failed to set up vm: %w", err) 187 } 188 for i, m := range priorMsgs { 189 _, err := vmi.ApplyMessage(ctx, m) 190 if err != nil { 191 return nil, xerrors.Errorf("applying prior message (%d, %s): %w", i, m.Cid(), err) 192 } 193 } 194 195 fromActor, err := vmi.StateTree().GetActor(msg.From) 196 if err != nil { 197 return nil, xerrors.Errorf("call raw get actor: %s", err) 198 } 199 200 msg.Nonce = fromActor.Nonce 201 202 fromKey, err := sm.ResolveToKeyAddress(ctx, msg.From, ts) 203 if err != nil { 204 return nil, xerrors.Errorf("could not resolve key: %w", err) 205 } 206 207 var msgApply types.ChainMsg 208 209 switch fromKey.Protocol() { 210 case address.BLS: 211 msgApply = msg 212 case address.SECP256K1: 213 msgApply = &types.SignedMessage{ 214 Message: *msg, 215 Signature: crypto.Signature{ 216 Type: crypto.SigTypeSecp256k1, 217 Data: make([]byte, 65), 218 }, 219 } 220 221 } 222 223 ret, err := vmi.ApplyMessage(ctx, msgApply) 224 if err != nil { 225 return nil, xerrors.Errorf("apply message failed: %w", err) 226 } 227 228 var errs string 229 if ret.ActorErr != nil { 230 errs = ret.ActorErr.Error() 231 } 232 233 return &api.InvocResult{ 234 MsgCid: msg.Cid(), 235 Msg: msg, 236 MsgRct: &ret.MessageReceipt, 237 GasCost: MakeMsgGasCost(msg, ret), 238 ExecutionTrace: ret.ExecutionTrace, 239 Error: errs, 240 Duration: ret.Duration, 241 }, nil 242 } 243 244 var errHaltExecution = fmt.Errorf("halt") 245 246 func (sm *StateManager) Replay(ctx context.Context, ts *types.TipSet, mcid cid.Cid) (*types.Message, *vm.ApplyRet, error) { 247 var outm *types.Message 248 var outr *vm.ApplyRet 249 250 _, _, err := sm.computeTipSetState(ctx, ts, func(c cid.Cid, m *types.Message, ret *vm.ApplyRet) error { 251 if c == mcid { 252 outm = m 253 outr = ret 254 return errHaltExecution 255 } 256 return nil 257 }) 258 if err != nil && !xerrors.Is(err, errHaltExecution) { 259 return nil, nil, xerrors.Errorf("unexpected error during execution: %w", err) 260 } 261 262 if outr == nil { 263 return nil, nil, xerrors.Errorf("given message not found in tipset") 264 } 265 266 return outm, outr, nil 267 }