github.com/celestiaorg/celestia-node@v0.15.0-beta.1/share/empty.go (about) 1 package share 2 3 import ( 4 "bytes" 5 "fmt" 6 "sync" 7 8 "github.com/celestiaorg/celestia-app/pkg/appconsts" 9 "github.com/celestiaorg/celestia-app/pkg/da" 10 "github.com/celestiaorg/celestia-app/pkg/shares" 11 "github.com/celestiaorg/rsmt2d" 12 ) 13 14 // EmptyRoot returns Root of the empty block EDS. 15 func EmptyRoot() *Root { 16 initEmpty() 17 return emptyBlockRoot 18 } 19 20 // EmptyExtendedDataSquare returns the EDS of the empty block data square. 21 func EmptyExtendedDataSquare() *rsmt2d.ExtendedDataSquare { 22 initEmpty() 23 return emptyBlockEDS 24 } 25 26 // EmptyBlockShares returns the shares of the empty block. 27 func EmptyBlockShares() []Share { 28 initEmpty() 29 return emptyBlockShares 30 } 31 32 var ( 33 emptyMu sync.Mutex 34 emptyBlockRoot *Root 35 emptyBlockEDS *rsmt2d.ExtendedDataSquare 36 emptyBlockShares []Share 37 ) 38 39 // initEmpty enables lazy initialization for constant empty block data. 40 func initEmpty() { 41 emptyMu.Lock() 42 defer emptyMu.Unlock() 43 if emptyBlockRoot != nil { 44 return 45 } 46 47 // compute empty block EDS and DAH for it 48 result := shares.TailPaddingShares(appconsts.MinShareCount) 49 emptyBlockShares = shares.ToBytes(result) 50 51 eds, err := da.ExtendShares(emptyBlockShares) 52 if err != nil { 53 panic(fmt.Errorf("failed to create empty EDS: %w", err)) 54 } 55 emptyBlockEDS = eds 56 57 emptyBlockRoot, err = NewRoot(eds) 58 if err != nil { 59 panic(fmt.Errorf("failed to create empty DAH: %w", err)) 60 } 61 minDAH := da.MinDataAvailabilityHeader() 62 if !bytes.Equal(minDAH.Hash(), emptyBlockRoot.Hash()) { 63 panic(fmt.Sprintf("mismatch in calculated minimum DAH and minimum DAH from celestia-app, "+ 64 "expected %s, got %s", minDAH.String(), emptyBlockRoot.String())) 65 } 66 67 // precompute Hash, so it's cached internally to avoid potential races 68 emptyBlockRoot.Hash() 69 }