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  }