Dero Web Wallet derosuite. This repo contains changes required for webwallet. With this changes any Dero daemon can become web wallet. All changes are related to daemon rpc server and wallet to make it light and faster.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
6.1KB

  1. // Copyright 2017-2018 DERO Project. All rights reserved.
  2. // Use of this source code in any form is governed by RESEARCH license.
  3. // license can be found in the LICENSE file.
  4. // GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8
  5. //
  6. //
  7. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
  8. // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  9. // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  10. // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  11. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  12. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  13. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  14. // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  15. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. // 64 bit arch will use this DB
  17. package storage
  18. import "os"
  19. import "fmt"
  20. import "sync"
  21. import "runtime"
  22. import "path/filepath"
  23. import "encoding/binary"
  24. //import "github.com/romana/rlog"
  25. //import bolt "github.com/coreos/bbolt"
  26. import "github.com/dgraph-io/badger"
  27. import log "github.com/sirupsen/logrus"
  28. import "github.com/dgraph-io/badger/options"
  29. import "github.com/deroproject/derosuite/globals"
  30. type BadgerDBStore struct {
  31. DB *badger.DB
  32. sync.Mutex // lock this struct TODO we must user a reader lock
  33. }
  34. // this object is returned
  35. type BadgerTXWrapper struct {
  36. bdb *BadgerDBStore
  37. tx *badger.Txn
  38. }
  39. var Badger_backend *BadgerDBStore = &BadgerDBStore{} // global variable
  40. func (b *BadgerDBStore) Init(params map[string]interface{}) (err error) {
  41. logger = globals.Logger.WithFields(log.Fields{"com": "STORE"})
  42. current_path := filepath.Join(globals.GetDataDirectory(), "derod_badger_database")
  43. if params["--simulator"] == true {
  44. current_path = filepath.Join(os.TempDir(), "derod_simulation_badger_database") // sp
  45. }
  46. logger.Infof("Initializing badger store at path %s", current_path)
  47. // Open the my.db data file in your current directory.
  48. // It will be created if it doesn't exist.
  49. opts := badger.DefaultOptions
  50. opts.Dir = current_path
  51. opts.ValueDir = current_path
  52. // tune to different RAM requirements based on arch
  53. if runtime.GOARCH == "amd64" {
  54. opts.TableLoadingMode = options.MemoryMap
  55. opts.ValueLogLoadingMode = options.MemoryMap
  56. } else { // 32 bit systems/arm etc use raw file IO, no memory mapping
  57. opts.TableLoadingMode = options.FileIO
  58. opts.ValueLogLoadingMode = options.FileIO
  59. logger.Infof("Running in low RAM mode")
  60. }
  61. db, err := badger.Open(opts)
  62. if err != nil {
  63. logger.Fatalf("Cannot open badgerdb store err %s", err)
  64. }
  65. b.DB = db
  66. // if simulation, delete the file , so as it gets cleaned up automcatically
  67. if params["--simulator"] == true {
  68. os.RemoveAll(current_path)
  69. }
  70. // place db in no sync mode
  71. //b.DB.NoSync = true
  72. return nil
  73. }
  74. func (b *BadgerDBStore) Shutdown() (err error) {
  75. logger.Infof("Shutting badgerdb store")
  76. if b.DB != nil {
  77. b.DB.Close()
  78. }
  79. return nil
  80. }
  81. // sync the DB to disk
  82. func (b *BadgerDBStore) Sync() {
  83. }
  84. // get a new writable/readable tx,
  85. // we will manage the writable txs manually
  86. // since a block may cause changes to a number of fields which must be reflected atomically
  87. func (b *BadgerDBStore) BeginTX(writable bool) (DBTX, error) {
  88. txwrapper := &BadgerTXWrapper{}
  89. tx := b.DB.NewTransaction(writable) // begin a new writable tx
  90. txwrapper.tx = tx
  91. txwrapper.bdb = b // parent DB reference
  92. return txwrapper, nil
  93. }
  94. func (b *BadgerTXWrapper) Commit() error {
  95. err := b.tx.Commit(nil)
  96. if err != nil {
  97. logger.Warnf("Error while committing tx, err %s", err)
  98. return err
  99. }
  100. b.tx.Discard() // tx must always be discarded (both if commited/rollback as per documentation)
  101. return nil
  102. }
  103. // Roll back existing changes to disk
  104. func (b *BadgerTXWrapper) Rollback() {
  105. b.tx.Discard()
  106. }
  107. // TODO implement this
  108. func (b *BadgerTXWrapper) Sync() {
  109. }
  110. // duplicates a byte array as badger db needs objects which are unmodifieable during the transaction
  111. func Duplicate(input []byte) []byte {
  112. dup := make([]byte, len(input), len(input))
  113. copy(dup, input)
  114. return dup
  115. }
  116. func (b *BadgerTXWrapper) StoreObject(universe_name []byte, galaxy_name []byte, solar_name []byte, key []byte, data []byte) (err error) {
  117. fullkey := make([]byte, 0, len(universe_name)+len(galaxy_name)+len(solar_name)+len(key))
  118. fullkey = append(fullkey, universe_name...)
  119. fullkey = append(fullkey, galaxy_name...)
  120. fullkey = append(fullkey, solar_name...)
  121. fullkey = append(fullkey, key...)
  122. return b.tx.Set(fullkey, Duplicate(data))
  123. }
  124. func (b *BadgerTXWrapper) LoadObject(universe_name []byte, galaxy_name []byte, solar_name []byte, key []byte) (data []byte, err error) {
  125. fullkey := make([]byte, 0, len(universe_name)+len(galaxy_name)+len(solar_name)+len(key))
  126. fullkey = append(fullkey, universe_name...)
  127. fullkey = append(fullkey, galaxy_name...)
  128. fullkey = append(fullkey, solar_name...)
  129. fullkey = append(fullkey, key...)
  130. item, err := b.tx.Get(fullkey)
  131. if err == badger.ErrKeyNotFound {
  132. return data, badger.ErrKeyNotFound
  133. }
  134. data, err = item.ValueCopy(nil)
  135. if err != nil {
  136. return data, badger.ErrKeyNotFound
  137. }
  138. return data, nil
  139. }
  140. // this function stores a uint64
  141. // this will automcatically use the transaction
  142. func (b *BadgerTXWrapper) StoreUint64(universe_bucket []byte, galaxy_bucket []byte, solar_bucket []byte, key []byte, data uint64) error {
  143. return b.StoreObject(universe_bucket, galaxy_bucket, solar_bucket, key, itob(data))
  144. }
  145. // this function loads the data as 64 byte integer
  146. func (b *BadgerTXWrapper) LoadUint64(universe_bucket []byte, galaxy_bucket []byte, solar_bucket []byte, key []byte) (uint64, error) {
  147. object_data, err := b.LoadObject(universe_bucket, galaxy_bucket, solar_bucket, key)
  148. if err != nil {
  149. return 0, err
  150. }
  151. if len(object_data) == 0 {
  152. return 0, fmt.Errorf("No value stored here, we should look more")
  153. }
  154. if len(object_data) != 8 {
  155. panic("Database corruption, invalid data ")
  156. }
  157. value := binary.BigEndian.Uint64(object_data)
  158. return value, nil
  159. }