123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- package extension
- import (
- "encoding/json"
- "io/ioutil"
- "os"
- "path/filepath"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
- )
- /*
- The file can have two formats:
- 1.
- {
- "psiContracts": {
- "psi1": {
- "contract1address": ...,
- "contract2address": ...,
- },
- ...
- }
- }
- 2.
- {
- "contract1address": ...,
- "contract2address": ...,
- }
- */
- const extensionContractData = "activeExtensions.json"
- type DataHandler interface {
- Load() (map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract, error)
- Save(extensionContracts map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract) error
- }
- type JsonFileDataHandler struct {
- saveFile string
- }
- func NewJsonFileDataHandler(dataDirectory string) *JsonFileDataHandler {
- return &JsonFileDataHandler{
- saveFile: filepath.Join(dataDirectory, extensionContractData),
- }
- }
- /*
- The strategy when loading the save file is too check if the newer "psiContracts" field is present.
- If so, then everything should exist under that key, and so we can unmarshal and return immediately.
- If not, then the save file was made from a previous version. Load up all the data as before and
- put it under the "private" PSI.
- It should never be the case the file contains both types of data at once.
- */
- func (handler *JsonFileDataHandler) Load() (map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract, error) {
- if _, err := os.Stat(handler.saveFile); !(err == nil || !os.IsNotExist(err)) {
- return map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract{types.DefaultPrivateStateIdentifier: {}}, nil
- }
- blob, err := ioutil.ReadFile(handler.saveFile)
- if err != nil {
- return nil, err
- }
- var untyped map[string]json.RawMessage
- if err := json.Unmarshal(blob, &untyped); err != nil {
- return nil, err
- }
- if psiContracts, ok := untyped["psiContracts"]; ok {
- var contracts map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract
- json.Unmarshal(psiContracts, &contracts)
- return contracts, nil
- }
- currentContracts := make(map[common.Address]*ExtensionContract)
- for key, val := range untyped {
- extAddress := common.HexToAddress(key)
- var ext ExtensionContract
- json.Unmarshal(val, &ext)
- currentContracts[extAddress] = &ext
- }
- return map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract{types.DefaultPrivateStateIdentifier: currentContracts}, nil
- }
- func (handler *JsonFileDataHandler) Save(extensionContracts map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract) error {
- //we want to put the map under "psiContracts" key to distinguish from existing data
- saveData := make(map[string]interface{})
- saveData["psiContracts"] = extensionContracts
- //no unmarshallable types, so can't error
- output, _ := json.Marshal(&saveData)
- if errSaving := ioutil.WriteFile(handler.saveFile, output, 0644); errSaving != nil {
- log.Error("Couldn't save outstanding extension contract details")
- return errSaving
- }
- return nil
- }
|