Update chain-validation, enable state root validation

This commit is contained in:
Aayush Rajasekaran 2020-03-27 18:26:34 -04:00
parent 34e9e9fe34
commit 8ec19812e3
6 changed files with 77 additions and 52 deletions

View File

@ -2,12 +2,12 @@ package validation
import (
"context"
"golang.org/x/xerrors"
"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/crypto"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
"github.com/ipfs/go-cid"
vtypes "github.com/filecoin-project/chain-validation/chain/types"
@ -31,39 +31,8 @@ func NewApplier() *Applier {
}
func (a *Applier) ApplyMessage(eCtx *vtypes.ExecutionContext, state vstate.VMWrapper, message *vtypes.Message) (vtypes.MessageReceipt, abi.TokenAmount, abi.TokenAmount, error) {
ctx := context.TODO()
st := state.(*StateWrapper)
base := st.Root()
randSrc := &vmRand{eCtx}
lotusVM, err := vm.NewVM(base, abi.ChainEpoch(eCtx.Epoch), randSrc, eCtx.Miner, st.bs, vdrivers.NewChainValidationSyscalls())
if err != nil {
return vtypes.MessageReceipt{}, big.Zero(), big.Zero(), err
}
lm := toLotusMsg(message)
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{}
}
st.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
return a.applyMessage(eCtx, state, lm)
}
func (a *Applier) ApplyTipSetMessages(state vstate.VMWrapper, blocks []vtypes.BlockMessagesInfo, epoch abi.ChainEpoch, rnd vstate.RandomnessSource) ([]vtypes.MessageReceipt, error) {
@ -99,7 +68,7 @@ func (a *Applier) ApplyTipSetMessages(state vstate.VMWrapper, blocks []vtypes.Bl
rval = []byte{} // chain validation tests expect empty arrays to not be nil...
}
receipts = append(receipts, vtypes.MessageReceipt{
ExitCode: exitcode.ExitCode(ret.ExitCode),
ExitCode: ret.ExitCode,
ReturnValue: rval,
GasUsed: vtypes.GasUnits(ret.GasUsed),
@ -114,6 +83,19 @@ func (a *Applier) ApplyTipSetMessages(state vstate.VMWrapper, blocks []vtypes.Bl
return receipts, nil
}
func (a *Applier) ApplySignedMessage(eCtx *vtypes.ExecutionContext, state vstate.VMWrapper, msg *vtypes.SignedMessage) (vtypes.MessageReceipt, abi.TokenAmount, abi.TokenAmount, error) {
var lm types.ChainMsg
switch msg.Signature.Type {
case crypto.SigTypeSecp256k1:
lm = toLotusSignedMsg(msg)
case crypto.SigTypeBLS:
lm = toLotusMsg(&msg.Message)
default:
return vtypes.MessageReceipt{}, big.Zero(), big.Zero(), xerrors.New("Unknown signature type")
}
// TODO: Validate the sig first
return a.applyMessage(eCtx, state, lm)
}
type randWrapper struct {
rnd vstate.RandomnessSource
@ -131,12 +113,47 @@ func (*vmRand) GetRandomness(ctx context.Context, dst crypto.DomainSeparationTag
panic("implement me")
}
func (a *Applier) applyMessage(eCtx *vtypes.ExecutionContext, state vstate.VMWrapper, lm types.ChainMsg) (vtypes.MessageReceipt, abi.TokenAmount, abi.TokenAmount, error) {
ctx := context.TODO()
st := state.(*StateWrapper)
base := st.Root()
randSrc := &vmRand{eCtx}
lotusVM, err := vm.NewVM(base, eCtx.Epoch, randSrc, eCtx.Miner, st.bs, vdrivers.NewChainValidationSyscalls())
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{}
}
st.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
}
func toLotusMsg(msg *vtypes.Message) *types.Message {
return &types.Message{
To: msg.To,
From: msg.From,
Nonce: uint64(msg.CallSeqNum),
Nonce: msg.CallSeqNum,
Method: msg.Method,
Value: types.BigInt{Int: msg.Value.Int},

View File

@ -8,13 +8,15 @@ type Config struct {
trackGas bool
checkExitCode bool
checkReturnValue bool
checkState bool
}
func NewConfig(gas, exit, ret bool) *Config {
func NewConfig(gas, exit, ret, state bool) *Config {
return &Config{
trackGas: gas,
checkExitCode: exit,
checkReturnValue: ret,
checkState: state,
}
}
@ -29,3 +31,7 @@ func (v Config) ValidateExitCode() bool {
func (v Config) ValidateReturnValue() bool {
return v.checkReturnValue
}
func (v Config) ValidateStateRoot() bool {
return v.checkState
}

View File

@ -42,6 +42,6 @@ func (f *Factories) NewValidationConfig() vstate.ValidationConfig {
trackGas := true
checkExit := true
checkRet := true
// ignore gas and return value assertions
return NewConfig(trackGas, checkExit, checkRet)
checkState := true
return NewConfig(trackGas, checkExit, checkRet, checkState)
}

View File

@ -2,6 +2,7 @@ package validation
import (
"fmt"
"github.com/minio/blake2b-simd"
"math/rand"
"github.com/filecoin-project/go-address"
@ -46,22 +47,24 @@ func (k *KeyManager) Sign(addr address.Address, data []byte) (acrypto.Signature,
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 {
if ki.Type == wallet.KTSecp256k1 {
sigType = acrypto.SigTypeBLS
} else if ki.Type == wallet.KTSecp256k1 {
sigType = acrypto.SigTypeSecp256k1
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")
}
return acrypto.Signature{
Type: sigType,
Data: sig,
}, nil
}

2
go.mod
View File

@ -11,7 +11,7 @@ require (
github.com/coreos/go-systemd/v22 v22.0.0
github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f // indirect
github.com/docker/go-units v0.4.0
github.com/filecoin-project/chain-validation v0.0.6-0.20200325210556-5a3014759d9c
github.com/filecoin-project/chain-validation v0.0.6-0.20200331055055-403d5af6c808
github.com/filecoin-project/filecoin-ffi v0.0.0-20200326153646-e899cc1dd072
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

3
go.sum
View File

@ -110,8 +110,7 @@ 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.3/go.mod h1:NCEGFjcWRjb8akWFSOXvU6n2efkWIqAeOKU6o5WBGQw=
github.com/filecoin-project/chain-validation v0.0.6-0.20200325210556-5a3014759d9c h1:I5xX6g6ySpRm9v6j3B5ML1OgeZDnAY/ppftDjdP6OMc=
github.com/filecoin-project/chain-validation v0.0.6-0.20200325210556-5a3014759d9c/go.mod h1:mXiAviXMZ2WVGmWNtjGr0JPMpNCNsPU774DawKZCzzM=
github.com/filecoin-project/chain-validation v0.0.6-0.20200331055055-403d5af6c808/go.mod h1:mXiAviXMZ2WVGmWNtjGr0JPMpNCNsPU774DawKZCzzM=
github.com/filecoin-project/go-address v0.0.0-20191219011437-af739c490b4f/go.mod h1:rCbpXPva2NKF9/J4X6sr7hbKBgQCxyFtRj7KOZqoIms=
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=