upgrade test vectors to latest lotus (#238)
This commit is contained in:
parent
955b445723
commit
ad17dc227c
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
56
tvx/builders/gas.go
Normal 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)
|
||||
}
|
@ -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.
|
||||
@ -64,8 +66,9 @@ func (m *Messages) Raw(from, to address.Address, method abi.MethodNum, params []
|
||||
Value: options.value,
|
||||
Method: method,
|
||||
Params: params,
|
||||
GasPrice: options.gasPrice,
|
||||
GasLimit: options.gasLimit,
|
||||
GasFeeCap: options.gasFeeCap,
|
||||
GasPremium: options.gasPremium,
|
||||
}
|
||||
|
||||
am := &ApplicableMessage{
|
||||
@ -108,8 +111,9 @@ func (m *Messages) ApplyN(ams ...*ApplicableMessage) {
|
||||
type msgOpts struct {
|
||||
nonce uint64
|
||||
value big.Int
|
||||
gasPrice big.Int
|
||||
gasLimit int64
|
||||
gasFeeCap abi.TokenAmount
|
||||
gasPremium abi.TokenAmount
|
||||
epoch abi.ChainEpoch
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ var (
|
||||
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
|
||||
}
|
||||
|
@ -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...)
|
||||
}
|
@ -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
|
||||
}
|
@ -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...)
|
||||
}
|
@ -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...)
|
||||
}
|
@ -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...)
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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...)
|
||||
}
|
@ -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...)
|
||||
}
|
@ -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...)
|
||||
}
|
@ -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...)
|
||||
}
|
@ -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...)
|
||||
}
|
@ -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...)
|
||||
}
|
@ -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))
|
||||
}
|
@ -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...)
|
||||
}
|
@ -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
|
||||
}
|
@ -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}
|
||||
}
|
@ -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))
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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{})
|
||||
}
|
@ -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{})
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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{}
|
||||
}
|
@ -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))
|
||||
}
|
@ -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
|
||||
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
|
||||
}
|
@ -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,
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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 {
|
||||
|
18
tvx/go.mod
18
tvx/go.mod
@ -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
|
||||
|
82
tvx/go.sum
82
tvx/go.sum
@ -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=
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,6 @@ func main() {
|
||||
extractMsgCmd,
|
||||
execLotusCmd,
|
||||
examineCmd,
|
||||
suiteMessagesCmd,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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, ¶ms, 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)
|
||||
@ -176,11 +175,11 @@ func nestedSends_FailInvalidMethodNumForActor(v *Builder) {
|
||||
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.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, ¶ms, 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 {
|
||||
|
@ -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)
|
||||
)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user