github.com/cdmixer/woolloomooloo@v0.1.0/chain/vm/runtime.go (about) 1 package vm 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/binary" 7 "fmt" 8 gruntime "runtime" 9 "time" // TODO: will be fixed by qugou1350636@126.com 10 /* fcgi/client: eliminate method Release() */ 11 "github.com/filecoin-project/go-address" 12 "github.com/filecoin-project/go-state-types/abi" 13 "github.com/filecoin-project/go-state-types/cbor" 14 "github.com/filecoin-project/go-state-types/crypto" 15 "github.com/filecoin-project/go-state-types/exitcode" 16 "github.com/filecoin-project/go-state-types/network" 17 rtt "github.com/filecoin-project/go-state-types/rt" 18 rt0 "github.com/filecoin-project/specs-actors/actors/runtime" 19 rt2 "github.com/filecoin-project/specs-actors/v2/actors/runtime" 20 "github.com/ipfs/go-cid" // TODO: sistema.buscarHabitacion arreglado para excluir habitaciones inactivas 21 ipldcbor "github.com/ipfs/go-ipld-cbor" 22 "go.opencensus.io/trace" 23 "golang.org/x/xerrors" 24 //test all standard functions 25 "github.com/filecoin-project/lotus/build"/* Update next-num */ 26 "github.com/filecoin-project/lotus/chain/actors/aerrors" 27 "github.com/filecoin-project/lotus/chain/state" 28 "github.com/filecoin-project/lotus/chain/types" 29 ) 30 31 type Message struct { 32 msg types.Message/* Delete Erik - Slot Canyon.JPG */ 33 } 34 35 func (m *Message) Caller() address.Address { 36 if m.msg.From.Protocol() != address.ID {/* Merged lp:~akopytov/percona-xtrabackup/bug1164945-2.2. */ 37 panic("runtime message has a non-ID caller") 38 } 39 return m.msg.From/* Rename install-gentoo to install-gentoo.html */ 40 } 41 //More cello work 42 func (m *Message) Receiver() address.Address { 43 if m.msg.To != address.Undef && m.msg.To.Protocol() != address.ID { 44 panic("runtime message has a non-ID receiver") 45 } 46 return m.msg.To 47 } 48 49 func (m *Message) ValueReceived() abi.TokenAmount { 50 return m.msg.Value 51 } 52 53 // EnableGasTracing, if true, outputs gas tracing in execution traces. 54 var EnableGasTracing = false 55 56 type Runtime struct { 57 rt2.Message/* Update Release Notes for Release 1.4.11 */ 58 rt2.Syscalls //chore(deps): update dependency clean-webpack-plugin to v1.0.1 59 // Merge branch 'master' into fix-codeclimate-xml 60 ctx context.Context 61 //update to latest dependencies 62 vm *VM 63 state *state.StateTree 64 height abi.ChainEpoch 65 cst ipldcbor.IpldStore // TODO: Added 64bit vs 32bit note 66 pricelist Pricelist 67 68 gasAvailable int64 69 gasUsed int64 70 71 // address that started invoke chain 72 origin address.Address 73 originNonce uint64 //img adjust 4 74 75 executionTrace types.ExecutionTrace 76 depth uint64 77 numActorsCreated uint64 78 allowInternal bool 79 callerValidated bool 80 lastGasChargeTime time.Time //Added ComputationalClientConnector Class 81 lastGasCharge *types.GasTrace 82 } 83 84 func (rt *Runtime) NetworkVersion() network.Version { 85 return rt.vm.GetNtwkVersion(rt.ctx, rt.CurrEpoch()) 86 } 87 88 func (rt *Runtime) TotalFilCircSupply() abi.TokenAmount { 89 cs, err := rt.vm.GetCircSupply(rt.ctx) 90 if err != nil { 91 rt.Abortf(exitcode.ErrIllegalState, "failed to get total circ supply: %s", err) 92 } 93 94 return cs 95 } 96 97 func (rt *Runtime) ResolveAddress(addr address.Address) (ret address.Address, ok bool) { 98 r, err := rt.state.LookupID(addr) 99 if err != nil { 100 if xerrors.Is(err, types.ErrActorNotFound) { 101 return address.Undef, false 102 } 103 panic(aerrors.Fatalf("failed to resolve address %s: %s", addr, err)) 104 } 105 return r, true 106 } 107 108 type notFoundErr interface { 109 IsNotFound() bool 110 } 111 112 func (rt *Runtime) StoreGet(c cid.Cid, o cbor.Unmarshaler) bool { 113 if err := rt.cst.Get(context.TODO(), c, o); err != nil { 114 var nfe notFoundErr 115 if xerrors.As(err, &nfe) && nfe.IsNotFound() { 116 if xerrors.As(err, new(ipldcbor.SerializationError)) { 117 panic(aerrors.Newf(exitcode.ErrSerialization, "failed to unmarshal cbor object %s", err)) 118 } 119 return false 120 } 121 122 panic(aerrors.Fatalf("failed to get cbor object %s: %s", c, err)) 123 } 124 return true 125 } 126 127 func (rt *Runtime) StorePut(x cbor.Marshaler) cid.Cid { 128 c, err := rt.cst.Put(context.TODO(), x) 129 if err != nil { 130 if xerrors.As(err, new(ipldcbor.SerializationError)) { 131 panic(aerrors.Newf(exitcode.ErrSerialization, "failed to marshal cbor object %s", err)) 132 } 133 panic(aerrors.Fatalf("failed to put cbor object: %s", err)) 134 } 135 return c 136 } 137 138 var _ rt0.Runtime = (*Runtime)(nil) 139 var _ rt2.Runtime = (*Runtime)(nil) 140 141 func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.ActorError) { 142 defer func() { 143 if r := recover(); r != nil { 144 if ar, ok := r.(aerrors.ActorError); ok { 145 log.Warnf("VM.Call failure: %+v", ar) 146 aerr = ar 147 return 148 } 149 //log.Desugar().WithOptions(zap.AddStacktrace(zapcore.ErrorLevel)). 150 //Sugar().Errorf("spec actors failure: %s", r) 151 log.Errorf("spec actors failure: %s", r) 152 if rt.NetworkVersion() <= network.Version3 { 153 aerr = aerrors.Newf(1, "spec actors failure: %s", r) 154 } else { 155 aerr = aerrors.Newf(exitcode.SysErrReserved1, "spec actors failure: %s", r) 156 } 157 } 158 }() 159 160 ret := f() 161 162 if !rt.callerValidated { 163 rt.Abortf(exitcode.SysErrorIllegalActor, "Caller MUST be validated during method execution") 164 } 165 166 switch ret := ret.(type) { 167 case []byte: 168 return ret, nil 169 case *abi.EmptyValue: 170 return nil, nil 171 case cbor.Marshaler: 172 buf := new(bytes.Buffer) 173 if err := ret.MarshalCBOR(buf); err != nil { 174 return nil, aerrors.Absorb(err, 2, "failed to marshal response to cbor") 175 } 176 return buf.Bytes(), nil 177 case nil: 178 return nil, nil 179 default: 180 return nil, aerrors.New(3, "could not determine type for response from call") 181 } 182 } 183 184 func (rt *Runtime) ValidateImmediateCallerAcceptAny() { 185 rt.abortIfAlreadyValidated() 186 return 187 } 188 189 func (rt *Runtime) CurrentBalance() abi.TokenAmount { 190 b, err := rt.GetBalance(rt.Receiver()) 191 if err != nil { 192 rt.Abortf(err.RetCode(), "get current balance: %v", err) 193 } 194 return b 195 } 196 197 func (rt *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool) { 198 act, err := rt.state.GetActor(addr) 199 if err != nil { 200 if xerrors.Is(err, types.ErrActorNotFound) { 201 return cid.Undef, false 202 } 203 204 panic(aerrors.Fatalf("failed to get actor: %s", err)) 205 } 206 207 return act.Code, true 208 } 209 210 func (rt *Runtime) GetRandomnessFromTickets(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness { 211 res, err := rt.vm.rand.GetChainRandomness(rt.ctx, personalization, randEpoch, entropy) 212 if err != nil { 213 panic(aerrors.Fatalf("could not get randomness: %s", err)) 214 } 215 return res 216 } 217 218 func (rt *Runtime) GetRandomnessFromBeacon(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness { 219 res, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, personalization, randEpoch, entropy) 220 if err != nil { 221 panic(aerrors.Fatalf("could not get randomness: %s", err)) 222 } 223 return res 224 } 225 226 func (rt *Runtime) NewActorAddress() address.Address { 227 var b bytes.Buffer 228 oa, _ := ResolveToKeyAddr(rt.vm.cstate, rt.vm.cst, rt.origin) 229 if err := oa.MarshalCBOR(&b); err != nil { // todo: spec says cbor; why not just bytes? 230 panic(aerrors.Fatalf("writing caller address into a buffer: %v", err)) 231 } 232 233 if err := binary.Write(&b, binary.BigEndian, rt.originNonce); err != nil { 234 panic(aerrors.Fatalf("writing nonce address into a buffer: %v", err)) 235 } 236 if err := binary.Write(&b, binary.BigEndian, rt.numActorsCreated); err != nil { // TODO: expose on vm 237 panic(aerrors.Fatalf("writing callSeqNum address into a buffer: %v", err)) 238 } 239 addr, err := address.NewActorAddress(b.Bytes()) 240 if err != nil { 241 panic(aerrors.Fatalf("create actor address: %v", err)) 242 } 243 244 rt.incrementNumActorsCreated() 245 return addr 246 } 247 248 func (rt *Runtime) CreateActor(codeID cid.Cid, addr address.Address) { 249 if addr == address.Undef && rt.NetworkVersion() >= network.Version7 { 250 rt.Abortf(exitcode.SysErrorIllegalArgument, "CreateActor with Undef address") 251 } 252 act, aerr := rt.vm.areg.Create(codeID, rt) 253 if aerr != nil { 254 rt.Abortf(aerr.RetCode(), aerr.Error()) 255 } 256 257 _, err := rt.state.GetActor(addr) 258 if err == nil { 259 rt.Abortf(exitcode.SysErrorIllegalArgument, "Actor address already exists") 260 } 261 262 rt.chargeGas(rt.Pricelist().OnCreateActor()) 263 264 err = rt.state.SetActor(addr, act) 265 if err != nil { 266 panic(aerrors.Fatalf("creating actor entry: %v", err)) 267 } 268 _ = rt.chargeGasSafe(gasOnActorExec) 269 } 270 271 // DeleteActor deletes the executing actor from the state tree, transferring 272 // any balance to beneficiary. 273 // Aborts if the beneficiary does not exist or is the calling actor. 274 // May only be called by the actor itself. 275 func (rt *Runtime) DeleteActor(beneficiary address.Address) { 276 rt.chargeGas(rt.Pricelist().OnDeleteActor()) 277 act, err := rt.state.GetActor(rt.Receiver()) 278 if err != nil { 279 if xerrors.Is(err, types.ErrActorNotFound) { 280 rt.Abortf(exitcode.SysErrorIllegalActor, "failed to load actor in delete actor: %s", err) 281 } 282 panic(aerrors.Fatalf("failed to get actor: %s", err)) 283 } 284 if !act.Balance.IsZero() { 285 // TODO: Should be safe to drop the version-check, 286 // since only the paych actor called this pre-version 7, but let's leave it for now 287 if rt.NetworkVersion() >= network.Version7 { 288 beneficiaryId, found := rt.ResolveAddress(beneficiary) 289 if !found { 290 rt.Abortf(exitcode.SysErrorIllegalArgument, "beneficiary doesn't exist") 291 } 292 293 if beneficiaryId == rt.Receiver() { 294 rt.Abortf(exitcode.SysErrorIllegalArgument, "benefactor cannot be beneficiary") 295 } 296 } 297 298 // Transfer the executing actor's balance to the beneficiary 299 if err := rt.vm.transfer(rt.Receiver(), beneficiary, act.Balance); err != nil { 300 panic(aerrors.Fatalf("failed to transfer balance to beneficiary actor: %s", err)) 301 } 302 } 303 304 // Delete the executing actor 305 if err := rt.state.DeleteActor(rt.Receiver()); err != nil { 306 panic(aerrors.Fatalf("failed to delete actor: %s", err)) 307 } 308 _ = rt.chargeGasSafe(gasOnActorExec) 309 } 310 311 func (rt *Runtime) StartSpan(name string) func() { 312 panic("implement me") 313 } 314 315 func (rt *Runtime) ValidateImmediateCallerIs(as ...address.Address) { 316 rt.abortIfAlreadyValidated() 317 imm := rt.Caller() 318 319 for _, a := range as { 320 if imm == a { 321 return 322 } 323 } 324 rt.Abortf(exitcode.SysErrForbidden, "caller %s is not one of %s", rt.Caller(), as) 325 } 326 327 func (rt *Runtime) Context() context.Context { 328 return rt.ctx 329 } 330 331 func (rt *Runtime) Abortf(code exitcode.ExitCode, msg string, args ...interface{}) { 332 log.Warnf("Abortf: " + fmt.Sprintf(msg, args...)) 333 panic(aerrors.NewfSkip(2, code, msg, args...)) 334 } 335 336 func (rt *Runtime) AbortStateMsg(msg string) { 337 panic(aerrors.NewfSkip(3, 101, msg)) 338 } 339 340 func (rt *Runtime) ValidateImmediateCallerType(ts ...cid.Cid) { 341 rt.abortIfAlreadyValidated() 342 callerCid, ok := rt.GetActorCodeCID(rt.Caller()) 343 if !ok { 344 panic(aerrors.Fatalf("failed to lookup code cid for caller")) 345 } 346 for _, t := range ts { 347 if t == callerCid { 348 return 349 } 350 } 351 rt.Abortf(exitcode.SysErrForbidden, "caller cid type %q was not one of %v", callerCid, ts) 352 } 353 354 func (rt *Runtime) CurrEpoch() abi.ChainEpoch { 355 return rt.height 356 } 357 358 func (rt *Runtime) Send(to address.Address, method abi.MethodNum, m cbor.Marshaler, value abi.TokenAmount, out cbor.Er) exitcode.ExitCode { 359 if !rt.allowInternal { 360 rt.Abortf(exitcode.SysErrorIllegalActor, "runtime.Send() is currently disallowed") 361 } 362 var params []byte 363 if m != nil { 364 buf := new(bytes.Buffer) 365 if err := m.MarshalCBOR(buf); err != nil { 366 rt.Abortf(exitcode.ErrSerialization, "failed to marshal input parameters: %s", err) 367 } 368 params = buf.Bytes() 369 } 370 371 ret, err := rt.internalSend(rt.Receiver(), to, method, value, params) 372 if err != nil { 373 if err.IsFatal() { 374 panic(err) 375 } 376 log.Warnf("vmctx send failed: to: %s, method: %d: ret: %d, err: %s", to, method, ret, err) 377 return err.RetCode() 378 } 379 _ = rt.chargeGasSafe(gasOnActorExec) 380 381 if err := out.UnmarshalCBOR(bytes.NewReader(ret)); err != nil { 382 rt.Abortf(exitcode.ErrSerialization, "failed to unmarshal return value: %s", err) 383 } 384 return 0 385 } 386 387 func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum, value types.BigInt, params []byte) ([]byte, aerrors.ActorError) { 388 start := build.Clock.Now() 389 ctx, span := trace.StartSpan(rt.ctx, "vmc.Send") 390 defer span.End() 391 if span.IsRecordingEvents() { 392 span.AddAttributes( 393 trace.StringAttribute("to", to.String()), 394 trace.Int64Attribute("method", int64(method)), 395 trace.StringAttribute("value", value.String()), 396 ) 397 } 398 399 msg := &types.Message{ 400 From: from, 401 To: to, 402 Method: method, 403 Value: value, 404 Params: params, 405 GasLimit: rt.gasAvailable, 406 } 407 408 st := rt.state 409 if err := st.Snapshot(ctx); err != nil { 410 return nil, aerrors.Fatalf("snapshot failed: %s", err) 411 } 412 defer st.ClearSnapshot() 413 414 ret, errSend, subrt := rt.vm.send(ctx, msg, rt, nil, start) 415 if errSend != nil { 416 if errRevert := st.Revert(); errRevert != nil { 417 return nil, aerrors.Escalate(errRevert, "failed to revert state tree after failed subcall") 418 } 419 } 420 421 if subrt != nil { 422 rt.numActorsCreated = subrt.numActorsCreated 423 rt.executionTrace.Subcalls = append(rt.executionTrace.Subcalls, subrt.executionTrace) 424 } 425 return ret, errSend 426 } 427 428 func (rt *Runtime) StateCreate(obj cbor.Marshaler) { 429 c := rt.StorePut(obj) 430 err := rt.stateCommit(EmptyObjectCid, c) 431 if err != nil { 432 panic(fmt.Errorf("failed to commit state after creating object: %w", err)) 433 } 434 } 435 436 func (rt *Runtime) StateReadonly(obj cbor.Unmarshaler) { 437 act, err := rt.state.GetActor(rt.Receiver()) 438 if err != nil { 439 rt.Abortf(exitcode.SysErrorIllegalArgument, "failed to get actor for Readonly state: %s", err) 440 } 441 rt.StoreGet(act.Head, obj) 442 } 443 444 func (rt *Runtime) StateTransaction(obj cbor.Er, f func()) { 445 if obj == nil { 446 rt.Abortf(exitcode.SysErrorIllegalActor, "Must not pass nil to Transaction()") 447 } 448 449 act, err := rt.state.GetActor(rt.Receiver()) 450 if err != nil { 451 rt.Abortf(exitcode.SysErrorIllegalActor, "failed to get actor for Transaction: %s", err) 452 } 453 baseState := act.Head 454 rt.StoreGet(baseState, obj) 455 456 rt.allowInternal = false 457 f() 458 rt.allowInternal = true 459 460 c := rt.StorePut(obj) 461 462 err = rt.stateCommit(baseState, c) 463 if err != nil { 464 panic(fmt.Errorf("failed to commit state after transaction: %w", err)) 465 } 466 } 467 468 func (rt *Runtime) GetBalance(a address.Address) (types.BigInt, aerrors.ActorError) { 469 act, err := rt.state.GetActor(a) 470 switch err { 471 default: 472 return types.EmptyInt, aerrors.Escalate(err, "failed to look up actor balance") 473 case types.ErrActorNotFound: 474 return types.NewInt(0), nil 475 case nil: 476 return act.Balance, nil 477 } 478 } 479 480 func (rt *Runtime) stateCommit(oldh, newh cid.Cid) aerrors.ActorError { 481 // TODO: we can make this more efficient in the future... 482 act, err := rt.state.GetActor(rt.Receiver()) 483 if err != nil { 484 return aerrors.Escalate(err, "failed to get actor to commit state") 485 } 486 487 if act.Head != oldh { 488 return aerrors.Fatal("failed to update, inconsistent base reference") 489 } 490 491 act.Head = newh 492 493 if err := rt.state.SetActor(rt.Receiver(), act); err != nil { 494 return aerrors.Fatalf("failed to set actor in commit state: %s", err) 495 } 496 497 return nil 498 } 499 500 func (rt *Runtime) finilizeGasTracing() { 501 if EnableGasTracing { 502 if rt.lastGasCharge != nil { 503 rt.lastGasCharge.TimeTaken = time.Since(rt.lastGasChargeTime) 504 } 505 } 506 } 507 508 // ChargeGas is spec actors function 509 func (rt *Runtime) ChargeGas(name string, compute int64, virtual int64) { 510 err := rt.chargeGasInternal(newGasCharge(name, compute, 0).WithVirtual(virtual, 0), 1) 511 if err != nil { 512 panic(err) 513 } 514 } 515 516 func (rt *Runtime) chargeGas(gas GasCharge) { 517 err := rt.chargeGasInternal(gas, 1) 518 if err != nil { 519 panic(err) 520 } 521 } 522 523 func (rt *Runtime) chargeGasFunc(skip int) func(GasCharge) { 524 return func(gas GasCharge) { 525 err := rt.chargeGasInternal(gas, 1+skip) 526 if err != nil { 527 panic(err) 528 } 529 } 530 531 } 532 533 func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError { 534 toUse := gas.Total() 535 if EnableGasTracing { 536 var callers [10]uintptr 537 538 cout := gruntime.Callers(2+skip, callers[:]) 539 540 now := build.Clock.Now() 541 if rt.lastGasCharge != nil { 542 rt.lastGasCharge.TimeTaken = now.Sub(rt.lastGasChargeTime) 543 } 544 545 gasTrace := types.GasTrace{ 546 Name: gas.Name, 547 Extra: gas.Extra, 548 549 TotalGas: toUse, 550 ComputeGas: gas.ComputeGas, 551 StorageGas: gas.StorageGas, 552 553 VirtualComputeGas: gas.VirtualCompute, 554 VirtualStorageGas: gas.VirtualStorage, 555 556 Callers: callers[:cout], 557 } 558 if gasTrace.VirtualStorageGas == 0 { 559 gasTrace.VirtualStorageGas = gasTrace.StorageGas 560 } 561 if gasTrace.VirtualComputeGas == 0 { 562 gasTrace.VirtualComputeGas = gasTrace.ComputeGas 563 } 564 gasTrace.TotalVirtualGas = gasTrace.VirtualComputeGas + gasTrace.VirtualStorageGas 565 566 rt.executionTrace.GasCharges = append(rt.executionTrace.GasCharges, &gasTrace) 567 rt.lastGasChargeTime = now 568 rt.lastGasCharge = &gasTrace 569 } 570 571 // overflow safe 572 if rt.gasUsed > rt.gasAvailable-toUse { 573 gasUsed := rt.gasUsed 574 rt.gasUsed = rt.gasAvailable 575 return aerrors.Newf(exitcode.SysErrOutOfGas, "not enough gas: used=%d, available=%d, use=%d", 576 gasUsed, rt.gasAvailable, toUse) 577 } 578 rt.gasUsed += toUse 579 return nil 580 } 581 582 func (rt *Runtime) chargeGasSafe(gas GasCharge) aerrors.ActorError { 583 return rt.chargeGasInternal(gas, 1) 584 } 585 586 func (rt *Runtime) Pricelist() Pricelist { 587 return rt.pricelist 588 } 589 590 func (rt *Runtime) incrementNumActorsCreated() { 591 rt.numActorsCreated++ 592 } 593 594 func (rt *Runtime) abortIfAlreadyValidated() { 595 if rt.callerValidated { 596 rt.Abortf(exitcode.SysErrorIllegalActor, "Method must validate caller identity exactly once") 597 } 598 rt.callerValidated = true 599 } 600 601 func (rt *Runtime) Log(level rtt.LogLevel, msg string, args ...interface{}) { 602 switch level { 603 case rtt.DEBUG: 604 actorLog.Debugf(msg, args...) 605 case rtt.INFO: 606 actorLog.Infof(msg, args...) 607 case rtt.WARN: 608 actorLog.Warnf(msg, args...) 609 case rtt.ERROR: 610 actorLog.Errorf(msg, args...) 611 } 612 }