Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

conformance: support multiple protocol versions. #4393

Merged
merged 4 commits into from
Oct 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions cmd/tvx/codenames.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package main

import (
"github.com/filecoin-project/go-state-types/abi"

"github.com/filecoin-project/lotus/build"
)

// ProtocolCodenames is a table that summarises the protocol codenames that
// will be set on extracted vectors, depending on the original execution height.
//
// Implementers rely on these names to filter the vectors they can run through
// their implementations, based on their support level
var ProtocolCodenames = []struct {
firstEpoch abi.ChainEpoch
name string
}{
{0, "genesis"},
{build.UpgradeBreezeHeight + 1, "breeze"},
{build.UpgradeSmokeHeight + 1, "smoke"},
{build.UpgradeIgnitionHeight + 1, "ignition"},
{build.UpgradeRefuelHeight + 1, "refuel"},
{build.UpgradeActorsV2Height + 1, "actorsv2"},
{build.UpgradeTapeHeight + 1, "tape"},
{build.UpgradeLiftoffHeight + 1, "liftoff"},
}

// GetProtocolCodename gets the protocol codename associated with a height.
func GetProtocolCodename(height abi.ChainEpoch) string {
for i, v := range ProtocolCodenames {
if height < v.firstEpoch {
// found the cutoff, return previous.
return ProtocolCodenames[i-1].name
}
}
return ProtocolCodenames[len(ProtocolCodenames)-1].name
}
28 changes: 28 additions & 0 deletions cmd/tvx/codenames_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

import (
"math"
"testing"

"github.com/filecoin-project/go-state-types/abi"

"github.com/filecoin-project/lotus/build"
)

func TestProtocolCodenames(t *testing.T) {
if height := abi.ChainEpoch(100); GetProtocolCodename(height) != "genesis" {
t.Fatal("expected genesis codename")
}

if height := abi.ChainEpoch(build.UpgradeBreezeHeight + 1); GetProtocolCodename(height) != "breeze" {
t.Fatal("expected breeze codename")
}

if height := build.UpgradeActorsV2Height + 1; GetProtocolCodename(height) != "actorsv2" {
t.Fatal("expected actorsv2 codename")
}

if height := abi.ChainEpoch(math.MaxInt64); GetProtocolCodename(height) != ProtocolCodenames[len(ProtocolCodenames)-1].name {
t.Fatal("expected last codename")
}
}
30 changes: 17 additions & 13 deletions cmd/tvx/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,24 @@ func runExecLotus(_ *cli.Context) error {

func executeTestVector(tv schema.TestVector) error {
log.Println("executing test vector:", tv.Meta.ID)
r := new(conformance.LogReporter)
switch class := tv.Class; class {
case "message":
conformance.ExecuteMessageVector(r, &tv)
case "tipset":
conformance.ExecuteTipsetVector(r, &tv)
default:
return fmt.Errorf("test vector class %s not supported", class)
}

if r.Failed() {
log.Println(color.HiRedString("❌ test vector failed"))
} else {
log.Println(color.GreenString("✅ test vector succeeded"))
for _, v := range tv.Pre.Variants {
r := new(conformance.LogReporter)

switch class, v := tv.Class, v; class {
case "message":
conformance.ExecuteMessageVector(r, &tv, &v)
case "tipset":
conformance.ExecuteTipsetVector(r, &tv, &v)
default:
return fmt.Errorf("test vector class %s not supported", class)
}

if r.Failed() {
log.Println(color.HiRedString("❌ test vector failed for variant %s", v.ID))
} else {
log.Println(color.GreenString("✅ test vector succeeded for variant %s", v.ID))
}
}

return nil
Expand Down
14 changes: 13 additions & 1 deletion cmd/tvx/extract.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,13 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error {
return err
}

nv, err := fapi.StateNetworkVersion(ctx, execTs.Key())
if err != nil {
return err
}

codename := GetProtocolCodename(execTs.Height())

// Write out the test vector.
vector := schema.TestVector{
Class: schema.ClassMessage,
Expand All @@ -363,10 +370,15 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error {
{Source: fmt.Sprintf("execution_tipset:%s", execTs.Key().String())},
{Source: "github.com/filecoin-project/lotus", Version: version.String()}},
},
Selector: schema.Selector{
schema.SelectorMinProtocolVersion: codename,
},
Randomness: recordingRand.Recorded(),
CAR: out.Bytes(),
Pre: &schema.Preconditions{
Epoch: int64(execTs.Height()),
Variants: []schema.Variant{
{ID: codename, Epoch: int64(execTs.Height()), NetworkVersion: uint(nv)},
},
CircSupply: circSupply.Int,
BaseFee: basefee.Int,
StateTree: &schema.StateTree{
Expand Down
22 changes: 15 additions & 7 deletions conformance/corpus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import (
"github.com/filecoin-project/test-vectors/schema"
)

var invokees = map[schema.Class]func(Reporter, *schema.TestVector, *schema.Variant){
schema.ClassMessage: ExecuteMessageVector,
schema.ClassTipset: ExecuteTipsetVector,
}

const (
// EnvSkipConformance, if 1, skips the conformance test suite.
EnvSkipConformance = "SKIP_CONFORMANCE"
Expand Down Expand Up @@ -120,13 +125,16 @@ func TestConformance(t *testing.T) {
}

// dispatch the execution depending on the vector class.
switch vector.Class {
case "message":
ExecuteMessageVector(t, &vector)
case "tipset":
ExecuteTipsetVector(t, &vector)
default:
t.Fatalf("test vector class not supported: %s", vector.Class)
invokee, ok := invokees[vector.Class]
if !ok {
t.Fatalf("unsupported test vector class: %s", vector.Class)
}

for _, variant := range vector.Pre.Variants {
variant := variant
t.Run(variant.ID, func(t *testing.T) {
invokee(t, &vector, &variant)
})
}
})
}
Expand Down
5 changes: 2 additions & 3 deletions conformance/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ type ExecuteTipsetResult struct {
// This method returns the the receipts root, the poststate root, and the VM
// message results. The latter _include_ implicit messages, such as cron ticks
// and reward withdrawal per miner.
func (d *Driver) ExecuteTipset(bs blockstore.Blockstore, ds ds.Batching, preroot cid.Cid, parentEpoch abi.ChainEpoch, tipset *schema.Tipset) (*ExecuteTipsetResult, error) {
func (d *Driver) ExecuteTipset(bs blockstore.Blockstore, ds ds.Batching, preroot cid.Cid, parentEpoch abi.ChainEpoch, tipset *schema.Tipset, execEpoch abi.ChainEpoch) (*ExecuteTipsetResult, error) {
var (
syscalls = vm.Syscalls(ffiwrapper.ProofVerifier)
vmRand = NewFixedRand()
Expand Down Expand Up @@ -121,11 +121,10 @@ func (d *Driver) ExecuteTipset(bs blockstore.Blockstore, ds ds.Batching, preroot
messages []*types.Message
results []*vm.ApplyRet

epoch = abi.ChainEpoch(tipset.Epoch)
basefee = abi.NewTokenAmount(tipset.BaseFee.Int64())
)

postcid, receiptsroot, err := sm.ApplyBlocks(context.Background(), parentEpoch, preroot, blocks, epoch, vmRand, func(_ cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
postcid, receiptsroot, err := sm.ApplyBlocks(context.Background(), parentEpoch, preroot, blocks, execEpoch, vmRand, func(_ cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
messages = append(messages, msg)
results = append(results, ret)
return nil
Expand Down
26 changes: 14 additions & 12 deletions conformance/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ import (
)

// ExecuteMessageVector executes a message-class test vector.
func ExecuteMessageVector(r Reporter, vector *schema.TestVector) {
func ExecuteMessageVector(r Reporter, vector *schema.TestVector, variant *schema.Variant) {
var (
ctx = context.Background()
epoch = vector.Pre.Epoch
root = vector.Pre.StateTree.RootCID
ctx = context.Background()
baseEpoch = variant.Epoch
root = vector.Pre.StateTree.RootCID
)

// Load the CAR into a new temporary Blockstore.
Expand All @@ -53,16 +53,16 @@ func ExecuteMessageVector(r Reporter, vector *schema.TestVector) {
r.Fatalf("failed to deserialize message: %s", err)
}

// add an epoch if one's set.
if m.Epoch != nil {
epoch = *m.Epoch
// add the epoch offset if one is set.
if m.EpochOffset != nil {
baseEpoch += *m.EpochOffset
}

// Execute the message.
var ret *vm.ApplyRet
ret, root, err = driver.ExecuteMessage(bs, ExecuteMessageParams{
Preroot: root,
Epoch: abi.ChainEpoch(epoch),
Epoch: abi.ChainEpoch(baseEpoch),
Message: msg,
BaseFee: BaseFeeOrDefault(vector.Pre.BaseFee),
CircSupply: CircSupplyOrDefault(vector.Pre.CircSupply),
Expand All @@ -86,10 +86,10 @@ func ExecuteMessageVector(r Reporter, vector *schema.TestVector) {
}

// ExecuteTipsetVector executes a tipset-class test vector.
func ExecuteTipsetVector(r Reporter, vector *schema.TestVector) {
func ExecuteTipsetVector(r Reporter, vector *schema.TestVector, variant *schema.Variant) {
var (
ctx = context.Background()
prevEpoch = vector.Pre.Epoch
baseEpoch = abi.ChainEpoch(variant.Epoch)
root = vector.Pre.StateTree.RootCID
tmpds = ds.NewMapDatastore()
)
Expand All @@ -105,9 +105,11 @@ func ExecuteTipsetVector(r Reporter, vector *schema.TestVector) {

// Apply every tipset.
var receiptsIdx int
var prevEpoch = baseEpoch
for i, ts := range vector.ApplyTipsets {
ts := ts // capture
ret, err := driver.ExecuteTipset(bs, tmpds, root, abi.ChainEpoch(prevEpoch), &ts)
execEpoch := baseEpoch + abi.ChainEpoch(ts.EpochOffset)
ret, err := driver.ExecuteTipset(bs, tmpds, root, prevEpoch, &ts, execEpoch)
if err != nil {
r.Fatalf("failed to apply tipset %d message: %s", i, err)
}
Expand All @@ -122,7 +124,7 @@ func ExecuteTipsetVector(r Reporter, vector *schema.TestVector) {
r.Errorf("post receipts root doesn't match; expected: %s, was: %s", expected, actual)
}

prevEpoch = ts.Epoch
prevEpoch = execEpoch
root = ret.PostStateRoot
}

Expand Down
2 changes: 1 addition & 1 deletion extern/test-vectors
Submodule test-vectors updated 1328 files
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ require (
github.com/filecoin-project/specs-actors v0.9.12
github.com/filecoin-project/specs-actors/v2 v2.1.0
github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796
github.com/filecoin-project/test-vectors/schema v0.0.4
github.com/filecoin-project/test-vectors/schema v0.0.5
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
github.com/go-kit/kit v0.10.0
github.com/go-ole/go-ole v1.2.4 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,8 @@ github.com/filecoin-project/specs-actors/v2 v2.1.0 h1:ocEuGz8DG2cUWw32c/tvF8D6xT
github.com/filecoin-project/specs-actors/v2 v2.1.0/go.mod h1:E7fAX4CZkDVQvDNRCxfq+hc3nx56KcCKyuZf0hlQJ20=
github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk=
github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g=
github.com/filecoin-project/test-vectors/schema v0.0.4 h1:QTRd0gb/NP4ZOTM7Dib5U3xE1/ToGDKnYLfxkC3t/m8=
github.com/filecoin-project/test-vectors/schema v0.0.4/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E=
github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg=
github.com/filecoin-project/test-vectors/schema v0.0.5/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as=
github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ=
Expand Down