From 651d1ad4c916e1e980c8697299c04b2dd03e7672 Mon Sep 17 00:00:00 2001 From: pk910 Date: Sun, 4 Aug 2024 13:33:50 +0200 Subject: [PATCH] fix panics on concurrent use (concurrent map writes) --- dynssz.go | 3 +++ fastssz.go | 3 +++ sszsize.go | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/dynssz.go b/dynssz.go index 7914301..230d895 100644 --- a/dynssz.go +++ b/dynssz.go @@ -9,10 +9,13 @@ package dynssz import ( "fmt" "reflect" + "sync" ) type DynSsz struct { + fastsszCompatMutex sync.Mutex fastsszCompatCache map[reflect.Type]*fastsszCompatibility + typeSizeMutex sync.RWMutex typeSizeCache map[reflect.Type]*cachedSszSize specValues map[string]any specValueCache map[string]*cachedSpecValue diff --git a/fastssz.go b/fastssz.go index fcf163c..9e3371d 100644 --- a/fastssz.go +++ b/fastssz.go @@ -77,6 +77,9 @@ type fastsszCompatibility struct { // that would prevent the use of fastssz for encoding or decoding. func (d *DynSsz) getFastsszCompatibility(targetType reflect.Type, sizeHints []sszSizeHint) (*fastsszCompatibility, error) { + d.fastsszCompatMutex.Lock() + defer d.fastsszCompatMutex.Unlock() + if cachedCompatibility := d.fastsszCompatCache[targetType]; cachedCompatibility != nil { return cachedCompatibility, nil } diff --git a/sszsize.go b/sszsize.go index d1f6749..9606f47 100644 --- a/sszsize.go +++ b/sszsize.go @@ -53,9 +53,12 @@ func (d *DynSsz) getSszSize(targetType reflect.Type, sizeHints []sszSizeHint) (i } // get size from cache if not influenced by a parent sizeHint + d.typeSizeMutex.RLock() if cachedSize := d.typeSizeCache[targetType]; cachedSize != nil && len(sizeHints) == 0 { + d.typeSizeMutex.RUnlock() return cachedSize.size, cachedSize.specval, nil } + d.typeSizeMutex.RUnlock() switch targetType.Kind() { case reflect.Struct: @@ -126,10 +129,12 @@ func (d *DynSsz) getSszSize(targetType reflect.Type, sizeHints []sszSizeHint) (i staticSize = -1 } else if len(sizeHints) == 0 { // cache size if it's static and not influenced by a parent sizeHint + d.typeSizeMutex.Lock() d.typeSizeCache[targetType] = &cachedSszSize{ size: staticSize, specval: hasSpecValue, } + d.typeSizeMutex.Unlock() } return staticSize, hasSpecValue, nil