github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/execution/engine/call_frame.go (about) 1 package engine 2 3 import ( 4 "github.com/hyperledger/burrow/acm/acmstate" 5 "github.com/hyperledger/burrow/crypto" 6 "github.com/hyperledger/burrow/execution/errors" 7 "github.com/hyperledger/burrow/permission" 8 ) 9 10 type CallFrame struct { 11 // Cache this State wraps 12 *acmstate.Cache 13 // Where we sync 14 backend acmstate.ReaderWriter 15 // In order for nested cache to inherit any options 16 cacheOptions []acmstate.CacheOption 17 // Depth of the call stack 18 callStackDepth uint64 19 // Max call stack depth 20 maxCallStackDepth uint64 21 } 22 23 // Create a new CallFrame to hold state updates at a particular level in the call stack 24 func NewCallFrame(st acmstate.ReaderWriter, cacheOptions ...acmstate.CacheOption) *CallFrame { 25 return newCallFrame(st, 0, 0, cacheOptions...) 26 } 27 28 func newCallFrame(st acmstate.ReaderWriter, stackDepth uint64, maxCallStackDepth uint64, cacheOptions ...acmstate.CacheOption) *CallFrame { 29 return &CallFrame{ 30 Cache: acmstate.NewCache(st, cacheOptions...), 31 backend: st, 32 cacheOptions: cacheOptions, 33 callStackDepth: stackDepth, 34 maxCallStackDepth: maxCallStackDepth, 35 } 36 } 37 38 // Put this CallFrame in permanent read-only mode 39 func (st *CallFrame) ReadOnly() *CallFrame { 40 acmstate.ReadOnly(st.Cache) 41 return st 42 } 43 44 func (st *CallFrame) WithMaxCallStackDepth(max uint64) *CallFrame { 45 st.maxCallStackDepth = max 46 return st 47 } 48 49 func (st *CallFrame) NewFrame(cacheOptions ...acmstate.CacheOption) (*CallFrame, error) { 50 if st.maxCallStackDepth > 0 && st.maxCallStackDepth == st.callStackDepth { 51 return nil, errors.Codes.CallStackOverflow 52 } 53 return newCallFrame(st.Cache, st.callStackDepth+1, st.maxCallStackDepth, 54 append(st.cacheOptions, cacheOptions...)...), nil 55 } 56 57 func (st *CallFrame) Sync() error { 58 err := st.Cache.Sync(st.backend) 59 if err != nil { 60 return errors.AsException(err) 61 } 62 return nil 63 } 64 65 func (st *CallFrame) CallStackDepth() uint64 { 66 return st.callStackDepth 67 } 68 69 func (st *CallFrame) CreateAccount(creator, address crypto.Address) error { 70 err := EnsurePermission(st, creator, permission.CreateAccount) 71 if err != nil { 72 return err 73 } 74 return CreateAccount(st, address) 75 }