@@ -11,6 +11,7 @@ import (
1111var (
1212 _ store.KVStoreService = (* GenesisKVStoreService )(nil )
1313 _ header.Service = (* GenesisHeaderService )(nil )
14+ _ store.KVStore = (* readonlyKVStore )(nil )
1415)
1516
1617type genesisContextKeyType struct {}
@@ -21,28 +22,41 @@ var genesisContextKey = genesisContextKeyType{}
2122// it backs the store.KVStoreService and header.Service interface implementations
2223// defined in this file.
2324type genesisContext struct {
24- state store.WriterMap
25+ state store.ReaderMap
2526}
2627
2728// NewGenesisContext creates a new genesis context.
28- func NewGenesisContext (state store.WriterMap ) genesisContext {
29+ func NewGenesisContext (state store.ReaderMap ) genesisContext {
2930 return genesisContext {
3031 state : state ,
3132 }
3233}
3334
34- // Run runs the provided function within the genesis context and returns an
35+ // Mutate runs the provided function within the genesis context and returns an
3536// updated store.WriterMap containing the state modifications made during InitGenesis.
36- func (g * genesisContext ) Run (
37+ func (g genesisContext ) Mutate (
3738 ctx context.Context ,
3839 fn func (ctx context.Context ) error ,
3940) (store.WriterMap , error ) {
41+ writerMap , ok := g .state .(store.WriterMap )
42+ if ! ok {
43+ return nil , fmt .Errorf ("mutate requires a store.WriterMap, got a %T" , g .state )
44+ }
4045 ctx = context .WithValue (ctx , genesisContextKey , g )
4146 err := fn (ctx )
4247 if err != nil {
4348 return nil , err
4449 }
45- return g .state , nil
50+ return writerMap , nil
51+ }
52+
53+ // Read runs the provided function within the genesis context.
54+ func (g genesisContext ) Read (
55+ ctx context.Context ,
56+ fn func (ctx context.Context ) error ,
57+ ) error {
58+ ctx = context .WithValue (ctx , genesisContextKey , g )
59+ return fn (ctx )
4660}
4761
4862// GenesisKVStoreService is a store.KVStoreService implementation that is used during
@@ -71,15 +85,24 @@ func (g *GenesisKVStoreService) OpenKVStore(ctx context.Context) store.KVStore {
7185 if v == nil {
7286 return g .executionService .OpenKVStore (ctx )
7387 }
74- genCtx , ok := v .(* genesisContext )
88+ genCtx , ok := v .(genesisContext )
7589 if ! ok {
7690 panic (fmt .Errorf ("unexpected genesis context type: %T" , v ))
7791 }
78- state , err := genCtx .state .GetWriter (g .actor )
92+ writerMap , ok := genCtx .state .(store.WriterMap )
93+ if ok {
94+ state , err := writerMap .GetWriter (g .actor )
95+ if err != nil {
96+ panic (err )
97+ }
98+ return state
99+
100+ }
101+ state , err := genCtx .state .GetReader (g .actor )
79102 if err != nil {
80103 panic (err )
81104 }
82- return state
105+ return readonlyKVStore { state }
83106}
84107
85108// GenesisHeaderService is a header.Service implementation that is used during
@@ -105,3 +128,15 @@ func NewGenesisHeaderService(executionService header.Service) *GenesisHeaderServ
105128 executionService : executionService ,
106129 }
107130}
131+
132+ type readonlyKVStore struct {
133+ store.Reader
134+ }
135+
136+ func (r readonlyKVStore ) Set (key , value []byte ) error {
137+ panic ("tried to call Set on a readonly store" )
138+ }
139+
140+ func (r readonlyKVStore ) Delete (key []byte ) error {
141+ panic ("tried to call Delete on a readonly store" )
142+ }
0 commit comments