66 "fmt"
77
88 "github.com/cometbft/cometbft/abci/types"
9+ cmttypes "github.com/cometbft/cometbft/types"
910
1011 "github.com/oasisprotocol/oasis-core/go/common/cbor"
1112 consensus "github.com/oasisprotocol/oasis-core/go/consensus/api"
@@ -16,47 +17,62 @@ import (
1617 "github.com/oasisprotocol/oasis-core/go/upgrade/migrations"
1718)
1819
19- // prepareSystemTxs prepares a list of system transactions to be included in a proposed block in
20- // case where the node is currently the block proposer.
21- func (mux * abciMux ) prepareSystemTxs () ([][]byte , []* types.ResponseDeliverTx , error ) {
22- var (
23- systemTxs [][]byte
24- systemTxResults []* types.ResponseDeliverTx
25- )
20+ // prepareSystemTxs prepares a list of system transactions to be included
21+ // in a proposed block in case where the node is currently the block proposer.
22+ func (mux * abciMux ) prepareSystemTxs () ([][]byte , error ) {
23+ blockMetaTx , err := mux .prepareBlockMetaTx ()
24+ if err != nil {
25+ return nil , fmt .Errorf ("failed to prepare block metadata transaction: %w" , err )
26+ }
27+ return [][]byte {blockMetaTx }, nil
28+ }
29+
30+ // prepareSystemTxResults prepares a list of system transaction results to be included
31+ // in a proposed block in case where the node is currently the block proposer.
32+ func (mux * abciMux ) prepareSystemTxResults () []* types.ResponseDeliverTx {
33+ blockMetaResults := mux .prepareBlockMetaTxResults ()
34+ return []* types.ResponseDeliverTx {blockMetaResults }
35+ }
2636
27- // Append block metadata as a system transaction.
37+ // prepareBlockMetaTx prepares block metadata system transaction.
38+ func (mux * abciMux ) prepareBlockMetaTx () ([]byte , error ) {
2839 stateRoot , err := mux .state .workingStateRoot ()
2940 if err != nil {
30- return nil , nil , fmt .Errorf ("failed to compute working state root: %w" , err )
41+ return nil , fmt .Errorf ("failed to compute working state root: %w" , err )
3142 }
3243 eventsRoot , err := mux .computeEventsRoot ()
3344 if err != nil {
34- return nil , nil , fmt .Errorf ("failed to compute events root: %w" , err )
45+ return nil , fmt .Errorf ("failed to compute events root: %w" , err )
3546 }
47+ resultsHash := mux .computeResultsHash ()
3648
3749 blockMeta := consensus .NewBlockMetadataTx (& consensus.BlockMetadata {
38- StateRoot : stateRoot ,
39- EventsRoot : eventsRoot ,
50+ StateRoot : stateRoot ,
51+ EventsRoot : eventsRoot ,
52+ ResultsHash : resultsHash ,
4053 })
4154 sigBlockMeta , err := transaction .Sign (mux .state .identity .ConsensusSigner , blockMeta )
4255 if err != nil {
43- return nil , nil , fmt .Errorf ("failed to sign block metadata transaction: %w" , err )
56+ return nil , fmt .Errorf ("failed to sign block metadata transaction: %w" , err )
4457 }
4558 sigBlockMetaRaw := cbor .Marshal (sigBlockMeta )
4659 if l := len (sigBlockMetaRaw ); l > consensus .BlockMetadataMaxSize {
4760 mux .logger .Error ("serialized block metadata larger than maximum allowed size" ,
4861 "meta_size" , l ,
4962 "max_meta_size" , consensus .BlockMetadataMaxSize ,
5063 )
51- return nil , nil , fmt .Errorf ("serialized block metadata would be oversized" )
64+ return nil , fmt .Errorf ("serialized block metadata would be oversized" )
5265 }
53- systemTxs = append (systemTxs , sigBlockMetaRaw )
54- systemTxResults = append (systemTxResults , & types.ResponseDeliverTx {
66+
67+ return sigBlockMetaRaw , nil
68+ }
69+
70+ // prepareBlockMetaTxResults prepares block metadata system transaction results.
71+ func (mux * abciMux ) prepareBlockMetaTxResults () * types.ResponseDeliverTx {
72+ return & types.ResponseDeliverTx {
5573 Code : types .CodeTypeOK ,
5674 Data : cbor .Marshal (nil ),
57- })
58-
59- return systemTxs , systemTxResults , nil
75+ }
6076}
6177
6278// processSystemTx processes a system transaction in DeliverTx context.
@@ -97,7 +113,7 @@ func (mux *abciMux) validateSystemTxs() error {
97113 for _ , tx := range mux .state .blockCtx .SystemTransactions {
98114 switch tx .Method {
99115 case consensus .MethodMeta :
100- // Block metadata, verify state root .
116+ // Decode block metadata .
101117 if hasBlockMetadata {
102118 return fmt .Errorf ("duplicate block metadata in block" )
103119 }
@@ -129,9 +145,16 @@ func (mux *abciMux) validateSystemTxs() error {
129145 return fmt .Errorf ("invalid events root in block metadata (expected: %x got: %x)" , eventsRoot , meta .EventsRoot )
130146 }
131147
148+ // Verify results hash.
149+ resultsHash := mux .computeResultsHash ()
150+ if ! bytes .Equal (resultsHash , meta .ResultsHash ) {
151+ return fmt .Errorf ("invalid results hash in block metadata (expected: %x got: %x)" , resultsHash , meta .ResultsHash )
152+ }
153+
132154 mux .logger .Debug ("validated block metadata" ,
133155 "state_root" , meta .StateRoot ,
134156 "events_root" , hex .EncodeToString (eventsRoot ),
157+ "results_hash" , hex .EncodeToString (resultsHash ),
135158 )
136159 default :
137160 return fmt .Errorf ("unknown system method: %s" , tx .Method )
@@ -171,3 +194,10 @@ func (mux *abciMux) computeEventsRoot() ([]byte, error) {
171194
172195 return merkle .RootHash (events ), nil
173196}
197+
198+ func (mux * abciMux ) computeResultsHash () []byte {
199+ if ! mux .state .ConsensusParameters ().IsFeatureVersion (migrations .Version256 ) {
200+ return nil
201+ }
202+ return cmttypes .NewResults (mux .state .proposal .resultsDeliverTx ).Hash ()
203+ }
0 commit comments