Skip to content

Commit

Permalink
Add fraud proof gossiping logic to light clients (cosmos#724)
Browse files Browse the repository at this point in the history
Resolves rollkit/rollkit#673.

---------

Co-authored-by: Manav Aggarwal <manavaggarwal1234@gmail.com>
  • Loading branch information
tzdybal and Manav-Aggarwal authored Feb 3, 2023
1 parent b82de97 commit 9563c74
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 6 deletions.
2 changes: 1 addition & 1 deletion node/full.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ func (n *FullNode) newHeaderValidator() p2p.GossipValidator {
func (n *FullNode) newFraudProofValidator() p2p.GossipValidator {
return func(fraudProofMsg *p2p.GossipMessage) bool {
n.Logger.Debug("fraud proof received", "from", fraudProofMsg.From, "bytes", len(fraudProofMsg.Data))
var fraudProof abci.FraudProof
fraudProof := abci.FraudProof{}
err := fraudProof.Unmarshal(fraudProofMsg.Data)
if err != nil {
n.Logger.Error("failed to deserialize fraud proof", "error", err)
Expand Down
103 changes: 99 additions & 4 deletions node/light.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,115 @@
package node

import (
"context"

ds "github.com/ipfs/go-datastore"
"github.com/libp2p/go-libp2p/core/crypto"
abciclient "github.com/tendermint/tendermint/abci/client"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/libs/service"
rpcclient "github.com/tendermint/tendermint/rpc/client"
tmtypes "github.com/tendermint/tendermint/types"

"github.com/rollkit/rollkit/config"
"github.com/rollkit/rollkit/p2p"
"github.com/rollkit/rollkit/store"
)

var _ Node = &LightNode{}

type LightNode struct {
service.BaseService

P2P *p2p.Client

app abciclient.Client

ctx context.Context
}

func (n *LightNode) GetClient() rpcclient.Client {
return NewLightClient(n)
func (ln *LightNode) GetClient() rpcclient.Client {
return NewLightClient(ln)
}

func newLightNode(
ctx context.Context,
conf config.NodeConfig,
p2pKey crypto.PrivKey,
appClient abciclient.Client,
genesis *tmtypes.GenesisDoc,
logger log.Logger,
) (*LightNode, error) {
datastore, err := openDatastore(conf, logger)
if err != nil {
return nil, err
}
client, err := p2p.NewClient(conf.P2P, p2pKey, genesis.ChainID, datastore, logger.With("module", "p2p"))
if err != nil {
return nil, err
}

node := &LightNode{
P2P: client,
app: appClient,
ctx: ctx,
}

node.P2P.SetTxValidator(node.falseValidator())
node.P2P.SetHeaderValidator(node.falseValidator())
node.P2P.SetFraudProofValidator(node.newFraudProofValidator())

node.BaseService = *service.NewBaseService(logger, "LightNode", node)

return node, nil
}

func newLightNode() (Node, error) {
return &LightNode{}, nil
func openDatastore(conf config.NodeConfig, logger log.Logger) (ds.TxnDatastore, error) {
if conf.RootDir == "" && conf.DBPath == "" { // this is used for testing
logger.Info("WARNING: working in in-memory mode")
return store.NewDefaultInMemoryKVStore()
}
return store.NewDefaultKVStore(conf.RootDir, conf.DBPath, "rollkit-light")
}

func (ln *LightNode) OnStart() error {
if err := ln.P2P.Start(ln.ctx); err != nil {
return err
}

return nil
}

// Dummy validator that always returns a callback function with boolean `false`
func (ln *LightNode) falseValidator() p2p.GossipValidator {
return func(*p2p.GossipMessage) bool {
return false
}
}

func (ln *LightNode) newFraudProofValidator() p2p.GossipValidator {
return func(fraudProofMsg *p2p.GossipMessage) bool {
ln.Logger.Info("fraud proof received", "from", fraudProofMsg.From, "bytes", len(fraudProofMsg.Data))
fraudProof := abci.FraudProof{}
err := fraudProof.Unmarshal(fraudProofMsg.Data)
if err != nil {
ln.Logger.Error("failed to deserialize fraud proof", "error", err)
return false
}

resp, err := ln.app.VerifyFraudProofSync(abci.RequestVerifyFraudProof{
FraudProof: &fraudProof,
ExpectedValidAppHash: fraudProof.ExpectedValidAppHash,
})
if err != nil {
return false
}

if resp.Success {
panic("received valid fraud proof! halting light client")
}

return false
}
}
9 changes: 8 additions & 1 deletion node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ func NewNode(
logger,
)
} else {
return newLightNode()
return newLightNode(
ctx,
conf,
p2pKey,
appClient,
genesis,
logger,
)
}
}

0 comments on commit 9563c74

Please sign in to comment.