github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/prefunds/prefunds.go (about) 1 package prefunds 2 3 import ( 4 "os" 5 "path/filepath" 6 7 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 8 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config" 9 "github.com/gocarina/gocsv" 10 ) 11 12 func GetPrefundPath(chain string) string { 13 return filepath.Join(config.MustGetPathToChainConfig(chain), "allocs.csv") 14 } 15 16 // Allocation is a single allocation in the genesis file 17 type Allocation struct { 18 Address base.Address `json:"address" csv:"address"` 19 Balance base.Wei `json:"balance" csv:"balance"` 20 } 21 22 // emptyAllocs is a list of empty allocations. We use this to return at least one allocation 23 var emptyAllocs = []Allocation{} 24 25 type allocCallback func(*Allocation, *any) (bool, error) 26 27 // TODO: In the c++ code, the prefunds were cached in memory. We should do the same here. 28 29 // LoadPrefunds loads the prefunds from the genesis file and processes each with provided callback if present 30 func LoadPrefunds(chain string, thePath string, userCallback allocCallback) ([]Allocation, error) { 31 allocations := make([]Allocation, 0, 4000) 32 callbackFunc := func(record Allocation) error { 33 if base.IsValidAddress(record.Address.Hex()) { 34 alloc := Allocation{ 35 Address: record.Address, 36 Balance: record.Balance, 37 } 38 // fmt.Println(alloc) 39 allocations = append(allocations, alloc) 40 if userCallback != nil { 41 if cont, err := userCallback(&alloc, nil); !cont || err != nil { 42 return err 43 } 44 } 45 } 46 return nil 47 } 48 49 if theFile, err := os.OpenFile(thePath, os.O_RDWR|os.O_CREATE, os.ModePerm); err != nil { 50 return emptyAllocs, err 51 52 } else { 53 defer theFile.Close() 54 if err := gocsv.UnmarshalToCallback(theFile, callbackFunc); err != nil { 55 return emptyAllocs, err 56 } 57 } 58 59 if len(allocations) == 0 { 60 allocations = emptyAllocs 61 } 62 63 return allocations, nil 64 } 65 66 func GetLargestPrefund(chain, thePath string) (Allocation, error) { 67 largest := Allocation{} 68 getLargest := func(alloc *Allocation, data *any) (bool, error) { 69 if alloc.Balance.Cmp(&largest.Balance) > 0 { 70 largest = *alloc 71 } 72 return true, nil 73 } 74 75 _, err := LoadPrefunds(chain, thePath, getLargest) 76 if err != nil { 77 return Allocation{}, err 78 } 79 80 return largest, nil 81 }