Skip to content

Commit d702582

Browse files
committed
Optimize snapshot traversal for EVM transactions
1 parent fe062d1 commit d702582

1 file changed

Lines changed: 61 additions & 1 deletion

File tree

fvm/evm/emulator/state/delta.go

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ var _ types.HotView = &DeltaView{}
6767

6868
// NewDeltaView constructs a new delta view
6969
func 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

Comments
 (0)