implement chain-validation driver

This commit is contained in:
frrist 2020-02-27 14:17:08 -08:00
parent 8f1bf7a0ed
commit b60458d236
12 changed files with 440 additions and 327 deletions

View File

@ -5,14 +5,13 @@ import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
"github.com/filecoin-project/go-sectorbuilder"
vchain "github.com/filecoin-project/chain-validation/pkg/chain"
vstate "github.com/filecoin-project/chain-validation/pkg/state"
vtypes "github.com/filecoin-project/chain-validation/pkg/state/types"
vtypes "github.com/filecoin-project/chain-validation/chain/types"
vstate "github.com/filecoin-project/chain-validation/state"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
)
@ -21,50 +20,66 @@ import (
type Applier struct {
}
var _ vchain.Applier = &Applier{}
var _ vstate.Applier = &Applier{}
func NewApplier() *Applier {
return &Applier{}
}
func (a *Applier) ApplyMessage(eCtx *vchain.ExecutionContext, state vstate.Wrapper, message interface{}) (vchain.MessageReceipt, error) {
func (a *Applier) ApplyMessage(eCtx *vtypes.ExecutionContext, state vstate.VMWrapper, message *vtypes.Message) (vtypes.MessageReceipt, error) {
ctx := context.TODO()
st := state.(*StateWrapper)
base := st.Cid()
base := st.Root()
randSrc := &vmRand{eCtx}
minerAddr, err := address.NewFromBytes(eCtx.MinerOwner.Bytes())
lotusVM, err := vm.NewVM(base, abi.ChainEpoch(eCtx.Epoch), randSrc, eCtx.Miner, st.bs, vm.Syscalls(sectorbuilder.ProofVerifier))
if err != nil {
return vchain.MessageReceipt{}, err
}
lotusVM, err := vm.NewVM(base, abi.ChainEpoch(eCtx.Epoch), randSrc, minerAddr, st.bs, vm.Syscalls(sectorbuilder.ProofVerifier))
if err != nil {
return vchain.MessageReceipt{}, err
return vtypes.MessageReceipt{}, err
}
ret, err := lotusVM.ApplyMessage(ctx, message.(*types.Message))
ret, err := lotusVM.ApplyMessage(ctx, toLotusMsg(message))
if err != nil {
return vchain.MessageReceipt{}, err
return vtypes.MessageReceipt{}, err
}
st.stateRoot, err = lotusVM.Flush(ctx)
if err != nil {
return vchain.MessageReceipt{}, err
return vtypes.MessageReceipt{}, err
}
mr := vchain.MessageReceipt{
ExitCode: ret.ExitCode,
mr := vtypes.MessageReceipt{
ExitCode: exitcode.ExitCode(ret.ExitCode),
ReturnValue: ret.Return,
GasUsed: vtypes.GasUnit(ret.GasUsed.Uint64()),
GasUsed: ret.GasUsed,
}
return mr, ret.ActorErr
}
func (a *Applier) ApplyTipSetMessages(state vstate.VMWrapper, blocks []vtypes.BlockMessagesInfo, epoch abi.ChainEpoch, rnd vstate.RandomnessSource) ([]vtypes.MessageReceipt, error) {
panic("implement me")
}
type vmRand struct {
eCtx *vchain.ExecutionContext
eCtx *vtypes.ExecutionContext
}
func (*vmRand) GetRandomness(ctx context.Context, dst crypto.DomainSeparationTag, h int64, input []byte) ([]byte, error) {
panic("implement me")
}
func toLotusMsg(msg *vtypes.Message) *types.Message {
return &types.Message{
To: msg.To,
From: msg.From,
Nonce: uint64(msg.CallSeqNum),
Method: msg.Method,
Value: types.BigInt{msg.Value.Int},
GasPrice: types.BigInt{msg.GasPrice.Int},
GasLimit: types.NewInt(uint64(msg.GasLimit)),
Params: msg.Params,
}
}

View File

@ -0,0 +1,24 @@
package validation
//
// ValidationConfig
//
type ValidationConfig struct {
trackGas bool
checkExitCode bool
checkReturnValue bool
}
func (v ValidationConfig) ValidateGas() bool {
return v.trackGas
}
func (v ValidationConfig) ValidateExitCode() bool {
return v.checkExitCode
}
func (v ValidationConfig) ValidateReturnValue() bool {
return v.checkReturnValue
}

View File

@ -1,27 +1,47 @@
package validation
import (
vchain "github.com/filecoin-project/chain-validation/pkg/chain"
vstate "github.com/filecoin-project/chain-validation/pkg/state"
"github.com/filecoin-project/chain-validation/pkg/suites"
"context"
vstate "github.com/filecoin-project/chain-validation/state"
acrypto "github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/abi"
)
type factories struct {
type Factories struct {
*Applier
}
var _ suites.Factories = &factories{}
var _ vstate.Factories = &Factories{}
func NewFactories() *factories {
func NewFactories() *Factories {
applier := NewApplier()
return &factories{applier}
return &Factories{applier}
}
func (f *factories) NewState() vstate.Wrapper {
func (f *Factories) NewState() vstate.VMWrapper {
return NewState()
}
func (f *factories) NewMessageFactory(wrapper vstate.Wrapper) vchain.MessageFactory {
signer := wrapper.(*StateWrapper).Signer()
return NewMessageFactory(signer)
func (f *Factories) NewKeyManager() vstate.KeyManager {
return newKeyManager()
}
type fakeRandSrc struct {
}
func (r fakeRandSrc) Randomness(_ context.Context, _ acrypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) (abi.Randomness, error) {
panic("implement me")
}
func (f *Factories) NewRandomnessSource() vstate.RandomnessSource {
return &fakeRandSrc{}
}
func (f *Factories) NewValidationConfig() vstate.ValidationConfig {
return &ValidationConfig{
trackGas: false,
checkExitCode: true,
checkReturnValue: true,
}
}

View File

@ -0,0 +1,99 @@
package validation
import (
"fmt"
"math/rand"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-crypto"
acrypto "github.com/filecoin-project/specs-actors/actors/crypto"
ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
)
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)
}
sig, err := crypto.Sign(ki.PrivateKey, data)
if err != nil {
return acrypto.Signature{}, err
}
var sigType acrypto.SigType
if ki.Type == wallet.KTBLS {
sigType = acrypto.SigTypeBLS
} else if ki.Type == wallet.KTSecp256k1 {
sigType = acrypto.SigTypeSecp256k1
} else {
panic("unknown signature type")
}
return acrypto.Signature{
Type: sigType,
Data: sig,
}, nil
}
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 := ffi.PrivateKeyGenerate()
key, err := wallet.NewKey(types.KeyInfo{
Type: wallet.KTBLS,
PrivateKey: sk[:],
})
if err != nil {
panic(err)
}
return key
}

View File

@ -1,99 +0,0 @@
package validation
import (
"context"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
vchain "github.com/filecoin-project/chain-validation/pkg/chain"
vactors "github.com/filecoin-project/chain-validation/pkg/state/actors"
vaddress "github.com/filecoin-project/chain-validation/pkg/state/address"
vtypes "github.com/filecoin-project/chain-validation/pkg/state/types"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/lotus/chain/types"
)
type Signer interface {
Sign(ctx context.Context, addr vaddress.Address, msg []byte) (*crypto.Signature, error)
}
type MessageFactory struct {
signer Signer
}
var _ vchain.MessageFactory = &MessageFactory{}
func NewMessageFactory(signer Signer) *MessageFactory {
return &MessageFactory{signer}
}
func (mf *MessageFactory) MakeMessage(from, to vaddress.Address, method vchain.MethodID, nonce uint64, value, gasPrice vtypes.BigInt, gasLimit vtypes.GasUnit, params []byte) (interface{}, error) {
fromDec, err := address.NewFromBytes(from.Bytes())
if err != nil {
return nil, err
}
toDec, err := address.NewFromBytes(to.Bytes())
if err != nil {
return nil, err
}
valueDec := types.BigInt{value.Int}
if int(method) >= len(methods) {
return nil, xerrors.Errorf("No method name for method %v", method)
}
methodId := methods[method]
msg := &types.Message{
toDec,
fromDec,
nonce,
valueDec,
types.BigInt{gasPrice.Int},
types.NewInt(uint64(gasLimit)),
abi.MethodNum(methodId),
params,
}
return msg, nil
}
func (mf *MessageFactory) FromSingletonAddress(addr vactors.SingletonActorID) vaddress.Address {
return fromSingletonAddress(addr)
}
func (mf *MessageFactory) FromActorCodeCid(code vactors.ActorCodeID) cid.Cid {
return fromActorCode(code)
}
// Maps method enumeration values to method names.
// This will change to a mapping to method ids when method dispatch is updated to use integers.
var methods = []uint64{
vchain.NoMethod: 0,
vchain.InitExec: uint64(builtin.MethodsInit.Exec),
vchain.StoragePowerConstructor: uint64(builtin.MethodsPower.Constructor),
vchain.StoragePowerCreateStorageMiner: uint64(builtin.MethodsPower.CreateMiner),
vchain.StorageMinerUpdatePeerID: 0, //actors.MAMethods.UpdatePeerID,
vchain.StorageMinerGetOwner: 0, //actors.MAMethods.GetOwner,
vchain.StorageMinerGetPower: 0, //actors.MAMethods.GetPower,
vchain.StorageMinerGetWorkerAddr: 0, //actors.MAMethods.GetWorkerAddr,
vchain.StorageMinerGetPeerID: 0, //actors.MAMethods.GetPeerID,
vchain.StorageMinerGetSectorSize: 0, //actors.MAMethods.GetSectorSize,
vchain.MultiSigConstructor: uint64(builtin.MethodsMultisig.Constructor),
vchain.MultiSigPropose: uint64(builtin.MethodsMultisig.Propose),
vchain.MultiSigApprove: uint64(builtin.MethodsMultisig.Approve),
vchain.MultiSigCancel: uint64(builtin.MethodsMultisig.Cancel),
vchain.MultiSigClearCompleted: uint64(builtin.MethodsMultisig.ClearCompleted),
vchain.MultiSigAddSigner: uint64(builtin.MethodsMultisig.AddSigner),
vchain.MultiSigRemoveSigner: uint64(builtin.MethodsMultisig.RemoveSigner),
vchain.MultiSigSwapSigner: uint64(builtin.MethodsMultisig.SwapSigner),
vchain.MultiSigChangeRequirement: uint64(builtin.MethodsMultisig.ChangeNumApprovalsThreshold),
// More to follow...
}

View File

@ -1,60 +0,0 @@
package validation
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
vchain "github.com/filecoin-project/chain-validation/pkg/chain"
vactors "github.com/filecoin-project/chain-validation/pkg/state/actors"
vaddress "github.com/filecoin-project/chain-validation/pkg/state/address"
vtypes "github.com/filecoin-project/chain-validation/pkg/state/types"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
)
func TestMessageFactory(t *testing.T) {
ks := wallet.NewMemKeyStore()
wallet, err := wallet.NewWallet(ks)
require.NoError(t, err)
factory := NewMessageFactory(&walletWrapper{wallet})
gasPrice := vtypes.NewInt(1)
gasLimit := vtypes.GasUnit(1000)
p := vchain.NewMessageProducer(factory, gasLimit, gasPrice)
sender, err := wallet.GenerateKey(types.KTSecp256k1)
require.NoError(t, err)
bfAddr := factory.FromSingletonAddress(vactors.BurntFundsAddress)
addr, err := vaddress.NewFromBytes(sender.Bytes())
require.NoError(t, err)
m, err := p.Transfer(addr, bfAddr, 0, 1)
require.NoError(t, err)
messages := p.Messages()
assert.Equal(t, 1, len(messages))
msg := m.(*types.Message)
assert.Equal(t, m, msg)
assert.Equal(t, sender, msg.From)
assert.Equal(t, actors.BurntFundsAddress, msg.To)
assert.Equal(t, types.NewInt(1), msg.Value)
}
type walletWrapper struct {
w *wallet.Wallet
}
func (ww *walletWrapper) Sign(ctx context.Context, vaddr vaddress.Address, msg []byte) (*types.Signature, error) {
addr, err := address.NewFromBytes(vaddr.Bytes())
if err != nil {
return nil, err
}
return ww.w.Sign(ctx, addr, msg)
}

View File

@ -2,51 +2,228 @@ package validation
import (
"context"
"fmt"
"math/rand"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore"
blockstore "github.com/ipfs/go-ipfs-blockstore"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/minio/blake2b-simd"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
vstate "github.com/filecoin-project/chain-validation/pkg/state"
vactors "github.com/filecoin-project/chain-validation/pkg/state/actors"
vaddress "github.com/filecoin-project/chain-validation/pkg/state/address"
vtypes "github.com/filecoin-project/chain-validation/pkg/state/types"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-crypto"
vstate "github.com/filecoin-project/chain-validation/state"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/gen/genesis"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/chain/wallet"
)
var _ vstate.VMWrapper = &StateWrapper{}
type StateWrapper struct {
// The blockstore underlying the state tree and storage.
bs blockstore.Blockstore
// HAMT-CBOR store on top of the blockstore.
cst cbor.IpldStore
// A store for encryption keys.
keys *keyStore
// CID of the root of the state tree.
stateRoot cid.Cid
// The root node of the state tree, essentially a cache of LoadStateTree(cst, stateRoot)
//tree *state.StateTree
// A look-through storage implementation.
storage *directStorage
}
var _ vstate.Wrapper = &StateWrapper{}
func NewState() *StateWrapper {
bs := blockstore.NewBlockstore(datastore.NewMapDatastore())
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, cst, root}
}
func (s *StateWrapper) Root() cid.Cid {
return s.stateRoot
}
func (s *StateWrapper) Store() adt.Store {
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
panic(err)
}
return &contextStore{tree.Store, context.Background()}
}
func (s *StateWrapper) Actor(addr address.Address) (vstate.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) (vstate.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) (vstate.Actor, address.Address, error) {
if addr == builtin.InitActorAddr || addr == builtin.StoragePowerActorAddr || addr == builtin.StorageMarketActorAddr {
act, err := s.SetupSingletonActor(addr)
if err != nil {
return nil, address.Undef, err
}
return act, addr, nil
}
tree, err := state.LoadStateTree(s.cst, s.Root())
if err != nil {
return nil, address.Undef, err
}
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, &actr.Actor)
if err != nil {
return nil, address.Undef, xerrors.Errorf("register new address for actor: %w", err)
}
return actr, 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() int64 {
return int64(a.Actor.Nonce)
}
func (a *actorWrapper) Balance() big.Int {
return a.Actor.Balance
}
//
// Storage
//
type contextStore struct {
cbor.IpldStore
ctx context.Context
}
func (s *contextStore) Context() context.Context {
return s.ctx
}
func (s *StateWrapper) SetupSingletonActor(addr address.Address) (vstate.Actor, error) {
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
return nil, err
}
switch addr {
case builtin.InitActorAddr:
// FIXME this is going to be a problem if go-filecoin and lotus setup their init actors with different netnames
// ideally lotus should use the init actor constructor
initact, err := genesis.SetupInitActor(s.bs, "chain-validation", nil)
if err != nil {
return nil, xerrors.Errorf("setup init actor: %w", err)
}
if err := tree.SetActor(builtin.InitActorAddr, initact); err != nil {
return nil, xerrors.Errorf("set init actor: %w", err)
}
return &actorWrapper{*initact}, s.flush(tree)
case builtin.StorageMarketActorAddr:
smact, err := genesis.SetupStorageMarketActor(s.bs)
if err != nil {
return nil, xerrors.Errorf("setup storage marker actor: %w", err)
}
if err := tree.SetActor(builtin.StorageMarketActorAddr, smact); err != nil {
return nil, xerrors.Errorf("set storage marker actor: %w", err)
}
return &actorWrapper{*smact}, s.flush(tree)
case builtin.StoragePowerActorAddr:
spact, err := genesis.SetupStoragePowerActor(s.bs)
if err != nil {
return nil, xerrors.Errorf("setup storage power actor: %w", err)
}
if err := tree.SetActor(builtin.StoragePowerActorAddr, spact); err != nil {
return nil, xerrors.Errorf("set storage power actor: %w", err)
}
return &actorWrapper{*spact}, s.flush(tree)
default:
return nil, xerrors.Errorf("%v is not a singleton actor address", addr)
}
}
/*
func NewState() *StateWrapper {
bs := blockstore.NewBlockstore(datastore.NewMapDatastore())
cst := cbor.NewCborStore(bs)
@ -72,7 +249,7 @@ func (s *StateWrapper) Cid() cid.Cid {
return s.stateRoot
}
func (s *StateWrapper) Actor(addr vaddress.Address) (vstate.Actor, error) {
func (s *StateWrapper) Actor(addr address.Address) (vstate.Actor, error) {
vaddr, err := address.NewFromBytes(addr.Bytes())
if err != nil {
return nil, err
@ -88,15 +265,15 @@ func (s *StateWrapper) Actor(addr vaddress.Address) (vstate.Actor, error) {
return &actorWrapper{*fcActor}, nil
}
func (s *StateWrapper) Storage(addr vaddress.Address) (vstate.Storage, error) {
func (s *StateWrapper) Storage(addr address.Address) (vstate.Storage, error) {
return s.storage, nil
}
func (s *StateWrapper) NewAccountAddress() (vaddress.Address, error) {
func (s *StateWrapper) NewAccountAddress() (address.Address, error) {
return s.keys.NewAddress()
}
func (s *StateWrapper) SetActor(addr vaddress.Address, code vactors.ActorCodeID, balance vtypes.BigInt) (vstate.Actor, vstate.Storage, error) {
func (s *StateWrapper) SetActor(addr address.Address, code vactors.ActorCodeID, balance vtypes.BigInt) (vstate.Actor, vstate.Storage, error) {
addrInt, err := address.NewFromBytes(addr.Bytes())
if err != nil {
return nil, nil, err
@ -192,7 +369,7 @@ func (s *StateWrapper) SetSingletonActor(addr vactors.SingletonActorID, balance
}
}
func (s *StateWrapper) Sign(ctx context.Context, addr vaddress.Address, data []byte) (*vtypes.Signature, error) {
func (s *StateWrapper) Sign(ctx context.Context, addr address.Address, data []byte) (*vtypes.Signature, error) {
sig, err := s.keys.Sign(ctx, addr, data)
if err != nil {
return nil, err
@ -218,23 +395,23 @@ func (s *StateWrapper) flush(tree *state.StateTree) (err error) {
//
type keyStore struct {
// Private keys by address
keys map[vaddress.Address]vtypes.KeyInfo
keys map[address.Address]vtypes.KeyInfo
// Seed for deterministic key generation.
seed int64
}
func newKeyStore() *keyStore {
return &keyStore{
keys: make(map[vaddress.Address]vtypes.KeyInfo),
keys: make(map[address.Address]vtypes.KeyInfo),
seed: 0,
}
}
func (s *keyStore) NewAddress() (vaddress.Address, error) {
func (s *keyStore) NewAddress() (address.Address, error) {
randSrc := rand.New(rand.NewSource(s.seed))
prv, err := crypto.GenerateKeyFromSeed(randSrc)
if err != nil {
return vaddress.Undef, err
return address.Undef, err
}
vki := vtypes.KeyInfo{
@ -246,18 +423,18 @@ func (s *keyStore) NewAddress() (vaddress.Address, error) {
PrivateKey: vki.PrivateKey,
})
if err != nil {
return vaddress.Undef, err
return address.Undef, err
}
vaddr, err := vaddress.NewFromBytes(key.Address.Bytes())
vaddr, err := address.NewFromBytes(key.Address.Bytes())
if err != nil {
return vaddress.Undef, err
return address.Undef, err
}
s.keys[vaddr] = vki
s.seed++
return vaddress.NewFromBytes(key.Address.Bytes())
return address.NewFromBytes(key.Address.Bytes())
}
func (s *keyStore) Sign(ctx context.Context, addr vaddress.Address, data []byte) (*types.Signature, error) {
func (s *keyStore) Sign(ctx context.Context, addr address.Address, data []byte) (*types.Signature, error) {
ki, ok := s.keys[addr]
if !ok {
return &types.Signature{}, fmt.Errorf("unknown address %v", addr)
@ -273,30 +450,6 @@ func (s *keyStore) Sign(ctx context.Context, addr vaddress.Address, data []byte)
}, nil
}
//
// 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) Nonce() uint64 {
return a.Actor.Nonce
}
func (a *actorWrapper) Balance() vtypes.BigInt {
return vtypes.NewInt(a.Actor.Balance.Uint64())
}
//
// Storage
@ -313,54 +466,4 @@ func (d *directStorage) Get(c cid.Cid, out interface{}) error {
return nil
}
func fromActorCode(code vactors.ActorCodeID) cid.Cid {
switch code {
case vactors.AccountActorCodeCid:
return actors.AccountCodeCid
case vactors.StorageMinerCodeCid:
return actors.StorageMinerCodeCid
case vactors.MultisigActorCodeCid:
return actors.MultisigCodeCid
case vactors.PaymentChannelActorCodeCid:
return actors.PaymentChannelCodeCid
default:
panic(fmt.Errorf("unknown actor code: %v", code))
}
}
func fromSingletonAddress(addr vactors.SingletonActorID) vaddress.Address {
switch addr {
case vactors.InitAddress:
out, err := vaddress.NewFromBytes(actors.InitAddress.Bytes())
if err != nil {
panic(err)
}
return out
case vactors.NetworkAddress:
out, err := vaddress.NewFromBytes(actors.NetworkAddress.Bytes())
if err != nil {
panic(err)
}
return out
case vactors.StorageMarketAddress:
out, err := vaddress.NewFromBytes(actors.StorageMarketAddress.Bytes())
if err != nil {
panic(err)
}
return out
case vactors.BurntFundsAddress:
out, err := vaddress.NewFromBytes(actors.BurntFundsAddress.Bytes())
if err != nil {
panic(err)
}
return out
case vactors.StoragePowerAddress:
out, err := vaddress.NewFromBytes(actors.StoragePowerAddress.Bytes())
if err != nil {
panic(err)
}
return out
default:
panic(fmt.Errorf("unknown singleton actor address: %v", addr))
}
}
*/

View File

@ -103,6 +103,8 @@ func cidToCommR(c cid.Cid) [32]byte {
func (ss *syscallShim) VerifySeal(info abi.SealVerifyInfo) error {
//_, span := trace.StartSpan(ctx, "ValidatePoRep")
//defer span.End()
// FIXME: sectorSize has been removed from the specs-actors syscall interface but is still required here.
ssize := abi.SectorSize(0)
miner, err := address.NewIDAddress(uint64(info.Miner))
if err != nil {

View File

@ -3,34 +3,36 @@ package vm_test
import (
"testing"
"github.com/filecoin-project/chain-validation/pkg/suites"
vsuites "github.com/filecoin-project/chain-validation/suites"
"github.com/filecoin-project/lotus/chain/validation"
vfactory "github.com/filecoin-project/lotus/chain/validation"
)
func TestStorageMinerValidation(t *testing.T) {
t.SkipNow()
factory := validation.NewFactories()
suites.CreateStorageMinerAndUpdatePeerID(t, factory)
func TestChainValidationSuite(t *testing.T) {
f := vfactory.NewFactories()
vsuites.TestValueTransferSimple(t, f)
vsuites.TestValueTransferAdvance(t, f)
vsuites.TestAccountActorCreation(t, f)
vsuites.TestInitActorSequentialIDAddressCreate(t, f)
// Skipping since multisig address resolution breaks tests
// https://github.com/filecoin-project/specs-actors/issues/184
// vsuites.TestMultiSigActor(t, f)
// Skipping since payment channel because runtime sys calls are not implemented in runtime adapter
// vsuites.TestPaych(t, f)
}
func TestValueTransfer(t *testing.T) {
factory := validation.NewFactories()
suites.AccountValueTransferSuccess(t, factory, 126)
suites.AccountValueTransferZeroFunds(t, factory, 112)
suites.AccountValueTransferOverBalanceNonZero(t, factory, 0)
suites.AccountValueTransferOverBalanceZero(t, factory, 0)
suites.AccountValueTransferToSelf(t, factory, 0)
suites.AccountValueTransferFromKnownToUnknownAccount(t, factory, 0)
suites.AccountValueTransferFromUnknownToKnownAccount(t, factory, 0)
suites.AccountValueTransferFromUnknownToUnknownAccount(t, factory, 0)
func TestMessageApplication(t *testing.T) {
f := vfactory.NewFactories()
vsuites.TestMessageApplicationEdgecases(t, f)
}
func TestMultiSig(t *testing.T) {
t.SkipNow()
factory := validation.NewFactories()
suites.MultiSigActorConstructor(t, factory)
suites.MultiSigActorProposeApprove(t, factory)
suites.MultiSigActorProposeCancel(t, factory)
func TestTipSetStuff(t *testing.T) {
f := vfactory.NewFactories()
vsuites.TestBlockMessageInfoApplication(t, f)
}

6
go.mod
View File

@ -10,7 +10,7 @@ require (
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/coreos/go-systemd/v22 v22.0.0
github.com/docker/go-units v0.4.0
github.com/filecoin-project/chain-validation v0.0.3
github.com/filecoin-project/chain-validation v0.0.6-0.20200227010210-ab4704e894ef
github.com/filecoin-project/filecoin-ffi v0.0.0-20200226205820-4da0bccccefb
github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e
@ -23,7 +23,7 @@ require (
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663
github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200228181617-f00e2c4cc050
github.com/filecoin-project/go-statestore v0.1.0
github.com/filecoin-project/specs-actors v0.0.0-20200302011114-7d19171ad051
github.com/filecoin-project/specs-actors v0.0.0-20200226225703-1fa643f1847f
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/google/uuid v1.1.1
@ -43,7 +43,7 @@ require (
github.com/ipfs/go-fs-lock v0.0.1
github.com/ipfs/go-graphsync v0.0.4
github.com/ipfs/go-hamt-ipld v0.0.15-0.20200204200533-99b8553ef242
github.com/ipfs/go-ipfs-blockstore v0.1.1
github.com/ipfs/go-ipfs-blockstore v0.1.3
github.com/ipfs/go-ipfs-chunker v0.0.1
github.com/ipfs/go-ipfs-ds-help v0.0.1
github.com/ipfs/go-ipfs-exchange-interface v0.0.1

12
go.sum
View File

@ -72,6 +72,7 @@ github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0=
github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis=
github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY=
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
github.com/dave/jennifer v1.4.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -99,6 +100,9 @@ github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGj
github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
github.com/filecoin-project/chain-validation v0.0.3 h1:luT/8kJ0WdMIqQ9Bm31W4JkuYCW0wUb26AvnD4WK59M=
github.com/filecoin-project/chain-validation v0.0.3/go.mod h1:NCEGFjcWRjb8akWFSOXvU6n2efkWIqAeOKU6o5WBGQw=
github.com/filecoin-project/chain-validation v0.0.6-0.20200227010210-ab4704e894ef h1:w0MgTRX6laEPigNZ1veqwWDO7MAfIZsHf/l1F7ELXTk=
github.com/filecoin-project/chain-validation v0.0.6-0.20200227010210-ab4704e894ef/go.mod h1:yU+n6LWc6EiLxzrTJNwe8ATSPqG4jfIPsYU6yui7KXY=
github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5 h1:/MmWluswvDIbuPvBct4q6HeQgVm62O2DzWYTB38kt4A=
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 h1:TooKBwR/g8jG0hZ3lqe9S5sy2vTUcLOZLlz3M5wGn2E=
github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
@ -130,6 +134,9 @@ github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.m
github.com/filecoin-project/specs-actors v0.0.0-20200226200336-94c9b92b2775/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
github.com/filecoin-project/specs-actors v0.0.0-20200302011114-7d19171ad051 h1:DX/fGDuARZwasW9ka9k1eK510bjHm/pfxY6JDjAxP1I=
github.com/filecoin-project/specs-actors v0.0.0-20200302011114-7d19171ad051/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
github.com/filecoin-project/specs-actors v0.0.0-20200220011005-b2a2fbf40362/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
github.com/filecoin-project/specs-actors v0.0.0-20200226225703-1fa643f1847f h1:qeUmau+W9eoS487mxjwG8sTT1SOMjpzUDH5hs0OwHTw=
github.com/filecoin-project/specs-actors v0.0.0-20200226225703-1fa643f1847f/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 h1:EzDjxMg43q1tA2c0MV3tNbaontnHLplHyFF6M5KiVP0=
@ -265,8 +272,8 @@ github.com/ipfs/go-hamt-ipld v0.0.15-0.20200204200533-99b8553ef242 h1:OYVGeYkGSR
github.com/ipfs/go-hamt-ipld v0.0.15-0.20200204200533-99b8553ef242/go.mod h1:kq3Pi+UP3oHhAdKexE+kHHYRKMoFNuGero0R7q3hWGg=
github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08=
github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw=
github.com/ipfs/go-ipfs-blockstore v0.1.1 h1:+PAFREAlSxLs9IEtrRcnJ/DqWkGlDa+l547WFZnohNw=
github.com/ipfs/go-ipfs-blockstore v0.1.1/go.mod h1:8gZOgIN5e+Xdg2YSGdwTTRbguSVjYyosIDRQCY8E9QM=
github.com/ipfs/go-ipfs-blockstore v0.1.3 h1:Nc/Uwc8KZgo5PsMUZT/Zt7zc0u/s+b/3c64ChQNttHc=
github.com/ipfs/go-ipfs-blockstore v0.1.3/go.mod h1:iNWVBoSQ7eMcaGo8+L3pKZABGTdWcqj1/hpoUu5bDps=
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 h1:cHUUxKFQ99pozdahi+uSC/3Y6HeRpi9oTeUHbE27SEw=
@ -766,7 +773,6 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM=
github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba h1:X4n8JG2e2biEZZXdBKt9HX7DN3bYGFUqljqqy0DqgnY=
github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba/go.mod h1:CHQnYnQUEPydYCwuy8lmTHfGmdw9TKrhWV0xLx8l0oM=
github.com/whyrusleeping/cbor-gen v0.0.0-20191116002219-891f55cd449d/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY=
github.com/whyrusleeping/cbor-gen v0.0.0-20191212224538-d370462a7e8a/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY=
github.com/whyrusleeping/cbor-gen v0.0.0-20191216205031-b047b6acb3c0/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY=
github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158 h1:WXhVOwj2USAXB5oMDwRl3piOux2XMV9TANaYxXHdkoE=

View File

@ -7,6 +7,7 @@ import (
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/ipfs/go-cid"
cid "github.com/ipfs/go-cid/_rsrch/cidiface"
"go.uber.org/fx"
"golang.org/x/xerrors"