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.
@@ -102,7 +118,7 @@ func (mux *abciMux) validateSystemTxs() error {
102118 for _ , tx := range mux .state .blockCtx .SystemTransactions {
103119 switch tx .Method {
104120 case consensus .MethodMeta :
105- // Block metadata, verify state root .
121+ // Decode block metadata .
106122 if hasBlockMetadata {
107123 return fmt .Errorf ("duplicate block metadata in block" )
108124 }
@@ -134,9 +150,16 @@ func (mux *abciMux) validateSystemTxs() error {
134150 return fmt .Errorf ("invalid events root in block metadata (expected: %x got: %x)" , eventsRoot , meta .EventsRoot )
135151 }
136152
153+ // Verify results hash.
154+ resultsHash := mux .computeResultsHash ()
155+ if ! bytes .Equal (resultsHash , meta .ResultsHash ) {
156+ return fmt .Errorf ("invalid results hash in block metadata (expected: %x got: %x)" , resultsHash , meta .ResultsHash )
157+ }
158+
137159 mux .logger .Debug ("validated block metadata" ,
138160 "state_root" , meta .StateRoot ,
139161 "events_root" , hex .EncodeToString (eventsRoot ),
162+ "results_hash" , hex .EncodeToString (resultsHash ),
140163 )
141164 default :
142165 return fmt .Errorf ("unknown system method: %s" , tx .Method )
@@ -176,3 +199,10 @@ func (mux *abciMux) computeEventsRoot() ([]byte, error) {
176199
177200 return merkle .RootHash (events ), nil
178201}
202+
203+ func (mux * abciMux ) computeResultsHash () []byte {
204+ if ! mux .state .ConsensusParameters ().IsFeatureVersion (migrations .Version256 ) {
205+ return nil
206+ }
207+ return cmttypes .NewResults (mux .state .proposal .resultsDeliverTx ).Hash ()
208+ }
0 commit comments