Charge gas per msg byte

License: MIT
Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
This commit is contained in:
Jakub Sztandera 2019-08-29 20:34:40 +02:00
parent 5c31b81701
commit a8e03d8a69

View File

@ -27,11 +27,13 @@ var log = logging.Logger("vm")
const ( const (
gasFundTransfer = 10 gasFundTransfer = 10
gasInvoke = 5
gasGetObj = 10 gasGetObj = 10
gasPutObj = 20 gasPutObj = 20
gasPutPerByte = 2 gasPutPerByte = 2
gasCommit = 50 gasCommit = 50
gasPerMessageByte = 2
) )
const ( const (
@ -138,7 +140,7 @@ func (vmc *VMContext) Send(to address.Address, method uint64, value types.BigInt
GasLimit: vmc.gasAvailable, GasLimit: vmc.gasAvailable,
} }
ret, err, _ := vmc.vm.send(ctx, msg, vmc) ret, err, _ := vmc.vm.send(ctx, msg, vmc, 0)
return ret, err return ret, err
} }
@ -294,7 +296,8 @@ type ApplyRet struct {
ActorErr aerrors.ActorError ActorErr aerrors.ActorError
} }
func (vm *VM) send(ctx context.Context, msg *types.Message, parent *VMContext) ([]byte, aerrors.ActorError, *VMContext) { func (vm *VM) send(ctx context.Context, msg *types.Message, parent *VMContext,
gasCharge uint64) ([]byte, aerrors.ActorError, *VMContext) {
st := vm.cstate st := vm.cstate
fromActor, err := st.GetActor(msg.From) fromActor, err := st.GetActor(msg.From)
@ -315,10 +318,10 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *VMContext) (
} }
} }
gasUsed := types.NewInt(0) gasUsed := types.NewInt(gasCharge)
origin := msg.From origin := msg.From
if parent != nil { if parent != nil {
gasUsed = parent.gasUsed gasUsed = types.BigAdd(parent.gasUsed, gasUsed)
origin = parent.origin origin = parent.origin
} }
vmctx := vm.makeVMContext(ctx, toActor.Head, msg, origin, gasUsed) vmctx := vm.makeVMContext(ctx, toActor.Head, msg, origin, gasUsed)
@ -382,6 +385,12 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet,
return nil, xerrors.Errorf("from actor not found: %w", err) return nil, xerrors.Errorf("from actor not found: %w", err)
} }
serMsg, err := msg.Serialize()
if err != nil {
return nil, xerrors.Errorf("could not serialize message: %w", err)
}
msgGasCost := uint64(len(serMsg)) * gasPerMessageByte
gascost := types.BigMul(msg.GasLimit, msg.GasPrice) gascost := types.BigMul(msg.GasLimit, msg.GasPrice)
totalCost := types.BigAdd(gascost, msg.Value) totalCost := types.BigAdd(gascost, msg.Value)
if types.BigCmp(fromActor.Balance, totalCost) < 0 { if types.BigCmp(fromActor.Balance, totalCost) < 0 {
@ -396,7 +405,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet,
} }
fromActor.Nonce++ fromActor.Nonce++
ret, actorErr, vmctx := vm.send(ctx, msg, nil) ret, actorErr, vmctx := vm.send(ctx, msg, nil, msgGasCost)
if aerrors.IsFatal(actorErr) { if aerrors.IsFatal(actorErr) {
return nil, xerrors.Errorf("fatal error: %w", actorErr) return nil, xerrors.Errorf("fatal error: %w", actorErr)
@ -534,6 +543,9 @@ func (vm *VM) Invoke(act *types.Actor, vmctx *VMContext, method uint64, params [
defer func() { defer func() {
vmctx.ctx = oldCtx vmctx.ctx = oldCtx
}() }()
if err := vmctx.ChargeGas(gasInvoke); err != nil {
return nil, aerrors.Wrap(err, "invokeing")
}
ret, err := vm.inv.Invoke(act, vmctx, method, params) ret, err := vm.inv.Invoke(act, vmctx, method, params)
if err != nil { if err != nil {
return nil, err return nil, err