github.com/iotexproject/iotex-core@v1.14.1-rc1/action/protocol/staking/patchstore.go (about) 1 // Copyright (c) 2020 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package staking 7 8 import ( 9 "encoding/csv" 10 "encoding/hex" 11 "fmt" 12 "io" 13 "os" 14 "path/filepath" 15 16 "github.com/pkg/errors" 17 ) 18 19 const ( 20 _name = "name" 21 _operator = "operator" 22 ) 23 24 // PatchStore is the patch store of staking protocol 25 type PatchStore struct { 26 dir string 27 } 28 29 // NewPatchStore creates a new staking patch store 30 func NewPatchStore(dir string) *PatchStore { 31 return &PatchStore{dir: dir} 32 } 33 34 func (store *PatchStore) pathOf(height uint64) string { 35 return filepath.Join(store.dir, fmt.Sprintf("%d.patch", height)) 36 } 37 38 func (store *PatchStore) read(reader *csv.Reader) (CandidateList, error) { 39 record, err := reader.Read() 40 if err != nil { 41 return nil, err 42 } 43 if len(record) != 1 { 44 return nil, errors.Errorf("invalid record %+v", record) 45 } 46 data, err := hex.DecodeString(record[0]) 47 if err != nil { 48 return nil, err 49 } 50 var list CandidateList 51 if err := list.Deserialize(data); err != nil { 52 return nil, err 53 } 54 return list, nil 55 } 56 57 // Read reads CandidateList by name and CandidateList by operator of given height 58 func (store *PatchStore) Read(height uint64) (CandidateList, CandidateList, CandidateList, error) { 59 file, err := os.Open(store.pathOf(height)) 60 if err != nil { 61 return nil, nil, nil, err 62 } 63 reader := csv.NewReader(file) 64 reader.FieldsPerRecord = -1 65 listByName, err := store.read(reader) 66 if err != nil { 67 return nil, nil, nil, err 68 } 69 listByOperator, err := store.read(reader) 70 if err != nil { 71 return nil, nil, nil, err 72 } 73 listByOwner, err := store.read(reader) 74 if err != nil && err != io.EOF { 75 // io.EOF indicates an empty owner list 76 return nil, nil, nil, err 77 } 78 return listByName, listByOperator, listByOwner, nil 79 }