From 06e9b98ca364da69f7e6cdb6e0ae82ac6e102234 Mon Sep 17 00:00:00 2001 From: Manav Aggarwal Date: Tue, 25 Jul 2023 16:30:37 +0200 Subject: [PATCH] code-hygiene: Move fraud proofs to feature branch (#1092) ## Overview Closes: #1094 Moved the existing fraud proof related code to this [branch](https://github.com/rollkit/rollkit/tree/with_abci_fraud_proofs). ## Checklist - [x] New and updated code has appropriate documentation - [x] New and updated code has new and/or updated testing - [x] Required CI checks are passing - [x] Visual proof for any user facing features like CLI or documentation updates - [x] Linked issues closed with keywords --------- Co-authored-by: Diego <31937514+Ferret-san@users.noreply.github.com> Co-authored-by: Ganesha Upadhyaya --- block/manager.go | 45 +------- config/config.go | 4 - config/config_test.go | 2 - config/defaults.go | 1 - go.mod | 5 +- go.sum | 4 +- mocks/Application.go | 42 -------- node/full.go | 71 ++++--------- node/full_client_test.go | 5 - node/full_node_integration_test.go | 159 +++------------------------- node/helpers_test.go | 4 +- node/light.go | 83 ++------------- node/proof_service_factory.go | 62 ----------- rpc/json/test_helpers.go | 2 - state/executor.go | 162 +++-------------------------- state/executor_test.go | 24 ++--- types/state_fraud_proof.go | 47 --------- 17 files changed, 67 insertions(+), 655 deletions(-) delete mode 100644 node/proof_service_factory.go delete mode 100644 types/state_fraud_proof.go diff --git a/block/manager.go b/block/manager.go index 17c9d4e1384..a87fdf62ad7 100644 --- a/block/manager.go +++ b/block/manager.go @@ -9,7 +9,6 @@ import ( "sync/atomic" "time" - "github.com/celestiaorg/go-fraud/fraudserv" abci "github.com/cometbft/cometbft/abci/types" cmcrypto "github.com/cometbft/cometbft/crypto" "github.com/cometbft/cometbft/crypto/merkle" @@ -120,7 +119,7 @@ func NewManager( conf.DABlockTime = defaultDABlockTime } - exec := state.NewBlockExecutor(proposerAddress, conf.NamespaceID, genesis.ChainID, mempool, proxyApp, conf.FraudProofs, eventBus, logger) + exec := state.NewBlockExecutor(proposerAddress, conf.NamespaceID, genesis.ChainID, mempool, proxyApp, eventBus, logger) if s.LastBlockHeight+1 == genesis.InitialHeight { res, err := exec.InitChain(genesis) if err != nil { @@ -246,45 +245,6 @@ func (m *Manager) AggregationLoop(ctx context.Context, lazy bool) { } } -func (m *Manager) SetFraudProofService(fraudProofServ *fraudserv.ProofService) { - m.executor.SetFraudProofService(fraudProofServ) -} - -func (m *Manager) ProcessFraudProof(ctx context.Context, cancel context.CancelFunc) { - defer cancel() - // subscribe to state fraud proof - sub, err := m.executor.FraudService.Subscribe(types.StateFraudProofType) - if err != nil { - m.logger.Error("failed to subscribe to fraud proof gossip", "error", err) - return - } - defer sub.Cancel() - - // blocks until a valid fraud proof is received via subscription - // sub.Proof is a blocking call that only returns on proof received or context ended - proof, err := sub.Proof(ctx) - if err != nil { - m.logger.Error("failed to receive gossiped fraud proof", "error", err) - return - } - - // only handle the state fraud proofs for now - fraudProof, ok := proof.(*types.StateFraudProof) - if !ok { - m.logger.Error("unexpected type received for state fraud proof", "error", err) - return - } - m.logger.Debug("fraud proof received", - "block height", fraudProof.BlockHeight, - "pre-state app hash", fraudProof.PreStateAppHash, - "expected valid app hash", fraudProof.ExpectedValidAppHash, - "length of state witness", len(fraudProof.StateWitness), - ) - - // halt chain - m.logger.Info("verified fraud proof, halting chain") -} - // SyncLoop is responsible for syncing blocks. // // SyncLoop processes headers gossiped in P2p network to know what's the latest block height, @@ -307,9 +267,6 @@ func (m *Manager) SyncLoop(ctx context.Context, cancel context.CancelFunc) { m.retrieveCond.Signal() err := m.trySyncNextBlock(ctx, daHeight) - if err != nil && err.Error() == fmt.Errorf("failed to ApplyBlock: %w", state.ErrFraudProofGenerated).Error() { - return - } if err != nil { m.logger.Info("failed to sync next block", "error", err) } diff --git a/config/config.go b/config/config.go index 7ca286a203a..b3f67034c04 100644 --- a/config/config.go +++ b/config/config.go @@ -18,7 +18,6 @@ const ( flagDABlockTime = "rollkit.da_block_time" flagDAStartHeight = "rollkit.da_start_height" flagNamespaceID = "rollkit.namespace_id" - flagFraudProofs = "rollkit.experimental_insecure_fraud_proofs" flagLight = "rollkit.light" flagTrustedHash = "rollkit.trusted_hash" flagLazyAggregator = "rollkit.lazy_aggregator" @@ -55,7 +54,6 @@ type BlockManagerConfig struct { // DAStartHeight allows skipping first DAStartHeight-1 blocks when querying for blocks. DAStartHeight uint64 `mapstructure:"da_start_height"` NamespaceID types.NamespaceID `mapstructure:"namespace_id"` - FraudProofs bool `mapstructure:"fraud_proofs"` } // GetViperConfig reads configuration parameters from Viper instance. @@ -70,7 +68,6 @@ func (nc *NodeConfig) GetViperConfig(v *viper.Viper) error { nc.BlockTime = v.GetDuration(flagBlockTime) nc.LazyAggregator = v.GetBool(flagLazyAggregator) nsID := v.GetString(flagNamespaceID) - nc.FraudProofs = v.GetBool(flagFraudProofs) nc.Light = v.GetBool(flagLight) bytes, err := hex.DecodeString(nsID) if err != nil { @@ -94,7 +91,6 @@ func AddFlags(cmd *cobra.Command) { cmd.Flags().Duration(flagDABlockTime, def.DABlockTime, "DA chain block time (for syncing)") cmd.Flags().Uint64(flagDAStartHeight, def.DAStartHeight, "starting DA block height (for syncing)") cmd.Flags().BytesHex(flagNamespaceID, def.NamespaceID[:], "namespace identifies (8 bytes in hex)") - cmd.Flags().Bool(flagFraudProofs, def.FraudProofs, "enable fraud proofs (experimental & insecure)") cmd.Flags().Bool(flagLight, def.Light, "run light client") cmd.Flags().String(flagTrustedHash, def.TrustedHash, "initial trusted hash to start the header exchange service") } diff --git a/config/config_test.go b/config/config_test.go index 8cb335f88d0..68b383d447a 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -26,7 +26,6 @@ func TestViperAndCobra(t *testing.T) { assert.NoError(cmd.Flags().Set(flagDAConfig, `{"json":true}`)) assert.NoError(cmd.Flags().Set(flagBlockTime, "1234s")) assert.NoError(cmd.Flags().Set(flagNamespaceID, "0102030405060708")) - assert.NoError(cmd.Flags().Set(flagFraudProofs, "false")) nc := DefaultNodeConfig assert.NoError(nc.GetViperConfig(v)) @@ -36,5 +35,4 @@ func TestViperAndCobra(t *testing.T) { assert.Equal(`{"json":true}`, nc.DAConfig) assert.Equal(1234*time.Second, nc.BlockTime) assert.Equal(types.NamespaceID{1, 2, 3, 4, 5, 6, 7, 8}, nc.NamespaceID) - assert.Equal(false, nc.FraudProofs) } diff --git a/config/defaults.go b/config/defaults.go index d3daedc3630..2a218cb25ba 100644 --- a/config/defaults.go +++ b/config/defaults.go @@ -23,7 +23,6 @@ var DefaultNodeConfig = NodeConfig{ BlockManagerConfig: BlockManagerConfig{ BlockTime: 30 * time.Second, NamespaceID: types.NamespaceID{}, - FraudProofs: false, }, DALayer: "mock", DAConfig: "", diff --git a/go.mod b/go.mod index 7073cc06e11..b62ac37fac0 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,11 @@ go 1.20 require ( cosmossdk.io/math v1.0.1 - github.com/celestiaorg/go-fraud v0.1.2 github.com/celestiaorg/go-header v0.2.12 github.com/celestiaorg/nmt v0.17.0 github.com/celestiaorg/rsmt2d v0.9.0 github.com/celestiaorg/utils v0.1.0 - github.com/cometbft/cometbft v0.37.0 + github.com/cometbft/cometbft v0.37.1 github.com/creachadair/taskgroup v0.3.2 github.com/dgraph-io/badger/v3 v3.2103.5 github.com/go-kit/kit v0.12.0 @@ -42,6 +41,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect + github.com/celestiaorg/go-fraud v0.1.2 // indirect github.com/celestiaorg/go-libp2p-messenger v0.2.0 // indirect github.com/celestiaorg/merkletree v0.0.0-20210714075610-a84dc3ddbbe4 // indirect github.com/cespare/xxhash v1.1.0 // indirect @@ -188,7 +188,6 @@ require ( ) replace ( - github.com/cometbft/cometbft => github.com/rollkit/cometbft v0.37.1 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.2-alpha.regen.4 google.golang.org/grpc => google.golang.org/grpc v1.33.2 ) diff --git a/go.sum b/go.sum index 9fb216a1fea..b816a2e46de 100644 --- a/go.sum +++ b/go.sum @@ -237,6 +237,8 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/cometbft/cometbft v0.37.1 h1:KLxkQTK2hICXYq21U2hn1W5hOVYUdQgDQ1uB+90xPIg= +github.com/cometbft/cometbft v0.37.1/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= @@ -1366,8 +1368,6 @@ github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4 github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rollkit/celestia-openrpc v0.1.1 h1:Ub8ydB1c0qDQJmYL+s7i5u9YiQyINxw88AL1S8A+Lig= github.com/rollkit/celestia-openrpc v0.1.1/go.mod h1:Or8y0vuAzJu3SLOahIOt96+y4Vxaf74vrPFkUJl0oj0= -github.com/rollkit/cometbft v0.37.1 h1:Nj8Tg3MQoinOI1HmESlqoAgViCAlBb6I2GmAnZoytlQ= -github.com/rollkit/cometbft v0.37.1/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= diff --git a/mocks/Application.go b/mocks/Application.go index 949cec58dff..3debc63c0e9 100644 --- a/mocks/Application.go +++ b/mocks/Application.go @@ -96,34 +96,6 @@ func (_m *Application) EndBlock(_a0 types.RequestEndBlock) types.ResponseEndBloc return r0 } -// GenerateFraudProof provides a mock function with given fields: _a0 -func (_m *Application) GenerateFraudProof(_a0 types.RequestGenerateFraudProof) types.ResponseGenerateFraudProof { - ret := _m.Called(_a0) - - var r0 types.ResponseGenerateFraudProof - if rf, ok := ret.Get(0).(func(types.RequestGenerateFraudProof) types.ResponseGenerateFraudProof); ok { - r0 = rf(_a0) - } else { - r0 = ret.Get(0).(types.ResponseGenerateFraudProof) - } - - return r0 -} - -// GetAppHash provides a mock function with given fields: _a0 -func (_m *Application) GetAppHash(_a0 types.RequestGetAppHash) types.ResponseGetAppHash { - ret := _m.Called(_a0) - - var r0 types.ResponseGetAppHash - if rf, ok := ret.Get(0).(func(types.RequestGetAppHash) types.ResponseGetAppHash); ok { - r0 = rf(_a0) - } else { - r0 = ret.Get(0).(types.ResponseGetAppHash) - } - - return r0 -} - // Info provides a mock function with given fields: _a0 func (_m *Application) Info(_a0 types.RequestInfo) types.ResponseInfo { ret := _m.Called(_a0) @@ -236,20 +208,6 @@ func (_m *Application) Query(_a0 types.RequestQuery) types.ResponseQuery { return r0 } -// VerifyFraudProof provides a mock function with given fields: _a0 -func (_m *Application) VerifyFraudProof(_a0 types.RequestVerifyFraudProof) types.ResponseVerifyFraudProof { - ret := _m.Called(_a0) - - var r0 types.ResponseVerifyFraudProof - if rf, ok := ret.Get(0).(func(types.RequestVerifyFraudProof) types.ResponseVerifyFraudProof); ok { - r0 = rf(_a0) - } else { - r0 = ret.Get(0).(types.ResponseVerifyFraudProof) - } - - return r0 -} - type mockConstructorTestingTNewApplication interface { mock.TestingT Cleanup(func()) diff --git a/node/full.go b/node/full.go index 9ea4793c4d3..e097fd5414c 100644 --- a/node/full.go +++ b/node/full.go @@ -7,8 +7,6 @@ import ( "errors" "fmt" - "github.com/celestiaorg/go-fraud/fraudserv" - "github.com/celestiaorg/go-header" ds "github.com/ipfs/go-datastore" ktds "github.com/ipfs/go-datastore/keytransform" "github.com/libp2p/go-libp2p/core/crypto" @@ -34,7 +32,6 @@ import ( "github.com/rollkit/rollkit/state/txindex" "github.com/rollkit/rollkit/state/txindex/kv" "github.com/rollkit/rollkit/store" - "github.com/rollkit/rollkit/types" ) // prefixes used in KV store to separate main node data from DALC data @@ -79,10 +76,8 @@ type FullNode struct { BlockIndexer indexer.BlockIndexer IndexerService *txindex.IndexerService - hExService *HeaderExchangeService - bExService *BlockExchangeService - fraudService *fraudserv.ProofService - proofServiceFactory ProofServiceFactory + hExService *HeaderExchangeService + bExService *BlockExchangeService // keep context here only because of API compatibility // - it's used in `OnStart` (defined in service.Service interface) @@ -167,16 +162,6 @@ func newFullNode( return nil, fmt.Errorf("HeaderExchangeService initialization error: %w", err) } - fraudProofFactory := NewProofServiceFactory( - client, - func(ctx context.Context, u uint64) (header.Header, error) { - return headerExchangeService.headerStore.GetByHeight(ctx, u) - }, - mainKV, - true, - genesis.ChainID, - ) - blockExchangeService, err := NewBlockExchangeService(ctx, mainKV, conf, genesis, client, logger.With("module", "BlockExchangeService")) if err != nil { return nil, fmt.Errorf("BlockExchangeService initialization error: %w", err) @@ -185,26 +170,25 @@ func newFullNode( ctx, cancel := context.WithCancel(ctx) node := &FullNode{ - proxyApp: proxyApp, - eventBus: eventBus, - genesis: genesis, - conf: conf, - P2P: client, - blockManager: blockManager, - dalc: dalc, - Mempool: mp, - mempoolIDs: mpIDs, - incomingTxCh: make(chan *p2p.GossipMessage), - Store: s, - TxIndexer: txIndexer, - IndexerService: indexerService, - BlockIndexer: blockIndexer, - hExService: headerExchangeService, - bExService: blockExchangeService, - proofServiceFactory: fraudProofFactory, - ctx: ctx, - cancel: cancel, - DoneBuildingBlock: doneBuildingChannel, + proxyApp: proxyApp, + eventBus: eventBus, + genesis: genesis, + conf: conf, + P2P: client, + blockManager: blockManager, + dalc: dalc, + Mempool: mp, + mempoolIDs: mpIDs, + incomingTxCh: make(chan *p2p.GossipMessage), + Store: s, + TxIndexer: txIndexer, + IndexerService: indexerService, + BlockIndexer: blockIndexer, + hExService: headerExchangeService, + bExService: blockExchangeService, + ctx: ctx, + cancel: cancel, + DoneBuildingBlock: doneBuildingChannel, } node.BaseService = *service.NewBaseService(logger, "Node", node) @@ -296,24 +280,12 @@ func (n *FullNode) OnStart() error { return fmt.Errorf("error while starting data availability layer client: %w", err) } - // since p2p pubsub and host are required to create ProofService, - // we have to delay the construction until Start and use the help of ProofServiceFactory - n.fraudService = n.proofServiceFactory.CreateProofService() - if err := n.fraudService.AddVerifier(types.StateFraudProofType, VerifierFn(n.proxyApp)); err != nil { - return fmt.Errorf("error while registering verifier for fraud service: %w", err) - } - if err = n.fraudService.Start(n.ctx); err != nil { - return fmt.Errorf("error while starting fraud exchange service: %w", err) - } - n.blockManager.SetFraudProofService(n.fraudService) - if n.conf.Aggregator { n.Logger.Info("working in aggregator mode", "block time", n.conf.BlockTime) go n.blockManager.AggregationLoop(n.ctx, n.conf.LazyAggregator) go n.headerPublishLoop(n.ctx) go n.blockPublishLoop(n.ctx) } - go n.blockManager.ProcessFraudProof(n.ctx, n.cancel) go n.blockManager.RetrieveLoop(n.ctx) go n.blockManager.SyncLoop(n.ctx, n.cancel) return nil @@ -341,7 +313,6 @@ func (n *FullNode) OnStop() { err = multierr.Append(err, n.P2P.Close()) err = multierr.Append(err, n.hExService.Stop()) err = multierr.Append(err, n.bExService.Stop()) - err = multierr.Append(err, n.fraudService.Stop(n.ctx)) n.Logger.Error("errors while stopping node:", "errors", err) } diff --git a/node/full_client_test.go b/node/full_client_test.go index b1ecd5770df..6a0ede85158 100644 --- a/node/full_client_test.go +++ b/node/full_client_test.go @@ -538,8 +538,6 @@ func TestTx(t *testing.T) { mockApp.On("Commit", mock.Anything).Return(abci.ResponseCommit{}) mockApp.On("DeliverTx", mock.Anything).Return(abci.ResponseDeliverTx{}) mockApp.On("CheckTx", mock.Anything).Return(abci.ResponseCheckTx{}) - mockApp.On("GetAppHash", mock.Anything).Return(abci.ResponseGetAppHash{}) - mockApp.On("GenerateFraudProof", mock.Anything).Return(abci.ResponseGenerateFraudProof{}) err = rpc.node.Start() require.NoError(err) @@ -842,8 +840,6 @@ func createApp(require *require.Assertions, vKeyToRemove cmcrypto.PrivKey, wg *s app.On("CheckTx", mock.Anything).Return(abci.ResponseCheckTx{}) app.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{}) app.On("Commit", mock.Anything).Return(abci.ResponseCommit{}) - app.On("GetAppHash", mock.Anything).Return(abci.ResponseGetAppHash{}) - app.On("GenerateFraudProof", mock.Anything).Return(abci.ResponseGenerateFraudProof{}) pbValKey, err := encoding.PubKeyToProto(vKeyToRemove.PubKey()) require.NoError(err) @@ -934,7 +930,6 @@ func TestMempool2Nodes(t *testing.T) { app.On("EndBlock", mock.Anything).Return(abci.ResponseEndBlock{}) app.On("Commit", mock.Anything).Return(abci.ResponseCommit{}) app.On("DeliverTx", mock.Anything).Return(abci.ResponseDeliverTx{}) - app.On("GetAppHash", mock.Anything).Return(abci.ResponseGetAppHash{}) ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/node/full_node_integration_test.go b/node/full_node_integration_test.go index 7045ec5ceb2..282e86efc98 100644 --- a/node/full_node_integration_test.go +++ b/node/full_node_integration_test.go @@ -8,7 +8,6 @@ import ( mrand "math/rand" "strconv" "strings" - "sync" "testing" "time" @@ -44,7 +43,6 @@ func TestAggregatorMode(t *testing.T) { app.On("DeliverTx", mock.Anything).Return(abci.ResponseDeliverTx{}) app.On("EndBlock", mock.Anything).Return(abci.ResponseEndBlock{}) app.On("Commit", mock.Anything).Return(abci.ResponseCommit{}) - app.On("GetAppHash", mock.Anything).Return(abci.ResponseGetAppHash{}) key, _, _ := crypto.GenerateEd25519Key(rand.Reader) anotherKey, _, _ := crypto.GenerateEd25519Key(rand.Reader) @@ -92,7 +90,7 @@ func TestTxGossipingAndAggregation(t *testing.T) { require := require.New(t) clientNodes := 4 - nodes, apps := createAndStartNodes(clientNodes, false, t) + nodes, apps := createAndStartNodes(clientNodes, t) aggApp := apps[0] apps = apps[1:] @@ -145,7 +143,6 @@ func TestLazyAggregator(t *testing.T) { app.On("DeliverTx", mock.Anything).Return(abci.ResponseDeliverTx{}) app.On("EndBlock", mock.Anything).Return(abci.ResponseEndBlock{}) app.On("Commit", mock.Anything).Return(abci.ResponseCommit{}) - app.On("GetAppHash", mock.Anything).Return(abci.ResponseGetAppHash{}) key, _, _ := crypto.GenerateEd25519Key(rand.Reader) genesisValidators, signingKey := getGenesisValidatorSetWithSigner(1) @@ -232,7 +229,7 @@ func testSingleAggregatorSingleFullNode(t *testing.T, useBlockExchange bool) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() clientNodes := 1 - nodes, _ := createNodes(aggCtx, ctx, clientNodes+1, false, t) + nodes, _ := createNodes(aggCtx, ctx, clientNodes+1, t) node1 := nodes[0] node2 := nodes[1] @@ -261,7 +258,7 @@ func testSingleAggregatorTwoFullNode(t *testing.T, useBlockExchange bool) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() clientNodes := 2 - nodes, _ := createNodes(aggCtx, ctx, clientNodes+1, false, t) + nodes, _ := createNodes(aggCtx, ctx, clientNodes+1, t) node1 := nodes[0] node2 := nodes[1] @@ -293,7 +290,7 @@ func testSingleAggregatorSingleFullNodeTrustedHash(t *testing.T, useBlockExchang ctx, cancel := context.WithCancel(context.Background()) defer cancel() clientNodes := 1 - nodes, _ := createNodes(aggCtx, ctx, clientNodes+1, false, t) + nodes, _ := createNodes(aggCtx, ctx, clientNodes+1, t) node1 := nodes[0] node2 := nodes[1] @@ -337,15 +334,15 @@ func testSingleAggregatorSingleFullNodeSingleLightNode(t *testing.T) { defer func() { require.NoError(dalc.Stop()) }() - sequencer, _ := createNode(aggCtx, 0, false, true, false, keys, t) - fullNode, _ := createNode(ctx, 1, false, false, false, keys, t) + sequencer, _ := createNode(aggCtx, 0, true, false, keys, t) + fullNode, _ := createNode(ctx, 1, false, false, keys, t) sequencer.(*FullNode).dalc = dalc sequencer.(*FullNode).blockManager.SetDALC(dalc) fullNode.(*FullNode).dalc = dalc fullNode.(*FullNode).blockManager.SetDALC(dalc) - lightNode, _ := createNode(ctx, 2, false, false, true, keys, t) + lightNode, _ := createNode(ctx, 2, false, true, keys, t) require.NoError(sequencer.Start()) defer func() { @@ -364,132 +361,13 @@ func testSingleAggregatorSingleFullNodeSingleLightNode(t *testing.T) { require.NoError(verifyNodesSynced(fullNode, lightNode, false)) } -func testSingleAggregatorSingleFullNodeFraudProofGossip(t *testing.T) { - assert := assert.New(t) - require := require.New(t) - - var wg sync.WaitGroup - aggCtx, aggCancel := context.WithCancel(context.Background()) - defer aggCancel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - clientNodes := 1 - nodes, apps := createNodes(aggCtx, ctx, clientNodes+1, true, t) - - for _, app := range apps { - app.On("VerifyFraudProof", mock.Anything).Return(abci.ResponseVerifyFraudProof{Success: true}).Run(func(args mock.Arguments) { - wg.Done() - }).Once() - } - - aggNode := nodes[0] - fullNode := nodes[1] - - wg.Add(clientNodes + 1) - require.NoError(aggNode.Start()) - defer func() { - require.NoError(aggNode.Stop()) - }() - require.NoError(waitForAtLeastNBlocks(aggNode, 2, false)) - require.NoError(fullNode.Start()) - defer func() { - require.NoError(fullNode.Stop()) - }() - - wg.Wait() - // aggregator should have 0 GenerateFraudProof calls and 1 VerifyFraudProof calls - apps[0].AssertNumberOfCalls(t, "GenerateFraudProof", 0) - apps[0].AssertNumberOfCalls(t, "VerifyFraudProof", 1) - // fullnode should have 1 GenerateFraudProof calls and 1 VerifyFraudProof calls - apps[1].AssertNumberOfCalls(t, "GenerateFraudProof", 1) - apps[1].AssertNumberOfCalls(t, "VerifyFraudProof", 1) - - n1Frauds, err := aggNode.fraudService.Get(aggCtx, types.StateFraudProofType) - require.NoError(err) - - n2Frauds, err := fullNode.fraudService.Get(aggCtx, types.StateFraudProofType) - require.NoError(err) - - assert.Equal(len(n1Frauds), 1, "number of fraud proofs received via gossip should be 1") - assert.Equal(len(n2Frauds), 1, "number of fraud proofs received via gossip should be 1") - assert.Equal(n1Frauds, n2Frauds, "the received fraud proofs after gossip must match") -} - -func testSingleAggregatorTwoFullNodeFraudProofSync(t *testing.T) { - assert := assert.New(t) - require := require.New(t) - - var wg sync.WaitGroup - aggCtx, aggCancel := context.WithCancel(context.Background()) - defer aggCancel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - clientNodes := 2 - nodes, apps := createNodes(aggCtx, ctx, clientNodes+1, true, t) - - for _, app := range apps { - app.On("VerifyFraudProof", mock.Anything).Return(abci.ResponseVerifyFraudProof{Success: true}).Run(func(args mock.Arguments) { - wg.Done() - }).Once() - } - - aggNode := nodes[0] - fullNode1 := nodes[1] - fullNode2 := nodes[2] - - wg.Add(clientNodes) - require.NoError(aggNode.Start()) - defer func() { - require.NoError(aggNode.Stop()) - }() - require.NoError(fullNode1.Start()) - defer func() { - require.NoError(fullNode1.Stop()) - }() - wg.Wait() - // aggregator should have 0 GenerateFraudProof calls and 1 VerifyFraudProof calls - apps[0].AssertNumberOfCalls(t, "GenerateFraudProof", 0) - apps[0].AssertNumberOfCalls(t, "VerifyFraudProof", 1) - // fullnode1 should have 1 GenerateFraudProof calls and 1 VerifyFraudProof calls - apps[1].AssertNumberOfCalls(t, "GenerateFraudProof", 1) - apps[1].AssertNumberOfCalls(t, "VerifyFraudProof", 1) - - n1Frauds, err := aggNode.fraudService.Get(ctx, types.StateFraudProofType) - require.NoError(err) - - n2Frauds, err := fullNode1.fraudService.Get(ctx, types.StateFraudProofType) - require.NoError(err) - assert.Equal(n1Frauds, n2Frauds, "number of fraud proofs gossiped between nodes must match") - - wg.Add(1) - // delay start node3 such that it can sync the fraud proof from peers, instead of listening to gossip - require.NoError(fullNode2.Start()) - defer func() { - require.NoError(fullNode2.Stop()) - }() - - wg.Wait() - // fullnode2 should have 1 GenerateFraudProof calls and 1 VerifyFraudProof calls - apps[2].AssertNumberOfCalls(t, "GenerateFraudProof", 1) - apps[2].AssertNumberOfCalls(t, "VerifyFraudProof", 1) - - n3Frauds, err := fullNode2.fraudService.Get(ctx, types.StateFraudProofType) - require.NoError(err) - assert.Equal(n1Frauds, n3Frauds, "number of fraud proofs gossiped between nodes must match") -} - -func TestFraudProofService(t *testing.T) { - t.Run("SingleAggregatorSingleFullNodeFraudProofGossip", testSingleAggregatorSingleFullNodeFraudProofGossip) - t.Run("SingleAggregatorTwoFullNodeFraudProofSync", testSingleAggregatorTwoFullNodeFraudProofSync) -} - // Creates a starts the given number of client nodes along with an aggregator node. Uses the given flag to decide whether to have the aggregator produce malicious blocks. -func createAndStartNodes(clientNodes int, isMalicious bool, t *testing.T) ([]*FullNode, []*mocks.Application) { +func createAndStartNodes(clientNodes int, t *testing.T) ([]*FullNode, []*mocks.Application) { aggCtx, aggCancel := context.WithCancel(context.Background()) defer aggCancel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - nodes, apps := createNodes(aggCtx, ctx, clientNodes+1, isMalicious, t) + nodes, apps := createNodes(aggCtx, ctx, clientNodes+1, t) startNodes(nodes, apps, t) defer func() { for _, n := range nodes { @@ -546,7 +424,7 @@ func startNodes(nodes []*FullNode, apps []*mocks.Application, t *testing.T) { } // Creates the given number of nodes the given nodes using the given wait group to synchornize them -func createNodes(aggCtx, ctx context.Context, num int, isMalicious bool, t *testing.T) ([]*FullNode, []*mocks.Application) { +func createNodes(aggCtx, ctx context.Context, num int, t *testing.T) ([]*FullNode, []*mocks.Application) { t.Helper() if aggCtx == nil { @@ -568,14 +446,14 @@ func createNodes(aggCtx, ctx context.Context, num int, isMalicious bool, t *test ds, _ := store.NewDefaultInMemoryKVStore() _ = dalc.Init([8]byte{}, nil, ds, log.TestingLogger()) _ = dalc.Start() - node, app := createNode(aggCtx, 0, isMalicious, true, false, keys, t) + node, app := createNode(aggCtx, 0, true, false, keys, t) apps[0] = app nodes[0] = node.(*FullNode) // use same, common DALC, so nodes can share data nodes[0].dalc = dalc nodes[0].blockManager.SetDALC(dalc) for i := 1; i < num; i++ { - node, apps[i] = createNode(ctx, i, isMalicious, false, false, keys, t) + node, apps[i] = createNode(ctx, i, false, false, keys, t) nodes[i] = node.(*FullNode) nodes[i].dalc = dalc nodes[i].blockManager.SetDALC(dalc) @@ -584,7 +462,7 @@ func createNodes(aggCtx, ctx context.Context, num int, isMalicious bool, t *test return nodes, apps } -func createNode(ctx context.Context, n int, isMalicious bool, aggregator bool, isLight bool, keys []crypto.PrivKey, t *testing.T) (Node, *mocks.Application) { +func createNode(ctx context.Context, n int, aggregator bool, isLight bool, keys []crypto.PrivKey, t *testing.T) (Node, *mocks.Application) { t.Helper() require := require.New(t) // nodes will listen on consecutive ports on local interface @@ -597,7 +475,6 @@ func createNode(ctx context.Context, n int, isMalicious bool, aggregator bool, i DABlockTime: 100 * time.Millisecond, BlockTime: 1 * time.Second, // blocks must be at least 1 sec apart for adjacent headers to get verified correctly NamespaceID: types.NamespaceID{8, 7, 6, 5, 4, 3, 2, 1}, - FraudProofs: true, } for i := 0; i < len(keys); i++ { if i == n { @@ -617,17 +494,7 @@ func createNode(ctx context.Context, n int, isMalicious bool, aggregator bool, i app.On("EndBlock", mock.Anything).Return(abci.ResponseEndBlock{}) app.On("Commit", mock.Anything).Return(abci.ResponseCommit{}) app.On("DeliverTx", mock.Anything).Return(abci.ResponseDeliverTx{}) - maliciousAppHash := []byte{9, 8, 7, 6} - nonMaliciousAppHash := []byte{1, 2, 3, 4} - if isMalicious && aggregator { - app.On("GetAppHash", mock.Anything).Return(abci.ResponseGetAppHash{AppHash: maliciousAppHash}) - } else { - app.On("GetAppHash", mock.Anything).Return(abci.ResponseGetAppHash{AppHash: nonMaliciousAppHash}) - } - if isMalicious && !aggregator { - app.On("GenerateFraudProof", mock.Anything).Return(abci.ResponseGenerateFraudProof{FraudProof: &abci.FraudProof{BlockHeight: 1, FraudulentBeginBlock: &abci.RequestBeginBlock{Hash: []byte("123")}, ExpectedValidAppHash: nonMaliciousAppHash}}) - } if ctx == nil { ctx = context.Background() } diff --git a/node/helpers_test.go b/node/helpers_test.go index 47ad7b0e11f..8f515fa8f86 100644 --- a/node/helpers_test.go +++ b/node/helpers_test.go @@ -40,8 +40,8 @@ func TestGetNodeHeight(t *testing.T) { for i := 0; i < num; i++ { keys[i], _, _ = crypto.GenerateEd25519Key(rand.Reader) } - fullNode, _ := createNode(ctx, 0, false, true, false, keys, t) - lightNode, _ := createNode(ctx, 1, false, true, true, keys, t) + fullNode, _ := createNode(ctx, 0, true, false, keys, t) + lightNode, _ := createNode(ctx, 1, true, true, keys, t) fullNode.(*FullNode).dalc = dalc fullNode.(*FullNode).blockManager.SetDALC(dalc) require.NoError(fullNode.Start()) diff --git a/node/light.go b/node/light.go index 0e92dba0f53..3c9217aa808 100644 --- a/node/light.go +++ b/node/light.go @@ -4,9 +4,6 @@ import ( "context" "fmt" - "github.com/celestiaorg/go-fraud/fraudserv" - "github.com/celestiaorg/go-header" - abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/libs/log" "github.com/cometbft/cometbft/libs/service" proxy "github.com/cometbft/cometbft/proxy" @@ -19,7 +16,6 @@ import ( "github.com/rollkit/rollkit/config" "github.com/rollkit/rollkit/p2p" "github.com/rollkit/rollkit/store" - "github.com/rollkit/rollkit/types" ) var _ Node = &LightNode{} @@ -31,9 +27,7 @@ type LightNode struct { proxyApp proxy.AppConns - hExService *HeaderExchangeService - fraudService *fraudserv.ProofService - proofServiceFactory ProofServiceFactory + hExService *HeaderExchangeService ctx context.Context cancel context.CancelFunc @@ -72,25 +66,14 @@ func newLightNode( return nil, fmt.Errorf("HeaderExchangeService initialization error: %w", err) } - fraudProofFactory := NewProofServiceFactory( - client, - func(ctx context.Context, u uint64) (header.Header, error) { - return headerExchangeService.headerStore.GetByHeight(ctx, u) - }, - datastore, - true, - genesis.ChainID, - ) - ctx, cancel := context.WithCancel(ctx) node := &LightNode{ - P2P: client, - proxyApp: proxyApp, - hExService: headerExchangeService, - proofServiceFactory: fraudProofFactory, - cancel: cancel, - ctx: ctx, + P2P: client, + proxyApp: proxyApp, + hExService: headerExchangeService, + cancel: cancel, + ctx: ctx, } node.P2P.SetTxValidator(node.falseValidator()) @@ -117,16 +100,6 @@ func (ln *LightNode) OnStart() error { return fmt.Errorf("error while starting header exchange service: %w", err) } - ln.fraudService = ln.proofServiceFactory.CreateProofService() - if err := ln.fraudService.AddVerifier(types.StateFraudProofType, VerifierFn(ln.proxyApp)); err != nil { - return fmt.Errorf("error while registering verifier for fraud service: %w", err) - } - if err := ln.fraudService.Start(ln.ctx); err != nil { - return fmt.Errorf("error while starting fraud exchange service: %w", err) - } - - go ln.ProcessFraudProof() - return nil } @@ -144,47 +117,3 @@ func (ln *LightNode) falseValidator() p2p.GossipValidator { return false } } - -func (ln *LightNode) ProcessFraudProof() { - // subscribe to state fraud proof - sub, err := ln.fraudService.Subscribe(types.StateFraudProofType) - if err != nil { - ln.Logger.Error("failed to subscribe to fraud proof gossip", "error", err) - return - } - - // continuously process the fraud proofs received via subscription - for { - proof, err := sub.Proof(ln.ctx) - if err != nil { - ln.Logger.Error("failed to receive gossiped fraud proof", "error", err) - return - } - - // only handle the state fraud proofs for now - fraudProof, ok := proof.(*types.StateFraudProof) - if !ok { - ln.Logger.Error("unexpected type received for state fraud proof", "error", err) - return - } - ln.Logger.Debug("fraud proof received", - "block height", fraudProof.BlockHeight, - "pre-state app hash", fraudProof.PreStateAppHash, - "expected valid app hash", fraudProof.ExpectedValidAppHash, - "length of state witness", len(fraudProof.StateWitness), - ) - - resp, err := ln.proxyApp.Consensus().VerifyFraudProofSync(abci.RequestVerifyFraudProof{ - FraudProof: &fraudProof.FraudProof, - ExpectedValidAppHash: fraudProof.ExpectedValidAppHash, - }) - if err != nil { - ln.Logger.Error("failed to verify fraud proof", "error", err) - continue - } - - if resp.Success { - panic("received valid fraud proof! halting light client") - } - } -} diff --git a/node/proof_service_factory.go b/node/proof_service_factory.go deleted file mode 100644 index 67381e88157..00000000000 --- a/node/proof_service_factory.go +++ /dev/null @@ -1,62 +0,0 @@ -package node - -import ( - "errors" - - "github.com/celestiaorg/go-fraud" - "github.com/celestiaorg/go-fraud/fraudserv" - abci "github.com/cometbft/cometbft/abci/types" - proxy "github.com/cometbft/cometbft/proxy" - "github.com/ipfs/go-datastore" - - "github.com/rollkit/rollkit/p2p" - "github.com/rollkit/rollkit/types" -) - -var VerifierFn = func(proxyApp proxy.AppConns) func(fraudProof fraud.Proof) (bool, error) { - return func(fraudProof fraud.Proof) (bool, error) { - stateFraudProof, ok := fraudProof.(*types.StateFraudProof) - if !ok { - return false, errors.New("unknown fraud proof") - } - resp, err := proxyApp.Consensus().VerifyFraudProofSync( - abci.RequestVerifyFraudProof{ - FraudProof: &stateFraudProof.FraudProof, - ExpectedValidAppHash: stateFraudProof.ExpectedValidAppHash, - }, - ) - if err != nil { - return false, err - } - return resp.Success, nil - } -} - -type ProofServiceFactory struct { - client *p2p.Client - getter fraud.HeaderFetcher - ds datastore.Datastore - syncerEnabled bool - networkID string -} - -func NewProofServiceFactory(c *p2p.Client, getter fraud.HeaderFetcher, ds datastore.Datastore, syncerEnabled bool, networkID string) ProofServiceFactory { - return ProofServiceFactory{ - client: c, - getter: getter, - ds: ds, - syncerEnabled: syncerEnabled, - networkID: networkID, - } -} - -func (factory *ProofServiceFactory) CreateProofService() *fraudserv.ProofService { - return fraudserv.NewProofService( - factory.client.PubSub(), - factory.client.Host(), - factory.getter, - factory.ds, - factory.syncerEnabled, - factory.networkID, - ) -} diff --git a/rpc/json/test_helpers.go b/rpc/json/test_helpers.go index d37bc65f253..a840d8addaf 100644 --- a/rpc/json/test_helpers.go +++ b/rpc/json/test_helpers.go @@ -32,8 +32,6 @@ func getRPC(t *testing.T) (*mocks.Application, rpcclient.Client) { app.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{}) app.On("EndBlock", mock.Anything).Return(abci.ResponseEndBlock{}) app.On("Commit", mock.Anything).Return(abci.ResponseCommit{}) - app.On("GetAppHash", mock.Anything).Return(abci.ResponseGetAppHash{}) - app.On("GenerateFraudProof", mock.Anything).Return(abci.ResponseGenerateFraudProof{}) app.On("CheckTx", mock.Anything).Return(abci.ResponseCheckTx{ GasWanted: 1000, GasUsed: 1000, diff --git a/state/executor.go b/state/executor.go index 2c5b89bd973..5cb6f38c8fe 100644 --- a/state/executor.go +++ b/state/executor.go @@ -7,7 +7,6 @@ import ( "fmt" "time" - "github.com/celestiaorg/go-fraud/fraudserv" abci "github.com/cometbft/cometbft/abci/types" cryptoenc "github.com/cometbft/cometbft/crypto/encoding" cmbytes "github.com/cometbft/cometbft/libs/bytes" @@ -23,38 +22,33 @@ import ( "github.com/rollkit/rollkit/types" ) -var ErrFraudProofGenerated = errors.New("failed to ApplyBlock: halting node due to fraud") var ErrEmptyValSetGenerated = errors.New("applying the validator changes would result in empty set") var ErrAddingValidatorToBased = errors.New("cannot add validators to empty validator set") // BlockExecutor creates and applies blocks and maintains state. type BlockExecutor struct { - proposerAddress []byte - namespaceID types.NamespaceID - chainID string - proxyApp proxy.AppConnConsensus - mempool mempool.Mempool - fraudProofsEnabled bool + proposerAddress []byte + namespaceID types.NamespaceID + chainID string + proxyApp proxy.AppConnConsensus + mempool mempool.Mempool eventBus *cmtypes.EventBus logger log.Logger - - FraudService *fraudserv.ProofService } // NewBlockExecutor creates new instance of BlockExecutor. // Proposer address and namespace ID will be used in all newly created blocks. -func NewBlockExecutor(proposerAddress []byte, namespaceID [8]byte, chainID string, mempool mempool.Mempool, proxyApp proxy.AppConnConsensus, fraudProofsEnabled bool, eventBus *cmtypes.EventBus, logger log.Logger) *BlockExecutor { +func NewBlockExecutor(proposerAddress []byte, namespaceID [8]byte, chainID string, mempool mempool.Mempool, proxyApp proxy.AppConnConsensus, eventBus *cmtypes.EventBus, logger log.Logger) *BlockExecutor { return &BlockExecutor{ - proposerAddress: proposerAddress, - namespaceID: namespaceID, - chainID: chainID, - proxyApp: proxyApp, - mempool: mempool, - fraudProofsEnabled: fraudProofsEnabled, - eventBus: eventBus, - logger: logger, + proposerAddress: proposerAddress, + namespaceID: namespaceID, + chainID: chainID, + proxyApp: proxyApp, + mempool: mempool, + eventBus: eventBus, + logger: logger, } } @@ -192,23 +186,6 @@ func (e *BlockExecutor) Commit(ctx context.Context, state types.State, block *ty return appHash, retainHeight, nil } -func (e *BlockExecutor) VerifyFraudProof(fraudProof *abci.FraudProof, expectedValidAppHash []byte) (bool, error) { - resp, err := e.proxyApp.VerifyFraudProofSync( - abci.RequestVerifyFraudProof{ - FraudProof: fraudProof, - ExpectedValidAppHash: expectedValidAppHash, - }, - ) - if err != nil { - return false, err - } - return resp.Success, nil -} - -func (e *BlockExecutor) SetFraudProofService(fraudProofServ *fraudserv.ProofService) { - e.FraudService = fraudProofServ -} - func (e *BlockExecutor) updateState(state types.State, block *types.Block, abciResponses *cmstate.ABCIResponses, validatorUpdates []*cmtypes.Validator) (types.State, error) { nValSet := state.NextValidators.Copy() lastHeightValSetChanged := state.LastHeightValidatorsChanged @@ -322,18 +299,6 @@ func (e *BlockExecutor) execute(ctx context.Context, state types.State, block *t validTxs := 0 invalidTxs := 0 - currentIsrs := block.Data.IntermediateStateRoots.RawRootsList - currentIsrIndex := 0 - - if e.fraudProofsEnabled && currentIsrs != nil { - expectedLength := len(block.Data.Txs) + 3 // before BeginBlock, after BeginBlock, after every Tx, after EndBlock - if len(currentIsrs) != expectedLength { - return nil, fmt.Errorf("invalid length of ISR list: %d, expected length: %d", len(currentIsrs), expectedLength) - } - } - - ISRs := make([][]byte, 0) - e.proxyApp.SetResponseCallback(func(req *abci.Request, res *abci.Response) { if r, ok := res.Value.(*abci.Response_DeliverTx); ok { txRes := r.DeliverTx @@ -348,41 +313,6 @@ func (e *BlockExecutor) execute(ctx context.Context, state types.State, block *t } }) - if e.fraudProofsEnabled { - isr, err := e.getAppHash() - if err != nil { - return nil, err - } - ISRs = append(ISRs, isr) - currentIsrIndex++ - } - - genAndGossipFraudProofIfNeeded := func(beginBlockRequest *abci.RequestBeginBlock, deliverTxRequests []*abci.RequestDeliverTx, endBlockRequest *abci.RequestEndBlock) (err error) { - if !e.fraudProofsEnabled { - return nil - } - isr, err := e.getAppHash() - if err != nil { - return err - } - ISRs = append(ISRs, isr) - isFraud := e.isFraudProofTrigger(isr, currentIsrs, currentIsrIndex) - if isFraud { - e.logger.Info("found fraud occurrence, generating a fraud proof...") - fraudProof, err := e.generateFraudProof(beginBlockRequest, deliverTxRequests, endBlockRequest) - if err != nil { - return err - } - // Gossip Fraud Proof - if err := e.FraudService.Broadcast(ctx, &types.StateFraudProof{FraudProof: *fraudProof}); err != nil { - return fmt.Errorf("failed to broadcast fraud proof: %w", err) - } - return ErrFraudProofGenerated - } - currentIsrIndex++ - return nil - } - hash := block.Hash() abciHeader, err := abciconv.ToABCIHeaderPB(&block.SignedHeader.Header) if err != nil { @@ -404,24 +334,12 @@ func (e *BlockExecutor) execute(ctx context.Context, state types.State, block *t return nil, err } - err = genAndGossipFraudProofIfNeeded(&beginBlockRequest, nil, nil) - if err != nil { - return nil, err - } - - deliverTxRequests := make([]*abci.RequestDeliverTx, 0, len(block.Data.Txs)) for _, tx := range block.Data.Txs { - deliverTxRequest := abci.RequestDeliverTx{Tx: tx} - deliverTxRequests = append(deliverTxRequests, &deliverTxRequest) - res := e.proxyApp.DeliverTxAsync(deliverTxRequest) + res := e.proxyApp.DeliverTxAsync(abci.RequestDeliverTx{Tx: tx}) if res.GetException() != nil { return nil, errors.New(res.GetException().GetError()) } - err = genAndGossipFraudProofIfNeeded(&beginBlockRequest, deliverTxRequests, nil) - if err != nil { - return nil, err - } } endBlockRequest := abci.RequestEndBlock{Height: block.SignedHeader.Header.Height()} abciResponses.EndBlock, err = e.proxyApp.EndBlockSync(endBlockRequest) @@ -429,53 +347,9 @@ func (e *BlockExecutor) execute(ctx context.Context, state types.State, block *t return nil, err } - err = genAndGossipFraudProofIfNeeded(&beginBlockRequest, deliverTxRequests, &endBlockRequest) - if err != nil { - return nil, err - } - - if e.fraudProofsEnabled && block.Data.IntermediateStateRoots.RawRootsList == nil { - // Block producer: Initial ISRs generated here - block.Data.IntermediateStateRoots.RawRootsList = ISRs - } - return abciResponses, nil } -func (e *BlockExecutor) isFraudProofTrigger(generatedIsr []byte, currentIsrs [][]byte, index int) bool { - if currentIsrs == nil { - return false - } - stateIsr := currentIsrs[index] - if !bytes.Equal(stateIsr, generatedIsr) { - e.logger.Debug("ISR Mismatch", "given_isr", stateIsr, "generated_isr", generatedIsr) - return true - } - return false -} - -func (e *BlockExecutor) generateFraudProof(beginBlockRequest *abci.RequestBeginBlock, deliverTxRequests []*abci.RequestDeliverTx, endBlockRequest *abci.RequestEndBlock) (*abci.FraudProof, error) { - generateFraudProofRequest := abci.RequestGenerateFraudProof{} - if beginBlockRequest == nil { - return nil, fmt.Errorf("begin block request cannot be a nil parameter") - } - generateFraudProofRequest.BeginBlockRequest = *beginBlockRequest - if deliverTxRequests != nil { - generateFraudProofRequest.DeliverTxRequests = deliverTxRequests - if endBlockRequest != nil { - generateFraudProofRequest.EndBlockRequest = endBlockRequest - } - } - resp, err := e.proxyApp.GenerateFraudProofSync(generateFraudProofRequest) - if err != nil { - return nil, err - } - if resp.FraudProof == nil { - return nil, fmt.Errorf("fraud proof generation failed") - } - return resp.FraudProof, nil -} - func (e *BlockExecutor) publishEvents(resp *cmstate.ABCIResponses, block *types.Block, state types.State) error { if e.eventBus == nil { return nil @@ -517,14 +391,6 @@ func (e *BlockExecutor) publishEvents(resp *cmstate.ABCIResponses, block *types. return err } -func (e *BlockExecutor) getAppHash() ([]byte, error) { - isrResp, err := e.proxyApp.GetAppHashSync(abci.RequestGetAppHash{}) - if err != nil { - return nil, err - } - return isrResp.AppHash, nil -} - func toRollkitTxs(txs cmtypes.Txs) types.Txs { rollkitTxs := make(types.Txs, len(txs)) for i := range txs { diff --git a/state/executor_test.go b/state/executor_test.go index f523c0f77b4..4862b10ab9f 100644 --- a/state/executor_test.go +++ b/state/executor_test.go @@ -26,7 +26,7 @@ import ( "github.com/rollkit/rollkit/types" ) -func doTestCreateBlock(t *testing.T, fraudProofsEnabled bool) { +func doTestCreateBlock(t *testing.T) { assert := assert.New(t) require := require.New(t) @@ -45,7 +45,7 @@ func doTestCreateBlock(t *testing.T, fraudProofsEnabled bool) { fmt.Println("Made NID") mpool := mempoolv1.NewTxMempool(logger, cfg.DefaultMempoolConfig(), proxy.NewAppConnMempool(client, proxy.NopMetrics()), 0) fmt.Println("Made a NewTxMempool") - executor := NewBlockExecutor([]byte("test address"), nsID, "test", mpool, proxy.NewAppConnConsensus(client, proxy.NopMetrics()), fraudProofsEnabled, nil, logger) + executor := NewBlockExecutor([]byte("test address"), nsID, "test", mpool, proxy.NewAppConnConsensus(client, proxy.NopMetrics()), nil, logger) fmt.Println("Made a New Block Executor") state := types.State{} @@ -89,14 +89,10 @@ func doTestCreateBlock(t *testing.T, fraudProofsEnabled bool) { } func TestCreateBlockWithFraudProofsDisabled(t *testing.T) { - doTestCreateBlock(t, false) + doTestCreateBlock(t) } -func TestCreateBlockWithFraudProofsEnabled(t *testing.T) { - doTestCreateBlock(t, true) -} - -func doTestApplyBlock(t *testing.T, fraudProofsEnabled bool) { +func doTestApplyBlock(t *testing.T) { assert := assert.New(t) require := require.New(t) @@ -107,13 +103,9 @@ func doTestApplyBlock(t *testing.T, fraudProofsEnabled bool) { app.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{}) app.On("DeliverTx", mock.Anything).Return(abci.ResponseDeliverTx{}) app.On("EndBlock", mock.Anything).Return(abci.ResponseEndBlock{}) - app.On("GenerateFraudProof", mock.Anything).Return(abci.ResponseGenerateFraudProof{}) var mockAppHash []byte _, err := rand.Read(mockAppHash[:]) require.NoError(err) - app.On("GetAppHash", mock.Anything).Return(abci.ResponseGetAppHash{ - AppHash: mockAppHash[:], - }) app.On("Commit", mock.Anything).Return(abci.ResponseCommit{ Data: mockAppHash[:], }) @@ -128,7 +120,7 @@ func doTestApplyBlock(t *testing.T, fraudProofsEnabled bool) { mpool := mempoolv1.NewTxMempool(logger, cfg.DefaultMempoolConfig(), proxy.NewAppConnMempool(client, proxy.NopMetrics()), 0) eventBus := cmtypes.NewEventBus() require.NoError(eventBus.Start()) - executor := NewBlockExecutor([]byte("test address"), nsID, chainID, mpool, proxy.NewAppConnConsensus(client, proxy.NopMetrics()), fraudProofsEnabled, eventBus, logger) + executor := NewBlockExecutor([]byte("test address"), nsID, chainID, mpool, proxy.NewAppConnConsensus(client, proxy.NopMetrics()), eventBus, logger) txQuery, err := query.New("tm.event='Tx'") require.NoError(err) @@ -243,9 +235,5 @@ func doTestApplyBlock(t *testing.T, fraudProofsEnabled bool) { } func TestApplyBlockWithFraudProofsDisabled(t *testing.T) { - doTestApplyBlock(t, false) -} - -func TestApplyBlockWithFraudProofsEnabled(t *testing.T) { - doTestApplyBlock(t, true) + doTestApplyBlock(t) } diff --git a/types/state_fraud_proof.go b/types/state_fraud_proof.go deleted file mode 100644 index 1bf834604bd..00000000000 --- a/types/state_fraud_proof.go +++ /dev/null @@ -1,47 +0,0 @@ -package types - -import ( - "github.com/celestiaorg/go-header" - abci "github.com/cometbft/cometbft/abci/types" - - "github.com/celestiaorg/go-fraud" -) - -// Implements Proof interface from https://github.com/celestiaorg/go-fraud/ - -const StateFraudProofType fraud.ProofType = "state-fraud" - -type StateFraudProof struct { - abci.FraudProof -} - -func init() { - fraud.Register(&StateFraudProof{}) -} - -func (fp *StateFraudProof) Type() fraud.ProofType { - return StateFraudProofType -} - -func (fp *StateFraudProof) HeaderHash() []byte { - return fp.FraudulentBeginBlock.Hash -} - -func (fp *StateFraudProof) Height() uint64 { - return uint64(fp.BlockHeight) -} - -func (fp *StateFraudProof) Validate(header.Header) error { - // TODO (ganesh): fill this later - return nil -} - -func (fp *StateFraudProof) MarshalBinary() (data []byte, err error) { - return fp.Marshal() -} - -func (fp *StateFraudProof) UnmarshalBinary(data []byte) error { - return fp.Unmarshal(data) -} - -var _ fraud.Proof = &StateFraudProof{}