NewDatabase create a single database instance using config.
(cfg *DBConfig, peers *proto.Peers, genesis *types.Block)
| 91 | |
| 92 | // NewDatabase create a single database instance using config. |
| 93 | func NewDatabase(cfg *DBConfig, peers *proto.Peers, |
| 94 | genesis *types.Block) (db *Database, err error) { |
| 95 | // ensure dir exists |
| 96 | if err = os.MkdirAll(cfg.DataDir, 0755); err != nil { |
| 97 | return |
| 98 | } |
| 99 | |
| 100 | if peers == nil || genesis == nil { |
| 101 | err = ErrInvalidDBConfig |
| 102 | return |
| 103 | } |
| 104 | |
| 105 | // get private key |
| 106 | var privateKey *asymmetric.PrivateKey |
| 107 | if privateKey, err = kms.GetLocalPrivateKey(); err != nil { |
| 108 | return |
| 109 | } |
| 110 | |
| 111 | var accountAddr proto.AccountAddress |
| 112 | if accountAddr, err = crypto.PubKeyHash(privateKey.PubKey()); err != nil { |
| 113 | return |
| 114 | } |
| 115 | |
| 116 | // init database |
| 117 | db = &Database{ |
| 118 | cfg: cfg, |
| 119 | dbID: cfg.DatabaseID, |
| 120 | mux: cfg.KayakMux, |
| 121 | connSeqEvictCh: make(chan uint64, 1), |
| 122 | privateKey: privateKey, |
| 123 | accountAddr: accountAddr, |
| 124 | } |
| 125 | |
| 126 | defer func() { |
| 127 | // on error recycle all resources |
| 128 | if err != nil { |
| 129 | // stop kayak runtime |
| 130 | if db.kayakRuntime != nil { |
| 131 | db.kayakRuntime.Shutdown() |
| 132 | } |
| 133 | |
| 134 | // close chain |
| 135 | if db.chain != nil { |
| 136 | db.chain.Stop() |
| 137 | } |
| 138 | } |
| 139 | }() |
| 140 | |
| 141 | // init storage |
| 142 | storageFile := filepath.Join(cfg.DataDir, StorageFileName) |
| 143 | storageDSN, err := storage.NewDSN(storageFile) |
| 144 | if err != nil { |
| 145 | return |
| 146 | } |
| 147 | |
| 148 | if cfg.EncryptionKey != "" { |
| 149 | storageDSN.AddParam("_crypto_key", cfg.EncryptionKey) |
| 150 | } |