github.com/annchain/OG@v0.0.9/arefactor_core/core/accessor.go (about) 1 // Copyright © 2019 Annchain Authors <EMAIL ADDRESS> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package core 15 16 import ( 17 "bytes" 18 "encoding/binary" 19 "fmt" 20 og_types "github.com/annchain/OG/arefactor/og_interface" 21 "github.com/annchain/OG/common" 22 "github.com/annchain/commongo/marshaller" 23 24 "github.com/annchain/OG/arefactor/types" 25 "github.com/annchain/OG/common/math" 26 "github.com/annchain/OG/ogdb" 27 log "github.com/sirupsen/logrus" 28 "strconv" 29 "sync" 30 ) 31 32 var ( 33 prefixGenesisKey = []byte("genesis") 34 prefixLatestConfirmedSeqKey = []byte("latestseq") 35 36 prefixReceiptKey = []byte("rp") 37 38 prefixTransactionKey = []byte("tx") 39 prefixTxHashFlowKey = []byte("fl") 40 41 contentPrefixTransaction = []byte("cptx") 42 contentPrefixSequencer = []byte("cpsq") 43 contentPrefixCampaign = []byte("cpcp") 44 contentPrefixTermChg = []byte("cptc") 45 contentPrefixArchive = []byte("cpac") 46 contentPrefixActionTx = []byte("cpax") 47 48 prefixAddrLatestNonceKey = []byte("aln") 49 50 prefixSeqHeightKey = []byte("sh") 51 prefixTxIndexKey = []byte("ti") 52 53 prefixAddressBalanceKey = []byte("ba") 54 55 prefixConfirmtime = []byte("cf") 56 57 prefixStateRootKey = []byte("stateroot") 58 ) 59 60 // TODO encode uint to specific length bytes 61 62 func genesisKey() []byte { 63 return prefixGenesisKey 64 } 65 66 func latestConfirmedSeqKey() []byte { 67 return prefixLatestConfirmedSeqKey 68 } 69 70 func receiptKey(seqID uint64) []byte { 71 return marshaller.AppendUint64(prefixReceiptKey, seqID) 72 } 73 74 func transactionKey(hash og_types.Hash) []byte { 75 return marshaller.AppendBytes(prefixTransactionKey, hash.Bytes()) 76 } 77 78 func confirmTimeKey(SeqHeight uint64) []byte { 79 return marshaller.AppendUint64(prefixConfirmtime, SeqHeight) 80 } 81 82 func txHashFlowKey(addr og_types.Address, nonce uint64) []byte { 83 key := marshaller.AppendBytes(prefixTxHashFlowKey, addr.Bytes()) 84 return marshaller.AppendUint64(key, nonce) 85 } 86 87 func addrLatestNonceKey(addr og_types.Address) []byte { 88 return marshaller.AppendBytes(prefixAddrLatestNonceKey, addr.Bytes()) 89 } 90 91 func addressBalanceKey(addr og_types.Address) []byte { 92 return marshaller.AppendBytes(prefixAddressBalanceKey, addr.Bytes()) 93 } 94 95 func seqHeightKey(seqID uint64) []byte { 96 return marshaller.AppendUint64(prefixSeqHeightKey, seqID) 97 } 98 99 func txIndexKey(seqID uint64) []byte { 100 return marshaller.AppendUint64(prefixTxIndexKey, seqID) 101 } 102 103 func stateRootKey() []byte { 104 return prefixStateRootKey 105 } 106 107 type Accessor struct { 108 db ogdb.Database 109 } 110 111 func NewAccessor(db ogdb.Database) *Accessor { 112 return &Accessor{ 113 db: db, 114 } 115 } 116 117 type Putter struct { 118 ogdb.Batch 119 wg *sync.WaitGroup 120 writeConcurrenceChan chan bool 121 err error 122 mu sync.RWMutex 123 } 124 125 func (ac *Accessor) NewBatch() *Putter { 126 return &Putter{Batch: ac.db.NewBatch(), 127 writeConcurrenceChan: make(chan bool, 100), wg: &sync.WaitGroup{}} 128 } 129 130 func (da *Accessor) put(putter *Putter, key []byte, data []byte) error { 131 if putter == nil || putter.Batch == nil { 132 err := da.db.Put(key, data) 133 if err != nil { 134 log.Errorf("write data to db batch err: %v", err) 135 } 136 return err 137 } 138 return putter.Put(key, data) 139 } 140 141 func (p Putter) Write() error { 142 if p.Batch == nil { 143 return nil 144 } 145 if p.err != nil { 146 return p.err 147 } 148 p.wg.Wait() 149 //fmt.Println(p.wg,&p.wg,"end", p, p.Batch.ValueSize()) 150 defer p.Batch.Reset() 151 return p.Batch.Write() 152 } 153 154 func (p *Putter) put(key []byte, data []byte) { 155 p.mu.Lock() 156 defer p.mu.Unlock() 157 //fmt.Println(p.wg,&p.wg,"start haha", p, p.Batch.ValueSize()) 158 err := p.Batch.Put(key, data) 159 if err != nil { 160 log.Errorf("write tx to db batch err: %v", err) 161 } 162 if err != nil { 163 p.err = err 164 } 165 <-p.writeConcurrenceChan 166 //fmt.Println("hihi", time.Now()) 167 //fmt.Println(p.wg, "inside",&p.wg,p,p.Batch.ValueSize()) 168 p.wg.Done() 169 //fmt.Println("done", time.Now()) 170 //fmt.Println(p.wg, "inside",&p.wg,p,p.Batch.ValueSize()) 171 } 172 173 func (p *Putter) Put(key []byte, data []byte) error { 174 if p.err != nil { 175 return p.err 176 } 177 put := func() { 178 p.put(key, data) 179 } 180 p.writeConcurrenceChan <- true 181 p.wg.Add(1) 182 go put() 183 return p.err 184 } 185 186 // ReadGenesis get genesis sequencer from db. 187 // return nil if there is no genesis. 188 func (da *Accessor) ReadGenesis() *types.Sequencer { 189 data, _ := da.db.Get(genesisKey()) 190 if len(data) == 0 { 191 return nil 192 } 193 var seq types.Sequencer 194 _, err := seq.UnmarshalMsg(data) 195 if err != nil { 196 return nil 197 } 198 return &seq 199 } 200 201 // WriteGenesis writes geneis into db. 202 func (da *Accessor) WriteGenesis(genesis *types.Sequencer) error { 203 data, err := genesis.MarshalMsg() 204 if err != nil { 205 return err 206 } 207 return da.put(nil, genesisKey(), data) 208 } 209 210 // ReadLatestConfirmedSeq get latest sequencer from db. 211 // return nil if there is no sequencer. 212 func (da *Accessor) ReadLatestConfirmedSeq() *types.Sequencer { 213 data, _ := da.db.Get(latestConfirmedSeqKey()) 214 if len(data) == 0 { 215 return nil 216 } 217 var seq types.Sequencer 218 _, err := seq.UnmarshalMsg(data) 219 if err != nil { 220 return nil 221 } 222 return &seq 223 } 224 225 // WriteLatestConfirmedSeq writes latest sequencer into db. 226 func (da *Accessor) WriteLatestConfirmedSeq(putter *Putter, seq *types.Sequencer) error { 227 data, err := seq.MarshalMsg() 228 if err != nil { 229 return err 230 } 231 return da.put(putter, latestConfirmedSeqKey(), data) 232 } 233 234 // ReadLastStateRoot read latest state root from db. 235 // TODO 236 // this is a temp function. The latest state root should be stored 237 // in latest sequencer. 238 func (da *Accessor) ReadLastStateRoot() og_types.Hash { 239 rootbyte, _ := da.db.Get(stateRootKey()) 240 return og_types.BytesToHash32(rootbyte) 241 } 242 243 // WriteLastStateRoot write latest state root into db. 244 // TODO 245 // this is a temp function. The latest state root should be stored 246 // in latest sequencer. 247 func (da *Accessor) WriteLastStateRoot(putter *Putter, root og_types.Hash) error { 248 return da.db.Put(stateRootKey(), root.Bytes()) 249 } 250 251 // ReadTransaction get tx or sequencer from ogdb. 252 func (da *Accessor) ReadTransaction(hash og_types.Hash) types.Txi { 253 data, _ := da.db.Get(transactionKey(hash)) 254 if len(data) == 0 { 255 return nil 256 } 257 prefixLen := len(contentPrefixTransaction) 258 prefix := data[:prefixLen] 259 data = data[prefixLen:] 260 if bytes.Equal(prefix, contentPrefixTransaction) { 261 tx := types.Tx{} 262 _, err := tx.UnmarshalMsg(data) 263 if err != nil { 264 log.WithError(err).Warn("unmarshal tx error") 265 return nil 266 } 267 return &tx 268 } 269 if bytes.Equal(prefix, contentPrefixSequencer) { 270 var sq types.Sequencer 271 _, err := sq.UnmarshalMsg(data) 272 if err != nil { 273 log.WithError(err).Warn("unmarshal seq error") 274 return nil 275 } 276 return &sq 277 } 278 //if bytes.Equal(prefix, contentPrefixCampaign) { 279 // var cp types.Campaign 280 // _, err := cp.UnmarshalMsg(data) 281 // if err != nil { 282 // log.WithError(err).Warn("unmarshal camp error") 283 // return nil 284 // } 285 // return &cp 286 //} 287 //if bytes.Equal(prefix, contentPrefixTermChg) { 288 // var tc types.TermChange 289 // _, err := tc.UnmarshalMsg(data) 290 // if err != nil { 291 // log.WithError(err).Warn("unmarshal termchg error") 292 // return nil 293 // } 294 // return &tc 295 //} 296 //if bytes.Equal(prefix, contentPrefixArchive) { 297 // var ac tx_types.Archive 298 // _, err := ac.UnmarshalMsg(data) 299 // if err != nil { 300 // log.WithError(err).Warn("unmarshal archive error") 301 // return nil 302 // } 303 // return &ac 304 //} 305 //if bytes.Equal(prefix, contentPrefixActionTx) { 306 // var ac tx_types.ActionTx 307 // _, err := ac.UnmarshalMsg(data) 308 // if err != nil { 309 // log.WithError(err).Warn("unmarshal archive error") 310 // return nil 311 // } 312 // return &ac 313 //} 314 315 return nil 316 } 317 318 // ReadTxByNonce get tx from db by sender's address and nonce. 319 func (da *Accessor) ReadTxByNonce(addr og_types.Address, nonce uint64) types.Txi { 320 data, _ := da.db.Get(txHashFlowKey(addr, nonce)) 321 if len(data) == 0 { 322 return nil 323 } 324 hash := og_types.BytesToHash32(data) 325 return da.ReadTransaction(hash) 326 } 327 328 // WriteTxHashByNonce writes tx hash into db and construct key with address and nonce. 329 func (da *Accessor) WriteTxHashByNonce(putter *Putter, addr og_types.Address, nonce uint64, hash og_types.Hash) error { 330 data := hash.Bytes() 331 var err error 332 key := txHashFlowKey(addr, nonce) 333 err = da.put(putter, key, data) 334 if err != nil { 335 return fmt.Errorf("write tx hash flow to db err: %v", err) 336 } 337 return nil 338 } 339 340 // ReadAddrLatestNonce get latest nonce of an address 341 func (da *Accessor) ReadAddrLatestNonce(addr og_types.Address) (uint64, error) { 342 has, _ := da.HasAddrLatestNonce(addr) 343 if !has { 344 return 0, fmt.Errorf("not exists") 345 } 346 data, err := da.db.Get(addrLatestNonceKey(addr)) 347 if len(data) == 0 { 348 return 0, err 349 } 350 nonce, parseErr := strconv.ParseUint(string(data), 10, 64) 351 if parseErr != nil { 352 return 0, fmt.Errorf("parse nonce from bytes to uint64 error: %v", parseErr) 353 } 354 return nonce, nil 355 } 356 357 // HasAddrLatestNonce returns true if addr already sent some txs. 358 func (da *Accessor) HasAddrLatestNonce(addr og_types.Address) (bool, error) { 359 return da.db.Has(addrLatestNonceKey(addr)) 360 } 361 362 //func (da *Accessor) writeConfirmTime(cf *types.ConfirmTime) error { 363 // data, err := cf.MarshalMsg(nil) 364 // if err != nil { 365 // return err 366 // } 367 // err = da.db.Put(confirmTimeKey(cf.SeqHeight), data) 368 // if err != nil { 369 // return fmt.Errorf("write tx to db batch err: %v", err) 370 // } 371 // 372 // return nil 373 //} 374 375 //func (da *Accessor) readConfirmTime(SeqHeight uint64) *types.ConfirmTime { 376 // data, _ := da.db.Get(confirmTimeKey(SeqHeight)) 377 // if len(data) == 0 { 378 // return nil 379 // } 380 // var cf types.ConfirmTime 381 // _, err := cf.UnmarshalMsg(data) 382 // if err != nil || cf.SeqHeight != SeqHeight { 383 // return nil 384 // } 385 // return &cf 386 //} 387 388 // WriteReceipts write a receipt map into db. 389 func (da *Accessor) WriteReceipts(putter *Putter, seqID uint64, receipts ReceiptSet) error { 390 data, err := receipts.MarshalMsg(nil) 391 if err != nil { 392 return fmt.Errorf("marshal seq%d's receipts err: %v", seqID, err) 393 } 394 err = da.put(putter, receiptKey(seqID), data) 395 if err != nil { 396 return fmt.Errorf("write seq%d's receipts err: %v", seqID, err) 397 } 398 return nil 399 } 400 401 // ReadReceipt try get receipt by tx hash and seqID. 402 func (da *Accessor) ReadReceipt(seqID uint64, hash og_types.Hash) *Receipt { 403 bundleBytes, _ := da.db.Get(receiptKey(seqID)) 404 if len(bundleBytes) == 0 { 405 return nil 406 } 407 var receipts ReceiptSet 408 _, err := receipts.UnmarshalMsg(bundleBytes) 409 if err != nil { 410 return nil 411 } 412 receipt, ok := receipts[hash.Hex()] 413 if !ok { 414 return nil 415 } 416 return receipt 417 } 418 419 // writeTransaction write the tx or sequencer into ogdb. 420 func (da *Accessor) WriteTransaction(putter *Putter, tx types.Txi) error { 421 var prefix, data []byte 422 var err error 423 424 // write tx 425 switch tx := tx.(type) { 426 case *types.Tx: 427 prefix = contentPrefixTransaction 428 data, err = tx.MarshalMsg() 429 case *types.Sequencer: 430 prefix = contentPrefixSequencer 431 data, err = tx.MarshalMsg() 432 //case *tx_types.Campaign: 433 // prefix = contentPrefixCampaign 434 // data, err = tx.MarshalMsg(nil) 435 //case *tx_types.TermChange: 436 // prefix = contentPrefixTermChg 437 // data, err = tx.MarshalMsg(nil) 438 //case *tx_types.Archive: 439 // prefix = contentPrefixArchive 440 // data, err = tx.MarshalMsg(nil) 441 case *types.ActionTx: 442 prefix = contentPrefixActionTx 443 data, err = tx.MarshalMsg() 444 default: 445 return fmt.Errorf("unknown tx type, must be *Tx, *Sequencer, *Campaign, *TermChange") 446 } 447 if err != nil { 448 return fmt.Errorf("marshal tx %s err: %v", tx.GetTxHash(), err) 449 } 450 data = append(prefix, data...) 451 key := transactionKey(tx.GetTxHash()) 452 da.put(putter, key, data) 453 454 return nil 455 } 456 457 // deleteTransaction delete the tx or sequencer. 458 func (da *Accessor) DeleteTransaction(hash og_types.Hash) error { 459 return da.db.Delete(transactionKey(hash)) 460 } 461 462 // ReadBalance get the balance of an address. 463 func (da *Accessor) ReadBalance(addr og_types.Address) *math.BigInt { 464 data, _ := da.db.Get(addressBalanceKey(addr)) 465 if len(data) == 0 { 466 return math.NewBigInt(0) 467 } 468 var bigint math.BigInt 469 _, err := bigint.UnmarshalMsg(data) 470 if err != nil { 471 return nil 472 } 473 return &bigint 474 } 475 476 // SetBalance write the balance of an address into ogdb. 477 // Data will be overwritten if it already exist in db. 478 func (da *Accessor) SetBalance(putter *Putter, addr og_types.Address, value *math.BigInt) error { 479 if value.Value.Abs(value.Value).Cmp(value.Value) != 0 { 480 return fmt.Errorf("the value of the balance must be positive!") 481 } 482 data, err := value.MarshalMsg(nil) 483 if err != nil { 484 return err 485 } 486 key := addressBalanceKey(addr) 487 return da.put(putter, key, data) 488 } 489 490 // DeleteBalance delete the balance of an address. 491 func (da *Accessor) DeleteBalance(addr og_types.Address) error { 492 return da.db.Delete(addressBalanceKey(addr)) 493 } 494 495 // AddBalance adds an amount of value to the address balance. Note that AddBalance 496 // doesn't hold any locks so upper level program must manage this. 497 func (da *Accessor) AddBalance(putter *Putter, addr og_types.Address, amount *math.BigInt) error { 498 if amount.Value.Abs(amount.Value).Cmp(amount.Value) != 0 { 499 return fmt.Errorf("add amount must be positive!") 500 } 501 balance := da.ReadBalance(addr) 502 // no balance exists 503 if balance == nil { 504 return da.SetBalance(putter, addr, amount) 505 } 506 newBalanceValue := balance.Value.Add(balance.Value, amount.Value) 507 return da.SetBalance(putter, addr, &math.BigInt{Value: newBalanceValue}) 508 } 509 510 // SubBalance subs an amount of value to the address balance. Note that SubBalance 511 // doesn't hold any locks so upper level program must manage this. 512 func (da *Accessor) SubBalance(putter *Putter, addr og_types.Address, amount *math.BigInt) error { 513 if amount.Value.Abs(amount.Value).Cmp(amount.Value) != 0 { 514 return fmt.Errorf("add amount must be positive!") 515 } 516 balance := da.ReadBalance(addr) 517 // no balance exists 518 if balance == nil { 519 return fmt.Errorf("address %s has no balance yet, cannot process sub", addr) 520 } 521 if balance.Value.Cmp(amount.Value) == -1 { 522 return fmt.Errorf("address %s has no enough balance to sub. balance: %d, sub amount: %d", 523 addr, balance.GetInt64(), amount.GetInt64()) 524 } 525 newBalanceValue := balance.Value.Sub(balance.Value, amount.Value) 526 return da.SetBalance(putter, addr, &math.BigInt{Value: newBalanceValue}) 527 } 528 529 // ReadSequencerByHeight get sequencer from db by sequencer id. 530 func (da *Accessor) ReadSequencerByHeight(SeqHeight uint64) (*types.Sequencer, error) { 531 data, _ := da.db.Get(seqHeightKey(SeqHeight)) 532 if len(data) == 0 { 533 return nil, fmt.Errorf("sequencer with SeqHeight %d not found", SeqHeight) 534 } 535 var seq types.Sequencer 536 _, err := seq.UnmarshalMsg(data) 537 if err != nil { 538 return nil, err 539 } 540 return &seq, nil 541 } 542 543 // WriteSequencerByHeight stores the sequencer into db and indexed by its id. 544 func (da *Accessor) WriteSequencerByHeight(putter *Putter, seq *types.Sequencer) error { 545 data, err := seq.MarshalMsg() 546 if err != nil { 547 return err 548 } 549 key := seqHeightKey(seq.Height) 550 return da.put(putter, key, data) 551 } 552 553 // ReadIndexedTxHashs get a list of txs that is confirmed by the sequencer that 554 // holds the id 'SeqHeight'. 555 func (da *Accessor) ReadIndexedTxHashs(SeqHeight uint64) ([]og_types.Hash, error) { 556 data, _ := da.db.Get(txIndexKey(SeqHeight)) 557 if len(data) == 0 { 558 return nil, fmt.Errorf("tx hashs with seq height %d not found", SeqHeight) 559 } 560 561 data, arrLen, err := marshaller.UnMarshalIMarshallerArrayHeader(data) 562 if err != nil { 563 return nil, fmt.Errorf("unmarshal tx hashes arr header error: %v", err) 564 } 565 hashs := make([]og_types.Hash, arrLen) 566 for i := 0; i < arrLen; i++ { 567 var hash og_types.Hash 568 hash, data, err = og_types.UnmarshalHash(data) 569 if err != nil { 570 return nil, fmt.Errorf("unmarshal tx hash error: %v", err) 571 } 572 hashs = append(hashs, hash) 573 } 574 return hashs, nil 575 } 576 577 // WriteIndexedTxHashs stores a list of tx hashs. These related hashs are all 578 // confirmed by sequencer that holds the id 'SeqHeight'. 579 func (da *Accessor) WriteIndexedTxHashs(putter *Putter, SeqHeight uint64, hashs []og_types.Hash) error { 580 hashsI := make([]marshaller.IMarshaller, len(hashs)) 581 for i := range hashsI { 582 hashsI[i] = hashs[i] 583 } 584 data, err := marshaller.MarshalIMarshallerArray(hashsI) 585 if err != nil { 586 return err 587 } 588 key := txIndexKey(SeqHeight) 589 return da.put(putter, key, data) 590 } 591 592 /** 593 Components 594 */ 595 596 func encodeUint64(n uint64) []byte { 597 b := make([]byte, 8) 598 binary.BigEndian.PutUint64(b, n) 599 return b 600 } 601 602 func encodeInt32(n int32) []byte { 603 return common.ByteInt32(n) 604 }