github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/orderer/common/bootstrap/file/bootstrap.go (about) 1 // Copyright hechain. All Rights Reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package file 5 6 import ( 7 "io" 8 "io/ioutil" 9 "os" 10 11 "github.com/golang/protobuf/proto" 12 "github.com/hechain20/hechain/orderer/common/bootstrap" 13 cb "github.com/hyperledger/fabric-protos-go/common" 14 "github.com/pkg/errors" 15 ) 16 17 type fileBootstrapper struct { 18 GenesisBlockFile string 19 } 20 21 // New returns a new static bootstrap helper. 22 func New(fileName string) bootstrap.Helper { 23 return &fileBootstrapper{ 24 GenesisBlockFile: fileName, 25 } 26 } 27 28 // NewReplacer returns a new bootstrap replacer. 29 func NewReplacer(fileName string) bootstrap.Replacer { 30 return &fileBootstrapper{ 31 GenesisBlockFile: fileName, 32 } 33 } 34 35 // GenesisBlock returns the genesis block to be used for bootstrapping. 36 func (b *fileBootstrapper) GenesisBlock() *cb.Block { 37 bootstrapFile, fileErr := ioutil.ReadFile(b.GenesisBlockFile) 38 if fileErr != nil { 39 panic(errors.Errorf("unable to bootstrap orderer. Error reading genesis block file: %v", fileErr)) 40 } 41 genesisBlock := &cb.Block{} 42 unmarshallErr := proto.Unmarshal(bootstrapFile, genesisBlock) 43 if unmarshallErr != nil { 44 panic(errors.Errorf("unable to bootstrap orderer. Error unmarshalling genesis block: %v", unmarshallErr)) 45 } 46 return genesisBlock 47 } // GenesisBlock 48 49 // ReplaceGenesisBlockFile creates a backup of the genesis block file, and then replaces 50 // it with the content of the given block. 51 // This is used during consensus-type migration in order to generate a bootstrap file that 52 // specifies the new consensus-type. 53 func (b *fileBootstrapper) ReplaceGenesisBlockFile(block *cb.Block) error { 54 buff, marshalErr := proto.Marshal(block) 55 if marshalErr != nil { 56 return errors.Wrap(marshalErr, "could not marshal block into a []byte") 57 } 58 59 genFileStat, statErr := os.Stat(b.GenesisBlockFile) 60 if statErr != nil { 61 return errors.Wrapf(statErr, "could not get the os.Stat of the genesis block file: %s", b.GenesisBlockFile) 62 } 63 64 if !genFileStat.Mode().IsRegular() { 65 return errors.Errorf("genesis block file: %s, is not a regular file", b.GenesisBlockFile) 66 } 67 68 backupFile := b.GenesisBlockFile + ".bak" 69 if err := backupGenesisFile(b.GenesisBlockFile, backupFile); err != nil { 70 return errors.Wrapf(err, "could not copy genesis block file (%s) into backup file: %s", 71 b.GenesisBlockFile, backupFile) 72 } 73 74 if err := ioutil.WriteFile(b.GenesisBlockFile, buff, genFileStat.Mode()); err != nil { 75 return errors.Wrapf(err, "could not write new genesis block into file: %s; use backup if necessary: %s", 76 b.GenesisBlockFile, backupFile) 77 } 78 79 return nil 80 } 81 82 func backupGenesisFile(src, dst string) error { 83 source, err := os.Open(src) 84 if err != nil { 85 return err 86 } 87 defer source.Close() 88 89 destination, err := os.Create(dst) 90 if err != nil { 91 return err 92 } 93 defer destination.Close() 94 95 _, err = io.Copy(destination, source) 96 return err 97 } 98 99 func (b *fileBootstrapper) CheckReadWrite() error { 100 genFileStat, statErr := os.Stat(b.GenesisBlockFile) 101 if statErr != nil { 102 return errors.Wrapf(statErr, "could not get the os.Stat of the genesis block file: %s", b.GenesisBlockFile) 103 } 104 105 if !genFileStat.Mode().IsRegular() { 106 return errors.Errorf("genesis block file: %s, is not a regular file", b.GenesisBlockFile) 107 } 108 109 genFile, openErr := os.OpenFile(b.GenesisBlockFile, os.O_RDWR, genFileStat.Mode().Perm()) 110 if openErr != nil { 111 if os.IsPermission(openErr) { 112 return errors.Wrapf(openErr, "genesis block file: %s, cannot be opened for read-write, check permissions", b.GenesisBlockFile) 113 } else { 114 return errors.Wrapf(openErr, "genesis block file: %s, cannot be opened for read-write", b.GenesisBlockFile) 115 } 116 } 117 genFile.Close() 118 119 return nil 120 }