Skip to content

Commit

Permalink
Merge pull request #4830 from filecoin-project/time/vm-flush
Browse files Browse the repository at this point in the history
Gas Balancing
  • Loading branch information
magik6k authored Nov 18, 2020
2 parents 9328d98 + 4982de8 commit c5470ee
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 45 deletions.
58 changes: 51 additions & 7 deletions chain/vm/gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,17 @@ package vm
import (
"fmt"

vmr2 "github.com/filecoin-project/specs-actors/v2/actors/runtime"
proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof"
"github.com/filecoin-project/lotus/build"

"github.com/filecoin-project/go-address"
addr "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
vmr2 "github.com/filecoin-project/specs-actors/v2/actors/runtime"
proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof"
"github.com/ipfs/go-cid"
)

const (
GasStorageMulti = 1000
GasComputeMulti = 1
)

type GasCharge struct {
Name string
Extra interface{}
Expand Down Expand Up @@ -132,6 +128,54 @@ var prices = map[abi.ChainEpoch]Pricelist{
verifyPostDiscount: true,
verifyConsensusFault: 495422,
},
abi.ChainEpoch(build.UpgradeCalicoHeight): &pricelistV0{
computeGasMulti: 1,
storageGasMulti: 1300,

onChainMessageComputeBase: 38863,
onChainMessageStorageBase: 36,
onChainMessageStoragePerByte: 1,

onChainReturnValuePerByte: 1,

sendBase: 29233,
sendTransferFunds: 27500,
sendTransferOnlyPremium: 159672,
sendInvokeMethod: -5377,

ipldGetBase: 114617,
ipldPutBase: 353640,
ipldPutPerByte: 1,

createActorCompute: 1108454,
createActorStorage: 36 + 40,
deleteActor: -(36 + 40), // -createActorStorage

verifySignature: map[crypto.SigType]int64{
crypto.SigTypeBLS: 16598605,
crypto.SigTypeSecp256k1: 1637292,
},

hashingBase: 31355,
computeUnsealedSectorCidBase: 98647,
verifySealBase: 2000, // TODO gas , it VerifySeal syscall is not used
verifyPostLookup: map[abi.RegisteredPoStProof]scalingCost{
abi.RegisteredPoStProof_StackedDrgWindow512MiBV1: {
flat: 117680921,
scale: 43780,
},
abi.RegisteredPoStProof_StackedDrgWindow32GiBV1: {
flat: 117680921,
scale: 43780,
},
abi.RegisteredPoStProof_StackedDrgWindow64GiBV1: {
flat: 117680921,
scale: 43780,
},
},
verifyPostDiscount: false,
verifyConsensusFault: 495422,
},
}

// PricelistByEpoch finds the latest prices for the given epoch
Expand Down
5 changes: 3 additions & 2 deletions chain/vm/gas_v0.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,13 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M

// OnIpldGet returns the gas used for storing an object
func (pl *pricelistV0) OnIpldGet() GasCharge {
return newGasCharge("OnIpldGet", pl.ipldGetBase, 0)
return newGasCharge("OnIpldGet", pl.ipldGetBase, 0).WithVirtual(114617, 0)
}

// OnIpldPut returns the gas used for storing an object
func (pl *pricelistV0) OnIpldPut(dataSize int) GasCharge {
return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte*pl.storageGasMulti).
WithExtra(dataSize)
WithExtra(dataSize).WithVirtual(400000, int64(dataSize)*1300)
}

// OnCreateActor returns the gas used for creating an actor
Expand Down Expand Up @@ -209,6 +209,7 @@ func (pl *pricelistV0) OnVerifyPost(info proof2.WindowPoStVerifyInfo) GasCharge
}

return newGasCharge("OnVerifyPost", gasUsed, 0).
WithVirtual(117680921+43780*int64(len(info.ChallengedSectors)), 0).
WithExtra(map[string]interface{}{
"type": sectorSize,
"size": len(info.ChallengedSectors),
Expand Down
9 changes: 8 additions & 1 deletion chain/vm/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,12 +539,19 @@ func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError
ComputeGas: gas.ComputeGas,
StorageGas: gas.StorageGas,

TotalVirtualGas: gas.VirtualCompute*GasComputeMulti + gas.VirtualStorage*GasStorageMulti,
VirtualComputeGas: gas.VirtualCompute,
VirtualStorageGas: gas.VirtualStorage,

Callers: callers[:cout],
}
if gasTrace.VirtualStorageGas == 0 {
gasTrace.VirtualStorageGas = gasTrace.StorageGas
}
if gasTrace.VirtualComputeGas == 0 {
gasTrace.VirtualComputeGas = gasTrace.ComputeGas
}
gasTrace.TotalVirtualGas = gasTrace.VirtualComputeGas + gasTrace.VirtualStorageGas

rt.executionTrace.GasCharges = append(rt.executionTrace.GasCharges, &gasTrace)
rt.lastGasChargeTime = now
rt.lastGasCharge = &gasTrace
Expand Down
56 changes: 47 additions & 9 deletions chain/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import (
"time"

"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/metrics"

block "github.com/ipfs/go-block-format"
cid "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log/v2"
mh "github.com/multiformats/go-multihash"
cbg "github.com/whyrusleeping/cbor-gen"
"go.opencensus.io/stats"
"go.opencensus.io/trace"
"golang.org/x/xerrors"

Expand Down Expand Up @@ -606,6 +608,8 @@ func (vm *VM) ActorBalance(addr address.Address) (types.BigInt, aerrors.ActorErr
return act.Balance, nil
}

type vmFlushKey struct{}

func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) {
_, span := trace.StartSpan(ctx, "vm.Flush")
defer span.End()
Expand All @@ -618,7 +622,7 @@ func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) {
return cid.Undef, xerrors.Errorf("flushing vm: %w", err)
}

if err := Copy(ctx, from, to, root); err != nil {
if err := Copy(context.WithValue(ctx, vmFlushKey{}, true), from, to, root); err != nil {
return cid.Undef, xerrors.Errorf("copying tree: %w", err)
}

Expand Down Expand Up @@ -675,21 +679,48 @@ func linksForObj(blk block.Block, cb func(cid.Cid)) error {
func Copy(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid) error {
ctx, span := trace.StartSpan(ctx, "vm.Copy") // nolint
defer span.End()
start := time.Now()

var numBlocks int
var totalCopySize int

var batch []block.Block
const batchSize = 128
const bufCount = 3
freeBufs := make(chan []block.Block, bufCount)
toFlush := make(chan []block.Block, bufCount)
for i := 0; i < bufCount; i++ {
freeBufs <- make([]block.Block, 0, batchSize)
}

errFlushChan := make(chan error)

go func() {
for b := range toFlush {
if err := to.PutMany(b); err != nil {
close(freeBufs)
errFlushChan <- xerrors.Errorf("batch put in copy: %w", err)
return
}
freeBufs <- b[:0]
}
close(errFlushChan)
close(freeBufs)
}()

var batch = <-freeBufs
batchCp := func(blk block.Block) error {
numBlocks++
totalCopySize += len(blk.RawData())

batch = append(batch, blk)
if len(batch) > 100 {
if err := to.PutMany(batch); err != nil {
return xerrors.Errorf("batch put in copy: %w", err)

if len(batch) >= batchSize {
toFlush <- batch
var ok bool
batch, ok = <-freeBufs
if !ok {
return <-errFlushChan
}
batch = batch[:0]
}
return nil
}
Expand All @@ -699,15 +730,22 @@ func Copy(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid) err
}

if len(batch) > 0 {
if err := to.PutMany(batch); err != nil {
return xerrors.Errorf("batch put in copy: %w", err)
}
toFlush <- batch
}
close(toFlush) // close the toFlush triggering the loop to end
err := <-errFlushChan // get error out or get nil if it was closed
if err != nil {
return err
}

span.AddAttributes(
trace.Int64Attribute("numBlocks", int64(numBlocks)),
trace.Int64Attribute("copySize", int64(totalCopySize)),
)
if yes, ok := ctx.Value(vmFlushKey{}).(bool); yes && ok {
took := metrics.SinceInMilliseconds(start)
stats.Record(ctx, metrics.VMFlushCopyCount.M(int64(numBlocks)), metrics.VMFlushCopyDuration.M(took))
}

return nil
}
Expand Down
11 changes: 11 additions & 0 deletions conformance/chaos/actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ const (
// MethodInspectRuntime is the identifier for the method that returns the
// current runtime values.
MethodInspectRuntime
// MethodCreateState is the identifier for the method that creates the chaos actor's state.
MethodCreateState
)

// Exports defines the methods this actor exposes publicly.
Expand All @@ -87,6 +89,7 @@ func (a Actor) Exports() []interface{} {
MethodMutateState: a.MutateState,
MethodAbortWith: a.AbortWith,
MethodInspectRuntime: a.InspectRuntime,
MethodCreateState: a.CreateState,
}
}

Expand Down Expand Up @@ -227,6 +230,14 @@ type MutateStateArgs struct {
Branch MutateStateBranch
}

// CreateState creates the chaos actor's state
func (a Actor) CreateState(rt runtime2.Runtime, _ *abi.EmptyValue) *abi.EmptyValue {
rt.ValidateImmediateCallerAcceptAny()
rt.StateCreate(&State{})

return nil
}

// MutateState attempts to mutate a state value in the actor.
func (a Actor) MutateState(rt runtime2.Runtime, args *MutateStateArgs) *abi.EmptyValue {
rt.ValidateImmediateCallerAcceptAny()
Expand Down
64 changes: 41 additions & 23 deletions conformance/chaos/actor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@ func TestMutateStateInTransaction(t *testing.T) {
var a Actor

rt.ExpectValidateCallerAny()
rt.StateCreate(&State{})
rt.Call(a.CreateState, nil)

rt.ExpectValidateCallerAny()
val := "__mutstat test"
rt.Call(a.MutateState, &MutateStateArgs{
Value: val,
Expand All @@ -155,23 +156,30 @@ func TestMutateStateAfterTransaction(t *testing.T) {
var a Actor

rt.ExpectValidateCallerAny()
rt.StateCreate(&State{})
rt.Call(a.CreateState, nil)

rt.ExpectValidateCallerAny()
val := "__mutstat test"
defer func() {
if r := recover(); r == nil {
t.Fatal("The code did not panic")
} else {
var st State
rt.GetState(&st)

// state should be updated successfully _in_ the transaction but not outside
if st.Value != val+"-in" {
t.Fatal("state was not updated")
}

rt.Verify()
}
}()
rt.Call(a.MutateState, &MutateStateArgs{
Value: val,
Branch: MutateAfterTransaction,
})

var st State
rt.GetState(&st)

// state should be updated successfully _in_ the transaction but not outside
if st.Value != val+"-in" {
t.Fatal("state was not updated")
}

rt.Verify()
}

func TestMutateStateReadonly(t *testing.T) {
Expand All @@ -182,22 +190,30 @@ func TestMutateStateReadonly(t *testing.T) {
var a Actor

rt.ExpectValidateCallerAny()
rt.StateCreate(&State{})
rt.Call(a.CreateState, nil)

rt.ExpectValidateCallerAny()
val := "__mutstat test"
defer func() {
if r := recover(); r == nil {
t.Fatal("The code did not panic")
} else {
var st State
rt.GetState(&st)

if st.Value != "" {
t.Fatal("state was not expected to be updated")
}

rt.Verify()
}
}()

rt.Call(a.MutateState, &MutateStateArgs{
Value: val,
Branch: MutateReadonly,
})

var st State
rt.GetState(&st)

if st.Value != "" {
t.Fatal("state was not expected to be updated")
}

rt.Verify()
}

func TestMutateStateInvalidBranch(t *testing.T) {
Expand Down Expand Up @@ -254,11 +270,13 @@ func TestInspectRuntime(t *testing.T) {
receiver := atesting2.NewIDAddr(t, 101)
builder := mock2.NewBuilder(context.Background(), receiver)

rt := builder.Build(t)
rt.SetCaller(caller, builtin2.AccountActorCodeID)
rt.StateCreate(&State{})
var a Actor

rt := builder.Build(t)
rt.ExpectValidateCallerAny()
rt.Call(a.CreateState, nil)

rt.SetCaller(caller, builtin2.AccountActorCodeID)
rt.ExpectValidateCallerAny()
ret := rt.Call(a.InspectRuntime, abi.Empty)
rtr, ok := ret.(*InspectRuntimeReturn)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ require (
github.com/filecoin-project/go-statestore v0.1.0
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b
github.com/filecoin-project/specs-actors v0.9.13
github.com/filecoin-project/specs-actors/v2 v2.3.0
github.com/filecoin-project/specs-actors/v2 v2.3.2
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506
github.com/filecoin-project/test-vectors/schema v0.0.5
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,8 @@ github.com/filecoin-project/specs-actors v0.9.12/go.mod h1:TS1AW/7LbG+615j4NsjMK
github.com/filecoin-project/specs-actors v0.9.13 h1:rUEOQouefi9fuVY/2HOroROJlZbOzWYXXeIh41KF2M4=
github.com/filecoin-project/specs-actors v0.9.13/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao=
github.com/filecoin-project/specs-actors/v2 v2.0.1/go.mod h1:v2NZVYinNIKA9acEMBm5wWXxqv5+frFEbekBFemYghY=
github.com/filecoin-project/specs-actors/v2 v2.3.0 h1:V7lHeF2ylfFi84F4y80u5FE4BpPHYGvB71kLrhXkJto=
github.com/filecoin-project/specs-actors/v2 v2.3.0/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y=
github.com/filecoin-project/specs-actors/v2 v2.3.2 h1:2Vcf4CGa29kRh4JJ02m+FbvD/p3YNnLGsaHfw7Uj49g=
github.com/filecoin-project/specs-actors/v2 v2.3.2/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y=
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw=
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g=
github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg=
Expand Down
Loading

0 comments on commit c5470ee

Please sign in to comment.