upgrade test vectors to latest lotus (#238)

This commit is contained in:
Raúl Kripalani 2020-08-16 00:03:58 +01:00 committed by GitHub
parent 955b445723
commit ad17dc227c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 410 additions and 2874 deletions

View File

@ -52,9 +52,6 @@ jobs:
- run:
name: "build tvx"
command: pushd tvx && go build .
- run:
name: "run messages test vector suite (deprecated api)"
command: pushd tvx && ./tvx suite-messages | ./tvx exec-lotus
- run:
name: "run messages test vector suite (new api) - msg_application"
command: pushd tvx/scripts/msg_application && go build . && ./msg_application | ../../tvx exec-lotus

View File

@ -7,7 +7,6 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/abi"
abi_spec "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"
@ -21,12 +20,39 @@ import (
// Actors is an object that manages actors in the test vector.
type Actors struct {
accounts []AddressHandle
miners []AddressHandle
// registered stores registered actors and their initial balances.
registered map[AddressHandle]abi.TokenAmount
b *Builder
}
func newActors(b *Builder) *Actors {
return &Actors{
registered: make(map[AddressHandle]abi.TokenAmount),
b: b,
}
}
// 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 h := range a.registered {
if h.ID == addr || h.Robust == addr {
return h
}
}
a.b.Assert.FailNowf("asked for initial balance 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 {
handle := a.HandleFor(addr)
return a.registered[handle]
}
// 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) {
@ -52,7 +78,7 @@ func (a *Actors) Account(typ address.Protocol, balance abi.TokenAmount) AddressH
actorState := &account.State{Address: addr}
handle := a.CreateActor(builtin.AccountActorCodeID, addr, balance, actorState)
a.accounts = append(a.accounts, handle)
a.registered[handle] = balance
return handle
}
@ -63,7 +89,7 @@ type MinerActorCfg struct {
}
// Miner creates an owner account, a worker account, and a miner actor managed
// by those accounts.
// 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())
@ -98,6 +124,7 @@ func (a *Actors) Miner(cfg MinerActorCfg) (minerActor, owner, worker AddressHand
EmptyArrayCid,
EmptyMapCid,
EmptyDeadlinesCid,
EmptyVestingFundsCid,
)
if err != nil {
panic(err)
@ -142,7 +169,7 @@ func (a *Actors) Miner(cfg MinerActorCfg) (minerActor, owner, worker AddressHand
panic(err)
}
a.miners = append(a.miners, handle)
a.registered[handle] = big.Zero()
return handle, owner, worker
}
@ -193,7 +220,7 @@ func (a *Actors) Header(addr address.Address) *types.Actor {
}
// Balance is a shortcut for Header(addr).Balance.
func (a *Actors) Balance(addr address.Address) abi_spec.TokenAmount {
func (a *Actors) Balance(addr address.Address) abi.TokenAmount {
return a.Header(addr).Balance
}

View File

@ -3,6 +3,7 @@ package builders
import (
"bytes"
"encoding/binary"
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
@ -14,6 +15,10 @@ type AddressHandle struct {
ID, Robust address.Address
}
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()

View File

@ -5,6 +5,7 @@ import (
"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"
@ -77,10 +78,60 @@ func (a *Asserter) EveryMessageResultSatisfies(predicate ApplyRetPredicate, exce
if _, ok := exceptm[m]; ok {
continue
}
a.NoError(predicate(m.Result), "message result predicate failed on message %d", i)
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)
}

View File

@ -32,6 +32,8 @@ 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.
@ -40,7 +42,9 @@ type Builder struct {
Assert *Asserter
Messages *Messages
Driver *lotus.Driver
Root cid.Cid
PreRoot cid.Cid
PostRoot cid.Cid
CurrRoot cid.Cid
Wallet *Wallet
StateTree *state.StateTree
Stores *ostate.Stores
@ -63,12 +67,13 @@ func MessageVector(metadata *schema.Metadata) *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 = &Actors{b: b}
b.Actors = newActors(b)
b.Messages = &Messages{b: b}
b.vector.Class = schema.ClassMessage
@ -92,7 +97,7 @@ func (b *Builder) CommitPreconditions() {
b.vector.Pre.Epoch = 0
b.vector.Pre.StateTree = &schema.StateTree{RootCID: preroot}
b.Root = preroot
b.CurrRoot, b.PreRoot = preroot, preroot
b.stage = StageApplies
b.Assert = newAsserter(b, StageApplies)
}
@ -109,7 +114,8 @@ func (b *Builder) CommitApplies() {
}
}
b.vector.Post.StateTree = &schema.StateTree{RootCID: b.Root}
b.PostRoot = b.CurrRoot
b.vector.Post.StateTree = &schema.StateTree{RootCID: b.CurrRoot}
b.stage = StageChecks
b.Assert = newAsserter(b, StageChecks)
}
@ -119,11 +125,11 @@ func (b *Builder) CommitApplies() {
// message and its receipt.
func (b *Builder) applyMessage(am *ApplicableMessage) {
var err error
am.Result, b.Root, err = b.Driver.ExecuteMessage(am.Message, b.Root, b.Stores.Blockstore, am.Epoch)
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.Root)
b.StateTree, err = state.LoadStateTree(b.Stores.CBORStore, b.CurrRoot)
b.Assert.NoError(err)
b.vector.ApplyMessages = append(b.vector.ApplyMessages, schema.Message{

56
tvx/builders/gas.go Normal file
View File

@ -0,0 +1,56 @@
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 {
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)
}

View File

@ -41,7 +41,9 @@ func (m *Messages) Sugar() *sugarMsg {
// All returns all ApplicableMessages that have been accumulated, in the same
// order they were added.
func (m *Messages) All() []*ApplicableMessage {
return m.messages
cpy := make([]*ApplicableMessage, len(m.messages))
copy(cpy, m.messages)
return cpy
}
// Typed adds a typed call to this message accumulator.
@ -58,14 +60,15 @@ func (m *Messages) Raw(from, to address.Address, method abi.MethodNum, params []
}
msg := &types.Message{
To: to,
From: from,
Nonce: options.nonce,
Value: options.value,
Method: method,
Params: params,
GasPrice: options.gasPrice,
GasLimit: options.gasLimit,
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{
@ -106,11 +109,12 @@ func (m *Messages) ApplyN(ams ...*ApplicableMessage) {
}
type msgOpts struct {
nonce uint64
value big.Int
gasPrice big.Int
gasLimit int64
epoch abi.ChainEpoch
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
@ -138,10 +142,17 @@ func GasLimit(limit int64) MsgOpt {
}
}
// GasPrice sets the gas price of a message.
func GasPrice(price int64) MsgOpt {
// GasFeeCap sets the gas fee cap of a message.
func GasFeeCap(feeCap int64) MsgOpt {
return func(opts *msgOpts) {
opts.gasPrice = big.NewInt(price)
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)
}
}

View File

@ -3,12 +3,27 @@ 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 {
@ -17,3 +32,45 @@ func ExitCode(expect exitcode.ExitCode) ApplyRetPredicate {
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
}
}

View File

@ -33,11 +33,12 @@ var (
var (
// initialized by calling initializeStoreWithAdtRoots
EmptyArrayCid cid.Cid
EmptyDeadlinesCid cid.Cid
EmptyMapCid cid.Cid
EmptyMultiMapCid cid.Cid
EmptyBitfieldCid cid.Cid
EmptyArrayCid cid.Cid
EmptyDeadlinesCid cid.Cid
EmptyMapCid cid.Cid
EmptyMultiMapCid cid.Cid
EmptyBitfieldCid cid.Cid
EmptyVestingFundsCid cid.Cid
)
const (
@ -151,13 +152,7 @@ func insertEmptyStructures(store adt_spec.Store) error {
return err
}
EmptyDeadlinesCid, err = store.Put(context.TODO(), &miner.Deadline{
Partitions: EmptyArrayCid,
ExpirationsEpochs: EmptyArrayCid,
PostSubmissions: abi_spec.NewBitField(),
EarlyTerminations: abi_spec.NewBitField(),
LiveSectors: 0,
})
EmptyDeadlinesCid, err = store.Put(context.TODO(), miner.ConstructDeadline(EmptyArrayCid))
if err != nil {
return err
}
@ -168,5 +163,10 @@ func insertEmptyStructures(store adt_spec.Store) error {
return err
}
EmptyVestingFundsCid, err = store.Put(context.Background(), miner.ConstructVestingFunds())
if err != nil {
return err
}
return nil
}

View File

@ -1,18 +0,0 @@
package chain
import (
"github.com/filecoin-project/go-address"
builtin_spec "github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/chain/types"
)
func (mp *MessageProducer) AccountConstructor(from, to address.Address, params *address.Address, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsAccount.Constructor, ser, opts...)
}
func (mp *MessageProducer) AccountPubkeyAddress(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsAccount.PubkeyAddress, ser, opts...)
}

View File

@ -1,56 +0,0 @@
package chain
import (
"encoding/binary"
addr "github.com/filecoin-project/go-address"
"github.com/multiformats/go-varint"
)
// If you use this method while writing a test you are more than likely doing something wrong.
func MustNewIDAddr(id uint64) addr.Address {
address, err := addr.NewIDAddress(id)
if err != nil {
panic(err)
}
return address
}
func MustNewSECP256K1Addr(pubkey string) addr.Address {
// the pubkey of a secp256k1 address is hashed for consistent length.
address, err := addr.NewSecp256k1Address([]byte(pubkey))
if err != nil {
panic(err)
}
return address
}
func MustNewBLSAddr(seed int64) addr.Address {
buf := make([]byte, addr.BlsPublicKeyBytes)
binary.PutVarint(buf, seed)
address, err := addr.NewBLSAddress(buf)
if err != nil {
panic(err)
}
return address
}
func MustNewActorAddr(data string) addr.Address {
address, err := addr.NewActorAddress([]byte(data))
if err != nil {
panic(err)
}
return address
}
func MustIDFromAddress(a addr.Address) uint64 {
if a.Protocol() != addr.ID {
panic("must be ID protocol address")
}
id, _, err := varint.FromUvarint(a.Payload())
if err != nil {
panic(err)
}
return id
}

View File

@ -1,19 +0,0 @@
package chain
import (
"github.com/filecoin-project/go-address"
builtin_spec "github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/cron"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/chain/types"
)
func (mp *MessageProducer) CronConstructor(from, to address.Address, params *cron.ConstructorParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsCron.Constructor, ser, opts...)
}
func (mp *MessageProducer) CronEpochTick(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsCron.EpochTick, ser, opts...)
}

View File

@ -1,18 +0,0 @@
package chain
import (
"github.com/filecoin-project/go-address"
builtin_spec "github.com/filecoin-project/specs-actors/actors/builtin"
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
"github.com/filecoin-project/lotus/chain/types"
)
func (mp *MessageProducer) InitConstructor(from, to address.Address, params *init_.ConstructorParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsInit.Constructor, ser, opts...)
}
func (mp *MessageProducer) InitExec(from, to address.Address, params *init_.ExecParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsInit.Exec, ser, opts...)
}

View File

@ -1,47 +0,0 @@
package chain
import (
"github.com/filecoin-project/go-address"
builtin_spec "github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/chain/types"
)
func (mp *MessageProducer) MarketConstructor(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMarket.Constructor, ser, opts...)
}
func (mp *MessageProducer) MarketAddBalance(from, to address.Address, params *address.Address, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMarket.AddBalance, ser, opts...)
}
func (mp *MessageProducer) MarketWithdrawBalance(from, to address.Address, params *market.WithdrawBalanceParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMarket.WithdrawBalance, ser, opts...)
}
func (mp *MessageProducer) MarketPublishStorageDeals(from, to address.Address, params *market.PublishStorageDealsParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMarket.PublishStorageDeals, ser, opts...)
}
func (mp *MessageProducer) MarketVerifyDealsForActivation(from, to address.Address, params *market.VerifyDealsForActivationParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMarket.VerifyDealsForActivation, ser, opts...)
}
func (mp *MessageProducer) MarketActivateDeals(from, to address.Address, params *market.ActivateDealsParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMarket.ActivateDeals, ser, opts...)
}
func (mp *MessageProducer) MarketOnMinerSectorsTerminate(from, to address.Address, params *market.OnMinerSectorsTerminateParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMarket.OnMinerSectorsTerminate, ser, opts...)
}
func (mp *MessageProducer) MarketComputeDataCommitment(from, to address.Address, params *market.ComputeDataCommitmentParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMarket.ComputeDataCommitment, ser, opts...)
}
func (mp *MessageProducer) MarketCronTick(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMarket.CronTick, ser, opts...)
}

View File

@ -1,94 +0,0 @@
package chain
import (
address "github.com/filecoin-project/go-address"
abi_spec "github.com/filecoin-project/specs-actors/actors/abi"
big_spec "github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/lotus/chain/types"
)
// The created messages are retained for subsequent export or evaluation in a VM.
type MessageProducer struct {
defaults msgOpts // Note non-pointer reference.
messages []*types.Message
}
// NewMessageProducer creates a new message producer, delegating message creation to `factory`.
func NewMessageProducer(defaultGasLimit int64, defaultGasPrice big_spec.Int) *MessageProducer {
return &MessageProducer{
defaults: msgOpts{
value: big_spec.Zero(),
gasLimit: defaultGasLimit,
gasPrice: defaultGasPrice,
},
}
}
// Messages returns a slice containing all messages created by the producer.
func (mp *MessageProducer) Messages() []*types.Message {
return mp.messages
}
// BuildFull creates and returns a single message.
func (mp *MessageProducer) BuildFull(from, to address.Address, method abi_spec.MethodNum, nonce uint64, value, gasPrice big_spec.Int, gasLimit int64, params []byte) *types.Message {
fm := &types.Message{
To: to,
From: from,
Nonce: nonce,
Value: value,
Method: method,
Params: params,
GasPrice: gasPrice,
GasLimit: gasLimit,
}
mp.messages = append(mp.messages, fm)
return fm
}
// Build creates and returns a single message, using default gas parameters unless modified by `opts`.
func (mp *MessageProducer) Build(from, to address.Address, method abi_spec.MethodNum, params []byte, opts ...MsgOpt) *types.Message {
values := mp.defaults
for _, opt := range opts {
opt(&values)
}
return mp.BuildFull(from, to, method, values.nonce, values.value, values.gasPrice, values.gasLimit, params)
}
// msgOpts specifies value and gas parameters for a message, supporting a functional options pattern
// for concise but customizable message construction.
type msgOpts struct {
nonce uint64
value big_spec.Int
gasPrice big_spec.Int
gasLimit int64
}
// MsgOpt is an option configuring message value or gas parameters.
type MsgOpt func(*msgOpts)
func Value(value big_spec.Int) MsgOpt {
return func(opts *msgOpts) {
opts.value = value
}
}
func Nonce(n uint64) MsgOpt {
return func(opts *msgOpts) {
opts.nonce = n
}
}
func GasLimit(limit int64) MsgOpt {
return func(opts *msgOpts) {
opts.gasLimit = limit
}
}
func GasPrice(price int64) MsgOpt {
return func(opts *msgOpts) {
opts.gasPrice = big_spec.NewInt(price)
}
}

View File

@ -1,85 +0,0 @@
package chain
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi/big"
builtin_spec "github.com/filecoin-project/specs-actors/actors/builtin"
"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/util/adt"
"github.com/filecoin-project/lotus/chain/types"
)
func (mp *MessageProducer) MinerConstructor(from, to address.Address, params *power.MinerConstructorParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.Constructor, ser, opts...)
}
func (mp *MessageProducer) MinerControlAddresses(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.ControlAddresses, ser, opts...)
}
func (mp *MessageProducer) MinerChangeWorkerAddress(from, to address.Address, params *miner.ChangeWorkerAddressParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.ChangeWorkerAddress, ser, opts...)
}
func (mp *MessageProducer) MinerChangePeerID(from, to address.Address, params *miner.ChangePeerIDParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.ChangePeerID, ser, opts...)
}
func (mp *MessageProducer) MinerSubmitWindowedPoSt(from, to address.Address, params *miner.SubmitWindowedPoStParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.SubmitWindowedPoSt, ser, opts...)
}
func (mp *MessageProducer) MinerPreCommitSector(from, to address.Address, params *miner.SectorPreCommitInfo, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.PreCommitSector, ser, opts...)
}
func (mp *MessageProducer) MinerProveCommitSector(from, to address.Address, params *miner.ProveCommitSectorParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.ProveCommitSector, ser, opts...)
}
func (mp *MessageProducer) MinerExtendSectorExpiration(from, to address.Address, params *miner.ExtendSectorExpirationParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.ExtendSectorExpiration, ser, opts...)
}
func (mp *MessageProducer) MinerTerminateSectors(from, to address.Address, params *miner.TerminateSectorsParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.TerminateSectors, ser, opts...)
}
func (mp *MessageProducer) MinerDeclareFaults(from, to address.Address, params *miner.DeclareFaultsParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.DeclareFaults, ser, opts...)
}
func (mp *MessageProducer) MinerDeclareFaultsRecovered(from, to address.Address, params *miner.DeclareFaultsRecoveredParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.DeclareFaultsRecovered, ser, opts...)
}
func (mp *MessageProducer) MinerOnDeferredCronEvent(from, to address.Address, params *miner.CronEventPayload, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.OnDeferredCronEvent, ser, opts...)
}
func (mp *MessageProducer) MinerCheckSectorProven(from, to address.Address, params *miner.CheckSectorProvenParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.CheckSectorProven, ser, opts...)
}
func (mp *MessageProducer) MinerAddLockedFund(from, to address.Address, params *big.Int, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.AddLockedFund, ser, opts...)
}
func (mp *MessageProducer) MinerReportConsensusFault(from, to address.Address, params *miner.ReportConsensusFaultParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.ReportConsensusFault, ser, opts...)
}
func (mp *MessageProducer) MinerWithdrawBalance(from, to address.Address, params *miner.WithdrawBalanceParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.WithdrawBalance, ser, opts...)
}
func (mp *MessageProducer) MinerConfirmSectorProofsValid(from, to address.Address, params *builtin_spec.ConfirmSectorProofsParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.ConfirmSectorProofsValid, ser, opts...)
}
func (mp *MessageProducer) MinerChangeMultiaddrs(from, to address.Address, params *miner.ChangeMultiaddrsParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMiner.ChangeMultiaddrs, ser, opts...)
}

View File

@ -1,42 +0,0 @@
package chain
import (
"github.com/filecoin-project/go-address"
builtin_spec "github.com/filecoin-project/specs-actors/actors/builtin"
multisig "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/types"
)
func (mp *MessageProducer) MultisigConstructor(from, to address.Address, params *multisig.ConstructorParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMultisig.Constructor, ser, opts...)
}
func (mp *MessageProducer) MultisigPropose(from, to address.Address, params *multisig.ProposeParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMultisig.Propose, ser, opts...)
}
func (mp *MessageProducer) MultisigApprove(from, to address.Address, params *multisig.TxnIDParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMultisig.Approve, ser, opts...)
}
func (mp *MessageProducer) MultisigCancel(from, to address.Address, params *multisig.TxnIDParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMultisig.Cancel, ser, opts...)
}
func (mp *MessageProducer) MultisigAddSigner(from, to address.Address, params *multisig.AddSignerParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMultisig.AddSigner, ser, opts...)
}
func (mp *MessageProducer) MultisigRemoveSigner(from, to address.Address, params *multisig.RemoveSignerParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMultisig.RemoveSigner, ser, opts...)
}
func (mp *MessageProducer) MultisigSwapSigner(from, to address.Address, params *multisig.SwapSignerParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMultisig.SwapSigner, ser, opts...)
}
func (mp *MessageProducer) MultisigChangeNumApprovalsThreshold(from, to address.Address, params *multisig.ChangeNumApprovalsThresholdParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsMultisig.ChangeNumApprovalsThreshold, ser, opts...)
}

View File

@ -1,27 +0,0 @@
package chain
import (
"github.com/filecoin-project/go-address"
builtin_spec "github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/chain/types"
)
func (mp *MessageProducer) PaychConstructor(from, to address.Address, params *paych.ConstructorParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPaych.Constructor, ser, opts...)
}
func (mp *MessageProducer) PaychUpdateChannelState(from, to address.Address, params *paych.UpdateChannelStateParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPaych.UpdateChannelState, ser, opts...)
}
func (mp *MessageProducer) PaychSettle(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPaych.Settle, ser, opts...)
}
func (mp *MessageProducer) PaychCollect(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPaych.Collect, ser, opts...)
}

View File

@ -1,49 +0,0 @@
package chain
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
builtin_spec "github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/chain/types"
)
func (mp *MessageProducer) PowerConstructor(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPower.Constructor, ser, opts...)
}
func (mp *MessageProducer) PowerCreateMiner(from, to address.Address, params *power.CreateMinerParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPower.CreateMiner, ser, opts...)
}
func (mp *MessageProducer) PowerUpdateClaimedPower(from, to address.Address, params *power.UpdateClaimedPowerParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPower.UpdateClaimedPower, ser, opts...)
}
func (mp *MessageProducer) PowerEnrollCronEvent(from, to address.Address, params *power.EnrollCronEventParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPower.EnrollCronEvent, ser, opts...)
}
func (mp *MessageProducer) PowerOnEpochTickEnd(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPower.OnEpochTickEnd, ser, opts...)
}
func (mp *MessageProducer) PowerUpdatePledgeTotal(from, to address.Address, params *big.Int, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPower.UpdatePledgeTotal, ser, opts...)
}
func (mp *MessageProducer) PowerOnConsensusFault(from, to address.Address, params *big.Int, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPower.OnConsensusFault, ser, opts...)
}
func (mp *MessageProducer) PowerSubmitPoRepForBulkVerify(from, to address.Address, params *abi.SealVerifyInfo, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPower.SubmitPoRepForBulkVerify, ser, opts...)
}
func (mp *MessageProducer) PowerCurrentTotalPower(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsPower.CurrentTotalPower, ser, opts...)
}

View File

@ -1,18 +0,0 @@
package chain
import (
"github.com/filecoin-project/go-address"
puppet "github.com/filecoin-project/specs-actors/actors/puppet"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/chain/types"
)
func (mp *MessageProducer) PuppetConstructor(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, puppet.MethodsPuppet.Constructor, ser, opts...)
}
func (mp *MessageProducer) PuppetSend(from, to address.Address, params *puppet.SendParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, puppet.MethodsPuppet.Send, ser, opts...)
}

View File

@ -1,28 +0,0 @@
package chain
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi/big"
builtin_spec "github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/chain/types"
)
func (mp *MessageProducer) RewardConstructor(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsReward.Constructor, ser, opts...)
}
func (mp *MessageProducer) RewardAwardBlockReward(from, to address.Address, params *reward.AwardBlockRewardParams, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsReward.AwardBlockReward, ser, opts...)
}
func (mp *MessageProducer) RewardLastPerEpochReward(from, to address.Address, params *adt.EmptyValue, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsReward.ThisEpochReward, ser, opts...)
}
func (mp *MessageProducer) RewardUpdateNetworkKPI(from, to address.Address, params *big.Int, opts ...MsgOpt) *types.Message {
ser := MustSerialize(params)
return mp.Build(from, to, builtin_spec.MethodsReward.UpdateNetworkKPI, ser, opts...)
}

View File

@ -1,38 +0,0 @@
package chain
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))
}

View File

@ -1,52 +0,0 @@
package chain
import (
"github.com/filecoin-project/go-address"
abi_spec "github.com/filecoin-project/specs-actors/actors/abi"
builtin_spec "github.com/filecoin-project/specs-actors/actors/builtin"
init_spec "github.com/filecoin-project/specs-actors/actors/builtin/init"
multisig_spec "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
paych_spec "github.com/filecoin-project/specs-actors/actors/builtin/paych"
power_spec "github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/filecoin-project/lotus/chain/types"
)
var noParams []byte
// Transfer builds a simple value transfer message and returns it.
func (mp *MessageProducer) Transfer(from, to address.Address, opts ...MsgOpt) *types.Message {
return mp.Build(from, to, builtin_spec.MethodSend, noParams, opts...)
}
func (mp *MessageProducer) CreatePaymentChannelActor(from, to address.Address, opts ...MsgOpt) *types.Message {
return mp.InitExec(from, builtin_spec.InitActorAddr, &init_spec.ExecParams{
CodeCID: builtin_spec.PaymentChannelActorCodeID,
ConstructorParams: MustSerialize(&paych_spec.ConstructorParams{
From: from,
To: to,
}),
}, opts...)
}
func (mp *MessageProducer) CreateMultisigActor(from address.Address, signers []address.Address, unlockDuration abi_spec.ChainEpoch, numApprovals uint64, opts ...MsgOpt) *types.Message {
return mp.InitExec(from, builtin_spec.InitActorAddr, &init_spec.ExecParams{
CodeCID: builtin_spec.MultisigActorCodeID,
ConstructorParams: MustSerialize(&multisig_spec.ConstructorParams{
Signers: signers,
NumApprovalsThreshold: numApprovals,
UnlockDuration: unlockDuration,
}),
}, opts...)
}
func (mp *MessageProducer) CreateMinerActor(owner, worker address.Address, sealProofType abi_spec.RegisteredSealProof, pid peer.ID, maddrs []abi_spec.Multiaddrs, opts ...MsgOpt) *types.Message {
return mp.PowerCreateMiner(owner, builtin_spec.StoragePowerActorAddr, &power_spec.CreateMinerParams{
Worker: worker,
Owner: owner,
SealProofType: sealProofType,
Peer: abi_spec.PeerID(pid),
Multiaddrs: maddrs,
}, opts...)
}

View File

@ -1,14 +0,0 @@
package types
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types"
)
// BlockMessagesInfo contains messages for one block in a tipset.
type BlockMessagesInfo struct {
BLSMessages []*types.Message
SECPMessages []*types.SignedMessage
Miner address.Address
TicketCount int64
}

View File

@ -1,17 +0,0 @@
package types
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
)
// ExecutionContext provides the context for execution of a message.
type ExecutionContext struct {
Epoch abi.ChainEpoch // The epoch number ("height") during which a message is executed.
Miner address.Address // The miner actor which earns gas fees from message execution.
}
// NewExecutionContext builds a new execution context.
func NewExecutionContext(epoch int64, miner address.Address) *ExecutionContext {
return &ExecutionContext{abi.ChainEpoch(epoch), miner}
}

View File

@ -1,20 +0,0 @@
package types
import (
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
)
// MessageReceipt is the return value of message application.
type MessageReceipt struct {
ExitCode exitcode.ExitCode
ReturnValue []byte
GasUsed GasUnits
}
type GasUnits int64
func (gu GasUnits) Big() big.Int {
return big.NewInt(int64(gu))
}

View File

@ -1,64 +0,0 @@
package types
import (
"fmt"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/ipfs/go-cid"
)
type Trackable interface {
GoSyntax() string
GoContainer() string
}
var _ Trackable = (*ApplyMessageResult)(nil)
var _ Trackable = (*ApplyTipSetResult)(nil)
type ApplyMessageResult struct {
Receipt MessageReceipt
Penalty abi.TokenAmount
Reward abi.TokenAmount
Root string
}
func (mr ApplyMessageResult) GoSyntax() string {
return fmt.Sprintf("types.ApplyMessageResult{Receipt: %#v, Penalty: abi.NewTokenAmount(%d), Reward: abi.NewTokenAmount(%d), Root: \"%s\"}", mr.Receipt, mr.Penalty, mr.Reward, mr.Root)
}
func (mr ApplyMessageResult) GoContainer() string {
return "[]types.ApplyMessageResult"
}
func (mr ApplyMessageResult) StateRoot() cid.Cid {
root, err := cid.Decode(mr.Root)
if err != nil {
panic(err)
}
return root
}
func (mr ApplyMessageResult) GasUsed() GasUnits {
return mr.Receipt.GasUsed
}
type ApplyTipSetResult struct {
Receipts []MessageReceipt
Root string
}
func (tr ApplyTipSetResult) GoSyntax() string {
return fmt.Sprintf("%#v", tr)
}
func (tr ApplyTipSetResult) GoContainer() string {
return "[]types.ApplyTipSetResult"
}
func (tr ApplyTipSetResult) StateRoot() cid.Cid {
root, err := cid.Decode(tr.Root)
if err != nil {
panic(err)
}
return root
}

View File

@ -1,15 +0,0 @@
package types
import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/ipfs/go-cid"
)
type PreSeal struct {
CommR cid.Cid
CommD cid.Cid
SectorID abi.SectorNumber
Deal market.DealProposal
ProofType abi.RegisteredProof
}

View File

@ -1,52 +0,0 @@
package wallet
import (
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/crypto"
ffi "github.com/filecoin-project/filecoin-ffi"
)
type blsSigner struct{}
func (blsSigner) GenPrivate() ([]byte, error) {
pk := ffi.PrivateKeyGenerate()
return pk[:], nil
}
func (blsSigner) ToPublic(priv []byte) ([]byte, error) {
var pk ffi.PrivateKey
copy(pk[:], priv)
pub := ffi.PrivateKeyPublicKey(pk)
return pub[:], nil
}
func (blsSigner) Sign(p []byte, msg []byte) ([]byte, error) {
var pk ffi.PrivateKey
copy(pk[:], p)
sig := ffi.PrivateKeySign(pk, msg)
return sig[:], nil
}
func (blsSigner) Verify(sig []byte, a address.Address, msg []byte) error {
digests := []ffi.Digest{ffi.Hash(ffi.Message(msg))}
var pubk ffi.PublicKey
copy(pubk[:], a.Payload())
pubkeys := []ffi.PublicKey{pubk}
var s ffi.Signature
copy(s[:], sig)
if !ffi.Verify(&s, digests, pubkeys) {
return fmt.Errorf("bls signature failed to verify")
}
return nil
}
func init() {
RegisterSignature(crypto.SigTypeBLS, blsSigner{})
}

View File

@ -1,57 +0,0 @@
package wallet
import (
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-crypto"
crypto2 "github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/minio/blake2b-simd"
)
type secpSigner struct{}
func (secpSigner) GenPrivate() ([]byte, error) {
priv, err := crypto.GenerateKey()
if err != nil {
return nil, err
}
return priv, nil
}
func (secpSigner) ToPublic(pk []byte) ([]byte, error) {
return crypto.PublicKey(pk), nil
}
func (secpSigner) Sign(pk []byte, msg []byte) ([]byte, error) {
b2sum := blake2b.Sum256(msg)
sig, err := crypto.Sign(pk, b2sum[:])
if err != nil {
return nil, err
}
return sig, nil
}
func (secpSigner) Verify(sig []byte, a address.Address, msg []byte) error {
b2sum := blake2b.Sum256(msg)
pubk, err := crypto.EcRecover(b2sum[:], sig)
if err != nil {
return err
}
maybeaddr, err := address.NewSecp256k1Address(pubk)
if err != nil {
return err
}
if a != maybeaddr {
return fmt.Errorf("signature did not match")
}
return nil
}
func init() {
RegisterSignature(crypto2.SigTypeSecp256k1, secpSigner{})
}

View File

@ -1,113 +0,0 @@
package wallet
import (
"errors"
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/ipsn/go-secp256k1"
blake2b "github.com/minio/blake2b-simd"
bls "github.com/filecoin-project/filecoin-ffi"
)
// KeyInfo is used for storing keys in KeyStore
type KeyInfo struct {
Type crypto.SigType
PrivateKey []byte
}
type Key struct {
KeyInfo
PublicKey []byte
Address address.Address
}
func NewKey(keyinfo KeyInfo) (*Key, error) {
k := &Key{
KeyInfo: keyinfo,
}
var err error
k.PublicKey, err = ToPublic(k.Type, k.PrivateKey)
if err != nil {
return nil, err
}
switch k.Type {
case crypto.SigTypeSecp256k1:
k.Address, err = address.NewSecp256k1Address(k.PublicKey)
if err != nil {
return nil, fmt.Errorf("converting Secp256k1 to address: %w", err)
}
case crypto.SigTypeBLS:
k.Address, err = address.NewBLSAddress(k.PublicKey)
if err != nil {
return nil, fmt.Errorf("converting BLS to address: %w", err)
}
default:
return nil, errors.New("unknown key type")
}
return k, nil
}
func Sign(data []byte, secretKey []byte, sigtype crypto.SigType) (crypto.Signature, error) {
var signature []byte
var err error
if sigtype == crypto.SigTypeSecp256k1 {
hash := blake2b.Sum256(data)
signature, err = SignSecp(secretKey, hash[:])
} else if sigtype == crypto.SigTypeBLS {
signature, err = SignBLS(secretKey, data)
} else {
err = fmt.Errorf("unknown signature type %d", sigtype)
}
return crypto.Signature{
Type: sigtype,
Data: signature,
}, err
}
func SignSecp(sk, msg []byte) ([]byte, error) {
return secp256k1.Sign(msg, sk)
}
// SignBLS signs the given message with BLS.
func SignBLS(sk, msg []byte) ([]byte, error) {
var privateKey bls.PrivateKey
copy(privateKey[:], sk)
sig := bls.PrivateKeySign(privateKey, msg)
return sig[:], nil
}
// ported from lotus
// SigShim is used for introducing signature functions
type SigShim interface {
GenPrivate() ([]byte, error)
ToPublic(pk []byte) ([]byte, error)
Sign(pk []byte, msg []byte) ([]byte, error)
Verify(sig []byte, a address.Address, msg []byte) error
}
var sigs map[crypto.SigType]SigShim
// RegisterSig should be only used during init
func RegisterSignature(typ crypto.SigType, vs SigShim) {
if sigs == nil {
sigs = make(map[crypto.SigType]SigShim)
}
sigs[typ] = vs
}
// ToPublic converts private key to public key
func ToPublic(sigType crypto.SigType, pk []byte) ([]byte, error) {
sv, ok := sigs[sigType]
if !ok {
return nil, fmt.Errorf("cannot generate public key of unsupported type: %v", sigType)
}
return sv.ToPublic(pk)
}

View File

@ -1,150 +0,0 @@
package drivers
import (
"context"
"errors"
acrypto "github.com/filecoin-project/specs-actors/actors/crypto"
"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/puppet"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
vtypes "github.com/filecoin-project/oni/tvx/chain/types"
)
// Applier applies messages to state trees and storage.
type Applier struct {
stateWrapper *StateWrapper
syscalls vm.SyscallBuilder
}
func NewApplier(sw *StateWrapper, syscalls vm.SyscallBuilder) *Applier {
return &Applier{sw, syscalls}
}
func (a *Applier) ApplyMessage(epoch abi.ChainEpoch, lm *types.Message) (vtypes.ApplyMessageResult, error) {
receipt, penalty, reward, err := a.applyMessage(epoch, lm)
return vtypes.ApplyMessageResult{
Receipt: receipt,
Penalty: penalty,
Reward: reward,
Root: a.stateWrapper.Root().String(),
}, err
}
func (a *Applier) ApplySignedMessage(epoch abi.ChainEpoch, msg *types.SignedMessage) (vtypes.ApplyMessageResult, error) {
var lm types.ChainMsg
switch msg.Signature.Type {
case acrypto.SigTypeSecp256k1:
lm = msg
case acrypto.SigTypeBLS:
lm = &msg.Message
default:
return vtypes.ApplyMessageResult{}, errors.New("Unknown signature type")
}
// TODO: Validate the sig first
receipt, penalty, reward, err := a.applyMessage(epoch, lm)
return vtypes.ApplyMessageResult{
Receipt: receipt,
Penalty: penalty,
Reward: reward,
Root: a.stateWrapper.Root().String(),
}, err
}
func (a *Applier) ApplyTipSetMessages(epoch abi.ChainEpoch, blocks []vtypes.BlockMessagesInfo, rnd RandomnessSource) (vtypes.ApplyTipSetResult, error) {
cs := store.NewChainStore(a.stateWrapper.bs, a.stateWrapper.ds, a.syscalls)
sm := stmgr.NewStateManager(cs)
var bms []stmgr.BlockMessages
for _, b := range blocks {
bm := stmgr.BlockMessages{
Miner: b.Miner,
WinCount: 1,
}
for _, m := range b.BLSMessages {
bm.BlsMessages = append(bm.BlsMessages, m)
}
for _, m := range b.SECPMessages {
bm.SecpkMessages = append(bm.SecpkMessages, m)
}
bms = append(bms, bm)
}
var receipts []vtypes.MessageReceipt
sroot, _, err := sm.ApplyBlocks(context.TODO(), epoch-1, a.stateWrapper.Root(), bms, epoch, &randWrapper{rnd}, func(c cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
if msg.From == builtin.SystemActorAddr {
return nil // ignore reward and cron calls
}
rval := ret.Return
if rval == nil {
rval = []byte{} // chain validation tests expect empty arrays to not be nil...
}
receipts = append(receipts, vtypes.MessageReceipt{
ExitCode: ret.ExitCode,
ReturnValue: rval,
GasUsed: vtypes.GasUnits(ret.GasUsed),
})
return nil
})
if err != nil {
return vtypes.ApplyTipSetResult{}, err
}
a.stateWrapper.stateRoot = sroot
return vtypes.ApplyTipSetResult{
Receipts: receipts,
Root: a.stateWrapper.Root().String(),
}, nil
}
func (a *Applier) applyMessage(epoch abi.ChainEpoch, lm types.ChainMsg) (vtypes.MessageReceipt, abi.TokenAmount, abi.TokenAmount, error) {
ctx := context.TODO()
base := a.stateWrapper.Root()
lotusVM, err := vm.NewVM(base, epoch, &vmRand{}, a.stateWrapper.bs, a.syscalls, nil)
// need to modify the VM invoker to add the puppet actor
chainValInvoker := vm.NewInvoker()
chainValInvoker.Register(puppet.PuppetActorCodeID, puppet.Actor{}, puppet.State{})
lotusVM.SetInvoker(chainValInvoker)
if err != nil {
return vtypes.MessageReceipt{}, big.Zero(), big.Zero(), err
}
ret, err := lotusVM.ApplyMessage(ctx, lm)
if err != nil {
return vtypes.MessageReceipt{}, big.Zero(), big.Zero(), err
}
rval := ret.Return
if rval == nil {
rval = []byte{}
}
a.stateWrapper.stateRoot, err = lotusVM.Flush(ctx)
if err != nil {
return vtypes.MessageReceipt{}, big.Zero(), big.Zero(), err
}
mr := vtypes.MessageReceipt{
ExitCode: ret.ExitCode,
ReturnValue: rval,
GasUsed: vtypes.GasUnits(ret.GasUsed),
}
return mr, ret.Penalty, abi.NewTokenAmount(ret.GasUsed), nil
}

View File

@ -1,21 +0,0 @@
package drivers
type Config struct {
checkExitCode bool
checkReturnValue bool
}
func NewConfig(exit, ret bool) *Config {
return &Config{
checkExitCode: exit,
checkReturnValue: ret,
}
}
func (v Config) ValidateExitCode() bool {
return v.checkExitCode
}
func (v Config) ValidateReturnValue() bool {
return v.checkReturnValue
}

View File

@ -1,28 +0,0 @@
package drivers
import (
"fmt"
"os"
)
var T dummyTestingT
type dummyTestingT struct{}
func (d dummyTestingT) FailNow() {
panic("fail now")
}
func (d dummyTestingT) Errorf(format string, args ...interface{}) {
fmt.Printf(format, args)
os.Exit(1)
}
func (d dummyTestingT) Fatalf(format string, args ...interface{}) {
d.Errorf(format, args)
}
func (d dummyTestingT) Fatal(args ...interface{}) {
fmt.Println(args)
os.Exit(1)
}

View File

@ -1,105 +0,0 @@
package drivers
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 KeyManager 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 newKeyManager() *KeyManager {
return &KeyManager{
keys: make(map[address.Address]*wallet.Key),
secpSeed: 0,
}
}
func (k *KeyManager) NewSECP256k1AccountAddress() address.Address {
secpKey := k.newSecp256k1Key()
k.keys[secpKey.Address] = secpKey
return secpKey.Address
}
func (k *KeyManager) NewBLSAccountAddress() address.Address {
blsKey := k.newBLSKey()
k.keys[blsKey.Address] = blsKey
return blsKey.Address
}
func (k *KeyManager) Sign(addr address.Address, data []byte) (acrypto.Signature, error) {
ki, ok := k.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 (k *KeyManager) newSecp256k1Key() *wallet.Key {
randSrc := rand.New(rand.NewSource(k.secpSeed))
prv, err := crypto.GenerateKeyFromSeed(randSrc)
if err != nil {
panic(err)
}
k.secpSeed++
key, err := wallet.NewKey(types.KeyInfo{
Type: wallet.KTSecp256k1,
PrivateKey: prv,
})
if err != nil {
panic(err)
}
return key
}
func (k *KeyManager) newBLSKey() *wallet.Key {
// FIXME: bls needs deterministic key generation
//sk := ffi.PrivateKeyGenerate(s.blsSeed)
// s.blsSeed++
sk := [32]byte{}
sk[0] = uint8(k.blsSeed) // hack to keep gas values determinist
k.blsSeed++
key, err := wallet.NewKey(types.KeyInfo{
Type: wallet.KTBLS,
PrivateKey: sk[:],
})
if err != nil {
panic(err)
}
return key
}

View File

@ -1,64 +0,0 @@
package drivers
import (
"encoding/binary"
"testing"
"github.com/filecoin-project/go-address"
commcid "github.com/filecoin-project/go-fil-commcid"
"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/market"
"github.com/filecoin-project/oni/tvx/chain/types"
)
type MockSectorBuilder struct {
t testing.TB
sectorSeq uint64
// PreSeal is intexted by sectorID
MinerSectors map[address.Address][]*types.PreSeal
}
func NewMockSectorBuilder(t testing.TB) *MockSectorBuilder {
return &MockSectorBuilder{
t: t,
sectorSeq: 0,
MinerSectors: make(map[address.Address][]*types.PreSeal),
}
}
func (msb *MockSectorBuilder) NewPreSealedSector(miner, client address.Address, pt abi.RegisteredProof, ssize abi.SectorSize, start, end abi.ChainEpoch) *types.PreSeal {
minerSectors := msb.MinerSectors[miner]
sectorID := len(minerSectors)
token := make([]byte, 32)
binary.PutUvarint(token, msb.sectorSeq)
// the only error we could get is if token isn't 32 long, ignore
D, _ := commcid.DataCommitmentV1ToCID(token)
R, _ := commcid.ReplicaCommitmentV1ToCID(token)
msb.sectorSeq++
preseal := &types.PreSeal{
CommR: R,
CommD: D,
SectorID: abi.SectorNumber(sectorID),
Deal: market.DealProposal{
PieceCID: D,
PieceSize: abi.PaddedPieceSize(ssize),
Client: client,
Provider: miner,
StartEpoch: start,
EndEpoch: end,
// TODO how do we want to interact with these values?
StoragePricePerEpoch: big.Zero(),
ProviderCollateral: big.Zero(),
ClientCollateral: big.Zero(),
},
ProofType: pt,
}
msb.MinerSectors[miner] = append(msb.MinerSectors[miner], preseal)
return preseal
}

View File

@ -1,44 +0,0 @@
package drivers
import (
"context"
abi_spec "github.com/filecoin-project/specs-actors/actors/abi"
acrypto "github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/abi"
)
// RandomnessSource provides randomness to actors.
type RandomnessSource interface {
Randomness(ctx context.Context, tag acrypto.DomainSeparationTag, epoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
}
// Specifies a domain for randomness generation.
type RandomnessType int
type randWrapper struct {
rnd RandomnessSource
}
func (w *randWrapper) GetRandomness(ctx context.Context, pers acrypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return w.rnd.Randomness(ctx, pers, round, entropy)
}
type vmRand struct {
}
func (*vmRand) GetRandomness(ctx context.Context, dst acrypto.DomainSeparationTag, h abi.ChainEpoch, input []byte) ([]byte, error) {
panic("implement me")
}
type fakeRandSrc struct {
}
func (r fakeRandSrc) Randomness(_ context.Context, _ acrypto.DomainSeparationTag, _ abi_spec.ChainEpoch, _ []byte) (abi_spec.Randomness, error) {
return abi_spec.Randomness("sausages"), nil
}
func NewRandomnessSource() RandomnessSource {
return &fakeRandSrc{}
}

View File

@ -1,206 +0,0 @@
package drivers
import (
"context"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/oni/tvx/chain"
abi_spec "github.com/filecoin-project/specs-actors/actors/abi"
big_spec "github.com/filecoin-project/specs-actors/actors/abi/big"
miner_spec "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power_spec "github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/runtime"
adt_spec "github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/ipfs/go-cid"
"github.com/stretchr/testify/require"
cbg "github.com/whyrusleeping/cbor-gen"
builtin_spec "github.com/filecoin-project/specs-actors/actors/builtin"
account_spec "github.com/filecoin-project/specs-actors/actors/builtin/account"
)
var (
SECP = address.SECP256K1
BLS = address.BLS
)
// StateDriver mutates and inspects a state.
type StateDriver struct {
st *StateWrapper
w *KeyManager
rs RandomnessSource
minerInfo *MinerInfo
// Mapping for IDAddresses to their pubkey/actor addresses. Used for lookup when signing messages.
actorIDMap map[address.Address]address.Address
}
// info about the state drivers builtin miner
type MinerInfo struct {
Owner address.Address
OwnerID address.Address
Worker address.Address
WorkerID address.Address
}
// NewStateDriver creates a new state driver for a state.
func NewStateDriver(st *StateWrapper, w *KeyManager) *StateDriver {
return &StateDriver{st, w, NewRandomnessSource(), nil, make(map[address.Address]address.Address)}
}
// State returns the state.
func (d *StateDriver) State() *StateWrapper {
return d.st
}
func (d *StateDriver) Wallet() *KeyManager {
return d.w
}
func (d *StateDriver) Randomness() RandomnessSource {
return d.rs
}
func (d *StateDriver) GetState(c cid.Cid, out cbg.CBORUnmarshaler) {
err := d.st.StoreGet(c, out)
require.NoError(T, err)
}
func (d *StateDriver) PutState(in cbg.CBORMarshaler) cid.Cid {
c, err := d.st.StorePut(in)
require.NoError(T, err)
return c
}
func (d *StateDriver) GetActorState(actorAddr address.Address, out cbg.CBORUnmarshaler) {
actor, err := d.State().Actor(actorAddr)
require.NoError(T, err)
require.NotNil(T, actor)
d.GetState(actor.Head(), out)
}
// NewAccountActor installs a new account actor, returning the address.
func (d *StateDriver) NewAccountActor(addrType address.Protocol, balanceAttoFil abi_spec.TokenAmount) (pubkey address.Address, id address.Address) {
var addr address.Address
switch addrType {
case address.SECP256K1:
addr = d.w.NewSECP256k1AccountAddress()
case address.BLS:
addr = d.w.NewBLSAccountAddress()
default:
require.FailNowf(T, "unsupported address", "protocol for account actor: %v", addrType)
}
_, idAddr, err := d.st.CreateActor(builtin_spec.AccountActorCodeID, addr, balanceAttoFil, &account_spec.State{Address: addr})
require.NoError(T, err)
d.actorIDMap[idAddr] = addr
return addr, idAddr
}
func (d *StateDriver) ActorPubKey(idAddress address.Address) address.Address {
if idAddress.Protocol() != address.ID {
T.Fatalf("ActorPubKey methods expects ID protocol address. actual: %v", idAddress.Protocol())
}
pubkeyAddr, found := d.actorIDMap[idAddress]
if !found {
T.Fatalf("Failed to find pubkey address for: %s", idAddress)
}
return pubkeyAddr
}
func (d *StateDriver) BuiltinMinerInfo() *MinerInfo {
return d.minerInfo
}
// create miner without sending a message. modify the init and power actor manually
func (d *StateDriver) newMinerAccountActor(sealProofType abi_spec.RegisteredSealProof, periodBoundary abi_spec.ChainEpoch) address.Address {
// creat a miner, owner, and its worker
minerOwnerPk, minerOwnerID := d.NewAccountActor(address.SECP256K1, big_spec.NewInt(1_000_000_000))
minerWorkerPk, minerWorkerID := d.NewAccountActor(address.BLS, big_spec.Zero())
expectedMinerActorIDAddress := chain.MustNewIDAddr(chain.MustIDFromAddress(minerWorkerID) + 1)
minerActorAddrs := computeInitActorExecReturn(minerWorkerPk, 0, 1, expectedMinerActorIDAddress)
d.minerInfo = &MinerInfo{
Owner: minerOwnerPk,
OwnerID: minerOwnerID,
Worker: minerWorkerPk,
WorkerID: minerWorkerID,
}
ss, err := sealProofType.SectorSize()
require.NoError(T, err)
ps, err := sealProofType.WindowPoStPartitionSectors()
require.NoError(T, err)
mi := &miner_spec.MinerInfo{
Owner: minerOwnerID,
Worker: minerWorkerID,
PendingWorkerKey: nil,
PeerId: abi_spec.PeerID("chain-validation"),
Multiaddrs: nil,
SealProofType: sealProofType,
SectorSize: ss,
WindowPoStPartitionSectors: ps,
}
mc, err := d.st.StorePut(mi)
require.NoError(T, err)
// create the miner actor s.t. it exists in the init actors map
minerState, err := miner_spec.ConstructState(mc, periodBoundary, EmptyBitfieldCid, EmptyArrayCid, EmptyMapCid, EmptyDeadlinesCid)
require.NoError(T, err)
_, minerActorIDAddr, err := d.State().CreateActor(builtin_spec.StorageMinerActorCodeID, minerActorAddrs.RobustAddress, big_spec.Zero(), minerState)
require.NoError(T, err)
require.Equal(T, expectedMinerActorIDAddress, minerActorIDAddr)
// a 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_spec.State
d.GetActorState(builtin_spec.StoragePowerActorAddr, &spa)
// set the miners claim
hm, err := adt_spec.AsMap(AsStore(d.State()), spa.Claims)
require.NoError(T, err)
// add claim for the miner
err = hm.Put(adt_spec.AddrKey(minerActorIDAddr), &power_spec.Claim{
RawBytePower: abi_spec.NewStoragePower(0),
QualityAdjPower: abi_spec.NewTokenAmount(0),
})
require.NoError(T, err)
// save the claim
spa.Claims, err = hm.Root()
require.NoError(T, err)
// update miner count
spa.MinerCount += 1
// update storage power actor's state in the tree
d.PutState(&spa)
return minerActorIDAddr
}
func AsStore(vmw *StateWrapper) adt_spec.Store {
return &storeWrapper{vmw: vmw}
}
type storeWrapper struct {
vmw *StateWrapper
}
func (s storeWrapper) Context() context.Context {
return context.TODO()
}
func (s storeWrapper) Get(ctx context.Context, c cid.Cid, out interface{}) error {
return s.vmw.StoreGet(c, out.(runtime.CBORUnmarshaler))
}
func (s storeWrapper) Put(ctx context.Context, v interface{}) (cid.Cid, error) {
return s.vmw.StorePut(v.(runtime.CBORMarshaler))
}

View File

@ -1,198 +0,0 @@
package drivers
import (
"context"
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/lib/blockstore"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/ipfs/go-datastore"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/lotus/chain/types"
)
type StateWrapper struct {
// The blockstore underlying the state tree and storage.
bs blockstore.Blockstore
ds datastore.Batching
// HAMT-CBOR store on top of the blockstore.
cst cbor.IpldStore
// CID of the root of the state tree.
stateRoot cid.Cid
}
func NewStateWrapper() *StateWrapper {
bs := blockstore.NewTemporary()
cst := cbor.NewCborStore(bs)
// Put EmptyObjectCid value in the store. When an actor is initially created its Head is set to this value.
_, err := cst.Put(context.TODO(), map[string]string{})
if err != nil {
panic(err)
}
treeImpl, err := state.NewStateTree(cst)
if err != nil {
panic(err) // Never returns error, the error return should be removed.
}
root, err := treeImpl.Flush(context.TODO())
if err != nil {
panic(err)
}
return &StateWrapper{
bs: bs,
ds: datastore.NewMapDatastore(),
cst: cst,
stateRoot: root,
}
}
func (s *StateWrapper) Root() cid.Cid {
return s.stateRoot
}
// StoreGet the value at key from vm store
func (s *StateWrapper) StoreGet(key cid.Cid, out runtime.CBORUnmarshaler) error {
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
return err
}
return tree.Store.Get(context.Background(), key, out)
}
// StorePut `value` into vm store
func (s *StateWrapper) StorePut(value runtime.CBORMarshaler) (cid.Cid, error) {
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
return cid.Undef, err
}
return tree.Store.Put(context.Background(), value)
}
func (s *StateWrapper) Actor(addr address.Address) (Actor, error) {
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
return nil, err
}
fcActor, err := tree.GetActor(addr)
if err != nil {
return nil, err
}
return &actorWrapper{*fcActor}, nil
}
func (s *StateWrapper) SetActorState(addr address.Address, balance abi.TokenAmount, actorState runtime.CBORMarshaler) (Actor, error) {
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
return nil, err
}
// actor should exist
act, err := tree.GetActor(addr)
if err != nil {
return nil, err
}
// add the state to the store and get a new head cid
actHead, err := tree.Store.Put(context.Background(), actorState)
if err != nil {
return nil, err
}
// update the actor object with new head and balance parameter
actr := &actorWrapper{types.Actor{
Code: act.Code,
Nonce: act.Nonce,
// updates
Head: actHead,
Balance: balance,
}}
if err := tree.SetActor(addr, &actr.Actor); err != nil {
return nil, err
}
return actr, s.flush(tree)
}
func (s *StateWrapper) CreateActor(code cid.Cid, addr address.Address, balance abi.TokenAmount, actorState runtime.CBORMarshaler) (Actor, address.Address, error) {
idAddr := addr
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
return nil, address.Undef, err
}
if addr.Protocol() != address.ID {
actHead, err := tree.Store.Put(context.Background(), actorState)
if err != nil {
return nil, address.Undef, err
}
actr := &actorWrapper{types.Actor{
Code: code,
Head: actHead,
Balance: balance,
}}
idAddr, err = tree.RegisterNewAddress(addr)
if err != nil {
return nil, address.Undef, fmt.Errorf("register new address for actor: %w", err)
}
if err := tree.SetActor(addr, &actr.Actor); err != nil {
return nil, address.Undef, fmt.Errorf("setting new actor for actor: %w", err)
}
}
// store newState
head, err := tree.Store.Put(context.Background(), actorState)
if err != nil {
return nil, address.Undef, err
}
// create and store actor object
a := types.Actor{
Code: code,
Head: head,
Balance: balance,
}
if err := tree.SetActor(idAddr, &a); err != nil {
return nil, address.Undef, err
}
return &actorWrapper{a}, idAddr, s.flush(tree)
}
// Flushes a state tree to storage and sets this state's root to that tree's root CID.
func (s *StateWrapper) flush(tree *state.StateTree) (err error) {
s.stateRoot, err = tree.Flush(context.TODO())
return
}
//
// Actor Wrapper
//
type actorWrapper struct {
types.Actor
}
func (a *actorWrapper) Code() cid.Cid {
return a.Actor.Code
}
func (a *actorWrapper) Head() cid.Cid {
return a.Actor.Head
}
func (a *actorWrapper) CallSeqNum() uint64 {
return a.Actor.Nonce
}
func (a *actorWrapper) Balance() big.Int {
return a.Actor.Balance
}

View File

@ -1,110 +0,0 @@
package drivers
import (
"bytes"
"github.com/filecoin-project/go-address"
commcid "github.com/filecoin-project/go-fil-commcid"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/ipfs/go-cid"
"github.com/minio/blake2b-simd"
)
var fakeVerifySignatureFunc = func(signature crypto.Signature, signer address.Address, plaintext []byte) error {
return nil
}
var defaultHashBlake2bFunc = func(data []byte) [32]byte {
return blake2b.Sum256(data)
}
var fakeComputerUnsealedSectorCIDFunc = func(proof abi.RegisteredSealProof, pieces []abi.PieceInfo) (cid.Cid, error) {
// Fake CID computation by hashing the piece info (rather than the real computation over piece commitments).
buf := bytes.Buffer{}
for _, p := range pieces {
err := p.MarshalCBOR(&buf)
if err != nil {
panic(err)
}
}
token := blake2b.Sum256(buf.Bytes())
return commcid.DataCommitmentV1ToCID(token[:])
}
var fakeVerifySealFunc = func(info abi.SealVerifyInfo) error {
return nil
}
var fakeVerifyPoStFunc = func(info abi.WindowPoStVerifyInfo) error {
return nil
}
var fakeBatchVerifySealfunc = func(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) {
out := make(map[address.Address][]bool)
for a, svis := range inp {
res := make([]bool, len(svis))
for i := range res {
res[i] = true
}
out[a] = res
}
return out, nil
}
var panicingVerifyConsensusFaultFunc = func(h1, h2, extra []byte) (*runtime.ConsensusFault, error) {
panic("implement me")
}
type ChainValidationSysCalls struct {
VerifySigFunc func(signature crypto.Signature, signer address.Address, plaintext []byte) error
HashBlake2bFunc func(data []byte) [32]byte
ComputeUnSealedSectorCIDFunc func(proof abi.RegisteredSealProof, pieces []abi.PieceInfo) (cid.Cid, error)
VerifySealFunc func(info abi.SealVerifyInfo) error
VerifyPoStFunc func(info abi.WindowPoStVerifyInfo) error
VerifyConsensusFaultFunc func(h1, h2, extra []byte) (*runtime.ConsensusFault, error)
BatchVerifySealsFunc func(map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error)
}
func NewChainValidationSysCalls() *ChainValidationSysCalls {
return &ChainValidationSysCalls{
HashBlake2bFunc: defaultHashBlake2bFunc,
VerifySigFunc: fakeVerifySignatureFunc,
ComputeUnSealedSectorCIDFunc: fakeComputerUnsealedSectorCIDFunc,
VerifySealFunc: fakeVerifySealFunc,
VerifyPoStFunc: fakeVerifyPoStFunc,
VerifyConsensusFaultFunc: panicingVerifyConsensusFaultFunc,
BatchVerifySealsFunc: fakeBatchVerifySealfunc,
}
}
func (c ChainValidationSysCalls) VerifySignature(signature crypto.Signature, signer address.Address, plaintext []byte) error {
return c.VerifySigFunc(signature, signer, plaintext)
}
func (c ChainValidationSysCalls) HashBlake2b(data []byte) [32]byte {
return c.HashBlake2bFunc(data)
}
func (c ChainValidationSysCalls) ComputeUnsealedSectorCID(proof abi.RegisteredSealProof, pieces []abi.PieceInfo) (cid.Cid, error) {
return c.ComputeUnSealedSectorCIDFunc(proof, pieces)
}
func (c ChainValidationSysCalls) VerifySeal(info abi.SealVerifyInfo) error {
return c.VerifySealFunc(info)
}
func (c ChainValidationSysCalls) VerifyPoSt(info abi.WindowPoStVerifyInfo) error {
return c.VerifyPoStFunc(info)
}
func (c ChainValidationSysCalls) VerifyConsensusFault(h1, h2, extra []byte) (*runtime.ConsensusFault, error) {
return c.VerifyConsensusFaultFunc(h1, h2, extra)
}
func (c ChainValidationSysCalls) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) {
return c.BatchVerifySealsFunc(inp)
}

View File

@ -1,615 +0,0 @@
package drivers
import (
"bytes"
"compress/gzip"
"context"
"encoding/binary"
"fmt"
"io"
"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/go-address"
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"
multisig_spec "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
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"
"github.com/filecoin-project/specs-actors/actors/runtime"
runtime_spec "github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
adt_spec "github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/ipfs/go-blockservice"
cid "github.com/ipfs/go-cid"
datastore "github.com/ipfs/go-datastore"
blockstore "github.com/ipfs/go-ipfs-blockstore"
offline "github.com/ipfs/go-ipfs-exchange-offline"
cbor "github.com/ipfs/go-ipld-cbor"
format "github.com/ipfs/go-ipld-format"
"github.com/ipfs/go-merkledag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/ipld/go-car"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/oni/tvx/chain"
vtypes "github.com/filecoin-project/oni/tvx/chain/types"
"github.com/filecoin-project/oni/tvx/schema"
)
var (
// initialized by calling initializeStoreWithAdtRoots
EmptyArrayCid cid.Cid
EmptyDeadlinesCid cid.Cid
EmptyMapCid cid.Cid
EmptyMultiMapCid cid.Cid
EmptyBitfieldCid cid.Cid
)
var (
DefaultInitActorState ActorState
DefaultRewardActorState ActorState
DefaultBurntFundsActorState ActorState
DefaultStoragePowerActorState ActorState
DefaultStorageMarketActorState ActorState
DefaultSystemActorState ActorState
DefaultCronActorState ActorState
DefaultBuiltinActorsState []ActorState
)
const (
TestSealProofType = abi_spec.RegisteredSealProof_StackedDrg2KiBV1
)
func init() {
ms := newMockStore()
if err := initializeStoreWithAdtRoots(ms); err != nil {
panic(err)
}
DefaultInitActorState = ActorState{
Addr: builtin_spec.InitActorAddr,
Balance: big_spec.Zero(),
Code: builtin_spec.InitActorCodeID,
State: init_spec.ConstructState(EmptyMapCid, "chain-validation"),
}
firstRewardState := reward_spec.ConstructState(big_spec.Zero())
firstRewardState.ThisEpochReward = big_spec.NewInt(1e17)
DefaultRewardActorState = ActorState{
Addr: builtin_spec.RewardActorAddr,
Balance: TotalNetworkBalance,
Code: builtin_spec.RewardActorCodeID,
State: firstRewardState,
}
DefaultBurntFundsActorState = ActorState{
Addr: builtin_spec.BurntFundsActorAddr,
Balance: big_spec.Zero(),
Code: builtin_spec.AccountActorCodeID,
State: &account_spec.State{Address: builtin_spec.BurntFundsActorAddr},
}
DefaultStoragePowerActorState = ActorState{
Addr: builtin_spec.StoragePowerActorAddr,
Balance: big_spec.Zero(),
Code: builtin_spec.StoragePowerActorCodeID,
State: power_spec.ConstructState(EmptyMapCid, EmptyMultiMapCid),
}
DefaultStorageMarketActorState = 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,
},
}
DefaultSystemActorState = ActorState{
Addr: builtin_spec.SystemActorAddr,
Balance: big_spec.Zero(),
Code: builtin_spec.SystemActorCodeID,
State: &system.State{},
}
DefaultCronActorState = 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,
},
}},
}
DefaultBuiltinActorsState = []ActorState{
DefaultInitActorState,
DefaultRewardActorState,
DefaultBurntFundsActorState,
DefaultStoragePowerActorState,
DefaultStorageMarketActorState,
DefaultSystemActorState,
DefaultCronActorState,
}
}
func initializeStoreWithAdtRoots(store adt_spec.Store) error {
var err error
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.Deadline{
Partitions: EmptyArrayCid,
ExpirationsEpochs: EmptyArrayCid,
PostSubmissions: abi_spec.NewBitField(),
EarlyTerminations: abi_spec.NewBitField(),
LiveSectors: 0,
})
if err != nil {
return err
}
emptyBitfield := bitfield.NewFromSet(nil)
EmptyBitfieldCid, err = store.Put(context.TODO(), emptyBitfield)
if err != nil {
return err
}
return nil
}
type mockStore struct {
ctx context.Context
cbor.IpldStore
}
func newMockStore() *mockStore {
bs := blockstore.NewBlockstore(datastore.NewMapDatastore())
cst := cbor.NewCborStore(bs)
return &mockStore{
ctx: context.Background(),
IpldStore: cst,
}
}
func (m mockStore) Context() context.Context {
return m.ctx
}
func NewTestDriver() *TestDriver {
syscalls := NewChainValidationSysCalls()
stateWrapper := NewStateWrapper()
applier := NewApplier(stateWrapper, func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime.Syscalls {
return syscalls
})
sd := NewStateDriver(stateWrapper, newKeyManager())
err := initializeStoreWithAdtRoots(AsStore(sd.st))
require.NoError(T, err)
for _, acts := range DefaultBuiltinActorsState {
_, _, err := sd.State().CreateActor(acts.Code, acts.Addr, acts.Balance, acts.State)
require.NoError(T, err)
}
minerActorIDAddr := sd.newMinerAccountActor(TestSealProofType, abi_spec.ChainEpoch(0))
exeCtx := vtypes.NewExecutionContext(1, minerActorIDAddr)
producer := chain.NewMessageProducer(1000000000, big_spec.NewInt(1)) // gas limit ; gas price
checkExit := true
checkRet := true
config := NewConfig(checkExit, checkRet)
vector := schema.TestVector{
Class: schema.ClassMessage,
Selector: "",
Meta: &schema.Metadata{
ID: "TK",
Version: "TK",
Gen: schema.GenerationData{
Source: "TK",
Version: "TK",
},
},
Pre: &schema.Preconditions{
StateTree: &schema.StateTree{},
},
Post: &schema.Postconditions{
StateTree: &schema.StateTree{},
},
}
return &TestDriver{
StateDriver: sd,
MessageProducer: producer,
ExeCtx: exeCtx,
Config: config,
SysCalls: syscalls,
applier: applier,
Vector: &vector,
}
}
type ActorState struct {
Addr address.Address
Balance abi_spec.TokenAmount
Code cid.Cid
State runtime_spec.CBORMarshaler
}
type TestDriver struct {
*StateDriver
applier *Applier
MessageProducer *chain.MessageProducer
TipSetMessageBuilder *TipSetMessageBuilder
ExeCtx *vtypes.ExecutionContext
Config *Config
SysCalls *ChainValidationSysCalls
// Vector is the test vector that is used when methods are called on the
// driver that apply messages.
Vector *schema.TestVector
}
//
// Unsigned Message Appliers
//
func (td *TestDriver) ApplyMessage(msg *types.Message) vtypes.ApplyMessageResult {
result := td.applyMessage(msg)
return result
}
func (td *TestDriver) ApplyOk(msg *types.Message) vtypes.ApplyMessageResult {
return td.ApplyExpect(msg, EmptyReturnValue)
}
func (td *TestDriver) ApplyExpect(msg *types.Message, retval []byte) vtypes.ApplyMessageResult {
return td.applyMessageExpectCodeAndReturn(msg, exitcode.Ok, retval)
}
func (td *TestDriver) ApplyFailure(msg *types.Message, code exitcode.ExitCode) vtypes.ApplyMessageResult {
return td.applyMessageExpectCodeAndReturn(msg, code, EmptyReturnValue)
}
func (td *TestDriver) applyMessageExpectCodeAndReturn(msg *types.Message, code exitcode.ExitCode, retval []byte) vtypes.ApplyMessageResult {
result := td.applyMessage(msg)
td.validateResult(result, code, retval)
return result
}
func (td *TestDriver) applyMessage(msg *types.Message) (result vtypes.ApplyMessageResult) {
defer func() {
if r := recover(); r != nil {
T.Fatalf("message application panicked: %v", r)
}
}()
epoch := td.ExeCtx.Epoch
result, err := td.applier.ApplyMessage(epoch, msg)
td.Vector.ApplyMessages = append(
td.Vector.ApplyMessages,
schema.Message{Epoch: &epoch, Bytes: chain.MustSerialize(msg)},
)
require.NoError(T, err)
return result
}
//
// Signed Message Appliers
//
func (td *TestDriver) ApplySigned(msg *types.Message) vtypes.ApplyMessageResult {
result := td.applyMessageSigned(msg)
return result
}
func (td *TestDriver) ApplySignedOk(msg *types.Message) vtypes.ApplyMessageResult {
return td.ApplySignedExpect(msg, EmptyReturnValue)
}
func (td *TestDriver) ApplySignedExpect(msg *types.Message, retval []byte) vtypes.ApplyMessageResult {
return td.applyMessageSignedExpectCodeAndReturn(msg, exitcode.Ok, retval)
}
func (td *TestDriver) ApplySignedFailure(msg *types.Message, code exitcode.ExitCode) vtypes.ApplyMessageResult {
return td.applyMessageExpectCodeAndReturn(msg, code, EmptyReturnValue)
}
func (td *TestDriver) applyMessageSignedExpectCodeAndReturn(msg *types.Message, code exitcode.ExitCode, retval []byte) vtypes.ApplyMessageResult {
result := td.applyMessageSigned(msg)
td.validateResult(result, code, retval)
return result
}
func (td *TestDriver) applyMessageSigned(msg *types.Message) (result vtypes.ApplyMessageResult) {
defer func() {
if r := recover(); r != nil {
T.Fatalf("message application panicked: %v", r)
}
}()
serMsg, err := msg.Serialize()
require.NoError(T, err)
msgSig, err := td.Wallet().Sign(msg.From, serMsg)
require.NoError(T, err)
smsgs := &types.SignedMessage{
Message: *msg,
Signature: msgSig,
}
epoch := td.ExeCtx.Epoch
result, err = td.applier.ApplySignedMessage(epoch, smsgs)
td.Vector.ApplyMessages = append(
td.Vector.ApplyMessages,
schema.Message{Epoch: &epoch, Bytes: chain.MustSerialize(smsgs)},
)
require.NoError(T, err)
return result
}
func (td *TestDriver) validateResult(result vtypes.ApplyMessageResult, code exitcode.ExitCode, retval []byte) {
if td.Config.ValidateExitCode() {
assert.Equal(T, code, result.Receipt.ExitCode, "Expected ExitCode: %s Actual ExitCode: %s", code.Error(), result.Receipt.ExitCode.Error())
}
if td.Config.ValidateReturnValue() {
assert.Equal(T, retval, result.Receipt.ReturnValue, "Expected ReturnValue: %v Actual ReturnValue: %v", retval, result.Receipt.ReturnValue)
}
}
func (td *TestDriver) AssertNoActor(addr address.Address) {
_, err := td.State().Actor(addr)
assert.Error(T, err, "expected no such actor %s", addr)
}
func (td *TestDriver) GetBalance(addr address.Address) abi_spec.TokenAmount {
actr, err := td.State().Actor(addr)
require.NoError(T, err)
return actr.Balance()
}
func (td *TestDriver) GetHead(addr address.Address) cid.Cid {
actr, err := td.State().Actor(addr)
require.NoError(T, err)
return actr.Head()
}
// AssertBalance checks an actor has an expected balance.
func (td *TestDriver) AssertBalance(addr address.Address, expected abi_spec.TokenAmount) {
actr, err := td.State().Actor(addr)
require.NoError(T, err)
assert.Equal(T, expected, actr.Balance(), fmt.Sprintf("expected actor %s balance: %s, actual balance: %s", addr, expected, actr.Balance()))
}
// Checks an actor's balance and callSeqNum.
func (td *TestDriver) AssertActor(addr address.Address, balance abi_spec.TokenAmount, callSeqNum uint64) {
actr, err := td.State().Actor(addr)
require.NoError(T, err)
assert.Equal(T, balance, actr.Balance(), fmt.Sprintf("expected actor %s balance: %s, actual balance: %s", addr, balance, actr.Balance()))
assert.Equal(T, callSeqNum, actr.CallSeqNum(), fmt.Sprintf("expected actor %s callSeqNum: %d, actual : %d", addr, callSeqNum, actr.CallSeqNum()))
}
func (td *TestDriver) AssertHead(addr address.Address, expected cid.Cid) {
head := td.GetHead(addr)
assert.Equal(T, expected, head, "expected actor %s head %s, actual %s", addr, expected, head)
}
func (td *TestDriver) AssertBalanceCallback(addr address.Address, thing func(actorBalance abi_spec.TokenAmount) bool) {
actr, err := td.State().Actor(addr)
require.NoError(T, err)
assert.True(T, thing(actr.Balance()))
}
func (td *TestDriver) AssertMultisigTransaction(multisigAddr address.Address, txnID multisig_spec.TxnID, txn multisig_spec.Transaction) {
var msState multisig_spec.State
td.GetActorState(multisigAddr, &msState)
txnMap, err := adt_spec.AsMap(AsStore(td.State()), msState.PendingTxns)
require.NoError(T, err)
var actualTxn multisig_spec.Transaction
found, err := txnMap.Get(txnID, &actualTxn)
require.NoError(T, err)
require.True(T, found)
assert.Equal(T, txn, actualTxn)
}
func (td *TestDriver) AssertMultisigContainsTransaction(multisigAddr address.Address, txnID multisig_spec.TxnID, contains bool) {
var msState multisig_spec.State
td.GetActorState(multisigAddr, &msState)
txnMap, err := adt_spec.AsMap(AsStore(td.State()), msState.PendingTxns)
require.NoError(T, err)
var actualTxn multisig_spec.Transaction
found, err := txnMap.Get(txnID, &actualTxn)
require.NoError(T, err)
assert.Equal(T, contains, found)
}
func (td *TestDriver) AssertMultisigState(multisigAddr address.Address, expected multisig_spec.State) {
var msState multisig_spec.State
td.GetActorState(multisigAddr, &msState)
assert.NotNil(T, msState)
assert.Equal(T, expected.InitialBalance, msState.InitialBalance, fmt.Sprintf("expected InitialBalance: %v, actual InitialBalance: %v", expected.InitialBalance, msState.InitialBalance))
assert.Equal(T, expected.NextTxnID, msState.NextTxnID, fmt.Sprintf("expected NextTxnID: %v, actual NextTxnID: %v", expected.NextTxnID, msState.NextTxnID))
assert.Equal(T, expected.NumApprovalsThreshold, msState.NumApprovalsThreshold, fmt.Sprintf("expected NumApprovalsThreshold: %v, actual NumApprovalsThreshold: %v", expected.NumApprovalsThreshold, msState.NumApprovalsThreshold))
assert.Equal(T, expected.StartEpoch, msState.StartEpoch, fmt.Sprintf("expected StartEpoch: %v, actual StartEpoch: %v", expected.StartEpoch, msState.StartEpoch))
assert.Equal(T, expected.UnlockDuration, msState.UnlockDuration, fmt.Sprintf("expected UnlockDuration: %v, actual UnlockDuration: %v", expected.UnlockDuration, msState.UnlockDuration))
for _, e := range expected.Signers {
assert.Contains(T, msState.Signers, e, fmt.Sprintf("expected Signer: %v, actual Signer: %v", e, msState.Signers))
}
}
func (td *TestDriver) ComputeInitActorExecReturn(from address.Address, originatorCallSeq uint64, newActorAddressCount uint64, expectedNewAddr address.Address) init_spec.ExecReturn {
return computeInitActorExecReturn(from, originatorCallSeq, newActorAddressCount, expectedNewAddr)
}
func computeInitActorExecReturn(from address.Address, originatorCallSeq uint64, newActorAddressCount uint64, expectedNewAddr address.Address) init_spec.ExecReturn {
buf := new(bytes.Buffer)
if from.Protocol() == address.ID {
T.Fatal("cannot compute init actor address return from ID address", from)
}
require.NoError(T, from.MarshalCBOR(buf))
require.NoError(T, binary.Write(buf, binary.BigEndian, originatorCallSeq))
require.NoError(T, binary.Write(buf, binary.BigEndian, newActorAddressCount))
out, err := address.NewActorAddress(buf.Bytes())
require.NoError(T, err)
return init_spec.ExecReturn{
IDAddress: expectedNewAddr,
RobustAddress: out,
}
}
func (td *TestDriver) MustCreateAndVerifyMultisigActor(nonce uint64, value abi_spec.TokenAmount, multisigAddr address.Address, from address.Address, params *multisig_spec.ConstructorParams, code exitcode.ExitCode, retval []byte) {
/* Create the Multisig actor*/
td.applyMessageExpectCodeAndReturn(
td.MessageProducer.CreateMultisigActor(from, params.Signers, params.UnlockDuration, params.NumApprovalsThreshold, chain.Nonce(nonce), chain.Value(value)),
code, retval)
/* Assert the actor state was setup as expected */
pendingTxMapRoot, err := adt_spec.MakeEmptyMap(newMockStore()).Root()
require.NoError(T, err)
initialBalance := big_spec.Zero()
startEpoch := abi_spec.ChainEpoch(0)
if params.UnlockDuration > 0 {
initialBalance = value
startEpoch = td.ExeCtx.Epoch
}
td.AssertMultisigState(multisigAddr, multisig_spec.State{
NextTxnID: 0,
InitialBalance: initialBalance,
StartEpoch: startEpoch,
Signers: params.Signers,
UnlockDuration: params.UnlockDuration,
NumApprovalsThreshold: params.NumApprovalsThreshold,
PendingTxns: pendingTxMapRoot,
})
td.AssertBalance(multisigAddr, value)
}
type RewardSummary struct {
Treasury abi_spec.TokenAmount
SimpleSupply abi_spec.TokenAmount
BaselineSupply abi_spec.TokenAmount
NextPerEpochReward abi_spec.TokenAmount
NextPerBlockReward abi_spec.TokenAmount
}
func (td *TestDriver) GetRewardSummary() *RewardSummary {
var rst reward_spec.State
td.GetActorState(builtin_spec.RewardActorAddr, &rst)
return &RewardSummary{
Treasury: td.GetBalance(builtin_spec.RewardActorAddr),
NextPerEpochReward: rst.ThisEpochReward,
NextPerBlockReward: big_spec.Div(rst.ThisEpochReward, big_spec.NewInt(builtin_spec.ExpectedLeadersPerEpoch)),
}
}
func (td *TestDriver) GetStateRoot() cid.Cid {
return td.st.stateRoot
}
func (td *TestDriver) UpdatePreStateRoot() {
td.Vector.Pre.StateTree.RootCID = td.st.stateRoot
}
func (td *TestDriver) UpdatePostStateRoot() {
td.Vector.Post.StateTree.RootCID = td.st.stateRoot
}
func (td *TestDriver) MustSerialize(w io.Writer) {
td.Vector.Post.StateTree.RootCID = td.st.stateRoot
td.Vector.CAR = td.MustMarshalGzippedCAR(td.Vector.Pre.StateTree.RootCID, td.Vector.Post.StateTree.RootCID)
fmt.Fprintln(w, string(td.Vector.MustMarshalJSON()))
}
func (td *TestDriver) MustMarshalGzippedCAR(roots ...cid.Cid) []byte {
var b bytes.Buffer
gw := gzip.NewWriter(&b)
err := td.MarshalCAR(gw, roots...)
if err != nil {
panic(err)
}
gw.Close()
return b.Bytes()
}
func (td *TestDriver) MarshalCAR(w io.Writer, roots ...cid.Cid) error {
ctx := context.Background()
offl := offline.Exchange(td.st.bs)
blkserv := blockservice.New(td.st.bs, offl)
dserv := merkledag.NewDAGService(blkserv)
var cids []cid.Cid
cids = append(cids, roots...)
if err := car.WriteCarWithWalker(ctx, dserv, cids, w, walker); err != nil {
return fmt.Errorf("failed to write car file: %w", err)
}
return nil
}
func walker(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
}

View File

@ -1,201 +0,0 @@
package drivers
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
vtypes "github.com/filecoin-project/oni/tvx/chain/types"
)
type TipSetMessageBuilder struct {
driver *TestDriver
bbs []*BlockBuilder
}
func NewTipSetMessageBuilder(testDriver *TestDriver) *TipSetMessageBuilder {
return &TipSetMessageBuilder{
driver: testDriver,
bbs: nil,
}
}
func (t *TipSetMessageBuilder) WithBlockBuilder(bb *BlockBuilder) *TipSetMessageBuilder {
t.bbs = append(t.bbs, bb)
return t
}
func (t *TipSetMessageBuilder) Apply() vtypes.ApplyTipSetResult {
result := t.apply()
t.Clear()
return result
}
func (t *TipSetMessageBuilder) ApplyAndValidate() vtypes.ApplyTipSetResult {
result := t.apply()
t.validateResult(result)
t.Clear()
return result
}
func (tb *TipSetMessageBuilder) apply() vtypes.ApplyTipSetResult {
var blks []vtypes.BlockMessagesInfo
for _, b := range tb.bbs {
blks = append(blks, b.build())
}
result, err := tb.driver.applier.ApplyTipSetMessages(tb.driver.ExeCtx.Epoch, blks, tb.driver.Randomness())
require.NoError(T, err)
//t.driver.StateTracker.TrackResult(result)
return result
}
func (tb *TipSetMessageBuilder) validateResult(result vtypes.ApplyTipSetResult) {
expected := []ExpectedResult{}
for _, b := range tb.bbs {
expected = append(expected, b.expectedResults...)
}
if len(result.Receipts) > len(expected) {
T.Fatalf("ApplyTipSetMessages returned more result than expected. Expected: %d, Actual: %d", len(expected), len(result.Receipts))
return
}
for i := range result.Receipts {
if tb.driver.Config.ValidateExitCode() {
assert.Equal(T, expected[i].ExitCode, result.Receipts[i].ExitCode, "Message Number: %d Expected ExitCode: %s Actual ExitCode: %s", i, expected[i].ExitCode.Error(), result.Receipts[i].ExitCode.Error())
}
if tb.driver.Config.ValidateReturnValue() {
assert.Equal(T, expected[i].ReturnVal, result.Receipts[i].ReturnValue, "Message Number: %d Expected ReturnValue: %v Actual ReturnValue: %v", i, expected[i].ReturnVal, result.Receipts[i].ReturnValue)
}
}
}
func (t *TipSetMessageBuilder) Clear() {
t.bbs = nil
}
type BlockBuilder struct {
TD *TestDriver
miner address.Address
ticketCount int64
secpMsgs []*types.SignedMessage
blsMsgs []*types.Message
expectedResults []ExpectedResult
}
type ExpectedResult struct {
ExitCode exitcode.ExitCode
ReturnVal []byte
}
func NewBlockBuilder(td *TestDriver, miner address.Address) *BlockBuilder {
return &BlockBuilder{
TD: td,
miner: miner,
ticketCount: 1,
secpMsgs: nil,
blsMsgs: nil,
expectedResults: nil,
}
}
func (bb *BlockBuilder) addResult(code exitcode.ExitCode, retval []byte) {
bb.expectedResults = append(bb.expectedResults, ExpectedResult{
ExitCode: code,
ReturnVal: retval,
})
}
func (bb *BlockBuilder) WithBLSMessageOk(blsMsg *types.Message) *BlockBuilder {
bb.blsMsgs = append(bb.blsMsgs, blsMsg)
bb.addResult(exitcode.Ok, EmptyReturnValue)
return bb
}
func (bb *BlockBuilder) WithBLSMessageDropped(blsMsg *types.Message) *BlockBuilder {
bb.blsMsgs = append(bb.blsMsgs, blsMsg)
return bb
}
func (bb *BlockBuilder) WithBLSMessageAndCode(bm *types.Message, code exitcode.ExitCode) *BlockBuilder {
bb.blsMsgs = append(bb.blsMsgs, bm)
bb.addResult(code, EmptyReturnValue)
return bb
}
func (bb *BlockBuilder) WithBLSMessageAndRet(bm *types.Message, retval []byte) *BlockBuilder {
bb.blsMsgs = append(bb.blsMsgs, bm)
bb.addResult(exitcode.Ok, retval)
return bb
}
func (bb *BlockBuilder) WithSECPMessageAndCode(bm *types.Message, code exitcode.ExitCode) *BlockBuilder {
secpMsg := bb.toSignedMessage(bm)
bb.secpMsgs = append(bb.secpMsgs, secpMsg)
bb.addResult(code, EmptyReturnValue)
return bb
}
func (bb *BlockBuilder) WithSECPMessageAndRet(bm *types.Message, retval []byte) *BlockBuilder {
secpMsg := bb.toSignedMessage(bm)
bb.secpMsgs = append(bb.secpMsgs, secpMsg)
bb.addResult(exitcode.Ok, retval)
return bb
}
func (bb *BlockBuilder) WithSECPMessageOk(bm *types.Message) *BlockBuilder {
secpMsg := bb.toSignedMessage(bm)
bb.secpMsgs = append(bb.secpMsgs, secpMsg)
bb.addResult(exitcode.Ok, EmptyReturnValue)
return bb
}
func (bb *BlockBuilder) WithSECPMessageDropped(bm *types.Message) *BlockBuilder {
secpMsg := bb.toSignedMessage(bm)
bb.secpMsgs = append(bb.secpMsgs, secpMsg)
return bb
}
func (bb *BlockBuilder) WithTicketCount(count int64) *BlockBuilder {
bb.ticketCount = count
return bb
}
func (bb *BlockBuilder) toSignedMessage(m *types.Message) *types.SignedMessage {
from := m.From
if from.Protocol() == address.ID {
from = bb.TD.ActorPubKey(from)
}
if from.Protocol() != address.SECP256K1 {
T.Fatalf("Invalid address for SECP signature, address protocol: %v", from.Protocol())
}
raw, err := m.Serialize()
require.NoError(T, err)
sig, err := bb.TD.Wallet().Sign(from, raw)
require.NoError(T, err)
return &types.SignedMessage{
Message: *m,
Signature: sig,
}
}
func (bb *BlockBuilder) build() vtypes.BlockMessagesInfo {
return vtypes.BlockMessagesInfo{
BLSMessages: bb.blsMsgs,
SECPMessages: bb.secpMsgs,
Miner: bb.miner,
TicketCount: bb.ticketCount,
}
}

View File

@ -1,39 +0,0 @@
package drivers
import (
"context"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/ipfs/go-cid"
big_spec "github.com/filecoin-project/specs-actors/actors/abi/big"
)
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{}
)
// Actor is an abstraction over the actor states stored in the root of the state tree.
type Actor interface {
Code() cid.Cid
Head() cid.Cid
CallSeqNum() uint64
Balance() big.Int
}
type contextStore struct {
cbor.IpldStore
ctx context.Context
}
func (s *contextStore) Context() context.Context {
return s.ctx
}

View File

@ -10,6 +10,7 @@ import (
"os"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/lib/blockstore"
"github.com/ipld/go-car"
"github.com/urfave/cli/v2"
@ -115,10 +116,21 @@ func executeTestVector(tv schema.TestVector) error {
}
fmt.Printf("executing message %v\n", i)
_, root, err = driver.ExecuteMessage(msg, root, bs, epoch)
var ret *vm.ApplyRet
ret, root, err = driver.ExecuteMessage(msg, root, bs, epoch)
if err != nil {
return err
}
if expected, actual := tv.Post.Receipts[i].ExitCode, ret.ExitCode; expected != actual {
return fmt.Errorf("exit code of msg %d did not match; expected: %s, got: %s", i, expected, actual)
}
if expected, actual := tv.Post.Receipts[i].GasUsed, ret.GasUsed; expected != actual {
return fmt.Errorf("gas used of msg %d did not match; expected: %d, got: %d", i, expected, actual)
}
// TODO assert return value
fmt.Printf("✅ message %d passed expectations\n", i)
}
if root != tv.Post.StateTree.RootCID {

View File

@ -4,25 +4,25 @@ go 1.14
require (
github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200716204036-cddc56607e1d
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef
github.com/filecoin-project/go-bitfield v0.1.2
github.com/filecoin-project/go-address v0.0.3
github.com/filecoin-project/go-bitfield v0.2.0
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03
github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f
github.com/filecoin-project/lotus v0.4.3-0.20200803225238-cd8537e76fc0
github.com/filecoin-project/sector-storage v0.0.0-20200803184904-3cab915fd225
github.com/filecoin-project/specs-actors v0.8.6
github.com/filecoin-project/lotus v0.4.3-0.20200814191300-4a0171d26aa5
github.com/filecoin-project/sector-storage v0.0.0-20200810171746-eac70842d8e0
github.com/filecoin-project/specs-actors v0.9.2
github.com/hashicorp/go-multierror v1.1.0
github.com/ipfs/go-block-format v0.0.2
github.com/ipfs/go-blockservice v0.1.4-0.20200624145336-a978cec6e834
github.com/ipfs/go-cid v0.0.7
github.com/ipfs/go-datastore v0.4.4
github.com/ipfs/go-hamt-ipld v0.1.1
github.com/ipfs/go-ipfs-blockstore v1.0.0
github.com/ipfs/go-ipfs-blockstore v1.0.1
github.com/ipfs/go-ipfs-exchange-interface v0.0.1
github.com/ipfs/go-ipfs-exchange-offline v0.0.1
github.com/ipfs/go-ipld-cbor v0.0.5-0.20200428170625-a0bd04d3cbdf
github.com/ipfs/go-ipld-format v0.2.0
github.com/ipfs/go-merkledag v0.3.1
github.com/ipfs/go-merkledag v0.3.2
github.com/ipld/go-car v0.1.1-0.20200526133713-1c7508d55aae
github.com/ipsn/go-secp256k1 v0.0.0-20180726113642-9d62b9f0bc52
github.com/libp2p/go-libp2p-core v0.6.1
@ -32,9 +32,11 @@ require (
github.com/multiformats/go-varint v0.0.6
github.com/stretchr/testify v1.6.1
github.com/urfave/cli/v2 v2.2.0
github.com/whyrusleeping/cbor-gen v0.0.0-20200723185710-6a3894a6352b
github.com/whyrusleeping/cbor-gen v0.0.0-20200812213548-958ddffe352c
)
replace github.com/filecoin-project/filecoin-ffi => ../extra/filecoin-ffi
replace github.com/filecoin-project/sector-storage => github.com/filecoin-project/lotus/extern/sector-storage v0.0.0-20200814191300-4a0171d26aa5
replace github.com/supranational/blst => github.com/supranational/blst v0.1.2-alpha.1

View File

@ -53,6 +53,7 @@ github.com/Stebalien/go-bitfield v0.0.0-20180330043415-076a62f9ce6e/go.mod h1:3o
github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo=
github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
@ -196,12 +197,12 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY=
github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8=
github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
github.com/filecoin-project/chain-validation v0.0.6-0.20200731192946-f90377ebe789 h1:/q6q6xNQWymV7qVXF2k5poF0QaWdJAqU00LacgANCuM=
github.com/filecoin-project/chain-validation v0.0.6-0.20200731192946-f90377ebe789/go.mod h1:JICNIbIEZ+qNJ/PQlHxjei6SaeBbW+yV2r4BcShsXfI=
github.com/filecoin-project/chain-validation v0.0.6-0.20200813000554-40c22fe26eef h1:MtQRSnJLsQOOlmsd/Ua5KWXimpxcaa715h6FUh/eJPY=
github.com/filecoin-project/chain-validation v0.0.6-0.20200813000554-40c22fe26eef/go.mod h1:SMj5VK1pYgqC8FXVEtOBRTc+9AIrYu+C+K3tAXi2Rk8=
github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U=
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef/go.mod h1:SrA+pWVoUivqKOfC+ckVYbx41hWz++HxJcrlmHNnebU=
github.com/filecoin-project/go-address v0.0.3 h1:eVfbdjEbpbzIrbiSa+PiGUY+oDK9HnUn+M1R/ggoHf8=
github.com/filecoin-project/go-address v0.0.3/go.mod h1:jr8JxKsYx+lQlQZmF5i2U0Z+cGQ59wMIps/8YW/lDj8=
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg=
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg=
github.com/filecoin-project/go-amt-ipld/v2 v2.1.0/go.mod h1:nfFPoGyX0CU9SkXX8EoCcSuHN1XcbN0c6KBh7yvP5fs=
@ -210,56 +211,55 @@ github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20200731171407-e559a0579161/
github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw=
github.com/filecoin-project/go-bitfield v0.0.1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY=
github.com/filecoin-project/go-bitfield v0.0.3/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY=
github.com/filecoin-project/go-bitfield v0.0.4-0.20200703174658-f4a5758051a1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY=
github.com/filecoin-project/go-bitfield v0.1.2 h1:TjLregCoyP1/5lm7WCM0axyV1myIHwbjGa21skuu5tk=
github.com/filecoin-project/go-bitfield v0.1.2/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM=
github.com/filecoin-project/go-bitfield v0.2.0 h1:gCtLcjskIPtdg4NfN7gQZSQF9yrBQ7mkT0qCJxzGI2Q=
github.com/filecoin-project/go-bitfield v0.2.0/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM=
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8=
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg=
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus=
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ=
github.com/filecoin-project/go-data-transfer v0.5.2/go.mod h1:4MI+n+8ryWvMaBxcWeR7N/Qo0KYM/kw3qHzsCfKux+E=
github.com/filecoin-project/go-data-transfer v0.5.3-0.20200731171043-3cb77ab72923 h1:XEIVbRCdg99gHn9pxS87yXa33E4sDn55hCTF8c1rdOw=
github.com/filecoin-project/go-data-transfer v0.5.3-0.20200731171043-3cb77ab72923/go.mod h1:Q3P3NTrzKr1SIib6oeGitpiAUK9V2ekMigF89lFn+Xk=
github.com/filecoin-project/go-data-transfer v0.6.1 h1:EA6X8fSiBRNVVwKm5pA7+njZnBbdqpRtedZagrrwHHI=
github.com/filecoin-project/go-data-transfer v0.6.1/go.mod h1:uRYBRKVBVM12CSusBtVrzDHkVw/3DKZpkxKJVP1Ydas=
github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA=
github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f h1:GxJzR3oRIMTPtpZ0b7QF8FKPK6/iPAc7trhlL5k/g+s=
github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ=
github.com/filecoin-project/go-fil-markets v0.5.3-0.20200731191349-05110623f114 h1:c+WNx8V0cn7Jyq2SNCelwCKHWHORUBi2+z4X9BWfuLg=
github.com/filecoin-project/go-fil-markets v0.5.3-0.20200731191349-05110623f114/go.mod h1:apWlYip7Uht5LECL0izk/rOtjStjVE0Z4gG3q/vwgOM=
github.com/filecoin-project/go-fil-markets v0.5.6 h1:WmBbV0qBU4NvLJ64xROpzrKUbkZxZqszZiEiCGmCEIY=
github.com/filecoin-project/go-fil-markets v0.5.6/go.mod h1:SJApXAKr5jyGpbzDEOhvemui0pih7hhT8r2MXJxCP1E=
github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24 h1:Jc7vkplmZYVuaEcSXGHDwefvZIdoyyaoGDLqSr8Svms=
github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200602181149-522144ab4e24/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM=
github.com/filecoin-project/go-multistore v0.0.2 h1:JZEddnXXt3mMzHi7bi9IH7Yi1NpGLy19J5Lk/xbxBMs=
github.com/filecoin-project/go-multistore v0.0.2/go.mod h1:edte5g7DHqJasFNOvdm9ZS6CjdfFTPoQ6xeKs1eOBIA=
github.com/filecoin-project/go-multistore v0.0.3 h1:vaRBY4YiA2UZFPK57RNuewypB8u0DzzQwqsL0XarpnI=
github.com/filecoin-project/go-multistore v0.0.3/go.mod h1:kaNqCC4IhU4B1uyr7YWFHd23TL4KM32aChS0jNkyUvQ=
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs=
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6/go.mod h1:0HgYnrkeSU4lu1p+LEOeDpFsNBssa0OGGriWdA4hvaE=
github.com/filecoin-project/go-paramfetch v0.0.1/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc=
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc=
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261 h1:A256QonvzRaknIIAuWhe/M2dpV2otzs3NBhi5TWa/UA=
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc=
github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
github.com/filecoin-project/go-statemachine v0.0.0-20200714194326-a77c3ae20989/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
github.com/filecoin-project/go-statemachine v0.0.0-20200730031800-c3336614d2a7 h1:KAF3WM/xSnl6G6RHX8vDJthg4+e4PSgBh72//6c6Qvc=
github.com/filecoin-project/go-statemachine v0.0.0-20200730031800-c3336614d2a7/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370 h1:Jbburj7Ih2iaJ/o5Q9A+EAeTabME6YII7FLi9SKUf5c=
github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ=
github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI=
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg=
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8=
github.com/filecoin-project/lotus v0.4.3-0.20200803225238-cd8537e76fc0 h1:A1IUDzAu/+BtSG7yqcv9hAM7bShsxOi6PB38970FfGM=
github.com/filecoin-project/lotus v0.4.3-0.20200803225238-cd8537e76fc0/go.mod h1:byIqtCuSkVu9LZm8dShhO/FojO9EbAV8DLG7jxGrnR0=
github.com/filecoin-project/sector-storage v0.0.0-20200712023225-1d67dcfa3c15/go.mod h1:salgVdX7qeXFo/xaiEQE29J4pPkjn71T0kt0n+VDBzo=
github.com/filecoin-project/sector-storage v0.0.0-20200730050024-3ee28c3b6d9a/go.mod h1:oOawOl9Yk+qeytLzzIryjI8iRbqo+qzS6EEeElP4PWA=
github.com/filecoin-project/sector-storage v0.0.0-20200803184904-3cab915fd225 h1:Or2lM5Cdsq0nDrSWp2YO70tjd8Ohg0jVWT/KGP3BX+I=
github.com/filecoin-project/sector-storage v0.0.0-20200803184904-3cab915fd225/go.mod h1:oOawOl9Yk+qeytLzzIryjI8iRbqo+qzS6EEeElP4PWA=
github.com/filecoin-project/lotus v0.4.3-0.20200814191300-4a0171d26aa5 h1:SVoV7UoT1TD9J7U81RMNihI4YsLVKOeV76+TIuvr7Zo=
github.com/filecoin-project/lotus v0.4.3-0.20200814191300-4a0171d26aa5/go.mod h1:GK90NidsVsJnhcgltfWYG82Zc4zuBWJAR5Vg/pSxavU=
github.com/filecoin-project/lotus/extern/sector-storage v0.0.0-20200814191300-4a0171d26aa5 h1:/lPV/KInHS/n+xyl2N83z0379WFlXLGXY2LLpqtEo0s=
github.com/filecoin-project/lotus/extern/sector-storage v0.0.0-20200814191300-4a0171d26aa5/go.mod h1:Z5rBce4dxbddSHyjkNFod4wcBa7/qRYCVlJwAaBBlco=
github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y=
github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
github.com/filecoin-project/specs-actors v0.7.3-0.20200716231407-60a2ae96d2e6/go.mod h1:JOMUa7EijvpOO4ofD1yeHNmqohkmmnhTvz/IpB6so4c=
github.com/filecoin-project/specs-actors v0.8.2/go.mod h1:Q3ACV5kBLvqPaYbthc/J1lGMJ5OwogmD9pzdtPRMdCw=
github.com/filecoin-project/specs-actors v0.8.5/go.mod h1:Q3ACV5kBLvqPaYbthc/J1lGMJ5OwogmD9pzdtPRMdCw=
github.com/filecoin-project/specs-actors v0.8.6 h1:EnmrHqpzURzGeSDbeui/snQTVzl/RXoSEgAf5xMREaI=
github.com/filecoin-project/specs-actors v0.8.6/go.mod h1:QRihI/fadrhWzt7HH6mT32upOdDFpSYCFnr3JEI1L50=
github.com/filecoin-project/specs-actors v0.8.7-0.20200811203034-272d022c1923/go.mod h1:hukRu6vKQrrS7Nt+fC/ql4PqWLSfmAWNshD/VDtARZU=
github.com/filecoin-project/specs-actors v0.9.2 h1:0JG0QLHw8pO6BPqPRe9eQxQW60biHAQsx1rlQ9QbzZ0=
github.com/filecoin-project/specs-actors v0.9.2/go.mod h1:YasnVUOUha0DN5wB+twl+V8LlDKVNknRG00kTJpsfFA=
github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea h1:iixjULRQFPn7Q9KlIqfwLJnlAXO10bbkI+xy5GKGdLY=
github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k=
github.com/filecoin-project/storage-fsm v0.0.0-20200730122205-d423ae90d8d4/go.mod h1:1CGbd11KkHuyWPT+xwwCol1zl/jnlpiKD2L4fzKxaiI=
github.com/filecoin-project/specs-storage v0.1.1-0.20200730063404-f7db367e9401 h1:jLzN1hwO5WpKPu8ASbW8fs1FUCsOWNvoBXzQhv+8/E8=
github.com/filecoin-project/specs-storage v0.1.1-0.20200730063404-f7db367e9401/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k=
github.com/filecoin-project/storage-fsm v0.0.0-20200805013058-9d9ea4e6331f/go.mod h1:1CGbd11KkHuyWPT+xwwCol1zl/jnlpiKD2L4fzKxaiI=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
@ -465,6 +465,7 @@ github.com/ipfs/go-datastore v0.3.0/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRV
github.com/ipfs/go-datastore v0.3.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw=
github.com/ipfs/go-datastore v0.4.0/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
github.com/ipfs/go-datastore v0.4.2/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
github.com/ipfs/go-datastore v0.4.4 h1:rjvQ9+muFaJ+QZ7dN5B1MSDNQ0JVZKkkES/rMZmA8X8=
github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
@ -488,9 +489,9 @@ github.com/ipfs/go-filestore v1.0.0 h1:QR7ekKH+q2AGiWDc7W2Q0qHuYSRZGUJqUn0GsegEP
github.com/ipfs/go-filestore v1.0.0/go.mod h1:/XOCuNtIe2f1YPbiXdYvD0BKLA0JR1MgPiFOdcuu9SM=
github.com/ipfs/go-fs-lock v0.0.1 h1:XHX8uW4jQBYWHj59XXcjg7BHlHxV9ZOYs6Y43yb7/l0=
github.com/ipfs/go-fs-lock v0.0.1/go.mod h1:DNBekbboPKcxs1aukPSaOtFA3QfSdi5C855v0i9XJ8Y=
github.com/ipfs/go-graphsync v0.0.6-0.20200721211002-c376cbe14c0a/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE=
github.com/ipfs/go-graphsync v0.0.6-0.20200731020347-9ff2ade94aa4 h1:+CTNtwsy6duetU8s2zEwrhZKfTnHQNYOiSZ2xsmIA4o=
github.com/ipfs/go-graphsync v0.0.6-0.20200731020347-9ff2ade94aa4/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE=
github.com/ipfs/go-graphsync v0.1.0/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE=
github.com/ipfs/go-graphsync v0.1.1 h1:bFDAYS0Z48yd8ROPI6f/zIVmJxaDLA6m8cVuJPKC5fE=
github.com/ipfs/go-graphsync v0.1.1/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE=
github.com/ipfs/go-hamt-ipld v0.0.15-0.20200131012125-dd88a59d3f2e/go.mod h1:9aQJu/i/TaRDW6jqB5U217dLIDopn50wxLdHXM2CTfE=
github.com/ipfs/go-hamt-ipld v0.0.15-0.20200204200533-99b8553ef242/go.mod h1:kq3Pi+UP3oHhAdKexE+kHHYRKMoFNuGero0R7q3hWGg=
github.com/ipfs/go-hamt-ipld v0.1.1 h1:0IQdvwnAAUKmDE+PMJa5y1QiwOPHpI9+eAbQEEEYthk=
@ -500,6 +501,8 @@ github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2Is
github.com/ipfs/go-ipfs-blockstore v0.1.4/go.mod h1:Jxm3XMVjh6R17WvxFEiyKBLUGr86HgIYJW/D/MwqeYQ=
github.com/ipfs/go-ipfs-blockstore v1.0.0 h1:pmFp5sFYsYVvMOp9X01AK3s85usVcLvkBTRsN6SnfUA=
github.com/ipfs/go-ipfs-blockstore v1.0.0/go.mod h1:knLVdhVU9L7CC4T+T4nvGdeUIPAXlnd9zmXfp+9MIjU=
github.com/ipfs/go-ipfs-blockstore v1.0.1 h1:fnuVj4XdZp4yExhd0CnUwAiMNJHiPnfInhiuwz4lW1w=
github.com/ipfs/go-ipfs-blockstore v1.0.1/go.mod h1:MGNZlHNEnR4KGgPHM3/k8lBySIOK2Ve+0KjZubKlaOE=
github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ=
github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk=
github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw=
@ -569,6 +572,8 @@ github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKy
github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk=
github.com/ipfs/go-merkledag v0.3.1 h1:3UqWINBEr3/N+r6OwgFXAddDP/8zpQX/8J7IGVOCqRQ=
github.com/ipfs/go-merkledag v0.3.1/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M=
github.com/ipfs/go-merkledag v0.3.2 h1:MRqj40QkrWkvPswXs4EfSslhZ4RVPRbxwX11js0t1xY=
github.com/ipfs/go-merkledag v0.3.2/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M=
github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg=
github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY=
github.com/ipfs/go-path v0.0.3/go.mod h1:zIRQUez3LuQIU25zFjC2hpBTHimWx7VK5bjZgRLbbdo=
@ -694,8 +699,8 @@ github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qD
github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El8cTaefiM=
github.com/libp2p/go-libp2p v0.9.2/go.mod h1:cunHNLDVus66Ct9iXXcjKRLdmHdFdHVe1TAnbubJQqQ=
github.com/libp2p/go-libp2p v0.10.0/go.mod h1:yBJNpb+mGJdgrwbKAKrhPU0u3ogyNFTfjJ6bdM+Q/G8=
github.com/libp2p/go-libp2p v0.10.2 h1:VQOo/Pbj9Ijco9jiMYN5ImAg236IjTXfnUPJ2OvbpLM=
github.com/libp2p/go-libp2p v0.10.2/go.mod h1:BYckt6lmS/oA1SlRETSPWSUulCQKiZuTVsymVMc//HQ=
github.com/libp2p/go-libp2p v0.10.3 h1:Bc8/VjmC+pICtK6xG8YgVutZvCdK0MsroWCHP+6AdFQ=
github.com/libp2p/go-libp2p v0.10.3/go.mod h1:0ER6iPSaPeQjryNgOnm9bLNpMJCYmuw54xJXsVR17eE=
github.com/libp2p/go-libp2p-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4=
github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE=
github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8=
@ -704,8 +709,8 @@ github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQ
github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI=
github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A=
github.com/libp2p/go-libp2p-autonat v0.2.3/go.mod h1:2U6bNWCNsAG9LEbwccBDQbjzQ8Krdjge1jLTE9rdoMM=
github.com/libp2p/go-libp2p-autonat v0.3.1 h1:60sc3NuQz+RxEb4ZVCRp/7uPtD7gnlLcOIKYNulzSIo=
github.com/libp2p/go-libp2p-autonat v0.3.1/go.mod h1:0OzOi1/cVc7UcxfOddemYD5vzEqi4fwRbnZcJGLi68U=
github.com/libp2p/go-libp2p-autonat v0.3.2 h1:OhDSwVVaq7liTaRIsFFYvsaPp0pn2yi0WazejZ4DUmo=
github.com/libp2p/go-libp2p-autonat v0.3.2/go.mod h1:0OzOi1/cVc7UcxfOddemYD5vzEqi4fwRbnZcJGLi68U=
github.com/libp2p/go-libp2p-autonat-svc v0.1.0/go.mod h1:fqi8Obl/z3R4PFVLm8xFtZ6PBL9MlV/xumymRFkKq5A=
github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc=
github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro=
@ -818,8 +823,8 @@ github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1
github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk=
github.com/libp2p/go-libp2p-pubsub v0.1.1/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q=
github.com/libp2p/go-libp2p-pubsub v0.3.2-0.20200527132641-c0712c6e92cf/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato=
github.com/libp2p/go-libp2p-pubsub v0.3.4-0.20200731161531-2b5243c72f0d h1:1kfMc74C1DZGh97VJpA5efPXWU3tmdRF/wKYbFYya/4=
github.com/libp2p/go-libp2p-pubsub v0.3.4-0.20200731161531-2b5243c72f0d/go.mod h1:DTMSVmZZfXodB/pvdTGrY2eHPZ9W2ev7hzTH83OKHrI=
github.com/libp2p/go-libp2p-pubsub v0.3.4 h1:8PollxXtUvzy0DMn5XFMg/JihjaKboWyk3ML6yRW1Lk=
github.com/libp2p/go-libp2p-pubsub v0.3.4/go.mod h1:DTMSVmZZfXodB/pvdTGrY2eHPZ9W2ev7hzTH83OKHrI=
github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU=
github.com/libp2p/go-libp2p-quic-transport v0.5.0/go.mod h1:IEcuC5MLxvZ5KuHKjRu+dr3LjCT1Be3rcD/4d8JrX8M=
github.com/libp2p/go-libp2p-quic-transport v0.7.1/go.mod h1:TD31to4E5exogR/GWHClXCfkktigjAl5rXSt7HoxNvY=
@ -1304,12 +1309,14 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:X
github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
github.com/whyrusleeping/cbor-gen v0.0.0-20200414195334-429a0b5e922e/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
github.com/whyrusleeping/cbor-gen v0.0.0-20200501232601-351665a6e756/go.mod h1:W5MvapuoHRP8rz4vxjwCK1pDqF1aQcWsV5PZ+AHbqdg=
github.com/whyrusleeping/cbor-gen v0.0.0-20200504204219-64967432584d/go.mod h1:W5MvapuoHRP8rz4vxjwCK1pDqF1aQcWsV5PZ+AHbqdg=
github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
github.com/whyrusleeping/cbor-gen v0.0.0-20200715143311-227fab5a2377/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
github.com/whyrusleeping/cbor-gen v0.0.0-20200723185710-6a3894a6352b h1:Tju61pLCTYt5KZ9Y4wJKNR+IXB1k29M+0w3eW48Xqy0=
github.com/whyrusleeping/cbor-gen v0.0.0-20200723185710-6a3894a6352b/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
github.com/whyrusleeping/cbor-gen v0.0.0-20200810223238-211df3b9e24c/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
github.com/whyrusleeping/cbor-gen v0.0.0-20200812213548-958ddffe352c h1:otRnI08JoahNBxUFqX3372Ab9GnTj8L5J9iP5ImyxGU=
github.com/whyrusleeping/cbor-gen v0.0.0-20200812213548-958ddffe352c/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8=
github.com/whyrusleeping/go-ctrlnet v0.0.0-20180313164037-f564fbbdaa95/go.mod h1:SJqKCCPXRfBFCwXjfNT/skfsceF7+MBFLI2OrvuRA7g=
@ -1405,7 +1412,6 @@ golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -1556,7 +1562,6 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -1617,7 +1622,6 @@ golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200108195415-316d2f248479/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
@ -1633,6 +1637,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=

View File

@ -15,6 +15,10 @@ import (
cbor "github.com/ipfs/go-ipld-cbor"
)
var (
BaseFee = abi.NewTokenAmount(100) // TODO make parametrisable through vector.
)
type Driver struct {
ctx context.Context
}
@ -39,7 +43,16 @@ func (d *Driver) ExecuteMessage(msg *types.Message, preroot cid.Cid, bs blocksto
}
log.Println("creating vm")
lvm, err := vm.NewVM(preroot, epoch, &vmRand{}, bs, mkFakedSigSyscalls(vm.Syscalls(ffiwrapper.ProofVerifier)), nil)
vmOpts := &vm.VMOpts{
StateBase: preroot,
Epoch: epoch,
Rand: &vmRand{},
Bstore: bs,
Syscalls: mkFakedSigSyscalls(vm.Syscalls(ffiwrapper.ProofVerifier)),
CircSupplyCalc: nil,
BaseFee: BaseFee,
}
lvm, err := vm.NewVM(vmOpts)
if err != nil {
return nil, cid.Undef, err
}

View File

@ -14,10 +14,15 @@ import (
cbor "github.com/ipfs/go-ipld-cbor"
)
type vmRand struct {
type vmRand struct{}
var _ vm.Rand = (*vmRand)(nil)
func (r *vmRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return []byte("i_am_random_____i_am_random_____"), nil // 32 bytes.
}
func (*vmRand) GetRandomness(ctx context.Context, dst crypto.DomainSeparationTag, h abi.ChainEpoch, input []byte) ([]byte, error) {
func (r *vmRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return []byte("i_am_random_____i_am_random_____"), nil // 32 bytes.
}

View File

@ -33,7 +33,6 @@ func main() {
extractMsgCmd,
execLotusCmd,
examineCmd,
suiteMessagesCmd,
},
}

View File

@ -12,7 +12,7 @@ import (
)
func failActorExecutionAborted(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
// Set up sender and receiver accounts.
var sender, receiver AddressHandle

View File

@ -8,31 +8,31 @@ import (
)
func failCoverReceiptGasCost(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
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), GasLimit(8))
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), GasPrice(10))
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), GasLimit(1))
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), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
var alice, bob, charlie AddressHandle
alice = v.Actors.Account(address.SECP256K1, balance1T)
@ -49,7 +49,7 @@ func failCoverTransferAccountCreationGasStepwise(v *Builder) {
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), GasPrice(1), GasLimit(tryGas))
v.Messages.Sugar().Transfer(alice.Robust, charlie.Robust, Value(transferAmnt), Nonce(nonce), GasPremium(1), GasLimit(tryGas))
nonce++
}
v.CommitApplies()

View File

@ -9,7 +9,7 @@ import (
)
func failInvalidActorNonce(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
alice := v.Actors.Account(address.SECP256K1, balance1T)
v.CommitPreconditions()
@ -26,7 +26,7 @@ func failInvalidActorNonce(v *Builder) {
}
func failInvalidReceiverMethod(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
alice := v.Actors.Account(address.SECP256K1, balance1T)
v.CommitPreconditions()

View File

@ -8,7 +8,7 @@ import (
)
func failUnknownSender(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
alice := v.Actors.Account(address.SECP256K1, balance1T)
v.CommitPreconditions()
@ -20,7 +20,7 @@ func failUnknownSender(v *Builder) {
}
func failUnknownReceiver(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
alice := v.Actors.Account(address.SECP256K1, balance1T)
v.CommitPreconditions()

View File

@ -4,10 +4,9 @@ import (
"bytes"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
builtin "github.com/filecoin-project/specs-actors/actors/builtin"
"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"
@ -38,7 +37,7 @@ func init() {
}
func nestedSends_OkBasic(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
stage := prepareStage(v, acctDefaultBalance, multisigBalance)
balanceBefore := v.Actors.Balance(stage.creator)
@ -47,13 +46,13 @@ func nestedSends_OkBasic(v *Builder) {
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.Receipt.GasUsed.Big()), nonce+1)
//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), big.NewInt(result.MessageReceipt.GasUsed)))
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), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
stage := prepareStage(v, acctDefaultBalance, multisigBalance)
balanceBefore := v.Actors.Balance(stage.creator)
@ -64,12 +63,12 @@ func nestedSends_OkToNewActor(v *Builder) {
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, big.NewInt(result.MessageReceipt.GasUsed)))
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), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
stage := prepareStage(v, acctDefaultBalance, multisigBalance)
balanceBefore := v.Actors.Balance(stage.creator)
@ -83,15 +82,15 @@ func nestedSends_OkToNewActorWithInvoke(v *Builder) {
// https://github.com/filecoin-project/specs-actors/issues/113
//expected := bytes.Buffer{}
//require.NoError(t, newAddr.MarshalCBOR(&expected))
//assert.Equal(t, expected.Bytes(), result.Receipt.ReturnValue)
//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, big.NewInt(result.MessageReceipt.GasUsed)))
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), GasPrice(1))
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)
@ -105,7 +104,7 @@ func nestedSends_OkRecursive(v *Builder) {
result := stage.sendOk(stage.msAddr, big.Zero(), builtin.MethodsMultisig.AddSigner, &params, nonce)
v.Assert.BalanceEq(stage.msAddr, multisigBalance)
v.Assert.Equal(big.Sub(balanceBefore, big.NewInt(result.MessageReceipt.GasUsed)), v.Actors.Balance(stage.creator))
v.Assert.Equal(big.Sub(balanceBefore, CalculateDeduction(result)), v.Actors.Balance(stage.creator))
var st multisig.State
v.Actors.ActorState(stage.msAddr, &st)
@ -113,7 +112,7 @@ func nestedSends_OkRecursive(v *Builder) {
}
func nestedSends_OKNonCBORParamsWithTransfer(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
stage := prepareStage(v, acctDefaultBalance, multisigBalance)
@ -128,7 +127,7 @@ func nestedSends_OKNonCBORParamsWithTransfer(v *Builder) {
}
func nestedSends_FailNonexistentIDAddress(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
stage := prepareStage(v, acctDefaultBalance, multisigBalance)
@ -141,7 +140,7 @@ func nestedSends_FailNonexistentIDAddress(v *Builder) {
}
func nestedSends_FailNonexistentActorAddress(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
stage := prepareStage(v, acctDefaultBalance, multisigBalance)
@ -154,7 +153,7 @@ func nestedSends_FailNonexistentActorAddress(v *Builder) {
}
func nestedSends_FailInvalidMethodNumNewActor(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
stage := prepareStage(v, acctDefaultBalance, multisigBalance)
@ -167,7 +166,7 @@ func nestedSends_FailInvalidMethodNumNewActor(v *Builder) {
}
func nestedSends_FailInvalidMethodNumForActor(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
stage := prepareStage(v, acctDefaultBalance, multisigBalance)
balanceBefore := v.Actors.Balance(stage.creator)
@ -175,12 +174,12 @@ func nestedSends_FailInvalidMethodNumForActor(v *Builder) {
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, big.NewInt(result.MessageReceipt.GasUsed))) // Pay gas, don't receive funds.
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), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
stage := prepareStage(v, acctDefaultBalance, multisigBalance)
balanceBefore := v.Actors.Balance(stage.creator)
@ -189,13 +188,13 @@ func nestedSends_FailMissingParams(v *Builder) {
amtSent := abi.NewTokenAmount(1)
result := stage.sendOk(stage.msAddr, amtSent, builtin.MethodsMultisig.AddSigner, params, nonce)
v.Assert.BalanceEq(stage.creator, big.Sub(balanceBefore, big.NewInt(result.MessageReceipt.GasUsed)))
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), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
stage := prepareStage(v, acctDefaultBalance, multisigBalance)
balanceBefore := v.Actors.Balance(stage.creator)
@ -210,13 +209,13 @@ func nestedSends_FailMismatchParams(v *Builder) {
amtSent := abi.NewTokenAmount(1)
result := stage.sendOk(stage.msAddr, amtSent, builtin.MethodsMultisig.AddSigner, &params, nonce)
v.Assert.BalanceEq(stage.creator, big.Sub(balanceBefore, big.NewInt(result.MessageReceipt.GasUsed)))
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), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
stage := prepareStage(v, acctDefaultBalance, multisigBalance)
prevHead := v.Actors.Head(builtin.RewardActorAddr)
@ -235,7 +234,7 @@ func nestedSends_FailInnerAbort(v *Builder) {
}
func nestedSends_FailAbortedExec(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
stage := prepareStage(v, acctDefaultBalance, multisigBalance)
prevHead := v.Actors.Head(builtin.InitActorAddr)
@ -258,7 +257,7 @@ func nestedSends_FailAbortedExec(v *Builder) {
}
func nestedSends_FailInsufficientFundsForTransferInInnerSend(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
// puppet actor has zero funds
puppetBalance := big.Zero()
@ -293,7 +292,7 @@ func nestedSends_FailInsufficientFundsForTransferInInnerSend(v *Builder) {
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.BalanceEq(alice.ID, big.Sub(acctDefaultBalance, big.NewInt(msg.Result.GasUsed)))
v.Assert.MessageSendersSatisfy(BalanceUpdated(big.Zero()), msg)
v.Assert.BalanceEq(bob.ID, big.Zero())
}
@ -325,7 +324,7 @@ func prepareStage(v *Builder, creatorBalance, msBalance abi.TokenAmount) *msStag
}
}
func (s *msStage) sendOk(to address.Address, value abi.TokenAmount, method abi.MethodNum, params runtime.CBORMarshaler, approverNonce uint64) *vm.ApplyRet {
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)
@ -345,7 +344,7 @@ func (s *msStage) sendOk(to address.Address, value abi.TokenAmount, method abi.M
// all messages succeeded.
s.v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.Ok))
return msg.Result
return msg
}
func (s *msStage) state() *multisig.State {

View File

@ -7,7 +7,7 @@ import (
)
var (
initialBal = abi.NewTokenAmount(200_000_000_000)
initialBal = abi.NewTokenAmount(1_000_000_000_000)
toSend = abi.NewTokenAmount(10_000)
)

View File

@ -8,12 +8,13 @@ import (
"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), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
// Set up sender and receiver accounts.
var sender, receiver AddressHandle
@ -41,10 +42,12 @@ func happyPathCreate(v *Builder) {
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), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
var (
timelock = abi.ChainEpoch(0)
@ -95,16 +98,24 @@ func happyPathUpdate(v *Builder) {
// Verify the paych state.
var state paych.State
v.Actors.ActorState(ret.RobustAddress, &state)
v.Assert.Len(state.LaneStates, 1)
ls := state.LaneStates[0]
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.Equal(lane, ls.ID)
v.Assert.EveryMessageSenderSatisfies(NonceUpdated())
}
func happyPathCollect(v *Builder) {
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPrice(1))
v.Messages.SetDefaults(GasLimit(1_000_000_000), GasPremium(1), GasFeeCap(200))
// Set up sender and receiver accounts.
var sender, receiver AddressHandle
@ -118,10 +129,10 @@ func happyPathCollect(v *Builder) {
v.CommitPreconditions()
// Construct the payment channel.
v.Messages.Sugar().CreatePaychActor(sender.Robust, receiver.Robust, Value(toSend))
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{
updateMsg := v.Messages.Typed(sender.Robust, paychAddr.Robust, PaychUpdateChannelState(&paych.UpdateChannelStateParams{
Sv: paych.SignedVoucher{
ChannelAddr: paychAddr.Robust,
TimeLockMin: 0,
@ -146,9 +157,9 @@ func happyPathCollect(v *Builder) {
// all messages succeeded.
v.Assert.EveryMessageResultSatisfies(ExitCode(exitcode.Ok))
// receiver_balance = initial_balance + paych_send - settle_paych_msg_gas - collect_paych_msg_gas
gasUsed := big.Add(big.NewInt(settleMsg.Result.MessageReceipt.GasUsed), big.NewInt(collectMsg.Result.MessageReceipt.GasUsed))
v.Assert.BalanceEq(receiver.Robust, big.Sub(big.Add(toSend, initialBal), gasUsed))
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)

View File

@ -246,10 +246,13 @@ func (sg *Surgeon) resolveAddresses(orig []address.Address, ist *init_.State) (r
ret = make([]address.Address, len(orig))
for i, addr := range orig {
resolved, err := ist.ResolveAddress(sg.stores.ADTStore, addr)
resolved, _, err := ist.ResolveAddress(sg.stores.ADTStore, addr)
if err != nil {
return nil, err
}
if resolved == address.Undef {
return nil, fmt.Errorf("address not found: %s", addr)
}
ret[i] = resolved
}