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  }