From 497bda21b28304a65ea8a43352443f0cc8845264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Sun, 16 Aug 2020 20:36:49 +0100 Subject: [PATCH] transfer builders and scripts to filecoin-project/test-vectors. (#242) --- .circleci/config.yml | 15 - tvx/builders/actors.go | 261 ------------ tvx/builders/address.go | 102 ----- tvx/builders/asserter.go | 143 ------- tvx/builders/builder.go | 198 --------- tvx/builders/gas.go | 59 --- tvx/builders/generator.go | 186 --------- tvx/builders/messages.go | 168 -------- tvx/builders/messages_sugar.go | 50 --- tvx/builders/messages_typed.go | 379 ------------------ tvx/builders/predicates.go | 76 ---- tvx/builders/serde.go | 38 -- tvx/builders/state_zero.go | 172 -------- tvx/builders/wallet.go | 105 ----- tvx/scripts/actor_creation/addresses.go | 43 -- tvx/scripts/actor_creation/main.go | 82 ---- tvx/scripts/actor_creation/on_tranfer.go | 41 -- tvx/scripts/msg_application/actor_exec.go | 49 --- tvx/scripts/msg_application/gas_cost.go | 58 --- tvx/scripts/msg_application/invalid_msgs.go | 38 -- tvx/scripts/msg_application/main.go | 98 ----- tvx/scripts/msg_application/unknown_actors.go | 37 -- tvx/scripts/multisig/main.go | 51 --- tvx/scripts/multisig/ok.go | 305 -------------- tvx/scripts/nested/main.go | 127 ------ tvx/scripts/nested/nested.go | 358 ----------------- tvx/scripts/paych/main.go | 45 --- tvx/scripts/paych/ok.go | 167 -------- tvx/scripts/transfer/basic.go | 43 -- tvx/scripts/transfer/main.go | 165 -------- tvx/scripts/transfer/self_transfer.go | 30 -- tvx/scripts/transfer/unknown.go | 52 --- 32 files changed, 3741 deletions(-) delete mode 100644 tvx/builders/actors.go delete mode 100644 tvx/builders/address.go delete mode 100644 tvx/builders/asserter.go delete mode 100644 tvx/builders/builder.go delete mode 100644 tvx/builders/gas.go delete mode 100644 tvx/builders/generator.go delete mode 100644 tvx/builders/messages.go delete mode 100644 tvx/builders/messages_sugar.go delete mode 100644 tvx/builders/messages_typed.go delete mode 100644 tvx/builders/predicates.go delete mode 100644 tvx/builders/serde.go delete mode 100644 tvx/builders/state_zero.go delete mode 100644 tvx/builders/wallet.go delete mode 100644 tvx/scripts/actor_creation/addresses.go delete mode 100644 tvx/scripts/actor_creation/main.go delete mode 100644 tvx/scripts/actor_creation/on_tranfer.go delete mode 100644 tvx/scripts/msg_application/actor_exec.go delete mode 100644 tvx/scripts/msg_application/gas_cost.go delete mode 100644 tvx/scripts/msg_application/invalid_msgs.go delete mode 100644 tvx/scripts/msg_application/main.go delete mode 100644 tvx/scripts/msg_application/unknown_actors.go delete mode 100644 tvx/scripts/multisig/main.go delete mode 100644 tvx/scripts/multisig/ok.go delete mode 100644 tvx/scripts/nested/main.go delete mode 100644 tvx/scripts/nested/nested.go delete mode 100644 tvx/scripts/paych/main.go delete mode 100644 tvx/scripts/paych/ok.go delete mode 100644 tvx/scripts/transfer/basic.go delete mode 100644 tvx/scripts/transfer/main.go delete mode 100644 tvx/scripts/transfer/self_transfer.go delete mode 100644 tvx/scripts/transfer/unknown.go diff --git a/.circleci/config.yml b/.circleci/config.yml index 17e0c1951..52efbfc59 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -52,21 +52,6 @@ jobs: - run: name: "build tvx" command: pushd tvx && go build . - - run: - name: "run messages test vector suite: msg_application" - command: pushd tvx/scripts/msg_application && go build . && ./msg_application | ../../tvx exec-lotus - - run: - name: "run messages test vector suite: nested send" - command: pushd tvx/scripts/nested && go build . && ./nested | ../../tvx exec-lotus - - run: - name: "run messages test vector suite: paych" - command: pushd tvx/scripts/paych && go build . && ./paych | ../../tvx exec-lotus - - run: - name: "run messages test vector suite: actor_creation" - command: pushd tvx/scripts/actor_creation && go build . && ./actor_creation | ../../tvx exec-lotus - - run: - name: "run messages test vector suite: transfer" - command: pushd tvx/scripts/transfer && go build . && ./transfer | ../../tvx exec-lotus soup-build-linux: executor: linux steps: diff --git a/tvx/builders/actors.go b/tvx/builders/actors.go deleted file mode 100644 index ba5ab7bdc..000000000 --- a/tvx/builders/actors.go +++ /dev/null @@ -1,261 +0,0 @@ -package builders - -import ( - "context" - "log" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/account" - "github.com/filecoin-project/specs-actors/actors/builtin/miner" - "github.com/filecoin-project/specs-actors/actors/builtin/power" - "github.com/filecoin-project/specs-actors/actors/runtime" - "github.com/filecoin-project/specs-actors/actors/util/adt" - "github.com/ipfs/go-cid" - cbg "github.com/whyrusleeping/cbor-gen" -) - -type registeredActor struct { - handle AddressHandle - initial abi.TokenAmount -} - -// Actors is an object that manages actors in the test vector. -type Actors struct { - // registered stores registered actors and their initial balances. - registered []registeredActor - - b *Builder -} - -func newActors(b *Builder) *Actors { - return &Actors{b: b} -} - -// Count returns the number of actors registered during preconditions. -func (a *Actors) Count() int { - return len(a.registered) -} - -// HandleFor gets the canonical handle for a registered address, which can -// appear at either ID or Robust position. -func (a *Actors) HandleFor(addr address.Address) AddressHandle { - for _, r := range a.registered { - if r.handle.ID == addr || r.handle.Robust == addr { - return r.handle - } - } - a.b.Assert.FailNowf("asked for handle of unknown actor", "actor: %s", addr) - return AddressHandle{} // will never reach here. -} - -// InitialBalance returns the initial balance of an actor that was registered -// during preconditions. It matches against both the ID and Robust -// addresses. It records an assertion failure if the actor is unknown. -func (a *Actors) InitialBalance(addr address.Address) abi.TokenAmount { - for _, r := range a.registered { - if r.handle.ID == addr || r.handle.Robust == addr { - return r.initial - } - } - a.b.Assert.FailNowf("asked for initial balance of unknown actor", "actor: %s", addr) - return big.Zero() // will never reach here. -} - -// Handles returns the AddressHandles for all registered actors. -func (a *Actors) Handles() []AddressHandle { - ret := make([]AddressHandle, 0, len(a.registered)) - for _, r := range a.registered { - ret = append(ret, r.handle) - } - return ret -} - -// AccountN creates many account actors of the specified kind, with the -// specified balance, and places their addresses in the supplied AddressHandles. -func (a *Actors) AccountN(typ address.Protocol, balance abi.TokenAmount, handles ...*AddressHandle) { - for _, handle := range handles { - h := a.Account(typ, balance) - *handle = h - } -} - -// Account creates a single account actor of the specified kind, with the -// specified balance, and returns its AddressHandle. -func (a *Actors) Account(typ address.Protocol, balance abi.TokenAmount) AddressHandle { - a.b.Assert.In(typ, address.SECP256K1, address.BLS) - - var addr address.Address - switch typ { - case address.SECP256K1: - addr = a.b.Wallet.NewSECP256k1Account() - case address.BLS: - addr = a.b.Wallet.NewBLSAccount() - } - - actorState := &account.State{Address: addr} - handle := a.CreateActor(builtin.AccountActorCodeID, addr, balance, actorState) - - a.registered = append(a.registered, registeredActor{handle, balance}) - return handle -} - -type MinerActorCfg struct { - SealProofType abi.RegisteredSealProof - PeriodBoundary abi.ChainEpoch - OwnerBalance abi.TokenAmount -} - -// Miner creates an owner account, a worker account, and a miner actor managed -// by those initial. -func (a *Actors) Miner(cfg MinerActorCfg) (minerActor, owner, worker AddressHandle) { - owner = a.Account(address.SECP256K1, cfg.OwnerBalance) - worker = a.Account(address.BLS, big.Zero()) - // expectedMinerActorIDAddress := chain.MustNewIDAddr(chain.MustIDFromAddress(minerWorkerID) + 1) - // minerActorAddrs := computeInitActorExecReturn(minerWorkerPk, 0, 1, expectedMinerActorIDAddress) - - ss, err := cfg.SealProofType.SectorSize() - a.b.Assert.NoError(err, "seal proof sector size") - - ps, err := cfg.SealProofType.WindowPoStPartitionSectors() - a.b.Assert.NoError(err, "seal proof window PoSt partition sectors") - - mi := &miner.MinerInfo{ - Owner: owner.ID, - Worker: worker.ID, - PendingWorkerKey: nil, - PeerId: abi.PeerID("chain-validation"), - Multiaddrs: nil, - SealProofType: cfg.SealProofType, - SectorSize: ss, - WindowPoStPartitionSectors: ps, - } - infoCid, err := a.b.Stores.CBORStore.Put(context.Background(), mi) - if err != nil { - panic(err) - } - - // create the miner actor s.t. it exists in the init actors map - minerState, err := miner.ConstructState(infoCid, - cfg.PeriodBoundary, - EmptyBitfieldCid, - EmptyArrayCid, - EmptyMapCid, - EmptyDeadlinesCid, - EmptyVestingFundsCid, - ) - if err != nil { - panic(err) - } - - minerActorAddr := worker.NextActorAddress(0, 0) - handle := a.CreateActor(builtin.StorageMinerActorCodeID, minerActorAddr, big.Zero(), minerState) - - // assert miner actor has been created, exists in the state tree, and has an entry in the init actor. - // next update the storage power actor to track the miner - - var spa power.State - a.ActorState(builtin.StoragePowerActorAddr, &spa) - - // set the miners claim - hm, err := adt.AsMap(adt.WrapStore(context.Background(), a.b.Stores.CBORStore), spa.Claims) - if err != nil { - panic(err) - } - - // add claim for the miner - err = hm.Put(adt.AddrKey(handle.ID), &power.Claim{ - RawBytePower: abi.NewStoragePower(0), - QualityAdjPower: abi.NewTokenAmount(0), - }) - if err != nil { - panic(err) - } - - // save the claim - spa.Claims, err = hm.Root() - if err != nil { - panic(err) - } - - // update miner count - spa.MinerCount += 1 - - // update storage power actor's state in the tree - _, err = a.b.Stores.CBORStore.Put(context.Background(), &spa) - if err != nil { - panic(err) - } - - a.registered = append(a.registered, registeredActor{handle, big.Zero()}) - return handle, owner, worker -} - -// CreateActor creates an actor in the state tree, of the specified kind, with -// the specified address and balance, and sets its state to the supplied state. -func (a *Actors) CreateActor(code cid.Cid, addr address.Address, balance abi.TokenAmount, state runtime.CBORMarshaler) AddressHandle { - var id address.Address - if addr.Protocol() != address.ID { - var err error - id, err = a.b.StateTree.RegisterNewAddress(addr) - if err != nil { - log.Panicf("register new address for actor: %v", err) - } - } - - // Store the new state. - head, err := a.b.StateTree.Store.Put(context.Background(), state) - if err != nil { - panic(err) - } - - // Set the actor's head to point to that state. - actr := &types.Actor{ - Code: code, - Head: head, - Balance: balance, - } - if err := a.b.StateTree.SetActor(addr, actr); err != nil { - log.Panicf("setting new actor for actor: %v", err) - } - return AddressHandle{id, addr} -} - -// ActorState retrieves the state of the supplied actor, and sets it in the -// provided object. It also returns the actor's header from the state tree. -func (a *Actors) ActorState(addr address.Address, out cbg.CBORUnmarshaler) *types.Actor { - actor := a.Header(addr) - err := a.b.StateTree.Store.Get(context.Background(), actor.Head, out) - a.b.Assert.NoError(err, "failed to load state for actorr %s; head=%s", addr, actor.Head) - return actor -} - -// Header returns the actor's header from the state tree. -func (a *Actors) Header(addr address.Address) *types.Actor { - actor, err := a.b.StateTree.GetActor(addr) - a.b.Assert.NoError(err, "failed to fetch actor %s from state", addr) - return actor -} - -// Balance is a shortcut for Header(addr).Balance. -func (a *Actors) Balance(addr address.Address) abi.TokenAmount { - return a.Header(addr).Balance -} - -// Head is a shortcut for Header(addr).Head. -func (a *Actors) Head(addr address.Address) cid.Cid { - return a.Header(addr).Head -} - -// Nonce is a shortcut for Header(addr).Nonce. -func (a *Actors) Nonce(addr address.Address) uint64 { - return a.Header(addr).Nonce -} - -// Code is a shortcut for Header(addr).Code. -func (a *Actors) Code(addr address.Address) cid.Cid { - return a.Header(addr).Code -} diff --git a/tvx/builders/address.go b/tvx/builders/address.go deleted file mode 100644 index e4deb3f2b..000000000 --- a/tvx/builders/address.go +++ /dev/null @@ -1,102 +0,0 @@ -package builders - -import ( - "bytes" - "encoding/binary" - "fmt" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/actors/aerrors" - "github.com/multiformats/go-varint" -) - -// AddressHandle encapsulates both the ID and Robust addresses of an actor. -type AddressHandle struct { - ID, Robust address.Address -} - -func (ah AddressHandle) IDAddr() address.Address { - return ah.ID -} - -func (ah AddressHandle) RobustAddr() address.Address { - return ah.Robust -} - -func (ah AddressHandle) String() string { - return fmt.Sprintf("AddressHandle[ID: %s, Robust: %s]", ah.ID, ah.Robust) -} - -// NextActorAddress predicts the address of the next actor created by this address. -// -// Code is adapted from vm.Runtime#NewActorAddress() -func (ah *AddressHandle) NextActorAddress(nonce, numActorsCreated uint64) address.Address { - var b bytes.Buffer - if err := ah.Robust.MarshalCBOR(&b); err != nil { - panic(aerrors.Fatalf("writing caller address into assert buffer: %v", err)) - } - - if err := binary.Write(&b, binary.BigEndian, nonce); err != nil { - panic(aerrors.Fatalf("writing nonce address into assert buffer: %v", err)) - } - if err := binary.Write(&b, binary.BigEndian, numActorsCreated); err != nil { - panic(aerrors.Fatalf("writing callSeqNum address into assert buffer: %v", err)) - } - addr, err := address.NewActorAddress(b.Bytes()) - if err != nil { - panic(aerrors.Fatalf("create actor address: %v", err)) - } - return addr -} - -// MustNewIDAddr returns an address.Address of kind ID. -func MustNewIDAddr(id uint64) address.Address { - addr, err := address.NewIDAddress(id) - if err != nil { - panic(err) - } - return addr -} - -// MustNewSECP256K1Addr returns an address.Address of kind secp256k1. -func MustNewSECP256K1Addr(pubkey string) address.Address { - // the pubkey of assert secp256k1 address is hashed for consistent length. - addr, err := address.NewSecp256k1Address([]byte(pubkey)) - if err != nil { - panic(err) - } - return addr -} - -// MustNewBLSAddr returns an address.Address of kind bls. -func MustNewBLSAddr(seed int64) address.Address { - buf := make([]byte, address.BlsPublicKeyBytes) - binary.PutVarint(buf, seed) - - addr, err := address.NewBLSAddress(buf) - if err != nil { - panic(err) - } - return addr -} - -// MustNewActorAddr returns an address.Address of kind actor. -func MustNewActorAddr(data string) address.Address { - addr, err := address.NewActorAddress([]byte(data)) - if err != nil { - panic(err) - } - return addr -} - -// MustIDFromAddress returns the integer ID from an ID address. -func MustIDFromAddress(a address.Address) uint64 { - if a.Protocol() != address.ID { - panic("must be ID protocol address") - } - id, _, err := varint.FromUvarint(a.Payload()) - if err != nil { - panic(err) - } - return id -} diff --git a/tvx/builders/asserter.go b/tvx/builders/asserter.go deleted file mode 100644 index d1001c6e2..000000000 --- a/tvx/builders/asserter.go +++ /dev/null @@ -1,143 +0,0 @@ -package builders - -import ( - "fmt" - "os" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/state" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/ipfs/go-cid" - "github.com/stretchr/testify/require" -) - -// Asserter offers useful assertions to verify outcomes at various stages of -// the test vector creation. -type Asserter struct { - *require.Assertions - - b *Builder - stage Stage -} - -var _ require.TestingT = &Asserter{} - -func newAsserter(b *Builder, stage Stage) *Asserter { - a := &Asserter{stage: stage, b: b} - a.Assertions = require.New(a) - return a -} - -// In is assert fluid version of require.Contains. It inverts the argument order, -// such that the admissible set can be supplied through assert variadic argument. -func (a *Asserter) In(v interface{}, set ...interface{}) { - a.Contains(set, v, "set %v does not contain element %v", set, v) -} - -// BalanceEq verifies that the balance of the address equals the expected one. -func (a *Asserter) BalanceEq(addr address.Address, expected abi.TokenAmount) { - actor, err := a.b.StateTree.GetActor(addr) - a.NoError(err, "failed to fetch actor %s from state", addr) - a.Equal(expected, actor.Balance, "balances mismatch for address %s", addr) -} - -// NonceEq verifies that the nonce of the actor equals the expected one. -func (a *Asserter) NonceEq(addr address.Address, expected uint64) { - actor, err := a.b.StateTree.GetActor(addr) - a.NoError(err, "failed to fetch actor %s from state", addr) - a.Equal(expected, actor.Nonce, "expected actor %s nonce: %d, got: %d", addr, expected, actor.Nonce) -} - -// HeadEq verifies that the head of the actor equals the expected one. -func (a *Asserter) HeadEq(addr address.Address, expected cid.Cid) { - actor, err := a.b.StateTree.GetActor(addr) - a.NoError(err, "failed to fetch actor %s from state", addr) - a.Equal(expected, actor.Head, "expected actor %s head: %v, got: %v", addr, expected, actor.Head) -} - -// ActorExists verifies that the actor exists in the state tree. -func (a *Asserter) ActorExists(addr address.Address) { - _, err := a.b.StateTree.GetActor(addr) - a.NoError(err, "expected no error while looking up actor %s", addr) -} - -// ActorExists verifies that the actor is absent from the state tree. -func (a *Asserter) ActorMissing(addr address.Address) { - _, err := a.b.StateTree.GetActor(addr) - a.Error(err, "expected error while looking up actor %s", addr) -} - -// EveryMessageResultSatisfies verifies that every message result satisfies the -// provided predicate. -func (a *Asserter) EveryMessageResultSatisfies(predicate ApplyRetPredicate, except ...*ApplicableMessage) { - exceptm := make(map[*ApplicableMessage]struct{}, len(except)) - for _, am := range except { - exceptm[am] = struct{}{} - } - for i, m := range a.b.Messages.messages { - if _, ok := exceptm[m]; ok { - continue - } - err := predicate(m.Result) - a.NoError(err, "message result predicate failed on message %d: %s", i, err) - } -} - -// EveryMessageSenderSatisfies verifies that the sender actors of the supplied -// messages match a condition. -// -// This function groups ApplicableMessages by sender actor, and calls the -// predicate for each unique sender, passing in the initial state (when -// preconditions were committed), the final state (could be nil), and the -// ApplicableMessages themselves. -func (a *Asserter) MessageSendersSatisfy(predicate ActorPredicate, ams ...*ApplicableMessage) { - bysender := make(map[AddressHandle][]*ApplicableMessage, len(ams)) - for _, am := range ams { - h := a.b.Actors.HandleFor(am.Message.From) - bysender[h] = append(bysender[h], am) - } - // we now have messages organized by unique senders. - for sender, amss := range bysender { - // get precondition state - pretree, err := state.LoadStateTree(a.b.Stores.CBORStore, a.b.PreRoot) - a.NoError(err) - prestate, err := pretree.GetActor(sender.Robust) - a.NoError(err) - - // get postcondition state; if actor has been deleted, we store a nil. - poststate, _ := a.b.StateTree.GetActor(sender.Robust) - - // invoke predicate. - err = predicate(sender, prestate, poststate, amss) - a.NoError(err, "'every sender actor' predicate failed for sender %s: %s", sender, err) - } -} - -// EveryMessageSenderSatisfies is sugar for MessageSendersSatisfy(predicate, Messages.All()), -// but supports an exclusion set to restrict the messages that will actually be asserted. -func (a *Asserter) EveryMessageSenderSatisfies(predicate ActorPredicate, except ...*ApplicableMessage) { - ams := a.b.Messages.All() - if len(except) > 0 { - filtered := ams[:0] - for _, ex := range except { - for _, am := range ams { - if am == ex { - continue - } - filtered = append(filtered, am) - } - } - ams = filtered - } - a.MessageSendersSatisfy(predicate, ams...) -} - -func (a *Asserter) FailNow() { - os.Exit(1) -} - -func (a *Asserter) Errorf(format string, args ...interface{}) { - id := a.b.vector.Meta.ID - stage := a.stage - fmt.Printf("❌ id: %s, stage: %s:"+format, append([]interface{}{id, stage}, args...)...) -} diff --git a/tvx/builders/builder.go b/tvx/builders/builder.go deleted file mode 100644 index ed5c17cc4..000000000 --- a/tvx/builders/builder.go +++ /dev/null @@ -1,198 +0,0 @@ -package builders - -import ( - "bytes" - "compress/gzip" - "context" - "encoding/json" - "io" - "log" - "os" - - "github.com/filecoin-project/lotus/chain/state" - "github.com/ipfs/go-cid" - format "github.com/ipfs/go-ipld-format" - "github.com/ipld/go-car" - - "github.com/filecoin-project/oni/tvx/lotus" - "github.com/filecoin-project/oni/tvx/schema" - ostate "github.com/filecoin-project/oni/tvx/state" -) - -type Stage string - -const ( - StagePreconditions = Stage("preconditions") - StageApplies = Stage("applies") - StageChecks = Stage("checks") - StageFinished = Stage("finished") -) - -func init() { - // disable logs, as we need a clean stdout output. - log.SetOutput(os.Stderr) - log.SetPrefix(">>> ") - - _ = os.Setenv("LOTUS_DISABLE_VM_BUF", "iknowitsabadidea") -} - -// TODO use stage.Surgeon with non-proxying blockstore. -type Builder struct { - Actors *Actors - Assert *Asserter - Messages *Messages - Driver *lotus.Driver - PreRoot cid.Cid - PostRoot cid.Cid - CurrRoot cid.Cid - Wallet *Wallet - StateTree *state.StateTree - Stores *ostate.Stores - - vector schema.TestVector - stage Stage -} - -// MessageVector creates a builder for a message-class vector. -func MessageVector(metadata *schema.Metadata) *Builder { - stores := ostate.NewLocalStores(context.Background()) - - // Create a brand new state tree. - st, err := state.NewStateTree(stores.CBORStore) - if err != nil { - panic(err) - } - - b := &Builder{ - stage: StagePreconditions, - Stores: stores, - StateTree: st, - PreRoot: cid.Undef, - Driver: lotus.NewDriver(context.Background()), - } - - b.Wallet = newWallet() - b.Assert = newAsserter(b, StagePreconditions) - b.Actors = newActors(b) - b.Messages = &Messages{b: b} - - b.vector.Class = schema.ClassMessage - b.vector.Meta = metadata - b.vector.Pre = &schema.Preconditions{} - b.vector.Post = &schema.Postconditions{} - - b.initializeZeroState() - - return b -} - -func (b *Builder) CommitPreconditions() { - if b.stage != StagePreconditions { - panic("called CommitPreconditions at the wrong time") - } - - // capture the preroot after applying all preconditions. - preroot := b.FlushState() - - b.vector.Pre.Epoch = 0 - b.vector.Pre.StateTree = &schema.StateTree{RootCID: preroot} - - b.CurrRoot, b.PreRoot = preroot, preroot - b.stage = StageApplies - b.Assert = newAsserter(b, StageApplies) -} - -func (b *Builder) CommitApplies() { - if b.stage != StageApplies { - panic("called CommitApplies at the wrong time") - } - - for _, am := range b.Messages.All() { - // apply all messages that are pending application. - if am.Result == nil { - b.applyMessage(am) - } - } - - b.PostRoot = b.CurrRoot - b.vector.Post.StateTree = &schema.StateTree{RootCID: b.CurrRoot} - b.stage = StageChecks - b.Assert = newAsserter(b, StageChecks) -} - -// applyMessage executes the provided message via the driver, records the new -// root, refreshes the state tree, and updates the underlying vector with the -// message and its receipt. -func (b *Builder) applyMessage(am *ApplicableMessage) { - var err error - am.Result, b.CurrRoot, err = b.Driver.ExecuteMessage(am.Message, b.CurrRoot, b.Stores.Blockstore, am.Epoch) - b.Assert.NoError(err) - - // replace the state tree. - b.StateTree, err = state.LoadStateTree(b.Stores.CBORStore, b.CurrRoot) - b.Assert.NoError(err) - - b.vector.ApplyMessages = append(b.vector.ApplyMessages, schema.Message{ - Bytes: MustSerialize(am.Message), - Epoch: &am.Epoch, - }) - b.vector.Post.Receipts = append(b.vector.Post.Receipts, &schema.Receipt{ - ExitCode: am.Result.ExitCode, - ReturnValue: am.Result.Return, - GasUsed: am.Result.GasUsed, - }) -} - -func (b *Builder) Finish(w io.Writer) { - if b.stage != StageChecks { - panic("called Finish at the wrong time") - } - - out := new(bytes.Buffer) - gw := gzip.NewWriter(out) - if err := b.WriteCAR(gw, b.vector.Pre.StateTree.RootCID, b.vector.Post.StateTree.RootCID); err != nil { - panic(err) - } - if err := gw.Flush(); err != nil { - panic(err) - } - if err := gw.Close(); err != nil { - panic(err) - } - - b.vector.CAR = out.Bytes() - - b.stage = StageFinished - b.Assert = nil - - encoder := json.NewEncoder(w) - if err := encoder.Encode(b.vector); err != nil { - panic(err) - } -} - -// WriteCAR recursively writes the tree referenced by the root as assert CAR into the -// supplied io.Writer. -// -// TODO use state.Surgeon instead. (This is assert copy of Surgeon#WriteCAR). -func (b *Builder) WriteCAR(w io.Writer, roots ...cid.Cid) error { - carWalkFn := func(nd format.Node) (out []*format.Link, err error) { - for _, link := range nd.Links() { - if link.Cid.Prefix().Codec == cid.FilCommitmentSealed || link.Cid.Prefix().Codec == cid.FilCommitmentUnsealed { - continue - } - out = append(out, link) - } - return out, nil - } - - return car.WriteCarWithWalker(context.Background(), b.Stores.DAGService, roots, w, carWalkFn) -} - -func (b *Builder) FlushState() cid.Cid { - preroot, err := b.StateTree.Flush(context.Background()) - if err != nil { - panic(err) - } - return preroot -} diff --git a/tvx/builders/gas.go b/tvx/builders/gas.go deleted file mode 100644 index 783e53d08..000000000 --- a/tvx/builders/gas.go +++ /dev/null @@ -1,59 +0,0 @@ -package builders - -import ( - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" - - "github.com/filecoin-project/oni/tvx/lotus" -) - -const ( - overuseNum = 11 - overuseDen = 10 -) - -// CalculateDeduction returns the balance that shall be deducted from the -// sender's account as a result of applying this message. -func CalculateDeduction(am *ApplicableMessage) big.Int { - if am.Result.GasUsed == 0 { - return big.Zero() - } - - m := am.Message - minerReward := GetMinerReward(m.GasLimit, m.GasPremium) // goes to the miner - burn := CalculateBurn(m.GasLimit, am.Result.GasUsed) // vanishes - deducted := big.Add(minerReward, burn) // sum of gas accrued - - if am.Result.ExitCode.IsSuccess() { - deducted = big.Add(deducted, m.Value) // message value - } - return deducted -} - -// GetMinerReward returns the amount that the miner gets to keep, which is -func GetMinerReward(gasLimit int64, gasPremium abi.TokenAmount) abi.TokenAmount { - return big.Mul(big.NewInt(gasLimit), gasPremium) -} - -func GetMinerPenalty(gasLimit int64) big.Int { - return big.Mul(lotus.BaseFee, big.NewInt(gasLimit)) -} - -// CalculateBurn calcualtes the amount that will be burnt, a function of the -// gas limit and the gas actually used. -func CalculateBurn(gasLimit int64, gasUsed int64) big.Int { - over := gasLimit - (overuseNum*gasUsed)/overuseDen - if over < 0 { - over = 0 - } - if over > gasUsed { - over = gasUsed - } - - overestimateGas := big.NewInt(gasLimit - gasUsed) - overestimateGas = big.Mul(overestimateGas, big.NewInt(over)) - overestimateGas = big.Div(overestimateGas, big.NewInt(gasUsed)) - - totalBurnGas := big.Add(overestimateGas, big.NewInt(gasUsed)) - return big.Mul(lotus.BaseFee, totalBurnGas) -} diff --git a/tvx/builders/generator.go b/tvx/builders/generator.go deleted file mode 100644 index 1f7c32cdd..000000000 --- a/tvx/builders/generator.go +++ /dev/null @@ -1,186 +0,0 @@ -package builders - -import ( - "bytes" - "encoding/json" - "flag" - "fmt" - "io" - "log" - "os" - "path/filepath" - "regexp" - "sync" - - "github.com/filecoin-project/oni/tvx/schema" -) - -// Generator is a batch generator and organizer of test vectors. -// -// Test vector scripts are simple programs (main function). Test vector scripts -// can delegate to the Generator to handle the execution, reporting and capture -// of emitted test vectors into files. -// -// Generator supports the following CLI flags: -// -// -o -// directory where test vector JSON files will be saved; if omitted, -// vectors will be written to stdout. -// -// -f -// regex filter to select a subset of vectors to execute; matched against -// the vector's ID. -// -// Scripts can bundle test vectors into "groups". The generator will execute -// each group in parallel, and will write each vector in a file: -// /--.json -type Generator struct { - OutputPath string - Filter *regexp.Regexp - - wg sync.WaitGroup -} - -// genData is the generation data to stamp into vectors. -// TODO in the future this should contain the commit of this tool and -// the builder api. -var genData = schema.GenerationData{ - Source: "script", - Version: "v0", -} - -type MessageVectorGenItem struct { - Metadata *schema.Metadata - Func func(*Builder) -} - -func NewGenerator() *Generator { - // Consume CLI parameters. - var ( - outputDir = flag.String("o", "", "directory where test vector JSON files will be saved; if omitted, vectors will be written to stdout") - filter = flag.String("f", "", "regex filter to select a subset of vectors to execute; matched against the vector's ID") - ) - - flag.Parse() - - ret := new(Generator) - - // If output directory is provided, we ensure it exists, or create it. - // Else, we'll output to stdout. - if dir := *outputDir; dir != "" { - err := ensureDirectory(dir) - if err != nil { - log.Fatal(err) - } - ret.OutputPath = dir - } - - // If a filter has been provided, compile it into a regex. - if *filter != "" { - exp, err := regexp.Compile(*filter) - if err != nil { - log.Fatalf("supplied regex %s is invalid: %s", *filter, err) - } - ret.Filter = exp - } - - return ret -} - -func (g *Generator) Wait() { - g.wg.Wait() -} - -func (g *Generator) MessageVectorGroup(group string, vectors ...*MessageVectorGenItem) { - g.wg.Add(1) - go func() { - defer g.wg.Done() - - var wg sync.WaitGroup - for _, item := range vectors { - if id := item.Metadata.ID; g.Filter != nil && !g.Filter.MatchString(id) { - log.Printf("skipping %s", id) - continue - } - - var w io.Writer - if g.OutputPath == "" { - w = os.Stdout - } else { - file := filepath.Join(g.OutputPath, fmt.Sprintf("%s--%s.json", group, item.Metadata.ID)) - out, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - log.Printf("failed to write to file %s: %s", file, err) - return - } - w = out - } - - wg.Add(1) - go func(item *MessageVectorGenItem) { - g.generateOne(w, item, w != os.Stdout) - wg.Done() - }(item) - } - - wg.Wait() - }() -} - -func (g *Generator) generateOne(w io.Writer, b *MessageVectorGenItem, indent bool) { - log.Printf("generating test vector: %s", b.Metadata.ID) - - // stamp with our generation data. - b.Metadata.Gen = genData - - vector := MessageVector(b.Metadata) - - // TODO: currently if an assertion fails, we call os.Exit(1), which - // aborts all ongoing vector generations. The Asserter should - // call runtime.Goexit() instead so only that goroutine is - // cancelled. The assertion error must bubble up somehow. - b.Func(vector) - - buf := new(bytes.Buffer) - vector.Finish(buf) - - final := buf - if indent { - // reparse and reindent. - final = new(bytes.Buffer) - if err := json.Indent(final, buf.Bytes(), "", "\t"); err != nil { - log.Printf("failed to indent json: %s", err) - } - } - - n, err := w.Write(final.Bytes()) - if err != nil { - log.Printf("failed to write to output: %s", err) - return - } - - log.Printf("generated test vector: %s (size: %d bytes)", b.Metadata.ID, n) -} - -// ensureDirectory checks if the provided path is a directory. If yes, it -// returns nil. If the path doesn't exist, it creates the directory and -// returns nil. If the path is not a directory, or another error occurs, an -// error is returned. -func ensureDirectory(path string) error { - switch stat, err := os.Stat(path); { - case os.IsNotExist(err): - // create directory. - log.Printf("creating directory %s", path) - err := os.MkdirAll(path, 0700) - if err != nil { - return fmt.Errorf("failed to create directory %s: %s", path, err) - } - - case err == nil && !stat.IsDir(): - return fmt.Errorf("path %s exists, but it's not a directory", path) - - case err != nil: - return fmt.Errorf("failed to stat directory %s: %w", path, err) - } - return nil -} diff --git a/tvx/builders/messages.go b/tvx/builders/messages.go deleted file mode 100644 index 58b91b4cf..000000000 --- a/tvx/builders/messages.go +++ /dev/null @@ -1,168 +0,0 @@ -package builders - -import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/chain/vm" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" -) - -// TypedCall represents a call to a known built-in actor kind. -type TypedCall func() (method abi.MethodNum, params []byte) - -// Messages accumulates the messages to be executed within the test vector. -type Messages struct { - b *Builder - defaults msgOpts - - messages []*ApplicableMessage -} - -// SetDefaults sets default options for all messages. -func (m *Messages) SetDefaults(opts ...MsgOpt) *Messages { - for _, opt := range opts { - opt(&m.defaults) - } - return m -} - -// ApplicableMessage represents a message to be applied on the test vector. -type ApplicableMessage struct { - Epoch abi.ChainEpoch - Message *types.Message - Result *vm.ApplyRet -} - -func (m *Messages) Sugar() *sugarMsg { - return &sugarMsg{m} -} - -// All returns all ApplicableMessages that have been accumulated, in the same -// order they were added. -func (m *Messages) All() []*ApplicableMessage { - cpy := make([]*ApplicableMessage, len(m.messages)) - copy(cpy, m.messages) - return cpy -} - -// Typed adds a typed call to this message accumulator. -func (m *Messages) Typed(from, to address.Address, typedm TypedCall, opts ...MsgOpt) *ApplicableMessage { - method, params := typedm() - return m.Raw(from, to, method, params, opts...) -} - -// Raw adds a raw message to this message accumulator. -func (m *Messages) Raw(from, to address.Address, method abi.MethodNum, params []byte, opts ...MsgOpt) *ApplicableMessage { - options := m.defaults - for _, opt := range opts { - opt(&options) - } - - msg := &types.Message{ - To: to, - From: from, - Nonce: options.nonce, - Value: options.value, - Method: method, - Params: params, - GasLimit: options.gasLimit, - GasFeeCap: options.gasFeeCap, - GasPremium: options.gasPremium, - } - - am := &ApplicableMessage{ - Epoch: options.epoch, - Message: msg, - } - - m.messages = append(m.messages, am) - return am -} - -// ApplyOne applies the provided message. The following constraints are checked: -// - all previous messages have been applied. -// - we know about this message (i.e. it has been added through Typed, Raw or Sugar). -func (m *Messages) ApplyOne(am *ApplicableMessage) { - var found bool - for i, other := range m.messages { - if other.Result != nil { - // message has been applied, continue. - continue - } - if am == other { - // we have scanned all preceding messages, and verified they had been applied. - // we are ready to perform the application. - found = true - break - } - // verify that preceding messages have been applied. - // this will abort if unsatisfied. - m.b.Assert.Nil(other.Result, "preceding messages must have been applied when calling Apply*; index of first unapplied: %d", i) - } - m.b.Assert.True(found, "ApplicableMessage not found") - m.b.applyMessage(am) -} - -// ApplyN calls ApplyOne for the supplied messages, in the order they are passed. -// The constraints described in ApplyOne apply. -func (m *Messages) ApplyN(ams ...*ApplicableMessage) { - for _, am := range ams { - m.ApplyOne(am) - } -} - -type msgOpts struct { - nonce uint64 - value big.Int - gasLimit int64 - gasFeeCap abi.TokenAmount - gasPremium abi.TokenAmount - epoch abi.ChainEpoch -} - -// MsgOpt is an option configuring message value, gas parameters, execution -// epoch, and other elements. -type MsgOpt func(*msgOpts) - -// Value sets a value on a message. -func Value(value big.Int) MsgOpt { - return func(opts *msgOpts) { - opts.value = value - } -} - -// Nonce sets the nonce of a message. -func Nonce(n uint64) MsgOpt { - return func(opts *msgOpts) { - opts.nonce = n - } -} - -// GasLimit sets the gas limit of a message. -func GasLimit(limit int64) MsgOpt { - return func(opts *msgOpts) { - opts.gasLimit = limit - } -} - -// GasFeeCap sets the gas fee cap of a message. -func GasFeeCap(feeCap int64) MsgOpt { - return func(opts *msgOpts) { - opts.gasFeeCap = big.NewInt(feeCap) - } -} - -// GasPremium sets the gas premium of a message. -func GasPremium(premium int64) MsgOpt { - return func(opts *msgOpts) { - opts.gasPremium = big.NewInt(premium) - } -} - -// Epoch sets the epoch in which a message is to be executed. -func Epoch(epoch abi.ChainEpoch) MsgOpt { - return func(opts *msgOpts) { - opts.epoch = epoch - } -} diff --git a/tvx/builders/messages_sugar.go b/tvx/builders/messages_sugar.go deleted file mode 100644 index bf6982db6..000000000 --- a/tvx/builders/messages_sugar.go +++ /dev/null @@ -1,50 +0,0 @@ -package builders - -import ( - "github.com/filecoin-project/go-address" - - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/builtin" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" - "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - "github.com/filecoin-project/specs-actors/actors/builtin/paych" - "github.com/filecoin-project/specs-actors/actors/builtin/power" - - "github.com/libp2p/go-libp2p-core/peer" -) - -type sugarMsg struct{ m *Messages } - -// Transfer enlists a value transfer message. -func (s *sugarMsg) Transfer(from, to address.Address, opts ...MsgOpt) *ApplicableMessage { - return s.m.Typed(from, to, Transfer(), opts...) -} - -func (s *sugarMsg) CreatePaychActor(from, to address.Address, opts ...MsgOpt) *ApplicableMessage { - ctorparams := &paych.ConstructorParams{ - From: from, - To: to, - } - return s.m.Typed(from, builtin.InitActorAddr, InitExec(&init_.ExecParams{ - CodeCID: builtin.PaymentChannelActorCodeID, - ConstructorParams: MustSerialize(ctorparams), - }), opts...) -} - -func (s *sugarMsg) CreateMultisigActor(from address.Address, params *multisig.ConstructorParams, opts ...MsgOpt) *ApplicableMessage { - return s.m.Typed(from, builtin.InitActorAddr, InitExec(&init_.ExecParams{ - CodeCID: builtin.MultisigActorCodeID, - ConstructorParams: MustSerialize(params), - }), opts...) -} - -func (s *sugarMsg) CreateMinerActor(owner, worker address.Address, sealProofType abi.RegisteredSealProof, pid peer.ID, maddrs []abi.Multiaddrs, opts ...MsgOpt) *ApplicableMessage { - params := &power.CreateMinerParams{ - Worker: worker, - Owner: owner, - SealProofType: sealProofType, - Peer: abi.PeerID(pid), - Multiaddrs: maddrs, - } - return s.m.Typed(owner, builtin.StoragePowerActorAddr, PowerCreateMiner(params), opts...) -} diff --git a/tvx/builders/messages_typed.go b/tvx/builders/messages_typed.go deleted file mode 100644 index c357ce9df..000000000 --- a/tvx/builders/messages_typed.go +++ /dev/null @@ -1,379 +0,0 @@ -package builders - -import ( - "github.com/filecoin-project/go-address" - - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" - "github.com/filecoin-project/specs-actors/actors/puppet" - "github.com/filecoin-project/specs-actors/actors/util/adt" - - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/cron" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" - "github.com/filecoin-project/specs-actors/actors/builtin/market" - "github.com/filecoin-project/specs-actors/actors/builtin/miner" - "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - "github.com/filecoin-project/specs-actors/actors/builtin/paych" - "github.com/filecoin-project/specs-actors/actors/builtin/power" - "github.com/filecoin-project/specs-actors/actors/builtin/reward" -) - -func Transfer() TypedCall { - return func() (method abi.MethodNum, params []byte) { - return builtin.MethodSend, []byte{} - } -} - -// ---------------------------------------------------------------------------- -// | ACCOUNT -// ---------------------------------------------------------------------------- - -func AccountConstructor(params *address.Address) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsAccount.Constructor, MustSerialize(params) - } -} - -func AccountPubkeyAddress(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsAccount.PubkeyAddress, MustSerialize(params) - } -} - -// ---------------------------------------------------------------------------- -// | MARKET -// ---------------------------------------------------------------------------- - -func MarketConstructor(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMarket.Constructor, MustSerialize(params) - } -} - -func MarketAddBalance(params *address.Address) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMarket.AddBalance, MustSerialize(params) - } -} -func MarketWithdrawBalance(params *market.WithdrawBalanceParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMarket.WithdrawBalance, MustSerialize(params) - } -} -func MarketPublishStorageDeals(params *market.PublishStorageDealsParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMarket.PublishStorageDeals, MustSerialize(params) - } -} -func MarketVerifyDealsForActivation(params *market.VerifyDealsForActivationParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMarket.VerifyDealsForActivation, MustSerialize(params) - } -} -func MarketActivateDeals(params *market.ActivateDealsParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMarket.ActivateDeals, MustSerialize(params) - } -} -func MarketOnMinerSectorsTerminate(params *market.OnMinerSectorsTerminateParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMarket.OnMinerSectorsTerminate, MustSerialize(params) - } -} -func MarketComputeDataCommitment(params *market.ComputeDataCommitmentParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMarket.ComputeDataCommitment, MustSerialize(params) - } -} -func MarketCronTick(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMarket.CronTick, MustSerialize(params) - } -} - -// ---------------------------------------------------------------------------- -// | MINER -// ---------------------------------------------------------------------------- - -func MinerConstructor(params *power.MinerConstructorParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.Constructor, MustSerialize(params) - } -} -func MinerControlAddresses(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.ControlAddresses, MustSerialize(params) - } -} -func MinerChangeWorkerAddress(params *miner.ChangeWorkerAddressParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.ChangeWorkerAddress, MustSerialize(params) - } -} -func MinerChangePeerID(params *miner.ChangePeerIDParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.ChangePeerID, MustSerialize(params) - } -} -func MinerSubmitWindowedPoSt(params *miner.SubmitWindowedPoStParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.SubmitWindowedPoSt, MustSerialize(params) - } -} -func MinerPreCommitSector(params *miner.SectorPreCommitInfo) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.PreCommitSector, MustSerialize(params) - } -} -func MinerProveCommitSector(params *miner.ProveCommitSectorParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.ProveCommitSector, MustSerialize(params) - } -} -func MinerExtendSectorExpiration(params *miner.ExtendSectorExpirationParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.ExtendSectorExpiration, MustSerialize(params) - } -} -func MinerTerminateSectors(params *miner.TerminateSectorsParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.TerminateSectors, MustSerialize(params) - } -} -func MinerDeclareFaults(params *miner.DeclareFaultsParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.DeclareFaults, MustSerialize(params) - } -} -func MinerDeclareFaultsRecovered(params *miner.DeclareFaultsRecoveredParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.DeclareFaultsRecovered, MustSerialize(params) - } -} -func MinerOnDeferredCronEvent(params *miner.CronEventPayload) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.OnDeferredCronEvent, MustSerialize(params) - } -} -func MinerCheckSectorProven(params *miner.CheckSectorProvenParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.CheckSectorProven, MustSerialize(params) - } -} -func MinerAddLockedFund(params *big.Int) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.AddLockedFund, MustSerialize(params) - } -} -func MinerReportConsensusFault(params *miner.ReportConsensusFaultParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.ReportConsensusFault, MustSerialize(params) - } -} -func MinerWithdrawBalance(params *miner.WithdrawBalanceParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.WithdrawBalance, MustSerialize(params) - } -} -func MinerConfirmSectorProofsValid(params *builtin.ConfirmSectorProofsParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.ConfirmSectorProofsValid, MustSerialize(params) - } -} -func MinerChangeMultiaddrs(params *miner.ChangeMultiaddrsParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMiner.ChangeMultiaddrs, MustSerialize(params) - } -} - -// ---------------------------------------------------------------------------- -// | MULTISIG -// ---------------------------------------------------------------------------- - -func MultisigConstructor(params *multisig.ConstructorParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMultisig.Constructor, MustSerialize(params) - } -} -func MultisigPropose(params *multisig.ProposeParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMultisig.Propose, MustSerialize(params) - } -} -func MultisigApprove(params *multisig.TxnIDParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMultisig.Approve, MustSerialize(params) - } -} -func MultisigCancel(params *multisig.TxnIDParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMultisig.Cancel, MustSerialize(params) - } -} -func MultisigAddSigner(params *multisig.AddSignerParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMultisig.AddSigner, MustSerialize(params) - } -} -func MultisigRemoveSigner(params *multisig.RemoveSignerParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMultisig.RemoveSigner, MustSerialize(params) - } -} -func MultisigSwapSigner(params *multisig.SwapSignerParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMultisig.SwapSigner, MustSerialize(params) - } -} -func MultisigChangeNumApprovalsThreshold(params *multisig.ChangeNumApprovalsThresholdParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsMultisig.ChangeNumApprovalsThreshold, MustSerialize(params) - } -} - -// ---------------------------------------------------------------------------- -// | POWER -// ---------------------------------------------------------------------------- - -func PowerConstructor(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPower.Constructor, MustSerialize(params) - } -} -func PowerCreateMiner(params *power.CreateMinerParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPower.CreateMiner, MustSerialize(params) - } -} -func PowerUpdateClaimedPower(params *power.UpdateClaimedPowerParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPower.UpdateClaimedPower, MustSerialize(params) - } -} -func PowerEnrollCronEvent(params *power.EnrollCronEventParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPower.EnrollCronEvent, MustSerialize(params) - } -} -func PowerOnEpochTickEnd(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPower.OnEpochTickEnd, MustSerialize(params) - } -} -func PowerUpdatePledgeTotal(params *big.Int) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPower.UpdatePledgeTotal, MustSerialize(params) - } -} -func PowerOnConsensusFault(params *big.Int) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPower.OnConsensusFault, MustSerialize(params) - } -} -func PowerSubmitPoRepForBulkVerify(params *abi.SealVerifyInfo) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPower.SubmitPoRepForBulkVerify, MustSerialize(params) - } -} -func PowerCurrentTotalPower(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPower.CurrentTotalPower, MustSerialize(params) - } -} - -// ---------------------------------------------------------------------------- -// | REWARD -// ---------------------------------------------------------------------------- - -func RewardConstructor(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsReward.Constructor, MustSerialize(params) - } -} -func RewardAwardBlockReward(params *reward.AwardBlockRewardParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsReward.AwardBlockReward, MustSerialize(params) - } -} -func RewardThisEpochReward(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsReward.ThisEpochReward, MustSerialize(params) - } -} -func RewardUpdateNetworkKPI(params *big.Int) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsReward.UpdateNetworkKPI, MustSerialize(params) - } -} - -// ---------------------------------------------------------------------------- -// | PAYCH -// ---------------------------------------------------------------------------- - -func PaychConstructor(params *paych.ConstructorParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPaych.Constructor, MustSerialize(params) - } -} -func PaychUpdateChannelState(params *paych.UpdateChannelStateParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPaych.UpdateChannelState, MustSerialize(params) - } -} -func PaychSettle(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPaych.Settle, MustSerialize(params) - } -} -func PaychCollect(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsPaych.Collect, MustSerialize(params) - } -} - -// ---------------------------------------------------------------------------- -// | CRON -// ---------------------------------------------------------------------------- - -func CronConstructor(params *cron.ConstructorParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsCron.Constructor, MustSerialize(params) - } -} -func CronEpochTick(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsCron.EpochTick, MustSerialize(params) - } -} - -// ---------------------------------------------------------------------------- -// | INIT -// ---------------------------------------------------------------------------- - -func InitConstructor(params *init_.ConstructorParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsInit.Constructor, MustSerialize(params) - } -} -func InitExec(params *init_.ExecParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return builtin.MethodsInit.Exec, MustSerialize(params) - } -} - -// ---------------------------------------------------------------------------- -// | PUPPET -// ---------------------------------------------------------------------------- - -func PuppetConstructor(params *adt.EmptyValue) TypedCall { - return func() (abi.MethodNum, []byte) { - return puppet.MethodsPuppet.Constructor, MustSerialize(params) - } -} - -func PuppetSend(params *puppet.SendParams) TypedCall { - return func() (abi.MethodNum, []byte) { - return puppet.MethodsPuppet.Send, MustSerialize(params) - } -} diff --git a/tvx/builders/predicates.go b/tvx/builders/predicates.go deleted file mode 100644 index 6e04636ff..000000000 --- a/tvx/builders/predicates.go +++ /dev/null @@ -1,76 +0,0 @@ -package builders - -import ( - "fmt" - - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/chain/vm" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" -) - -// ApplyRetPredicate evaluates a given condition against the result of a -// message application. -type ApplyRetPredicate func(ret *vm.ApplyRet) error - -// OptionalActor is a marker type to warn that the value can be nil. -type OptionalActor = types.Actor - -// ActorPredicate evaluates whether the actor that participates in the provided -// messages satisfies a given condition. The initial state (after preconditions) -// and final state (after applies) are supplied. -type ActorPredicate func(handle AddressHandle, initial *OptionalActor, final *OptionalActor, amss []*ApplicableMessage) error - -// ExitCode returns an ApplyRetPredicate that passes if the exit code of the -// message execution matches the argument. -func ExitCode(expect exitcode.ExitCode) ApplyRetPredicate { - return func(ret *vm.ApplyRet) error { - if ret.ExitCode == expect { - return nil - } - return fmt.Errorf("message exit code was %d; expected %d", ret.ExitCode, expect) - } -} - -// BalanceUpdated returns a ActorPredicate that checks whether the balance -// of the actor has been deducted the gas cost and the outgoing value transfers, -// and has been increased by the offset (or decreased, if the argument is negative). -func BalanceUpdated(offset abi.TokenAmount) ActorPredicate { - return func(handle AddressHandle, initial *types.Actor, final *OptionalActor, amss []*ApplicableMessage) error { - if initial == nil || final == nil { - return fmt.Errorf("BalanceUpdated predicate expected non-nil state") - } - - // accumulate all balance deductions: ∑(burnt + premium + transferred value) - deducted := big.Zero() - for _, am := range amss { - d := CalculateDeduction(am) - deducted = big.Add(deducted, d) - } - - expected := big.Sub(initial.Balance, deducted) - expected = big.Add(expected, offset) - if !final.Balance.Equals(expected) { - return fmt.Errorf("expected balance %s, was: %s", expected, final.Balance) - } - return nil - } -} - -// NonceUpdated returns a ActorPredicate that checks whether the nonce -// of the actor has been updated to the nonce of the last message + 1. -func NonceUpdated() ActorPredicate { - return func(handle AddressHandle, initial *types.Actor, final *OptionalActor, amss []*ApplicableMessage) error { - if initial == nil || final == nil { - return fmt.Errorf("BalanceUpdated predicate expected non-nil state") - } - - // the nonce should be equal to the nonce of the last message + 1. - last := amss[len(amss)-1] - if expected, actual := last.Message.Nonce+1, final.Nonce; expected != actual { - return fmt.Errorf("for actor: %s: expected nonce %d, got %d", handle, expected, actual) - } - return nil - } -} diff --git a/tvx/builders/serde.go b/tvx/builders/serde.go deleted file mode 100644 index e520f880d..000000000 --- a/tvx/builders/serde.go +++ /dev/null @@ -1,38 +0,0 @@ -package builders - -import ( - "bytes" - "fmt" - - cbg "github.com/whyrusleeping/cbor-gen" -) - -func MustSerialize(i cbg.CBORMarshaler) []byte { - out, err := Serialize(i) - if err != nil { - panic(err) - } - return out -} - -func Serialize(i cbg.CBORMarshaler) ([]byte, error) { - buf := new(bytes.Buffer) - if err := i.MarshalCBOR(buf); err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -func MustDeserialize(b []byte, out interface{}) { - if err := Deserialize(b, out); err != nil { - panic(err) - } -} - -func Deserialize(b []byte, out interface{}) error { - um, ok := out.(cbg.CBORUnmarshaler) - if !ok { - return fmt.Errorf("type %T does not implement UnmarshalCBOR", out) - } - return um.UnmarshalCBOR(bytes.NewReader(b)) -} diff --git a/tvx/builders/state_zero.go b/tvx/builders/state_zero.go deleted file mode 100644 index 13fa34a27..000000000 --- a/tvx/builders/state_zero.go +++ /dev/null @@ -1,172 +0,0 @@ -package builders - -import ( - "context" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-bitfield" - abi_spec "github.com/filecoin-project/specs-actors/actors/abi" - big_spec "github.com/filecoin-project/specs-actors/actors/abi/big" - builtin_spec "github.com/filecoin-project/specs-actors/actors/builtin" - account_spec "github.com/filecoin-project/specs-actors/actors/builtin/account" - cron_spec "github.com/filecoin-project/specs-actors/actors/builtin/cron" - init_spec "github.com/filecoin-project/specs-actors/actors/builtin/init" - market_spec "github.com/filecoin-project/specs-actors/actors/builtin/market" - "github.com/filecoin-project/specs-actors/actors/builtin/miner" - power_spec "github.com/filecoin-project/specs-actors/actors/builtin/power" - reward_spec "github.com/filecoin-project/specs-actors/actors/builtin/reward" - "github.com/filecoin-project/specs-actors/actors/builtin/system" - runtime_spec "github.com/filecoin-project/specs-actors/actors/runtime" - adt_spec "github.com/filecoin-project/specs-actors/actors/util/adt" - "github.com/ipfs/go-cid" -) - -const ( - totalFilecoin = 2_000_000_000 - filecoinPrecision = 1_000_000_000_000_000_000 -) - -var ( - TotalNetworkBalance = big_spec.Mul(big_spec.NewInt(totalFilecoin), big_spec.NewInt(filecoinPrecision)) - EmptyReturnValue = []byte{} -) - -var ( - // initialized by calling initializeStoreWithAdtRoots - EmptyArrayCid cid.Cid - EmptyDeadlinesCid cid.Cid - EmptyMapCid cid.Cid - EmptyMultiMapCid cid.Cid - EmptyBitfieldCid cid.Cid - EmptyVestingFundsCid cid.Cid -) - -const ( - TestSealProofType = abi_spec.RegisteredSealProof_StackedDrg2KiBV1 -) - -func (b *Builder) initializeZeroState() { - if err := insertEmptyStructures(b.Stores.ADTStore); err != nil { - panic(err) - } - - type ActorState struct { - Addr address.Address - Balance abi_spec.TokenAmount - Code cid.Cid - State runtime_spec.CBORMarshaler - } - - var actors []ActorState - - actors = append(actors, ActorState{ - Addr: builtin_spec.InitActorAddr, - Balance: big_spec.Zero(), - Code: builtin_spec.InitActorCodeID, - State: init_spec.ConstructState(EmptyMapCid, "chain-validation"), - }) - - zeroRewardState := reward_spec.ConstructState(big_spec.Zero()) - zeroRewardState.ThisEpochReward = big_spec.NewInt(1e17) - - actors = append(actors, ActorState{ - Addr: builtin_spec.RewardActorAddr, - Balance: TotalNetworkBalance, - Code: builtin_spec.RewardActorCodeID, - State: zeroRewardState, - }) - - actors = append(actors, ActorState{ - Addr: builtin_spec.BurntFundsActorAddr, - Balance: big_spec.Zero(), - Code: builtin_spec.AccountActorCodeID, - State: &account_spec.State{Address: builtin_spec.BurntFundsActorAddr}, - }) - - actors = append(actors, ActorState{ - Addr: builtin_spec.StoragePowerActorAddr, - Balance: big_spec.Zero(), - Code: builtin_spec.StoragePowerActorCodeID, - State: power_spec.ConstructState(EmptyMapCid, EmptyMultiMapCid), - }) - - actors = append(actors, ActorState{ - Addr: builtin_spec.StorageMarketActorAddr, - Balance: big_spec.Zero(), - Code: builtin_spec.StorageMarketActorCodeID, - State: &market_spec.State{ - Proposals: EmptyArrayCid, - States: EmptyArrayCid, - PendingProposals: EmptyMapCid, - EscrowTable: EmptyMapCid, - LockedTable: EmptyMapCid, - NextID: abi_spec.DealID(0), - DealOpsByEpoch: EmptyMultiMapCid, - LastCron: 0, - }, - }) - - actors = append(actors, ActorState{ - Addr: builtin_spec.SystemActorAddr, - Balance: big_spec.Zero(), - Code: builtin_spec.SystemActorCodeID, - State: &system.State{}, - }) - - actors = append(actors, ActorState{ - Addr: builtin_spec.CronActorAddr, - Balance: big_spec.Zero(), - Code: builtin_spec.CronActorCodeID, - State: &cron_spec.State{Entries: []cron_spec.Entry{ - { - Receiver: builtin_spec.StoragePowerActorAddr, - MethodNum: builtin_spec.MethodsPower.OnEpochTickEnd, - }, - }}, - }) - - for _, act := range actors { - _ = b.Actors.CreateActor(act.Code, act.Addr, act.Balance, act.State) - } -} - -func insertEmptyStructures(store adt_spec.Store) error { - var err error - _, err = store.Put(context.TODO(), []struct{}{}) - if err != nil { - return err - } - - EmptyArrayCid, err = adt_spec.MakeEmptyArray(store).Root() - if err != nil { - return err - } - - EmptyMapCid, err = adt_spec.MakeEmptyMap(store).Root() - if err != nil { - return err - } - - EmptyMultiMapCid, err = adt_spec.MakeEmptyMultimap(store).Root() - if err != nil { - return err - } - - EmptyDeadlinesCid, err = store.Put(context.TODO(), miner.ConstructDeadline(EmptyArrayCid)) - if err != nil { - return err - } - - emptyBitfield := bitfield.NewFromSet(nil) - EmptyBitfieldCid, err = store.Put(context.TODO(), emptyBitfield) - if err != nil { - return err - } - - EmptyVestingFundsCid, err = store.Put(context.Background(), miner.ConstructVestingFunds()) - if err != nil { - return err - } - - return nil -} diff --git a/tvx/builders/wallet.go b/tvx/builders/wallet.go deleted file mode 100644 index 30fbd9907..000000000 --- a/tvx/builders/wallet.go +++ /dev/null @@ -1,105 +0,0 @@ -package builders - -import ( - "fmt" - "math/rand" - - "github.com/minio/blake2b-simd" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-crypto" - acrypto "github.com/filecoin-project/specs-actors/actors/crypto" - - "github.com/filecoin-project/lotus/chain/wallet" - - "github.com/filecoin-project/lotus/chain/types" -) - -type Wallet struct { - // Private keys by address - keys map[address.Address]*wallet.Key - - // Seed for deterministic secp key generation. - secpSeed int64 - // Seed for deterministic bls key generation. - blsSeed int64 // nolint: structcheck -} - -func newWallet() *Wallet { - return &Wallet{ - keys: make(map[address.Address]*wallet.Key), - secpSeed: 0, - } -} - -func (w *Wallet) NewSECP256k1Account() address.Address { - secpKey := w.newSecp256k1Key() - w.keys[secpKey.Address] = secpKey - return secpKey.Address -} - -func (w *Wallet) NewBLSAccount() address.Address { - blsKey := w.newBLSKey() - w.keys[blsKey.Address] = blsKey - return blsKey.Address -} - -func (w *Wallet) Sign(addr address.Address, data []byte) (acrypto.Signature, error) { - ki, ok := w.keys[addr] - if !ok { - return acrypto.Signature{}, fmt.Errorf("unknown address %v", addr) - } - var sigType acrypto.SigType - if ki.Type == wallet.KTSecp256k1 { - sigType = acrypto.SigTypeBLS - hashed := blake2b.Sum256(data) - sig, err := crypto.Sign(ki.PrivateKey, hashed[:]) - if err != nil { - return acrypto.Signature{}, err - } - - return acrypto.Signature{ - Type: sigType, - Data: sig, - }, nil - } else if ki.Type == wallet.KTBLS { - panic("lotus validator cannot sign BLS messages") - } else { - panic("unknown signature type") - } - -} - -func (w *Wallet) newSecp256k1Key() *wallet.Key { - randSrc := rand.New(rand.NewSource(w.secpSeed)) - prv, err := crypto.GenerateKeyFromSeed(randSrc) - if err != nil { - panic(err) - } - w.secpSeed++ - key, err := wallet.NewKey(types.KeyInfo{ - Type: wallet.KTSecp256k1, - PrivateKey: prv, - }) - if err != nil { - panic(err) - } - return key -} - -func (w *Wallet) newBLSKey() *wallet.Key { - // FIXME: bls needs deterministic key generation - //sk := ffi.PrivateKeyGenerate(s.blsSeed) - // s.blsSeed++ - sk := [32]byte{} - sk[0] = uint8(w.blsSeed) // hack to keep gas values determinist - w.blsSeed++ - key, err := wallet.NewKey(types.KeyInfo{ - Type: wallet.KTBLS, - PrivateKey: sk[:], - }) - if err != nil { - panic(err) - } - return key -} diff --git a/tvx/scripts/actor_creation/addresses.go b/tvx/scripts/actor_creation/addresses.go deleted file mode 100644 index 307d62321..000000000 --- a/tvx/scripts/actor_creation/addresses.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - . "github.com/filecoin-project/oni/tvx/builders" - - "github.com/filecoin-project/specs-actors/actors/abi/big" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" - - "github.com/filecoin-project/go-address" -) - -func sequentialAddresses(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - initial := big.NewInt(1_000_000_000_000_000) - - // Set up sender and receiver accounts. - var sender, receiver AddressHandle - v.Actors.AccountN(address.SECP256K1, initial, &sender, &receiver) - v.CommitPreconditions() - - // Create 10 payment channels. - for i := uint64(0); i < 10; i++ { - v.Messages.Sugar().CreatePaychActor(sender.Robust, receiver.Robust, Value(big.NewInt(1000)), Nonce(i)) - } - v.CommitApplies() - - for i, am := range v.Messages.All() { - expectedActorAddr := AddressHandle{ - ID: MustNewIDAddr(MustIDFromAddress(receiver.ID) + uint64(i) + 1), - Robust: sender.NextActorAddress(am.Message.Nonce, 0), - } - - // Verify that the return contains the expected addresses. - var ret init_.ExecReturn - MustDeserialize(am.Result.Return, &ret) - v.Assert.Equal(expectedActorAddr.Robust, ret.RobustAddress) - v.Assert.Equal(expectedActorAddr.ID, ret.IDAddress) - } - - v.Assert.EveryMessageSenderSatisfies(BalanceUpdated(big.Zero())) - v.Assert.EveryMessageSenderSatisfies(NonceUpdated()) -} diff --git a/tvx/scripts/actor_creation/main.go b/tvx/scripts/actor_creation/main.go deleted file mode 100644 index 460388316..000000000 --- a/tvx/scripts/actor_creation/main.go +++ /dev/null @@ -1,82 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - - . "github.com/filecoin-project/oni/tvx/builders" - "github.com/filecoin-project/oni/tvx/schema" -) - -func main() { - g := NewGenerator() - - g.MessageVectorGroup("addresses", - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "sequential-10", - Version: "v1", - Desc: "actor addresses are sequential", - }, - Func: sequentialAddresses, - }, - ) - - g.MessageVectorGroup("on_transfer", - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok-create-secp256k1", - Version: "v1", - }, - Func: actorCreationOnTransfer(actorCreationOnTransferParams{ - senderType: address.SECP256K1, - senderBal: abi.NewTokenAmount(1_000_000_000_000_000), - receiverAddr: MustNewSECP256K1Addr("publickeyfoo"), - amount: abi.NewTokenAmount(10_000), - exitCode: exitcode.Ok, - }), - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok-create-bls", - Version: "v1", - }, - Func: actorCreationOnTransfer(actorCreationOnTransferParams{ - senderType: address.SECP256K1, - senderBal: abi.NewTokenAmount(1_000_000_000_000_000), - receiverAddr: MustNewBLSAddr(1), - amount: abi.NewTokenAmount(10_000), - exitCode: exitcode.Ok, - }), - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-secp256k1-insufficient-balance", - Version: "v1", - }, - Func: actorCreationOnTransfer(actorCreationOnTransferParams{ - senderType: address.SECP256K1, - senderBal: abi.NewTokenAmount(9_999), - receiverAddr: MustNewSECP256K1Addr("publickeyfoo"), - amount: abi.NewTokenAmount(10_000), - exitCode: exitcode.SysErrSenderStateInvalid, - }), - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-bls-insufficient-balance", - Version: "v1", - }, - Func: actorCreationOnTransfer(actorCreationOnTransferParams{ - senderType: address.SECP256K1, - senderBal: abi.NewTokenAmount(9_999), - receiverAddr: MustNewBLSAddr(1), - amount: abi.NewTokenAmount(10_000), - exitCode: exitcode.SysErrSenderStateInvalid, - }), - }, - ) - - g.Wait() -} diff --git a/tvx/scripts/actor_creation/on_tranfer.go b/tvx/scripts/actor_creation/on_tranfer.go deleted file mode 100644 index ec9a1e90b..000000000 --- a/tvx/scripts/actor_creation/on_tranfer.go +++ /dev/null @@ -1,41 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/abi/big" - - . "github.com/filecoin-project/oni/tvx/builders" -) - -type actorCreationOnTransferParams struct { - senderType address.Protocol - senderBal abi.TokenAmount - receiverAddr address.Address - amount abi.TokenAmount - exitCode exitcode.ExitCode -} - -func actorCreationOnTransfer(params actorCreationOnTransferParams) func(v *Builder) { - return func(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - // Set up sender account. - sender := v.Actors.Account(params.senderType, params.senderBal) - v.CommitPreconditions() - - // Perform the transfer. - v.Messages.Sugar().Transfer(sender.ID, params.receiverAddr, Value(params.amount), Nonce(0)) - v.CommitApplies() - - v.Assert.EveryMessageResultSatisfies(ExitCode(params.exitCode)) - v.Assert.EveryMessageSenderSatisfies(BalanceUpdated(big.Zero())) - - if params.exitCode.IsSuccess() { - v.Assert.EveryMessageSenderSatisfies(NonceUpdated()) - v.Assert.BalanceEq(params.receiverAddr, params.amount) - } - } -} diff --git a/tvx/scripts/msg_application/actor_exec.go b/tvx/scripts/msg_application/actor_exec.go deleted file mode 100644 index 3ffecae55..000000000 --- a/tvx/scripts/msg_application/actor_exec.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" - "github.com/filecoin-project/specs-actors/actors/builtin/paych" - "github.com/filecoin-project/specs-actors/actors/crypto" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - - . "github.com/filecoin-project/oni/tvx/builders" -) - -func failActorExecutionAborted(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - // Set up sender and receiver accounts. - var sender, receiver AddressHandle - var paychAddr AddressHandle - - v.Actors.AccountN(address.SECP256K1, balance1T, &sender, &receiver) - paychAddr = AddressHandle{ - ID: MustNewIDAddr(MustIDFromAddress(receiver.ID) + 1), - Robust: sender.NextActorAddress(0, 0), - } - v.CommitPreconditions() - - // Construct the payment channel. - createMsg := v.Messages.Sugar().CreatePaychActor(sender.Robust, receiver.Robust, Value(abi.NewTokenAmount(10_000))) - - // Update the payment channel. - updateMsg := v.Messages.Typed(sender.Robust, paychAddr.Robust, PaychUpdateChannelState(&paych.UpdateChannelStateParams{ - Sv: paych.SignedVoucher{ - ChannelAddr: paychAddr.Robust, - TimeLockMin: abi.ChainEpoch(10), - Lane: 123, - Nonce: 1, - Amount: big.NewInt(10), - Signature: &crypto.Signature{ - Type: crypto.SigTypeBLS, - Data: []byte("Grrr im an invalid signature, I cause panics in the payment channel actor"), - }, - }}), Nonce(1), Value(big.Zero())) - - v.CommitApplies() - - v.Assert.Equal(exitcode.Ok, createMsg.Result.ExitCode) - v.Assert.Equal(exitcode.ErrIllegalArgument, updateMsg.Result.ExitCode) -} diff --git a/tvx/scripts/msg_application/gas_cost.go b/tvx/scripts/msg_application/gas_cost.go deleted file mode 100644 index 281405b16..000000000 --- a/tvx/scripts/msg_application/gas_cost.go +++ /dev/null @@ -1,58 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - - . "github.com/filecoin-project/oni/tvx/builders" -) - -func failCoverReceiptGasCost(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - alice := v.Actors.Account(address.SECP256K1, balance1T) - v.CommitPreconditions() - - v.Messages.Sugar().Transfer(alice.ID, alice.ID, Value(transferAmnt), Nonce(0), GasPremium(1), GasLimit(8)) - v.CommitApplies() - - v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.SysErrOutOfGas)) -} - -func failCoverOnChainSizeGasCost(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - alice := v.Actors.Account(address.SECP256K1, balance1T) - v.CommitPreconditions() - - v.Messages.Sugar().Transfer(alice.ID, alice.ID, Value(transferAmnt), Nonce(0), GasPremium(10), GasLimit(1)) - v.CommitApplies() - - v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.SysErrOutOfGas)) -} - -func failCoverTransferAccountCreationGasStepwise(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - var alice, bob, charlie AddressHandle - alice = v.Actors.Account(address.SECP256K1, balance1T) - bob.Robust, charlie.Robust = MustNewSECP256K1Addr("1"), MustNewSECP256K1Addr("2") - v.CommitPreconditions() - - var nonce uint64 - ref := v.Messages.Sugar().Transfer(alice.Robust, bob.Robust, Value(transferAmnt), Nonce(nonce)) - nonce++ - v.Messages.ApplyOne(ref) - v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.Ok)) - - // decrease the gas cost by `gasStep` for each apply and ensure `SysErrOutOfGas` is always returned. - trueGas := ref.Result.GasUsed - gasStep := trueGas / 100 - for tryGas := trueGas - gasStep; tryGas > 0; tryGas -= gasStep { - v.Messages.Sugar().Transfer(alice.Robust, charlie.Robust, Value(transferAmnt), Nonce(nonce), GasPremium(1), GasLimit(tryGas)) - nonce++ - } - v.CommitApplies() - - v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.SysErrOutOfGas), ref) -} diff --git a/tvx/scripts/msg_application/invalid_msgs.go b/tvx/scripts/msg_application/invalid_msgs.go deleted file mode 100644 index 7c23f8135..000000000 --- a/tvx/scripts/msg_application/invalid_msgs.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/abi/big" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - - . "github.com/filecoin-project/oni/tvx/builders" -) - -func failInvalidActorNonce(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - alice := v.Actors.Account(address.SECP256K1, balance1T) - v.CommitPreconditions() - - // invalid nonce from known account. - msg1 := v.Messages.Sugar().Transfer(alice.ID, alice.ID, Value(transferAmnt), Nonce(1)) - - // invalid nonce from an unknown account. - msg2 := v.Messages.Sugar().Transfer(unknown, alice.ID, Value(transferAmnt), Nonce(1)) - v.CommitApplies() - - v.Assert.Equal(msg1.Result.ExitCode, exitcode.SysErrSenderStateInvalid) - v.Assert.Equal(msg2.Result.ExitCode, exitcode.SysErrSenderInvalid) -} - -func failInvalidReceiverMethod(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - alice := v.Actors.Account(address.SECP256K1, balance1T) - v.CommitPreconditions() - - v.Messages.Typed(alice.ID, alice.ID, MarketComputeDataCommitment(nil), Nonce(0), Value(big.Zero())) - v.CommitApplies() - - v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.SysErrInvalidMethod)) -} diff --git a/tvx/scripts/msg_application/main.go b/tvx/scripts/msg_application/main.go deleted file mode 100644 index 359262e76..000000000 --- a/tvx/scripts/msg_application/main.go +++ /dev/null @@ -1,98 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/specs-actors/actors/abi" - - . "github.com/filecoin-project/oni/tvx/builders" - "github.com/filecoin-project/oni/tvx/schema" -) - -var ( - unknown = MustNewIDAddr(10000000) - balance1T = abi.NewTokenAmount(1_000_000_000_000) - transferAmnt = abi.NewTokenAmount(10) -) - -func main() { - g := NewGenerator() - - g.MessageVectorGroup("gas_cost", - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "msg-apply-fail-receipt-gas", - Version: "v1", - Desc: "fail to cover gas cost for message receipt on chain", - }, - Func: failCoverReceiptGasCost, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "msg-apply-fail-onchainsize-gas", - Version: "v1", - Desc: "not enough gas to pay message on-chain-size cost", - }, - Func: failCoverOnChainSizeGasCost, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "msg-apply-fail-transfer-accountcreation-gas", - Version: "v1", - Desc: "fail not enough gas to cover account actor creation on transfer", - }, - Func: failCoverTransferAccountCreationGasStepwise, - }) - - g.MessageVectorGroup("invalid_msgs", - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "msg-apply-fail-invalid-nonce", - Version: "v1", - Desc: "invalid actor nonce", - }, - Func: failInvalidActorNonce, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "msg-apply-fail-invalid-receiver-method", - Version: "v1", - Desc: "invalid receiver method", - }, - Func: failInvalidReceiverMethod, - }, - ) - - g.MessageVectorGroup("unknown_actors", - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "msg-apply-fail-unknown-sender", - Version: "v1", - Desc: "fail due to lack of gas when sender is unknown", - }, - Func: failUnknownSender, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "msg-apply-fail-unknown-receiver", - Version: "v1", - Desc: "inexistent receiver", - Comment: `Note that this test is not a valid message, since it is using -an unknown actor. However in the event that an invalid message isn't filtered by -block validation we need to ensure behaviour is consistent across VM implementations.`, - }, - Func: failUnknownReceiver, - }, - ) - - g.MessageVectorGroup("actor_exec", - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "msg-apply-fail-actor-execution-illegal-arg", - Version: "v1", - Desc: "abort during actor execution due to illegal argument", - }, - Func: failActorExecutionAborted, - }, - ) - - g.Wait() -} diff --git a/tvx/scripts/msg_application/unknown_actors.go b/tvx/scripts/msg_application/unknown_actors.go deleted file mode 100644 index 347ca2d55..000000000 --- a/tvx/scripts/msg_application/unknown_actors.go +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - - . "github.com/filecoin-project/oni/tvx/builders" -) - -func failUnknownSender(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - alice := v.Actors.Account(address.SECP256K1, balance1T) - v.CommitPreconditions() - - v.Messages.Sugar().Transfer(unknown, alice.ID, Value(transferAmnt), Nonce(0)) - v.CommitApplies() - - v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.SysErrSenderInvalid)) -} - -func failUnknownReceiver(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - alice := v.Actors.Account(address.SECP256K1, balance1T) - v.CommitPreconditions() - - // Sending a message to non-existent ID address must produce an error. - unknownID := MustNewIDAddr(10000000) - v.Messages.Sugar().Transfer(alice.ID, unknownID, Value(transferAmnt), Nonce(0)) - - unknownActor := MustNewActorAddr("1234") - v.Messages.Sugar().Transfer(alice.ID, unknownActor, Value(transferAmnt), Nonce(1)) - v.CommitApplies() - - v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.SysErrInvalidReceiver)) -} diff --git a/tvx/scripts/multisig/main.go b/tvx/scripts/multisig/main.go deleted file mode 100644 index f8885c832..000000000 --- a/tvx/scripts/multisig/main.go +++ /dev/null @@ -1,51 +0,0 @@ -package main - -import ( - . "github.com/filecoin-project/oni/tvx/builders" - "github.com/filecoin-project/oni/tvx/schema" -) - -const ( - gasLimit = 1_000_000_000 - gasFeeCap = 200 -) - -func main() { - g := NewGenerator() - defer g.Wait() - - g.MessageVectorGroup("basic", - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok-create", - Version: "v1", - Desc: "multisig actor constructor ok", - }, - Func: constructor, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok-propose-and-cancel", - Version: "v1", - Desc: "multisig actor propose and cancel ok", - }, - Func: proposeAndCancelOk, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok-propose-and-approve", - Version: "v1", - Desc: "multisig actor propose, unauthorized proposals+approval, and approval ok", - }, - Func: proposeAndApprove, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok-add-signer", - Version: "v1", - Desc: "multisig actor accepts only AddSigner messages that go through a reflexive flow", - }, - Func: addSigner, - }, - ) -} diff --git a/tvx/scripts/multisig/ok.go b/tvx/scripts/multisig/ok.go deleted file mode 100644 index d76bce8eb..000000000 --- a/tvx/scripts/multisig/ok.go +++ /dev/null @@ -1,305 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" - "github.com/filecoin-project/specs-actors/actors/builtin" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" - "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - "github.com/filecoin-project/specs-actors/actors/util/adt" - - "github.com/filecoin-project/go-address" - "github.com/minio/blake2b-simd" - - . "github.com/filecoin-project/oni/tvx/builders" -) - -func constructor(v *Builder) { - var balance = abi.NewTokenAmount(1_000_000_000_000) - var amount = abi.NewTokenAmount(10) - - v.Messages.SetDefaults(GasLimit(gasLimit), GasPremium(1), GasFeeCap(gasFeeCap)) - - // Set up one account. - alice := v.Actors.Account(address.SECP256K1, balance) - v.CommitPreconditions() - - createMultisig(v, alice, []address.Address{alice.ID}, 1, Value(amount), Nonce(0)) - v.CommitApplies() -} - -func proposeAndCancelOk(v *Builder) { - var ( - initial = abi.NewTokenAmount(1_000_000_000_000) - amount = abi.NewTokenAmount(10) - unlockDuration = abi.ChainEpoch(10) - ) - - v.Messages.SetDefaults(Value(big.Zero()), Epoch(1), GasLimit(gasLimit), GasPremium(1), GasFeeCap(gasFeeCap)) - - // Set up three accounts: alice and bob (signers), and charlie (outsider). - var alice, bob, charlie AddressHandle - v.Actors.AccountN(address.SECP256K1, initial, &alice, &bob, &charlie) - v.CommitPreconditions() - - // create the multisig actor; created by alice. - multisigAddr := createMultisig(v, alice, []address.Address{alice.ID, bob.ID}, 2, Value(amount), Nonce(0)) - - // alice proposes that charlie should receive 'amount' FIL. - hash := proposeOk(v, proposeOpts{ - multisigAddr: multisigAddr, - sender: alice.ID, - recipient: charlie.ID, - amount: amount, - }, Nonce(1)) - - // bob cancels alice's transaction. This fails as bob did not create alice's transaction. - bobCancelMsg := v.Messages.Typed(bob.ID, multisigAddr, MultisigCancel(&multisig.TxnIDParams{ - ID: multisig.TxnID(0), - ProposalHash: hash, - }), Nonce(0)) - v.Messages.ApplyOne(bobCancelMsg) - v.Assert.Equal(bobCancelMsg.Result.ExitCode, exitcode.ErrForbidden) - - // alice cancels their transaction; charlie doesn't receive any FIL, - // the multisig actor's balance is empty, and the transaction is canceled. - aliceCancelMsg := v.Messages.Typed(alice.ID, multisigAddr, MultisigCancel(&multisig.TxnIDParams{ - ID: multisig.TxnID(0), - ProposalHash: hash, - }), Nonce(2)) - v.Messages.ApplyOne(aliceCancelMsg) - v.Assert.Equal(exitcode.Ok, aliceCancelMsg.Result.ExitCode) - - v.CommitApplies() - - // verify balance is untouched. - v.Assert.BalanceEq(multisigAddr, amount) - - // reload the multisig state and verify - var multisigState multisig.State - v.Actors.ActorState(multisigAddr, &multisigState) - v.Assert.Equal(&multisig.State{ - Signers: []address.Address{alice.ID, bob.ID}, - NumApprovalsThreshold: 2, - NextTxnID: 1, - InitialBalance: amount, - StartEpoch: 1, - UnlockDuration: unlockDuration, - PendingTxns: EmptyMapCid, - }, &multisigState) -} - -func proposeAndApprove(v *Builder) { - var ( - initial = abi.NewTokenAmount(1_000_000_000_000) - amount = abi.NewTokenAmount(10) - unlockDuration = abi.ChainEpoch(10) - ) - - v.Messages.SetDefaults(Value(big.Zero()), Epoch(1), GasLimit(gasLimit), GasPremium(1), GasFeeCap(gasFeeCap)) - - // Set up three accounts: alice and bob (signers), and charlie (outsider). - var alice, bob, charlie AddressHandle - v.Actors.AccountN(address.SECP256K1, initial, &alice, &bob, &charlie) - v.CommitPreconditions() - - // create the multisig actor; created by alice. - multisigAddr := createMultisig(v, alice, []address.Address{alice.ID, bob.ID}, 2, Value(amount), Nonce(0)) - - // alice proposes that charlie should receive 'amount' FIL. - hash := proposeOk(v, proposeOpts{ - multisigAddr: multisigAddr, - sender: alice.ID, - recipient: charlie.ID, - amount: amount, - }, Nonce(1)) - - // charlie proposes himself -> fails. - charliePropose := v.Messages.Typed(charlie.ID, multisigAddr, - MultisigPropose(&multisig.ProposeParams{ - To: charlie.ID, - Value: amount, - Method: builtin.MethodSend, - Params: nil, - }), Nonce(0)) - v.Messages.ApplyOne(charliePropose) - v.Assert.Equal(exitcode.ErrForbidden, charliePropose.Result.ExitCode) - - // charlie attempts to accept the pending transaction -> fails. - charlieApprove := v.Messages.Typed(charlie.ID, multisigAddr, - MultisigApprove(&multisig.TxnIDParams{ - ID: multisig.TxnID(0), - ProposalHash: hash, - }), Nonce(1)) - v.Messages.ApplyOne(charlieApprove) - v.Assert.Equal(exitcode.ErrForbidden, charlieApprove.Result.ExitCode) - - // bob approves transfer of 'amount' FIL to charlie. - // epoch is unlockDuration + 1 - bobApprove := v.Messages.Typed(bob.ID, multisigAddr, - MultisigApprove(&multisig.TxnIDParams{ - ID: multisig.TxnID(0), - ProposalHash: hash, - }), Nonce(0), Epoch(unlockDuration+1)) - v.Messages.ApplyOne(bobApprove) - v.Assert.Equal(exitcode.Ok, bobApprove.Result.ExitCode) - - v.CommitApplies() - - var approveRet multisig.ApproveReturn - MustDeserialize(bobApprove.Result.Return, &approveRet) - v.Assert.Equal(multisig.ApproveReturn{ - Applied: true, - Code: 0, - Ret: nil, - }, approveRet) - - // assert that the multisig balance has been drained, and charlie's incremented. - v.Assert.BalanceEq(multisigAddr, big.Zero()) - v.Assert.MessageSendersSatisfy(BalanceUpdated(amount), charliePropose, charlieApprove) - - // reload the multisig state and verify - var multisigState multisig.State - v.Actors.ActorState(multisigAddr, &multisigState) - v.Assert.Equal(&multisig.State{ - Signers: []address.Address{alice.ID, bob.ID}, - NumApprovalsThreshold: 2, - NextTxnID: 1, - InitialBalance: amount, - StartEpoch: 1, - UnlockDuration: unlockDuration, - PendingTxns: EmptyMapCid, - }, &multisigState) -} - -func addSigner(v *Builder) { - var ( - initial = abi.NewTokenAmount(1_000_000_000_000) - amount = abi.NewTokenAmount(10) - ) - - v.Messages.SetDefaults(Value(big.Zero()), Epoch(1), GasLimit(gasLimit), GasPremium(1), GasFeeCap(gasFeeCap)) - - // Set up three accounts: alice and bob (signers), and charlie (outsider). - var alice, bob, charlie AddressHandle - v.Actors.AccountN(address.SECP256K1, initial, &alice, &bob, &charlie) - v.CommitPreconditions() - - // create the multisig actor; created by alice. - multisigAddr := createMultisig(v, alice, []address.Address{alice.ID}, 1, Value(amount), Nonce(0)) - - addParams := &multisig.AddSignerParams{ - Signer: bob.ID, - Increase: false, - } - - // attempt to add bob as a signer; this fails because the addition needs to go through - // the multisig flow, as it is subject to the same approval policy. - v.Messages.Typed(alice.ID, multisigAddr, MultisigAddSigner(addParams), Nonce(1)) - - // go through the multisig wallet. - // since approvals = 1, this auto-approves the transaction. - v.Messages.Typed(alice.ID, multisigAddr, MultisigPropose(&multisig.ProposeParams{ - To: multisigAddr, - Value: big.Zero(), - Method: builtin.MethodsMultisig.AddSigner, - Params: MustSerialize(addParams), - }), Nonce(2)) - - // TODO also exercise the approvals = 2 case with explicit approval. - - v.CommitApplies() - - // reload the multisig state and verify that bob is now a signer. - var multisigState multisig.State - v.Actors.ActorState(multisigAddr, &multisigState) - v.Assert.Equal(&multisig.State{ - Signers: []address.Address{alice.ID, bob.ID}, - NumApprovalsThreshold: 1, - NextTxnID: 1, - InitialBalance: amount, - StartEpoch: 1, - UnlockDuration: 10, - PendingTxns: EmptyMapCid, - }, &multisigState) -} - -type proposeOpts struct { - multisigAddr address.Address - sender address.Address - recipient address.Address - amount abi.TokenAmount -} - -func proposeOk(v *Builder, proposeOpts proposeOpts, opts ...MsgOpt) []byte { - propose := &multisig.ProposeParams{ - To: proposeOpts.recipient, - Value: proposeOpts.amount, - Method: builtin.MethodSend, - Params: nil, - } - proposeMsg := v.Messages.Typed(proposeOpts.sender, proposeOpts.multisigAddr, MultisigPropose(propose), opts...) - - v.Messages.ApplyOne(proposeMsg) - - // verify that the multisig state contains the outstanding TX. - var multisigState multisig.State - v.Actors.ActorState(proposeOpts.multisigAddr, &multisigState) - - id := multisig.TxnID(0) - actualTxn := loadMultisigTxn(v, multisigState, id) - v.Assert.Equal(&multisig.Transaction{ - To: propose.To, - Value: propose.Value, - Method: propose.Method, - Params: propose.Params, - Approved: []address.Address{proposeOpts.sender}, - }, actualTxn) - - return makeProposalHash(v, actualTxn) -} - -func createMultisig(v *Builder, creator AddressHandle, approvers []address.Address, threshold uint64, opts ...MsgOpt) address.Address { - const unlockDuration = abi.ChainEpoch(10) - // create the multisig actor. - params := &multisig.ConstructorParams{ - Signers: approvers, - NumApprovalsThreshold: threshold, - UnlockDuration: unlockDuration, - } - msg := v.Messages.Sugar().CreateMultisigActor(creator.ID, params, opts...) - v.Messages.ApplyOne(msg) - - // verify ok - v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.Ok)) - - // verify the assigned addess is as expected. - var ret init_.ExecReturn - MustDeserialize(msg.Result.Return, &ret) - v.Assert.Equal(creator.NextActorAddress(msg.Message.Nonce, 0), ret.RobustAddress) - handles := v.Actors.Handles() - v.Assert.Equal(MustNewIDAddr(MustIDFromAddress(handles[len(handles)-1].ID)+1), ret.IDAddress) - - // the multisig address's balance is incremented by the value sent to it. - v.Assert.BalanceEq(ret.IDAddress, msg.Message.Value) - - return ret.IDAddress -} - -func loadMultisigTxn(v *Builder, state multisig.State, id multisig.TxnID) *multisig.Transaction { - pending, err := adt.AsMap(v.Stores.ADTStore, state.PendingTxns) - v.Assert.NoError(err) - - var actualTxn multisig.Transaction - found, err := pending.Get(id, &actualTxn) - v.Assert.True(found) - v.Assert.NoError(err) - return &actualTxn -} - -func makeProposalHash(v *Builder, txn *multisig.Transaction) []byte { - ret, err := multisig.ComputeProposalHash(txn, blake2b.Sum256) - v.Assert.NoError(err) - return ret -} diff --git a/tvx/scripts/nested/main.go b/tvx/scripts/nested/main.go deleted file mode 100644 index bbaa06fc6..000000000 --- a/tvx/scripts/nested/main.go +++ /dev/null @@ -1,127 +0,0 @@ -package main - -import ( - . "github.com/filecoin-project/oni/tvx/builders" - "github.com/filecoin-project/oni/tvx/schema" -) - -func main() { - g := NewGenerator() - - g.MessageVectorGroup("nested_sends", - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok-basic", - Version: "v1", - Desc: "", - }, - Func: nestedSends_OkBasic, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok-to-new-actor", - Version: "v1", - Desc: "", - }, - Func: nestedSends_OkToNewActor, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok-to-new-actor-with-invoke", - Version: "v1", - Desc: "", - }, - Func: nestedSends_OkToNewActorWithInvoke, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok-recursive", - Version: "v1", - Desc: "", - }, - Func: nestedSends_OkRecursive, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok-non-cbor-params-with-transfer", - Version: "v1", - Desc: "", - }, - Func: nestedSends_OKNonCBORParamsWithTransfer, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-non-existent-id-address", - Version: "v1", - Desc: "", - }, - Func: nestedSends_FailNonexistentIDAddress, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-non-existent-actor-address", - Version: "v1", - Desc: "", - }, - Func: nestedSends_FailNonexistentActorAddress, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-invalid-method-num-new-actor", - Version: "v1", - Desc: "", - }, - Func: nestedSends_FailInvalidMethodNumNewActor, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-invalid-method-num-for-actor", - Version: "v1", - Desc: "", - }, - Func: nestedSends_FailInvalidMethodNumForActor, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-missing-params", - Version: "v1", - Desc: "", - }, - Func: nestedSends_FailMissingParams, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-mismatch-params", - Version: "v1", - Desc: "", - }, - Func: nestedSends_FailMismatchParams, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-inner-abort", - Version: "v1", - Desc: "", - }, - Func: nestedSends_FailInnerAbort, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-aborted-exec", - Version: "v1", - Desc: "", - }, - Func: nestedSends_FailAbortedExec, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-insufficient-funds-for-transfer-in-inner-send", - Version: "v1", - Desc: "", - }, - Func: nestedSends_FailInsufficientFundsForTransferInInnerSend, - }, - ) - - g.Wait() -} diff --git a/tvx/scripts/nested/nested.go b/tvx/scripts/nested/nested.go deleted file mode 100644 index a516031a0..000000000 --- a/tvx/scripts/nested/nested.go +++ /dev/null @@ -1,358 +0,0 @@ -package main - -import ( - "bytes" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" - "github.com/filecoin-project/specs-actors/actors/builtin" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" - "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - "github.com/filecoin-project/specs-actors/actors/builtin/paych" - "github.com/filecoin-project/specs-actors/actors/builtin/reward" - "github.com/filecoin-project/specs-actors/actors/puppet" - "github.com/filecoin-project/specs-actors/actors/runtime" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - "github.com/filecoin-project/specs-actors/actors/util/adt" - typegen "github.com/whyrusleeping/cbor-gen" - - . "github.com/filecoin-project/oni/tvx/builders" -) - -var ( - acctDefaultBalance = abi.NewTokenAmount(1_000_000_000_000) - multisigBalance = abi.NewTokenAmount(1_000_000_000) - nonce = uint64(1) - PuppetAddress address.Address -) - -func init() { - var err error - // the address before the burnt funds address - PuppetAddress, err = address.NewIDAddress(builtin.FirstNonSingletonActorId - 2) - if err != nil { - panic(err) - } -} - -func nestedSends_OkBasic(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - balanceBefore := v.Actors.Balance(stage.creator) - - // Multisig sends back to the creator. - amtSent := abi.NewTokenAmount(1) - result := stage.sendOk(stage.creator, amtSent, builtin.MethodSend, nil, nonce) - - //td.AssertActor(stage.creator, big.Sub(big.Add(balanceBefore, amtSent), result.Result.Receipt.GasUsed.Big()), nonce+1) - v.Assert.NonceEq(stage.creator, nonce+1) - v.Assert.BalanceEq(stage.creator, big.Sub(big.Add(balanceBefore, amtSent), CalculateDeduction(result))) -} - -func nestedSends_OkToNewActor(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - balanceBefore := v.Actors.Balance(stage.creator) - - // Multisig sends to new address. - newAddr := v.Wallet.NewSECP256k1Account() - amtSent := abi.NewTokenAmount(1) - result := stage.sendOk(newAddr, amtSent, builtin.MethodSend, nil, nonce) - - v.Assert.BalanceEq(stage.msAddr, big.Sub(multisigBalance, amtSent)) - v.Assert.BalanceEq(stage.creator, big.Sub(balanceBefore, CalculateDeduction(result))) - v.Assert.BalanceEq(newAddr, amtSent) -} - -func nestedSends_OkToNewActorWithInvoke(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - balanceBefore := v.Actors.Balance(stage.creator) - - // Multisig sends to new address and invokes pubkey method at the same time. - newAddr := v.Wallet.NewSECP256k1Account() - amtSent := abi.NewTokenAmount(1) - result := stage.sendOk(newAddr, amtSent, builtin.MethodsAccount.PubkeyAddress, nil, nonce) - // TODO: use an explicit Approve() and check the return value is the correct pubkey address - // when the multisig Approve() method plumbs through the inner exit code and value. - // https://github.com/filecoin-project/specs-actors/issues/113 - //expected := bytes.Buffer{} - //require.NoError(t, newAddr.MarshalCBOR(&expected)) - //assert.Equal(t, expected.Bytes(), result.Result.Receipt.ReturnValue) - - v.Assert.BalanceEq(stage.msAddr, big.Sub(multisigBalance, amtSent)) - v.Assert.BalanceEq(stage.creator, big.Sub(balanceBefore, CalculateDeduction(result))) - v.Assert.BalanceEq(newAddr, amtSent) -} - -func nestedSends_OkRecursive(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - another := v.Actors.Account(address.SECP256K1, big.Zero()) - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - balanceBefore := v.Actors.Balance(stage.creator) - - // Multisig sends to itself. - params := multisig.AddSignerParams{ - Signer: another.ID, - Increase: false, - } - result := stage.sendOk(stage.msAddr, big.Zero(), builtin.MethodsMultisig.AddSigner, ¶ms, nonce) - - v.Assert.BalanceEq(stage.msAddr, multisigBalance) - v.Assert.Equal(big.Sub(balanceBefore, CalculateDeduction(result)), v.Actors.Balance(stage.creator)) - - var st multisig.State - v.Actors.ActorState(stage.msAddr, &st) - v.Assert.Equal([]address.Address{stage.creator, another.ID}, st.Signers) -} - -func nestedSends_OKNonCBORParamsWithTransfer(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - - newAddr := v.Wallet.NewSECP256k1Account() - amtSent := abi.NewTokenAmount(1) - // So long as the parameters are not actually used by the method, a message can carry arbitrary bytes. - params := typegen.Deferred{Raw: []byte{1, 2, 3, 4}} - stage.sendOk(newAddr, amtSent, builtin.MethodSend, ¶ms, nonce) - - v.Assert.BalanceEq(stage.msAddr, big.Sub(multisigBalance, amtSent)) - v.Assert.BalanceEq(newAddr, amtSent) -} - -func nestedSends_FailNonexistentIDAddress(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - - newAddr := MustNewIDAddr(1234) - amtSent := abi.NewTokenAmount(1) - stage.sendOk(newAddr, amtSent, builtin.MethodSend, nil, nonce) - - v.Assert.BalanceEq(stage.msAddr, multisigBalance) // No change. - v.Assert.ActorMissing(newAddr) -} - -func nestedSends_FailNonexistentActorAddress(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - - newAddr := MustNewActorAddr("1234") - amtSent := abi.NewTokenAmount(1) - stage.sendOk(newAddr, amtSent, builtin.MethodSend, nil, nonce) - - v.Assert.BalanceEq(stage.msAddr, multisigBalance) // No change. - v.Assert.ActorMissing(newAddr) -} - -func nestedSends_FailInvalidMethodNumNewActor(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - - newAddr := v.Wallet.NewSECP256k1Account() - amtSent := abi.NewTokenAmount(1) - stage.sendOk(newAddr, amtSent, abi.MethodNum(99), nil, nonce) - - v.Assert.BalanceEq(stage.msAddr, multisigBalance) // No change. - v.Assert.ActorMissing(newAddr) -} - -func nestedSends_FailInvalidMethodNumForActor(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - balanceBefore := v.Actors.Balance(stage.creator) - - amtSent := abi.NewTokenAmount(1) - result := stage.sendOk(stage.creator, amtSent, abi.MethodNum(99), nil, nonce) - - v.Assert.BalanceEq(stage.msAddr, multisigBalance) // No change. - v.Assert.BalanceEq(stage.creator, big.Sub(balanceBefore, CalculateDeduction(result))) // Pay gas, don't receive funds. -} - -func nestedSends_FailMissingParams(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - balanceBefore := v.Actors.Balance(stage.creator) - - params := adt.Empty // Missing params required by AddSigner - amtSent := abi.NewTokenAmount(1) - result := stage.sendOk(stage.msAddr, amtSent, builtin.MethodsMultisig.AddSigner, params, nonce) - - v.Assert.BalanceEq(stage.creator, big.Sub(balanceBefore, CalculateDeduction(result))) - v.Assert.BalanceEq(stage.msAddr, multisigBalance) // No change. - v.Assert.Equal(1, len(stage.state().Signers)) // No new signers -} - -func nestedSends_FailMismatchParams(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - balanceBefore := v.Actors.Balance(stage.creator) - - // Wrong params for AddSigner - params := multisig.ProposeParams{ - To: stage.creator, - Value: big.Zero(), - Method: builtin.MethodSend, - Params: nil, - } - amtSent := abi.NewTokenAmount(1) - result := stage.sendOk(stage.msAddr, amtSent, builtin.MethodsMultisig.AddSigner, ¶ms, nonce) - - v.Assert.BalanceEq(stage.creator, big.Sub(balanceBefore, CalculateDeduction(result))) - v.Assert.BalanceEq(stage.msAddr, multisigBalance) // No change. - v.Assert.Equal(1, len(stage.state().Signers)) // No new signers -} - -func nestedSends_FailInnerAbort(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - prevHead := v.Actors.Head(builtin.RewardActorAddr) - - // AwardBlockReward will abort unless invoked by the system actor - params := reward.AwardBlockRewardParams{ - Miner: stage.creator, - Penalty: big.Zero(), - GasReward: big.Zero(), - } - amtSent := abi.NewTokenAmount(1) - stage.sendOk(builtin.RewardActorAddr, amtSent, builtin.MethodsReward.AwardBlockReward, ¶ms, nonce) - - v.Assert.BalanceEq(stage.msAddr, multisigBalance) // No change. - v.Assert.HeadEq(builtin.RewardActorAddr, prevHead) -} - -func nestedSends_FailAbortedExec(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - stage := prepareStage(v, acctDefaultBalance, multisigBalance) - prevHead := v.Actors.Head(builtin.InitActorAddr) - - // Illegal paych constructor params (addresses are not accounts) - ctorParams := paych.ConstructorParams{ - From: builtin.SystemActorAddr, - To: builtin.SystemActorAddr, - } - execParams := init_.ExecParams{ - CodeCID: builtin.PaymentChannelActorCodeID, - ConstructorParams: MustSerialize(&ctorParams), - } - - amtSent := abi.NewTokenAmount(1) - stage.sendOk(builtin.InitActorAddr, amtSent, builtin.MethodsInit.Exec, &execParams, nonce) - - v.Assert.BalanceEq(stage.msAddr, multisigBalance) // No change. - v.Assert.HeadEq(builtin.InitActorAddr, prevHead) // Init state unchanged. -} - -func nestedSends_FailInsufficientFundsForTransferInInnerSend(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - // puppet actor has zero funds - puppetBalance := big.Zero() - _ = v.Actors.CreateActor(puppet.PuppetActorCodeID, PuppetAddress, puppetBalance, &puppet.State{}) - - alice := v.Actors.Account(address.SECP256K1, acctDefaultBalance) - bob := v.Actors.Account(address.SECP256K1, big.Zero()) - - v.CommitPreconditions() - - // alice tells the puppet actor to send funds to bob, the puppet actor has 0 balance so the inner send will fail, - // and alice will pay the gas cost. - amtSent := abi.NewTokenAmount(1) - msg := v.Messages.Typed(alice.ID, PuppetAddress, PuppetSend(&puppet.SendParams{ - To: bob.ID, - Value: amtSent, - Method: builtin.MethodSend, - Params: nil, - }), Nonce(0), Value(big.Zero())) - - v.Messages.ApplyOne(msg) - - v.CommitApplies() - - // the outer message should be applied successfully - v.Assert.Equal(exitcode.Ok, msg.Result.ExitCode) - - var puppetRet puppet.SendReturn - MustDeserialize(msg.Result.MessageReceipt.Return, &puppetRet) - - // the inner message should fail - v.Assert.Equal(exitcode.SysErrInsufficientFunds, puppetRet.Code) - - // alice should be charged for the gas cost and bob should have not received any funds. - v.Assert.MessageSendersSatisfy(BalanceUpdated(big.Zero()), msg) - v.Assert.BalanceEq(bob.ID, big.Zero()) -} - -type msStage struct { - v *Builder - creator address.Address // Address of the creator and sole signer of the multisig. - msAddr address.Address // Address of the multisig actor from which nested messages are sent. -} - -// Creates a multisig actor with its creator as sole approver. -func prepareStage(v *Builder, creatorBalance, msBalance abi.TokenAmount) *msStage { - // Set up sender and receiver accounts. - creator := v.Actors.Account(address.SECP256K1, creatorBalance) - v.CommitPreconditions() - - msg := v.Messages.Sugar().CreateMultisigActor(creator.ID, &multisig.ConstructorParams{ - Signers: []address.Address{creator.ID}, - NumApprovalsThreshold: 1, - UnlockDuration: 0, - }, Value(msBalance), Nonce(0)) - v.Messages.ApplyOne(msg) - - v.Assert.Equal(msg.Result.ExitCode, exitcode.Ok) - - // Verify init actor return. - var ret init_.ExecReturn - MustDeserialize(msg.Result.Return, &ret) - - return &msStage{ - v: v, - creator: creator.ID, - msAddr: ret.IDAddress, - } -} - -func (s *msStage) sendOk(to address.Address, value abi.TokenAmount, method abi.MethodNum, params runtime.CBORMarshaler, approverNonce uint64) *ApplicableMessage { - buf := bytes.Buffer{} - if params != nil { - err := params.MarshalCBOR(&buf) - if err != nil { - panic(err) - } - } - pparams := multisig.ProposeParams{ - To: to, - Value: value, - Method: method, - Params: buf.Bytes(), - } - msg := s.v.Messages.Typed(s.creator, s.msAddr, MultisigPropose(&pparams), Nonce(approverNonce), Value(big.NewInt(0))) - s.v.CommitApplies() - - // all messages succeeded. - s.v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.Ok)) - - return msg -} - -func (s *msStage) state() *multisig.State { - var msState multisig.State - s.v.Actors.ActorState(s.msAddr, &msState) - return &msState -} diff --git a/tvx/scripts/paych/main.go b/tvx/scripts/paych/main.go deleted file mode 100644 index 45de0d7a9..000000000 --- a/tvx/scripts/paych/main.go +++ /dev/null @@ -1,45 +0,0 @@ -package main - -import ( - . "github.com/filecoin-project/oni/tvx/builders" - "github.com/filecoin-project/oni/tvx/schema" - "github.com/filecoin-project/specs-actors/actors/abi" -) - -var ( - initialBal = abi.NewTokenAmount(1_000_000_000_000) - toSend = abi.NewTokenAmount(10_000) -) - -func main() { - g := NewGenerator() - - g.MessageVectorGroup("paych", - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "create-ok", - Version: "v1", - Desc: "", - }, - Func: happyPathCreate, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "update-ok", - Version: "v1", - Desc: "", - }, - Func: happyPathUpdate, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "collect-ok", - Version: "v1", - Desc: "", - }, - Func: happyPathCollect, - }, - ) - - g.Wait() -} diff --git a/tvx/scripts/paych/ok.go b/tvx/scripts/paych/ok.go deleted file mode 100644 index 7a9083ae6..000000000 --- a/tvx/scripts/paych/ok.go +++ /dev/null @@ -1,167 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" - "github.com/filecoin-project/specs-actors/actors/builtin/paych" - "github.com/filecoin-project/specs-actors/actors/crypto" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - "github.com/filecoin-project/specs-actors/actors/util/adt" - - . "github.com/filecoin-project/oni/tvx/builders" -) - -func happyPathCreate(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - // Set up sender and receiver accounts. - var sender, receiver AddressHandle - v.Actors.AccountN(address.SECP256K1, initialBal, &sender, &receiver) - v.CommitPreconditions() - - // Add the constructor message. - createMsg := v.Messages.Sugar().CreatePaychActor(sender.Robust, receiver.Robust, Value(toSend)) - v.CommitApplies() - - expectedActorAddr := AddressHandle{ - ID: MustNewIDAddr(MustIDFromAddress(receiver.ID) + 1), - Robust: sender.NextActorAddress(0, 0), - } - - // Verify init actor return. - var ret init_.ExecReturn - MustDeserialize(createMsg.Result.Return, &ret) - v.Assert.Equal(expectedActorAddr.Robust, ret.RobustAddress) - v.Assert.Equal(expectedActorAddr.ID, ret.IDAddress) - - // Verify the paych state. - var state paych.State - actor := v.Actors.ActorState(ret.IDAddress, &state) - v.Assert.Equal(sender.ID, state.From) - v.Assert.Equal(receiver.ID, state.To) - v.Assert.Equal(toSend, actor.Balance) - - v.Assert.EveryMessageSenderSatisfies(NonceUpdated()) -} - -func happyPathUpdate(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - var ( - timelock = abi.ChainEpoch(0) - lane = uint64(123) - nonce = uint64(1) - amount = big.NewInt(10) - ) - - // Set up sender and receiver accounts. - var sender, receiver AddressHandle - var paychAddr AddressHandle - - v.Actors.AccountN(address.SECP256K1, initialBal, &sender, &receiver) - paychAddr = AddressHandle{ - ID: MustNewIDAddr(MustIDFromAddress(receiver.ID) + 1), - Robust: sender.NextActorAddress(0, 0), - } - v.CommitPreconditions() - - // Construct the payment channel. - createMsg := v.Messages.Sugar().CreatePaychActor(sender.Robust, receiver.Robust, Value(toSend)) - - // Update the payment channel. - v.Messages.Typed(sender.Robust, paychAddr.Robust, PaychUpdateChannelState(&paych.UpdateChannelStateParams{ - Sv: paych.SignedVoucher{ - ChannelAddr: paychAddr.Robust, - TimeLockMin: timelock, - TimeLockMax: 0, // TimeLockMax set to 0 means no timeout - Lane: lane, - Nonce: nonce, - Amount: amount, - MinSettleHeight: 0, - Signature: &crypto.Signature{ - Type: crypto.SigTypeBLS, - Data: []byte("signature goes here"), // TODO may need to generate an actual signature - }, - }}), Nonce(1), Value(big.Zero())) - - v.CommitApplies() - - // all messages succeeded. - v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.Ok)) - - // Verify init actor return. - var ret init_.ExecReturn - MustDeserialize(createMsg.Result.Return, &ret) - - // Verify the paych state. - var state paych.State - v.Actors.ActorState(ret.RobustAddress, &state) - - arr, err := adt.AsArray(v.Stores.ADTStore, state.LaneStates) - v.Assert.NoError(err) - v.Assert.EqualValues(1, arr.Length()) - - var ls paych.LaneState - found, err := arr.Get(lane, &ls) - v.Assert.NoError(err) - v.Assert.True(found) - - v.Assert.Equal(amount, ls.Redeemed) - v.Assert.Equal(nonce, ls.Nonce) - - v.Assert.EveryMessageSenderSatisfies(NonceUpdated()) -} - -func happyPathCollect(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - // Set up sender and receiver accounts. - var sender, receiver AddressHandle - var paychAddr AddressHandle - v.Actors.AccountN(address.SECP256K1, initialBal, &sender, &receiver) - paychAddr = AddressHandle{ - ID: MustNewIDAddr(MustIDFromAddress(receiver.ID) + 1), - Robust: sender.NextActorAddress(0, 0), - } - - v.CommitPreconditions() - - // Construct the payment channel. - createMsg := v.Messages.Sugar().CreatePaychActor(sender.Robust, receiver.Robust, Value(toSend)) - - // Update the payment channel. - updateMsg := v.Messages.Typed(sender.Robust, paychAddr.Robust, PaychUpdateChannelState(&paych.UpdateChannelStateParams{ - Sv: paych.SignedVoucher{ - ChannelAddr: paychAddr.Robust, - TimeLockMin: 0, - TimeLockMax: 0, // TimeLockMax set to 0 means no timeout - Lane: 1, - Nonce: 1, - Amount: toSend, - MinSettleHeight: 0, - Signature: &crypto.Signature{ - Type: crypto.SigTypeBLS, - Data: []byte("signature goes here"), // TODO may need to generate an actual signature - }, - }}), Nonce(1), Value(big.Zero())) - - settleMsg := v.Messages.Typed(receiver.Robust, paychAddr.Robust, PaychSettle(nil), Value(big.Zero()), Nonce(0)) - - // advance the epoch so the funds may be redeemed. - collectMsg := v.Messages.Typed(receiver.Robust, paychAddr.Robust, PaychCollect(nil), Value(big.Zero()), Nonce(1), Epoch(paych.SettleDelay)) - - v.CommitApplies() - - // all messages succeeded. - v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.Ok)) - - v.Assert.MessageSendersSatisfy(BalanceUpdated(big.Zero()), createMsg, updateMsg) - v.Assert.MessageSendersSatisfy(BalanceUpdated(toSend), settleMsg, collectMsg) - v.Assert.EveryMessageSenderSatisfies(NonceUpdated()) - - // the paych actor should have been deleted after the collect - v.Assert.ActorMissing(paychAddr.Robust) - v.Assert.ActorMissing(paychAddr.ID) -} diff --git a/tvx/scripts/transfer/basic.go b/tvx/scripts/transfer/basic.go deleted file mode 100644 index e38728a0b..000000000 --- a/tvx/scripts/transfer/basic.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/abi/big" - - . "github.com/filecoin-project/oni/tvx/builders" -) - -type basicTransferParams struct { - senderType address.Protocol - senderBal abi.TokenAmount - receiverType address.Protocol - amount abi.TokenAmount - exitCode exitcode.ExitCode -} - -func basicTransfer(params basicTransferParams) func(v *Builder) { - return func(v *Builder) { - v.Messages.SetDefaults(GasLimit(gasLimit), GasPremium(1), GasFeeCap(gasFeeCap)) - - // Set up sender and receiver accounts. - var sender, receiver AddressHandle - sender = v.Actors.Account(params.senderType, params.senderBal) - receiver = v.Actors.Account(params.receiverType, big.Zero()) - v.CommitPreconditions() - - // Perform the transfer. - v.Messages.Sugar().Transfer(sender.ID, receiver.ID, Value(params.amount), Nonce(0)) - v.CommitApplies() - - v.Assert.EveryMessageResultSatisfies(ExitCode(params.exitCode)) - v.Assert.EveryMessageSenderSatisfies(BalanceUpdated(big.Zero())) - - if params.exitCode.IsSuccess() { - v.Assert.EveryMessageSenderSatisfies(NonceUpdated()) - v.Assert.BalanceEq(receiver.ID, params.amount) - } - } -} diff --git a/tvx/scripts/transfer/main.go b/tvx/scripts/transfer/main.go deleted file mode 100644 index acaab53d9..000000000 --- a/tvx/scripts/transfer/main.go +++ /dev/null @@ -1,165 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - - . "github.com/filecoin-project/oni/tvx/builders" - "github.com/filecoin-project/oni/tvx/schema" -) - -const ( - gasLimit = 1_000_000_000 - gasFeeCap = 200 -) - -func main() { - g := NewGenerator() - defer g.Wait() - - g.MessageVectorGroup("basic", - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok", - Version: "v1", - Desc: "successfully transfer funds from sender to receiver", - }, - Func: basicTransfer(basicTransferParams{ - senderType: address.SECP256K1, - senderBal: abi.NewTokenAmount(10 * gasLimit * gasFeeCap), - receiverType: address.SECP256K1, - amount: abi.NewTokenAmount(50), - exitCode: exitcode.Ok, - }), - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "ok-zero", - Version: "v1", - Desc: "successfully transfer zero funds from sender to receiver", - }, - Func: basicTransfer(basicTransferParams{ - senderType: address.SECP256K1, - senderBal: abi.NewTokenAmount(10 * gasFeeCap * gasLimit), - receiverType: address.SECP256K1, - amount: abi.NewTokenAmount(0), - exitCode: exitcode.Ok, - }), - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-exceed-balance", - Version: "v1", - Desc: "fail to transfer more funds than sender balance > 0", - }, - Func: basicTransfer(basicTransferParams{ - senderType: address.SECP256K1, - senderBal: abi.NewTokenAmount(10 * gasFeeCap * gasLimit), - receiverType: address.SECP256K1, - amount: abi.NewTokenAmount(10*gasFeeCap*gasLimit - gasFeeCap*gasLimit + 1), - exitCode: exitcode.SysErrInsufficientFunds, - }), - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-balance-equal-gas", - Version: "v1", - Desc: "fail to transfer more funds than sender has when sender balance matches gas limit", - }, - Func: basicTransfer(basicTransferParams{ - senderType: address.SECP256K1, - senderBal: abi.NewTokenAmount(gasFeeCap * gasLimit), - receiverType: address.SECP256K1, - amount: abi.NewTokenAmount(1), - exitCode: exitcode.SysErrInsufficientFunds, - }), - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-balance-under-gaslimit", - Version: "v1", - Desc: "fail to transfer when sender balance under gas limit", - }, - Func: basicTransfer(basicTransferParams{ - senderType: address.SECP256K1, - senderBal: abi.NewTokenAmount(gasFeeCap*gasLimit - 1), - receiverType: address.SECP256K1, - amount: abi.NewTokenAmount(0), - exitCode: exitcode.SysErrSenderStateInvalid, - }), - }, - ) - - g.MessageVectorGroup("self_transfer", - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "secp-to-secp-addresses", - Version: "v1", - }, - Func: selfTransfer(AddressHandle.RobustAddr, AddressHandle.RobustAddr), - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "secp-to-id-addresses", - Version: "v1", - }, - Func: selfTransfer(AddressHandle.RobustAddr, AddressHandle.IDAddr), - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "id-to-secp-addresses", - Version: "v1", - }, - Func: selfTransfer(AddressHandle.IDAddr, AddressHandle.RobustAddr), - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "id-to-id-addresses", - Version: "v1", - }, - Func: selfTransfer(AddressHandle.IDAddr, AddressHandle.IDAddr), - }, - ) - - g.MessageVectorGroup("unknown_accounts", - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-unknown-sender-known-receiver", - Version: "v1", - Desc: "fail to transfer from unknown account to known address", - }, - Func: failTransferUnknownSenderKnownReceiver, - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "fail-unknown-sender-unknown-receiver", - Version: "v1", - Desc: "fail to transfer from unknown address to unknown address", - }, - Func: failTransferUnknownSenderUnknownReceiver, - }, - - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "secp-to-id-addresses", - Version: "v1", - }, - Func: selfTransfer(AddressHandle.RobustAddr, AddressHandle.IDAddr), - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "id-to-secp-addresses", - Version: "v1", - }, - Func: selfTransfer(AddressHandle.IDAddr, AddressHandle.RobustAddr), - }, - &MessageVectorGenItem{ - Metadata: &schema.Metadata{ - ID: "id-to-id-addresses", - Version: "v1", - }, - Func: selfTransfer(AddressHandle.IDAddr, AddressHandle.IDAddr), - }, - ) -} diff --git a/tvx/scripts/transfer/self_transfer.go b/tvx/scripts/transfer/self_transfer.go deleted file mode 100644 index e6e158eee..000000000 --- a/tvx/scripts/transfer/self_transfer.go +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - - . "github.com/filecoin-project/oni/tvx/builders" -) - -func selfTransfer(from, to func(h AddressHandle) address.Address) func(v *Builder) { - return func(v *Builder) { - initial := abi.NewTokenAmount(1_000_000_000_000) - transfer := abi.NewTokenAmount(10) - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - // Set up sender account. - account := v.Actors.Account(address.SECP256K1, initial) - v.CommitPreconditions() - - // Perform the transfer. - msg := v.Messages.Sugar().Transfer(from(account), to(account), Value(transfer), Nonce(0)) - v.CommitApplies() - - v.Assert.Equal(exitcode.Ok, msg.Result.ExitCode) - - // the transfer balance comes back to us. - v.Assert.EveryMessageSenderSatisfies(BalanceUpdated(transfer)) - } -} diff --git a/tvx/scripts/transfer/unknown.go b/tvx/scripts/transfer/unknown.go deleted file mode 100644 index f64e9c5bc..000000000 --- a/tvx/scripts/transfer/unknown.go +++ /dev/null @@ -1,52 +0,0 @@ -package main - -import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" - - . "github.com/filecoin-project/oni/tvx/builders" -) - -var ( - initial = abi.NewTokenAmount(1_000_000_000_000) - transfer = Value(abi.NewTokenAmount(10)) -) - -func failTransferUnknownSenderKnownReceiver(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - // Set up receiver account. - receiver := v.Actors.Account(address.SECP256K1, initial) - v.CommitPreconditions() - - // create a new random sender. - sender := v.Wallet.NewSECP256k1Account() - - // perform the transfer. - v.Messages.Sugar().Transfer(sender, receiver.Robust, transfer, Nonce(0)) - v.CommitApplies() - - v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.SysErrSenderInvalid)) - v.Assert.ActorMissing(sender) - v.Assert.ActorExists(receiver.Robust) - v.Assert.BalanceEq(receiver.Robust, initial) -} - -func failTransferUnknownSenderUnknownReceiver(v *Builder) { - v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200)) - - // no accounts in the system. - v.CommitPreconditions() - - // create new random senders and resceivers. - sender, receiver := v.Wallet.NewSECP256k1Account(), v.Wallet.NewSECP256k1Account() - - // perform the transfer. - v.Messages.Sugar().Transfer(sender, receiver, transfer, Nonce(0)) - v.CommitApplies() - - v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.SysErrSenderInvalid)) - v.Assert.ActorMissing(sender) - v.Assert.ActorMissing(receiver) -}