@@ -67,6 +67,17 @@ var _ types.HotView = &DeltaView{}
6767
6868// NewDeltaView constructs a new delta view
6969func NewDeltaView (parent types.ReadOnlyView ) * DeltaView {
70+ refund := parent .GetRefund ()
71+ // The root node will be of type `BaseView`, so we should
72+ // check if we are dealing with `DeltaView`, for parent
73+ // skipping
74+ dt , ok := parent .(* DeltaView )
75+ if ok && ! dt .hasData () {
76+ // If my parent doesn't have any writes, I can just
77+ // delegate "upstream" queries to its parent
78+ parent = dt .parent
79+ }
80+
7081 return & DeltaView {
7182 parent : parent ,
7283
@@ -83,7 +94,7 @@ func NewDeltaView(parent types.ReadOnlyView) *DeltaView {
8394 slots : make (map [types.SlotAddress ]gethCommon.Hash ),
8495
8596 // for refund we just copy the data
86- refund : parent . GetRefund () ,
97+ refund : refund ,
8798 }
8899}
89100
@@ -584,3 +595,52 @@ func (d *DeltaView) DirtySlots() map[types.SlotAddress]struct{} {
584595 }
585596 return dirtySlots
586597}
598+
599+ // hasData returns whether any state modifications are recorded in this view
600+ func (d * DeltaView ) hasData () bool {
601+ if len (d .dirtyAddresses ) > 0 {
602+ return true
603+ }
604+
605+ if len (d .created ) > 0 {
606+ return true
607+ }
608+
609+ if len (d .newContract ) > 0 {
610+ return true
611+ }
612+
613+ if len (d .toBeDestructed ) > 0 {
614+ return true
615+ }
616+
617+ if len (d .recreated ) > 0 {
618+ return true
619+ }
620+
621+ if len (d .balances ) > 0 {
622+ return true
623+ }
624+
625+ if len (d .nonces ) > 0 {
626+ return true
627+ }
628+
629+ if len (d .codes ) > 0 {
630+ return true
631+ }
632+
633+ if len (d .codeHashes ) > 0 {
634+ return true
635+ }
636+
637+ if len (d .slots ) > 0 {
638+ return true
639+ }
640+
641+ if len (d .transient ) > 0 {
642+ return true
643+ }
644+
645+ return false
646+ }
0 commit comments