Skip to content

Commit

Permalink
Fix/consensus fault error (#4586)
Browse files Browse the repository at this point in the history
* fix report consensus fault msg excute error

* make lint happy
  • Loading branch information
hunjixin authored Nov 6, 2021
1 parent d264a3e commit 3fbc105
Show file tree
Hide file tree
Showing 16 changed files with 160 additions and 91 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ require (
github.com/filecoin-project/specs-actors/v3 v3.1.1
github.com/filecoin-project/specs-actors/v4 v4.0.1
github.com/filecoin-project/specs-actors/v5 v5.0.4
github.com/filecoin-project/specs-actors/v6 v6.0.0
github.com/filecoin-project/specs-actors/v6 v6.0.1
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506
github.com/filecoin-project/test-vectors/schema v0.0.5
github.com/filecoin-project/venus-auth v1.3.1-0.20210809053831-012d55d5f578
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,8 @@ github.com/filecoin-project/specs-actors/v4 v4.0.1/go.mod h1:TkHXf/l7Wyw4ZejyXIP
github.com/filecoin-project/specs-actors/v5 v5.0.0-20210512015452-4fe3889fff57/go.mod h1:283yBMMUSDB2abcjP/hhrwTkhb9h3sfM6KGrep/ZlBI=
github.com/filecoin-project/specs-actors/v5 v5.0.4 h1:OY7BdxJWlUfUFXWV/kpNBYGXNPasDIedf42T3sGx08s=
github.com/filecoin-project/specs-actors/v5 v5.0.4/go.mod h1:5BAKRAMsOOlD8+qCw4UvT/lTLInCJ3JwOWZbX8Ipwq4=
github.com/filecoin-project/specs-actors/v6 v6.0.0 h1:i+16MFE8GScWWUF0kG7x2RZ5Hqpz0CeyBHTpnijCJ6I=
github.com/filecoin-project/specs-actors/v6 v6.0.0/go.mod h1:V1AYfi5GkHXipx1mnVivoICZh3wtwPxDVuds+fbfQtk=
github.com/filecoin-project/specs-actors/v6 v6.0.1 h1:laxvHNsvrq83Y9n+W7znVCePi3oLyRf0Rkl4jFO8Wew=
github.com/filecoin-project/specs-actors/v6 v6.0.1/go.mod h1:V1AYfi5GkHXipx1mnVivoICZh3wtwPxDVuds+fbfQtk=
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw=
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g=
github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg=
Expand Down
2 changes: 1 addition & 1 deletion pkg/chain/randomness.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (g *GenesisRandomnessSource) GetChainRandomnessV1(ctx context.Context, pers

func (g *GenesisRandomnessSource) GetChainRandomnessV2(ctx context.Context, pers crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000 ))).Read(out) //nolint
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out) //nolint
return out, nil
}

Expand Down
39 changes: 21 additions & 18 deletions pkg/consensus/call_invoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package consensus
import (
"context"
"fmt"
"github.com/filecoin-project/venus/pkg/vm/vmcontext"

"github.com/filecoin-project/go-address"
acrypto "github.com/filecoin-project/go-state-types/crypto"
Expand Down Expand Up @@ -63,15 +64,16 @@ func (c *Expected) CallWithGas(ctx context.Context, msg *types.UnsignedMessage,
}
return cs.FilCirculating, nil
},
NtwkVersionGetter: c.fork.GetNtwkVersion,
Rnd: NewHeadRandomness(c.rnd, ts.Key()),
BaseFee: ts.At(0).ParentBaseFee,
Epoch: ts.Height(),
GasPriceSchedule: c.gasPirceSchedule,
PRoot: stateRoot,
Bsstore: c.bstore,
SysCallsImpl: c.syscallsImpl,
Fork: c.fork,
LookbackStateGetter: vmcontext.LookbackStateGetterForTipset(c.chainState, c.fork, ts),
NtwkVersionGetter: c.fork.GetNtwkVersion,
Rnd: NewHeadRandomness(c.rnd, ts.Key()),
BaseFee: ts.At(0).ParentBaseFee,
Epoch: ts.Height(),
GasPriceSchedule: c.gasPirceSchedule,
PRoot: stateRoot,
Bsstore: c.bstore,
SysCallsImpl: c.syscallsImpl,
Fork: c.fork,
}

vmi, err := vm.NewVM(vmOption)
Expand Down Expand Up @@ -195,15 +197,16 @@ func (c *Expected) Call(ctx context.Context, msg *types.UnsignedMessage, ts *typ
}
return dertail.FilCirculating, nil
},
NtwkVersionGetter: c.fork.GetNtwkVersion,
Rnd: NewHeadRandomness(c.rnd, ts.Key()),
BaseFee: ts.At(0).ParentBaseFee,
Epoch: pheight + 1,
GasPriceSchedule: c.gasPirceSchedule,
Fork: c.fork,
PRoot: ts.At(0).ParentStateRoot,
Bsstore: c.bstore,
SysCallsImpl: c.syscallsImpl,
LookbackStateGetter: vmcontext.LookbackStateGetterForTipset(c.chainState, c.fork, ts),
NtwkVersionGetter: c.fork.GetNtwkVersion,
Rnd: NewHeadRandomness(c.rnd, ts.Key()),
BaseFee: ts.At(0).ParentBaseFee,
Epoch: pheight + 1,
GasPriceSchedule: c.gasPirceSchedule,
Fork: c.fork,
PRoot: ts.At(0).ParentStateRoot,
Bsstore: c.bstore,
SysCallsImpl: c.syscallsImpl,
}

return c.processor.ProcessImplicitMessage(ctx, msg, vmOption)
Expand Down
21 changes: 12 additions & 9 deletions pkg/consensus/expected.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package consensus
import "C"
import (
"context"
"github.com/filecoin-project/venus/pkg/vm/vmcontext"
"time"

"golang.org/x/xerrors"
Expand Down Expand Up @@ -83,6 +84,7 @@ type StateViewer interface {
type chainReader interface {
GetTipSet(types.TipSetKey) (*types.TipSet, error)
GetHead() *types.TipSet
StateView(ts *types.TipSet) (*appstate.View, error)
GetTipSetStateRoot(*types.TipSet) (cid.Cid, error)
GetTipSetReceiptsRoot(*types.TipSet) (cid.Cid, error)
GetGenesisBlock(context.Context) (*types.BlockHeader, error)
Expand Down Expand Up @@ -204,15 +206,16 @@ func (c *Expected) RunStateTransition(ctx context.Context,
}
return dertail.FilCirculating, nil
},
NtwkVersionGetter: c.fork.GetNtwkVersion,
Rnd: NewHeadRandomness(c.rnd, ts.Key()),
BaseFee: ts.At(0).ParentBaseFee,
Fork: c.fork,
Epoch: ts.At(0).Height,
GasPriceSchedule: c.gasPirceSchedule,
Bsstore: c.bstore,
PRoot: parentStateRoot,
SysCallsImpl: c.syscallsImpl,
LookbackStateGetter: vmcontext.LookbackStateGetterForTipset(c.chainState, c.fork, ts),
NtwkVersionGetter: c.fork.GetNtwkVersion,
Rnd: NewHeadRandomness(c.rnd, ts.Key()),
BaseFee: ts.At(0).ParentBaseFee,
Fork: c.fork,
Epoch: ts.At(0).Height,
GasPriceSchedule: c.gasPirceSchedule,
Bsstore: c.bstore,
PRoot: parentStateRoot,
SysCallsImpl: c.syscallsImpl,
}
root, receipts, err := c.processor.ProcessTipSet(ctx, pts, ts, blockMessageInfo, vmOption)
if err != nil {
Expand Down
43 changes: 35 additions & 8 deletions pkg/consensusfault/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@ import (
"context"
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/venus/pkg/fork"
"github.com/filecoin-project/venus/pkg/types"
"github.com/filecoin-project/venus/pkg/types/specactors/adt"
"github.com/filecoin-project/venus/pkg/types/specactors/builtin/miner"
"github.com/filecoin-project/venus/pkg/types/specactors/policy"
"github.com/filecoin-project/venus/pkg/vm"
"github.com/filecoin-project/venus/pkg/vm/vmcontext"
cbornode "github.com/ipfs/go-ipld-cbor"

"github.com/filecoin-project/venus/pkg/config"
"github.com/pkg/errors"
Expand Down Expand Up @@ -42,7 +48,7 @@ func NewFaultChecker(chain chainReader, fork fork.IFork) *ConsensusFaultChecker
// Checks validity of the submitted consensus fault with the two block headers needed to prove the fault
// and an optional extra one to check common ancestry (as needed).
// Note that the blocks are ordered: the method requires a.Epoch() <= b.Epoch().
func (s *ConsensusFaultChecker) VerifyConsensusFault(ctx context.Context, h1, h2, extra []byte, view FaultStateView) (*runtime5.ConsensusFault, error) {
func (s *ConsensusFaultChecker) VerifyConsensusFault(ctx context.Context, h1, h2, extra []byte, curEpoch abi.ChainEpoch, msg vm.VmMessage, gasIpld cbornode.IpldStore, view vm.SyscallsStateView, getter vmcontext.LookbackStateGetter) (*runtime5.ConsensusFault, error) {
if bytes.Equal(h1, h2) {
return nil, fmt.Errorf("no consensus fault: blocks identical")
}
Expand Down Expand Up @@ -91,7 +97,7 @@ func (s *ConsensusFaultChecker) VerifyConsensusFault(ctx context.Context, h1, h2
}
}
// Time-offset mining fault: two blocks with the same parent but different epochs.
// The height check is redundant at time of writing, but included for robustness to future changes to this method.
// The curEpoch check is redundant at time of writing, but included for robustness to future changes to this method.
// The blocks have a common ancestor by definition (the parent).
if b1.Parents.Equals(b2.Parents) && b1.Height != b2.Height {
fault = &runtime5.ConsensusFault{
Expand Down Expand Up @@ -124,12 +130,12 @@ func (s *ConsensusFaultChecker) VerifyConsensusFault(ctx context.Context, h1, h2

// Expensive validation: signatures.
b1Version := s.fork.GetNtwkVersion(ctx, b1.Height)
err := verifyBlockSignature(ctx, view, b1, b1Version)
err := verifyBlockSignature(ctx, b1, b1Version, curEpoch, msg.To, gasIpld, view, getter)
if err != nil {
return nil, err
}
b2Version := s.fork.GetNtwkVersion(ctx, b2.Height)
err = verifyBlockSignature(ctx, view, b2, b2Version)
err = verifyBlockSignature(ctx, b2, b2Version, curEpoch, msg.To, gasIpld, view, getter)
if err != nil {
return nil, err
}
Expand All @@ -138,15 +144,36 @@ func (s *ConsensusFaultChecker) VerifyConsensusFault(ctx context.Context, h1, h2
}

// Checks whether a block header is correctly signed in the context of the parent state to which it refers.
func verifyBlockSignature(ctx context.Context, view FaultStateView, blk types.BlockHeader, nv network.Version) error {
minerInfo, err := view.MinerInfo(ctx, blk.Miner, nv)
func verifyBlockSignature(ctx context.Context, blk types.BlockHeader, nv network.Version, curEpoch abi.ChainEpoch, receiver address.Address, gasIpld cbornode.IpldStore, view FaultStateView, getter vmcontext.LookbackStateGetter) error {
if nv >= network.Version7 && blk.Height < -policy.ChainFinality {

This comment has been minimized.

Copy link
@arajasek

arajasek Nov 7, 2021

Collaborator

What is blk.Height < -policy.ChainFinality enforcing? Seems like it does nothing?

This comment has been minimized.

Copy link
@hunjixin

hunjixin Nov 8, 2021

Author Contributor

This comment has been minimized.

Copy link
@hunjixin

hunjixin Nov 8, 2021

Author Contributor

thanks

return xerrors.Errorf("cannot get worker key (currEpoch %d, height %d)", curEpoch, blk.Height)
}

lbstate, err := getter(ctx, blk.Height)
if err != nil {
panic(errors.Wrapf(err, "failed to inspect miner addresses"))
return xerrors.Errorf("fialed to look back state at height %d", blk.Height)
}

act, err := lbstate.LoadActor(ctx, receiver)
if err != nil {
return errors.Wrapf(err, "failed to get miner actor")
}

mas, err := miner.Load(adt.WrapStore(ctx, gasIpld), act)
if err != nil {
return xerrors.Errorf("failed to load state for miner %s", receiver)
}

info, err := mas.Info()
if err != nil {
return xerrors.Errorf("failed to get miner info for miner %s", receiver)
}

if blk.BlockSig == nil {
return errors.Errorf("no consensus fault: block %s has nil signature", blk.Cid())
}
err = state.NewSignatureValidator(view).ValidateSignature(ctx, blk.SignatureData(), minerInfo.Worker, *blk.BlockSig)

err = state.NewSignatureValidator(view).ValidateSignature(ctx, blk.SignatureData(), info.Worker, *blk.BlockSig)
if err != nil {
return errors.Wrapf(err, "no consensus fault: block %s signature invalid", blk.Cid())
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/constants/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
)

// BuildVersion is the local build version, set by build system
const BuildVersion = "1.1.0"
const BuildVersion = "1.1.2"

// software version
func UserVersion() string {
Expand Down
5 changes: 5 additions & 0 deletions pkg/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,8 @@ type ActorCodeLoader = dispatch.CodeLoader

// ActorMethodSignature wraps a specific method and allows you to encode/decodes input/output bytes into concrete types.
type ActorMethodSignature = dispatch.MethodSignature

type ILookBack = vmcontext.ILookBack
type LookbackStateGetter = vmcontext.LookbackStateGetter

//type LookbackStateGetterForTipset = vmcontext.LookbackStateGetterForTipset
12 changes: 7 additions & 5 deletions pkg/vm/vmcontext/runtime_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,13 @@ type runtimeAdapter struct {

func newRuntimeAdapter(ctx *invocationContext) *runtimeAdapter {
return &runtimeAdapter{ctx: ctx, syscalls: syscalls{
impl: ctx.vm.vmOption.SysCallsImpl,
ctx: ctx.vm.context,
gasTank: ctx.gasTank,
pricelist: ctx.vm.pricelist,
stateView: ctx.stateView(),
impl: ctx.vm.vmOption.SysCallsImpl,
vm: ctx.vm,
gasBlockStore: ctx.gasIpld,
vmMsg: ctx.msg,
gasTank: ctx.gasTank,
pricelist: ctx.vm.pricelist,
stateView: ctx.stateView(),
}}
}

Expand Down
25 changes: 14 additions & 11 deletions pkg/vm/vmcontext/syscalls.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package vmcontext

import (
"context"
cbornode "github.com/ipfs/go-ipld-cbor"
goruntime "runtime"
"sync"

Expand Down Expand Up @@ -35,15 +36,17 @@ type SyscallsImpl interface {
BatchVerifySeals(ctx context.Context, vis map[address.Address][]proof5.SealVerifyInfo) (map[address.Address][]bool, error)
VerifyAggregateSeals(aggregate proof5.AggregateSealVerifyProofAndInfos) error
VerifyPoSt(ctx context.Context, info proof5.WindowPoStVerifyInfo) error
VerifyConsensusFault(ctx context.Context, h1, h2, extra []byte, view SyscallsStateView) (*rt5.ConsensusFault, error)
VerifyConsensusFault(ctx context.Context, h1, h2, extra []byte, curEpoch abi.ChainEpoch, msg VmMessage, gasIpld cbornode.IpldStore, view SyscallsStateView, getter LookbackStateGetter) (*rt5.ConsensusFault, error)
}

type syscalls struct {
impl SyscallsImpl
ctx context.Context
gasTank *gas.GasTracker
pricelist gas.Pricelist
stateView SyscallsStateView
impl SyscallsImpl
vm *VM
gasBlockStore cbornode.IpldStore
vmMsg VmMessage
gasTank *gas.GasTracker
pricelist gas.Pricelist
stateView SyscallsStateView
}

var _ rt5.Syscalls = (*syscalls)(nil)
Expand All @@ -54,7 +57,7 @@ func (sys syscalls) VerifySignature(signature crypto.Signature, signer address.A
return err
}
sys.gasTank.Charge(charge, "VerifySignature")
return sys.impl.VerifySignature(sys.ctx, sys.stateView, signature, signer, plaintext)
return sys.impl.VerifySignature(sys.vm.context, sys.stateView, signature, signer, plaintext)
}

func (sys syscalls) HashBlake2b(data []byte) [32]byte {
Expand All @@ -64,22 +67,22 @@ func (sys syscalls) HashBlake2b(data []byte) [32]byte {

func (sys syscalls) ComputeUnsealedSectorCID(proof abi.RegisteredSealProof, pieces []abi.PieceInfo) (cid.Cid, error) {
sys.gasTank.Charge(sys.pricelist.OnComputeUnsealedSectorCid(proof, pieces), "ComputeUnsealedSectorCID")
return sys.impl.ComputeUnsealedSectorCID(sys.ctx, proof, pieces)
return sys.impl.ComputeUnsealedSectorCID(sys.vm.context, proof, pieces)
}

func (sys syscalls) VerifySeal(info proof5.SealVerifyInfo) error {
sys.gasTank.Charge(sys.pricelist.OnVerifySeal(info), "VerifySeal")
return sys.impl.VerifySeal(sys.ctx, info)
return sys.impl.VerifySeal(sys.vm.context, info)
}

func (sys syscalls) VerifyPoSt(info proof5.WindowPoStVerifyInfo) error {
sys.gasTank.Charge(sys.pricelist.OnVerifyPost(info), "VerifyWindowPoSt")
return sys.impl.VerifyPoSt(sys.ctx, info)
return sys.impl.VerifyPoSt(sys.vm.context, info)
}

func (sys syscalls) VerifyConsensusFault(h1, h2, extra []byte) (*rt5.ConsensusFault, error) {
sys.gasTank.Charge(sys.pricelist.OnVerifyConsensusFault(), "VerifyConsensusFault")
return sys.impl.VerifyConsensusFault(sys.ctx, h1, h2, extra, sys.stateView)
return sys.impl.VerifyConsensusFault(sys.vm.context, h1, h2, extra, sys.vm.currentEpoch, sys.vmMsg, sys.gasBlockStore, sys.stateView, sys.vm.vmOption.LookbackStateGetter)
}

var BatchSealVerifyParallelism = 2 * goruntime.NumCPU()
Expand Down
20 changes: 20 additions & 0 deletions pkg/vm/vmcontext/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
acrypto "github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/exitcode"
"github.com/filecoin-project/venus/pkg/state"
"github.com/filecoin-project/venus/pkg/util/blockstoreutil"

"github.com/filecoin-project/go-state-types/abi"
Expand All @@ -20,9 +21,11 @@ import (
type ExecCallBack func(cid.Cid, VmMessage, *Ret) error
type CircSupplyCalculator func(context.Context, abi.ChainEpoch, tree.Tree) (abi.TokenAmount, error)
type NtwkVersionGetter func(context.Context, abi.ChainEpoch) network.Version
type LookbackStateGetter func(context.Context, abi.ChainEpoch) (*state.View, error)

type VmOption struct { //nolint
CircSupplyCalculator CircSupplyCalculator
LookbackStateGetter LookbackStateGetter
NtwkVersionGetter NtwkVersionGetter
Rnd HeadChainRandomness
BaseFee abi.TokenAmount
Expand All @@ -35,6 +38,23 @@ type VmOption struct { //nolint
SysCallsImpl SyscallsImpl
}

//ChainRandomness define randomness method in filecoin
type ILookBack interface {
StateView(ts *types.TipSet) (*state.View, error)
GetLookbackTipSetForRound(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch, version network.Version) (*types.TipSet, cid.Cid, error)
}

func LookbackStateGetterForTipset(backer ILookBack, fork fork.IFork, ts *types.TipSet) LookbackStateGetter {
return func(ctx context.Context, round abi.ChainEpoch) (*state.View, error) {
ver := fork.GetNtwkVersion(ctx, round)
ts, _, err := backer.GetLookbackTipSetForRound(ctx, ts, round, ver)
if err != nil {
return nil, err
}
return backer.StateView(ts)
}
}

//ChainRandomness define randomness method in filecoin
type HeadChainRandomness interface {
ChainGetRandomnessFromBeacon(ctx context.Context, personalization acrypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
Expand Down
1 change: 0 additions & 1 deletion pkg/vm/vmcontext/vmcontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,6 @@ func (vm *VM) applyMessage(msg *types.UnsignedMessage, onChainMsgSize int) (*Ret
// This Method does not actually execute the message itself,
// but rather deals with the pre/post processing of a message.
// (see: `invocationContext.invoke()` for the dispatch and execution)

// initiate gas tracking
gasTank := gas.NewGasTracker(msg.GasLimit)
// pre-send
Expand Down
Loading

0 comments on commit 3fbc105

Please sign in to comment.