github.com/datachainlab/burrow@v0.25.0/execution/state/dump.go (about)

     1  package state
     2  
     3  import (
     4  	"encoding/json"
     5  	"io"
     6  	"os"
     7  
     8  	amino "github.com/tendermint/go-amino"
     9  
    10  	"github.com/hyperledger/burrow/acm"
    11  	"github.com/hyperledger/burrow/dump"
    12  	"github.com/hyperledger/burrow/execution/exec"
    13  	"github.com/hyperledger/burrow/txs/payload"
    14  )
    15  
    16  var cdc = amino.NewCodec()
    17  
    18  type DumpReader interface {
    19  	Next() (*dump.Dump, error)
    20  }
    21  
    22  type FileDumpReader struct {
    23  	file    *os.File
    24  	decoder *json.Decoder
    25  }
    26  
    27  func NewFileDumpReader(filename string) (DumpReader, error) {
    28  	f, err := os.OpenFile(filename, os.O_RDONLY, 0644)
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  
    33  	return &FileDumpReader{file: f}, nil
    34  }
    35  
    36  func (f *FileDumpReader) Next() (*dump.Dump, error) {
    37  	var row dump.Dump
    38  	var err error
    39  
    40  	if f.decoder != nil {
    41  		err = f.decoder.Decode(&row)
    42  	} else {
    43  		_, err = cdc.UnmarshalBinaryLengthPrefixedReader(f.file, &row, 0)
    44  
    45  		if err != nil && err != io.EOF && f.decoder == nil {
    46  			f.file.Seek(0, 0)
    47  
    48  			f.decoder = json.NewDecoder(f.file)
    49  
    50  			return f.Next()
    51  		}
    52  	}
    53  
    54  	if err == io.EOF {
    55  		return nil, nil
    56  	}
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  
    61  	return &row, err
    62  }
    63  
    64  func (s *State) LoadDump(reader DumpReader) error {
    65  	txs := make([]*exec.TxExecution, 0)
    66  
    67  	var tx *exec.TxExecution
    68  
    69  	for {
    70  		row, err := reader.Next()
    71  
    72  		if err != nil {
    73  			return err
    74  		}
    75  
    76  		if row == nil {
    77  			break
    78  		}
    79  
    80  		if row.Account != nil {
    81  			if row.Account.Address != acm.GlobalPermissionsAddress {
    82  				s.writeState.UpdateAccount(row.Account)
    83  			}
    84  		}
    85  		if row.AccountStorage != nil {
    86  			for _, storage := range row.AccountStorage.Storage {
    87  				err := s.writeState.SetStorage(row.AccountStorage.Address, storage.Key, storage.Value)
    88  				if err != nil {
    89  					return err
    90  				}
    91  			}
    92  		}
    93  		if row.Name != nil {
    94  			s.writeState.UpdateName(row.Name)
    95  		}
    96  		if row.EVMEvent != nil {
    97  
    98  			if tx != nil && row.Height != tx.Height {
    99  				txs = append(txs, tx)
   100  				tx = nil
   101  			}
   102  			if tx == nil {
   103  				tx = &exec.TxExecution{
   104  					TxHeader: &exec.TxHeader{
   105  						TxType: payload.TypeCall,
   106  						TxHash: make([]byte, 32),
   107  						Height: row.Height,
   108  						Origin: &exec.Origin{
   109  							ChainID: row.EVMEvent.ChainID,
   110  							Time:    row.EVMEvent.Time,
   111  						},
   112  					},
   113  				}
   114  			}
   115  
   116  			tx.Events = append(tx.Events, &exec.Event{
   117  				Header: &exec.Header{
   118  					TxType:    payload.TypeCall,
   119  					EventType: exec.TypeLog,
   120  					Height:    row.Height,
   121  				},
   122  				Log: row.EVMEvent.Event,
   123  			})
   124  		}
   125  	}
   126  
   127  	if tx != nil {
   128  		txs = append(txs, tx)
   129  	}
   130  
   131  	return s.writeState.AddBlock(&exec.BlockExecution{
   132  		Height:       0,
   133  		TxExecutions: txs,
   134  	})
   135  }
   136  
   137  func (s *State) Dump() string {
   138  	return s.writeState.forest.Dump()
   139  }