github.com/annchain/OG@v0.0.9/arefactor_core/core/dag.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 "fmt" 18 "sort" 19 "sync" 20 21 ogTypes "github.com/annchain/OG/arefactor/og_interface" 22 "github.com/annchain/OG/arefactor/types" 23 "github.com/annchain/OG/arefactor_core/core/state" 24 "github.com/annchain/OG/common/math" 25 "github.com/annchain/OG/ogdb" 26 evm "github.com/annchain/OG/vm/eth/core/vm" 27 "github.com/annchain/OG/vm/ovm" 28 vmtypes "github.com/annchain/OG/vm/types" 29 30 log "github.com/sirupsen/logrus" 31 ) 32 33 var ( 34 // empty address is the address used for contract creation, it 35 // is filled in [tx.To]. 36 emptyAddress = ogTypes.BytesToAddress20(nil) 37 38 emptyRoot = ogTypes.BytesToHash32(nil) 39 40 DefaultGasLimit = uint64(10000000000) 41 42 DefaultCoinbase, _ = ogTypes.HexToAddress20("0x1234567812345678AABBCCDDEEFF998877665544") 43 ) 44 45 type DagConfig struct { 46 GenesisPath string 47 } 48 49 //type Ledger interface { 50 // GetTx(hash ogTypes.Hash) types.Txi 51 // GetBalance(addr ogTypes.Address, tokenID int32) *math.BigInt 52 // GetLatestNonce(addr ogTypes.Address) (uint64, error) 53 //} 54 55 type Dag struct { 56 conf DagConfig 57 58 db ogdb.Database 59 accessor *Accessor 60 61 txProcessor TxProcessor 62 vmProcessor VmProcessor 63 64 genesis *types.Sequencer 65 latestSequencer *types.Sequencer 66 latestStateDB *state.StateDB 67 confirmedSequencer *types.Sequencer 68 confirmedStateDB *state.StateDB 69 cachedBatches *CachedConfirms // stores speculated sequencers, use state root as batch key 70 pendedBatches *CachedConfirms // stores pushed sequencers, use sequencer hash as batch key 71 72 //txcached *txcached 73 74 OnConsensusTXConfirmed chan []types.Txi 75 close chan struct{} 76 77 mu sync.RWMutex 78 } 79 80 func NewDag(conf DagConfig, stateDBConfig state.StateDBConfig, db ogdb.Database, txProcessor TxProcessor, vmProcessor VmProcessor) (*Dag, error) { 81 dag := &Dag{ 82 conf: conf, 83 db: db, 84 accessor: NewAccessor(db), 85 //txcached: newTxcached(10000), // TODO delete txcached later 86 txProcessor: txProcessor, 87 vmProcessor: vmProcessor, 88 cachedBatches: newCachedConfirms(), 89 pendedBatches: newCachedConfirms(), 90 close: make(chan struct{}), 91 } 92 93 genesis, latestConfirmedSeq := dag.LoadLatestConfirmedSeq() 94 if genesis == nil { 95 genesis, balance := DefaultGenesis(conf.GenesisPath) 96 statedb, err := state.NewStateDB(stateDBConfig, state.NewDatabase(db), emptyRoot) 97 if err != nil { 98 return nil, fmt.Errorf("create statedb err: %v", err) 99 } 100 dag.latestStateDB = statedb 101 dag.confirmedStateDB = statedb 102 if err := dag.Init(genesis, balance); err != nil { 103 return nil, err 104 } 105 return dag, nil 106 } 107 dag.genesis = genesis 108 dag.latestSequencer = latestConfirmedSeq 109 dag.confirmedSequencer = latestConfirmedSeq 110 111 root := latestConfirmedSeq.StateRoot 112 log.Infof("the root loaded from last state is: %x", root.Bytes()) 113 statedb, err := state.NewStateDB(stateDBConfig, state.NewDatabase(db), root) 114 if err != nil { 115 return nil, fmt.Errorf("create statedb err: %v", err) 116 } 117 dag.latestStateDB = statedb 118 dag.confirmedStateDB = statedb 119 120 if dag.GetHeight() > 0 && root.Length() == 0 { 121 panic("should not be empty hash. Database may be corrupted. Please clean datadir") 122 } 123 return dag, nil 124 } 125 126 func DefaultDagConfig() DagConfig { 127 return DagConfig{} 128 } 129 130 func (dag *Dag) Start() { 131 log.Infof("Dag Start") 132 133 } 134 135 func (dag *Dag) Stop() { 136 close(dag.close) 137 138 dag.latestStateDB.Stop() 139 for _, batch := range dag.pendedBatches.batches { 140 batch.stop() 141 } 142 log.Infof("Dag Stopped") 143 } 144 145 // Init inits genesis sequencer and genesis state of the network. 146 func (dag *Dag) Init(genesis *types.Sequencer, genesisBalance map[ogTypes.AddressKey]*math.BigInt) error { 147 if genesis.Height != 0 { 148 return fmt.Errorf("invalheight genesis: height is not zero") 149 } 150 var err error 151 152 // init genesis balance 153 for addrKey, value := range genesisBalance { 154 addr, _ := ogTypes.HexToAddress20(string(addrKey)) 155 dag.latestStateDB.SetBalance(addr, value) 156 } 157 // commit state and init a genesis state root 158 root, err := dag.latestStateDB.Commit() 159 if err != nil { 160 return fmt.Errorf("commit genesis state err: %v", err) 161 } 162 trieDB := dag.latestStateDB.Database().TrieDB() 163 err = trieDB.Commit(root, false) 164 if err != nil { 165 return fmt.Errorf("commit genesis trie err: %v", err) 166 } 167 168 // write genesis 169 genesis.StateRoot = root 170 err = dag.accessor.WriteGenesis(genesis) 171 if err != nil { 172 return err 173 } 174 err = dag.writeSequencer(nil, genesis) 175 if err != nil { 176 return err 177 } 178 179 // set latest sequencer 180 err = dag.accessor.WriteLatestConfirmedSeq(nil, genesis) 181 if err != nil { 182 return err 183 } 184 log.Tracef("successfully store genesis: %s", genesis) 185 186 dag.genesis = genesis 187 dag.latestSequencer = genesis 188 dag.confirmedSequencer = genesis 189 190 log.Infof("Dag finish init") 191 return nil 192 } 193 194 // LoadLatestConfirmedSeq load genesis and latest confirmed sequencer from db. 195 func (dag *Dag) LoadLatestConfirmedSeq() (*types.Sequencer, *types.Sequencer) { 196 dag.mu.Lock() 197 defer dag.mu.Unlock() 198 199 genesis := dag.accessor.ReadGenesis() 200 if genesis == nil { 201 return nil, nil 202 } 203 dag.genesis = genesis 204 205 seq := dag.accessor.ReadLatestConfirmedSeq() 206 if seq == nil { 207 return nil, nil 208 } else { 209 return genesis, seq 210 } 211 } 212 213 // Genesis returns the genesis tx of dag 214 func (dag *Dag) Genesis() *types.Sequencer { 215 dag.mu.RLock() 216 defer dag.mu.RUnlock() 217 218 return dag.genesis 219 } 220 221 // LatestSequencer returns the latest sequencer stored in dag 222 func (dag *Dag) LatestSequencer() *types.Sequencer { 223 dag.mu.RLock() 224 defer dag.mu.RUnlock() 225 226 return dag.latestSequencer 227 } 228 229 func (dag *Dag) LatestSequencerHash() ogTypes.Hash { 230 dag.mu.RLock() 231 defer dag.mu.RUnlock() 232 233 return dag.latestSequencer.GetTxHash() 234 } 235 236 func (dag *Dag) ConfirmedSequencer() *types.Sequencer { 237 dag.mu.RLock() 238 defer dag.mu.RUnlock() 239 240 return dag.confirmedSequencer 241 } 242 243 func (dag *Dag) ConfirmedSequencerHash() ogTypes.Hash { 244 dag.mu.RLock() 245 defer dag.mu.RUnlock() 246 247 return dag.confirmedSequencer.GetTxHash() 248 } 249 250 //GetHeight get cuurent height 251 func (dag *Dag) GetHeight() uint64 { 252 dag.mu.RLock() 253 defer dag.mu.RUnlock() 254 255 return dag.latestSequencer.Height 256 } 257 258 func (dag *Dag) GetConfirmedHeight() uint64 { 259 dag.mu.RLock() 260 defer dag.mu.RUnlock() 261 262 return dag.confirmedSequencer.Height 263 264 } 265 266 //// Accessor returns the db accessor of dag 267 //func (dag *Dag) Accessor() *Accessor { 268 // return dag.accessor 269 //} 270 271 func (dag *Dag) Speculate(pushBatch *PushBatch) (ogTypes.Hash, error) { 272 dag.mu.Lock() 273 defer dag.mu.Unlock() 274 275 return dag.speculate(pushBatch) 276 } 277 278 // Push trys to move a tx from tx pool to dag db. 279 func (dag *Dag) Push(batch *PushBatch) error { 280 dag.mu.Lock() 281 defer dag.mu.Unlock() 282 283 return dag.push(batch) 284 } 285 286 func (dag *Dag) Commit(seqHash ogTypes.Hash) error { 287 dag.mu.Lock() 288 defer dag.mu.Unlock() 289 290 return dag.commit(seqHash) 291 } 292 293 // GetTx gets tx from dag network indexed by tx hash 294 func (dag *Dag) GetTx(hash ogTypes.Hash) types.Txi { 295 dag.mu.RLock() 296 defer dag.mu.RUnlock() 297 298 return dag.getTx(hash) 299 } 300 301 func (dag *Dag) getTx(hash ogTypes.Hash) types.Txi { 302 tx, _ := dag.pendedBatches.getTxAndReceipt(hash) 303 if tx != nil { 304 return tx 305 } 306 return dag.accessor.ReadTransaction(hash) 307 } 308 309 func (dag *Dag) GetConfirmedTx(hash ogTypes.Hash) types.Txi { 310 dag.mu.RLock() 311 defer dag.mu.RUnlock() 312 313 return dag.accessor.ReadTransaction(hash) 314 } 315 316 func (dag *Dag) getConfirmedTx(hash ogTypes.Hash) types.Txi { 317 return dag.accessor.ReadTransaction(hash) 318 } 319 320 func (dag *Dag) ExistTx(baseSeqHash ogTypes.Hash, hash ogTypes.Hash) bool { 321 dag.mu.RLock() 322 defer dag.mu.RUnlock() 323 324 if dag.pendedBatches.existTx(baseSeqHash, hash) { 325 return true 326 } 327 return dag.accessor.ReadTransaction(hash) != nil 328 } 329 330 // GetTxByNonce gets tx from dag by sender's address and tx nonce 331 func (dag *Dag) GetTxByNonce(baseSeqHash ogTypes.Hash, addr ogTypes.Address, nonce uint64) types.Txi { 332 dag.mu.RLock() 333 defer dag.mu.RUnlock() 334 335 return dag.getTxByNonce(baseSeqHash, addr, nonce) 336 } 337 338 func (dag *Dag) getTxByNonce(baseSeqHash ogTypes.Hash, addr ogTypes.Address, nonce uint64) types.Txi { 339 tx := dag.pendedBatches.getTxByNonce(baseSeqHash, addr, nonce) 340 if tx != nil { 341 return tx 342 } 343 return dag.accessor.ReadTxByNonce(addr, nonce) 344 } 345 346 // GetTxs get a bundle of txs according to a hash list. 347 func (dag *Dag) GetTxis(hashs []ogTypes.Hash) types.Txis { 348 dag.mu.RLock() 349 defer dag.mu.RUnlock() 350 351 return dag.getTxis(hashs) 352 } 353 354 func (dag *Dag) getTxis(hashs []ogTypes.Hash) types.Txis { 355 var txs types.Txis 356 for _, hash := range hashs { 357 tx := dag.getTx(hash) 358 if tx != nil { 359 txs = append(txs, tx) 360 } 361 } 362 return txs 363 } 364 365 //func (dag *Dag) getTxisByType(hashs []ogTypes.Hash, baseType types.TxBaseType) types.Txis { 366 // var txs types.Txis 367 // for _, hash := range hashs { 368 // tx := dag.getTxAndReceipt(hash) 369 // if tx != nil && tx.GetType() == baseType { 370 // txs = append(txs, tx) 371 // } 372 // } 373 // return txs 374 //} 375 376 // GetTxConfirmHeight returns the height of sequencer that confirm this tx. 377 func (dag *Dag) GetTxConfirmHeight(hash ogTypes.Hash) (uint64, error) { 378 dag.mu.RLock() 379 defer dag.mu.RUnlock() 380 381 return dag.getTxConfirmHeight(hash) 382 } 383 384 func (dag *Dag) getTxConfirmHeight(hash ogTypes.Hash) (uint64, error) { 385 tx := dag.getTx(hash) 386 if tx == nil { 387 return 0, fmt.Errorf("hash not exists: %s", hash) 388 } 389 return tx.GetBase().GetHeight(), nil 390 } 391 392 func (dag *Dag) GetTxisByHeight(height uint64) types.Txis { 393 dag.mu.RLock() 394 defer dag.mu.RUnlock() 395 396 if height > dag.latestSequencer.GetHeight() { 397 return nil 398 } 399 baseSeqHash := dag.latestSequencer.GetTxHash() 400 txs := dag.pendedBatches.getTxsByHeight(baseSeqHash, height) 401 if txs != nil { 402 return txs 403 } 404 405 hashs, err := dag.accessor.ReadIndexedTxHashs(height) 406 if err != nil { 407 log.WithError(err).WithField("height", height).Trace("hashes not found") 408 return nil 409 } 410 if len(hashs) == 0 { 411 return nil 412 } 413 log.WithField("len tx ", len(hashs)).WithField("height", height).Trace("get txs") 414 return dag.getTxis(hashs) 415 } 416 417 //func (dag *Dag) GetTxsByNumberAndType(height uint64, txType types.TxBaseType) types.Txis { 418 // dag.mu.RLock() 419 // defer dag.mu.RUnlock() 420 // 421 // hashs := dag.getTxsHashesByHeight(height) 422 // if hashs == nil { 423 // return nil 424 // } 425 // if len(hashs) == 0 { 426 // return nil 427 // } 428 // log.WithField("len tx ", len(hashs)).WithField("height", height).Trace("get txs") 429 // return dag.getTxisByType(hashs, txType) 430 //} 431 432 func (dag *Dag) GetReceipt(hash ogTypes.Hash) *Receipt { 433 dag.mu.RLock() 434 defer dag.mu.RUnlock() 435 436 _, receipt := dag.pendedBatches.getTxAndReceipt(hash) 437 if receipt != nil { 438 return receipt 439 } 440 tx := dag.getConfirmedTx(hash) 441 if tx == nil { 442 return nil 443 } 444 seqid := tx.GetHeight() 445 return dag.accessor.ReadReceipt(seqid, hash) 446 } 447 448 func (dag *Dag) GetSequencerByHash(hash ogTypes.Hash) *types.Sequencer { 449 dag.mu.RLock() 450 defer dag.mu.RUnlock() 451 452 tx := dag.getTx(hash) 453 switch tx := tx.(type) { 454 case *types.Sequencer: 455 return tx 456 default: 457 return nil 458 } 459 } 460 461 // GetSequencerByHeight only support those confirmed sequencers 462 func (dag *Dag) GetSequencerByHeight(height uint64) *types.Sequencer { 463 dag.mu.RLock() 464 defer dag.mu.RUnlock() 465 466 return dag.getSequencerByHeight(height) 467 } 468 469 func (dag *Dag) getSequencerByHeight(height uint64) *types.Sequencer { 470 if height == 0 { 471 return dag.genesis 472 } 473 if height > dag.latestSequencer.Height { 474 return nil 475 } 476 baseSeqHash := dag.latestSequencer.GetTxHash() 477 seq := dag.pendedBatches.getSeqByHeight(baseSeqHash, height) 478 if seq != nil { 479 return seq 480 } 481 seq, err := dag.accessor.ReadSequencerByHeight(height) 482 if err != nil || seq == nil { 483 log.WithField("height", height).WithError(err).Warn("head not found") 484 return nil 485 } 486 return seq 487 } 488 489 //func (dag *Dag) GetSequencerHashByHeight(height uint64) ogTypes.Hash { 490 // dag.mu.RLock() 491 // defer dag.mu.RUnlock() 492 // 493 // return dag.getSequencerHashByHeight(height) 494 //} 495 // 496 //func (dag *Dag) getSequencerHashByHeight(height uint64) ogTypes.Hash { 497 // seq, err := dag.accessor.ReadSequencerByHeight(height) 498 // if err != nil || seq == nil { 499 // log.WithField("height", height).Warn("head not found") 500 // return nil 501 // } 502 // hash := seq.GetTxHash() 503 // return hash 504 //} 505 506 func (dag *Dag) GetSequencer(hash ogTypes.Hash, seqHeight uint64) *types.Sequencer { 507 dag.mu.RLock() 508 defer dag.mu.RUnlock() 509 510 tx := dag.getTx(hash) 511 switch tx := tx.(type) { 512 case *types.Sequencer: 513 if tx.Height != seqHeight { 514 log.Warn("seq height mismatch ") 515 return nil 516 } 517 return tx 518 default: 519 return nil 520 } 521 } 522 523 func (dag *Dag) GetBalance(baseSeqHash ogTypes.Hash, addr ogTypes.Address, tokenID int32) *math.BigInt { 524 dag.mu.RLock() 525 defer dag.mu.RUnlock() 526 527 return dag.getBalance(baseSeqHash, addr, tokenID) 528 } 529 530 func (dag *Dag) getBalance(baseSeqHash ogTypes.Hash, addr ogTypes.Address, tokenID int32) *math.BigInt { 531 db := dag.getDB(baseSeqHash) 532 if db == nil { 533 return nil 534 } 535 return db.GetTokenBalance(addr, tokenID) 536 } 537 538 func (dag *Dag) GetAllTokenBalance(baseSeqHash ogTypes.Hash, addr ogTypes.Address) state.BalanceSet { 539 dag.mu.RLock() 540 defer dag.mu.RUnlock() 541 542 return dag.getAlltokenBalance(baseSeqHash, addr) 543 } 544 545 func (dag *Dag) getAlltokenBalance(baseSeqHash ogTypes.Hash, addr ogTypes.Address) state.BalanceSet { 546 db := dag.getDB(baseSeqHash) 547 if db == nil { 548 return nil 549 } 550 return db.GetAllTokenBalance(addr) 551 } 552 553 func (dag *Dag) GetToken(baseSeqHash ogTypes.Hash, tokenId int32) *state.TokenObject { 554 dag.mu.RLock() 555 defer dag.mu.RUnlock() 556 557 return dag.getToken(baseSeqHash, tokenId) 558 } 559 560 func (dag *Dag) getToken(baseSeqHash ogTypes.Hash, tokenId int32) *state.TokenObject { 561 db := dag.getDB(baseSeqHash) 562 if db == nil { 563 return nil 564 } 565 if tokenId > db.LatestTokenID() { 566 return nil 567 } 568 return db.GetTokenObject(tokenId) 569 } 570 571 func (dag *Dag) GetLatestTokenId(baseSeqHash ogTypes.Hash) int32 { 572 dag.mu.RLock() 573 defer dag.mu.RUnlock() 574 575 return dag.getLatestTokenId(baseSeqHash) 576 } 577 578 func (dag *Dag) getLatestTokenId(baseSeqHash ogTypes.Hash) int32 { 579 db := dag.getDB(baseSeqHash) 580 if db == nil { 581 return -1 582 } 583 return db.LatestTokenID() 584 } 585 586 func (dag *Dag) GetTokens(baseSeqHash ogTypes.Hash) []*state.TokenObject { 587 dag.mu.RLock() 588 defer dag.mu.RUnlock() 589 590 return dag.getTokens(baseSeqHash) 591 } 592 593 func (dag *Dag) getTokens(baseSeqHash ogTypes.Hash) []*state.TokenObject { 594 tokens := make([]*state.TokenObject, 0) 595 lid := dag.getLatestTokenId(baseSeqHash) 596 597 for i := int32(0); i <= lid; i++ { 598 token := dag.getToken(baseSeqHash, i) 599 tokens = append(tokens, token) 600 } 601 return tokens 602 } 603 604 // GetLatestNonce returns the latest tx of an address. 605 func (dag *Dag) GetLatestNonce(baseSeqHash ogTypes.Hash, addr ogTypes.Address) (uint64, error) { 606 dag.mu.RLock() 607 defer dag.mu.RUnlock() 608 609 return dag.getLatestNonce(baseSeqHash, addr) 610 } 611 612 func (dag *Dag) getLatestNonce(baseSeqHash ogTypes.Hash, addr ogTypes.Address) (uint64, error) { 613 db := dag.getDB(baseSeqHash) 614 if db == nil { 615 return 0, fmt.Errorf("base sequencer not found: %s", baseSeqHash.Hex()) 616 } 617 return db.GetNonce(addr), nil 618 } 619 620 // GetState get contract's state from statedb. 621 func (dag *Dag) GetState(baseSeqHash ogTypes.Hash, addr ogTypes.Address, key ogTypes.Hash) ogTypes.Hash { 622 dag.mu.RLock() 623 defer dag.mu.RUnlock() 624 625 return dag.getState(baseSeqHash, addr, key) 626 } 627 628 func (dag *Dag) getState(baseSeqHash ogTypes.Hash, addr ogTypes.Address, key ogTypes.Hash) ogTypes.Hash { 629 db := dag.getDB(baseSeqHash) 630 if db == nil { 631 return nil 632 } 633 return db.GetState(addr, key) 634 } 635 636 func (dag *Dag) getDB(baseSeqHash ogTypes.Hash) *state.StateDB { 637 if baseSeqHash.Cmp(dag.ConfirmedSequencerHash()) == 0 { 638 return dag.confirmedStateDB 639 } 640 confirmBatch := dag.pendedBatches.getConfirmBatch(baseSeqHash) 641 if confirmBatch != nil { 642 return confirmBatch.db 643 } 644 return nil 645 } 646 647 ////GetTxsByAddress get all txs from this address 648 //func (dag *Dag) GetTxsByAddress(addr ogTypes.Address) []types.Txi { 649 // dag.mu.RLock() 650 // defer dag.mu.RUnlock() 651 // 652 // return dag.getTxsByAddress(addr) 653 //} 654 // 655 //func (dag *Dag) getTxsByAddress(addr ogTypes.Address) []types.Txi { 656 // nonce, err := dag.getLatestNonce(addr) 657 // if (err != nil) || (nonce == 0) { 658 // return nil 659 // } 660 // var i int64 661 // var txs []types.Txi 662 // for i = int64(nonce); i > 0; i-- { 663 // tx := dag.getTxByNonce(addr, uint64(i)) 664 // if tx != nil { 665 // txs = append(txs, tx) 666 // } 667 // } 668 // if len(txs) == 0 { 669 // return nil 670 // } 671 // return txs 672 //} 673 674 // RollBack rolls back the dag network. 675 func (dag *Dag) RollBack() { 676 // TODO 677 } 678 679 func (dag *Dag) speculate(pushBatch *PushBatch) (ogTypes.Hash, error) { 680 log.Tracef("speculate the batch: %s", pushBatch.String()) 681 682 confirmBatch, err := dag.process(pushBatch) 683 if err != nil { 684 return nil, err 685 } 686 dag.cachedBatches.purePush(confirmBatch.db.Root(), confirmBatch) 687 return confirmBatch.db.Root(), nil 688 } 689 690 func (dag *Dag) push(pushBatch *PushBatch) error { 691 log.Tracef("push the pushBatch: %s", pushBatch.String()) 692 693 var err error 694 seq := pushBatch.Seq 695 696 //var confirmBatch *ConfirmBatch 697 confirmBatch := dag.cachedBatches.getConfirmBatch(seq.StateRoot) 698 if confirmBatch == nil { 699 confirmBatch, err = dag.process(pushBatch) 700 if err != nil { 701 return err 702 } 703 } else { 704 confirmBatch.seq = seq 705 dag.cachedBatches.pureDelete(seq.StateRoot) 706 } 707 708 root := confirmBatch.db.Root() 709 710 // flush triedb into diskdb. 711 triedb := confirmBatch.db.Database().TrieDB() 712 err = triedb.Commit(root, false) 713 if err != nil { 714 return fmt.Errorf("can't flush trie from triedb to diskdb, err: %v", err) 715 } 716 717 // change chosen batch if current is higher than chosen one 718 if seq.Height > dag.latestSequencer.Height { 719 dag.latestSequencer = seq 720 dag.latestStateDB = confirmBatch.db 721 } 722 dag.pendedBatches.push(seq.GetTxHash(), confirmBatch) 723 724 log.Tracef("successfully store seq: %s", seq.GetTxHash()) 725 log.WithField("height", seq.Height).WithField("txs number ", len(pushBatch.Txs)).Info("new height") 726 return nil 727 } 728 729 func (dag *Dag) commit(seqHash ogTypes.Hash) (err error) { 730 confirmBatch := dag.pendedBatches.getConfirmBatch(seqHash) 731 if confirmBatch == nil { 732 return fmt.Errorf("can't find pended seq: %s", seqHash.Hex()) 733 } 734 735 err = dag.flushAllToDB(confirmBatch) 736 if err != nil { 737 return err 738 } 739 740 dag.pendedBatches.confirm(confirmBatch) 741 dag.confirmedSequencer = confirmBatch.seq 742 return nil 743 } 744 745 func (dag *Dag) process(pushBatch *PushBatch) (*ConfirmBatch, error) { 746 var err error 747 seq := pushBatch.Seq 748 sort.Sort(pushBatch.Txs) 749 750 parentSeqI := dag.getTx(seq.GetParentSeqHash()) 751 if parentSeqI != nil && parentSeqI.GetType() != types.TxBaseTypeSequencer { 752 return nil, fmt.Errorf("parent sequencer not exists: %s", seq.GetParentSeqHash().Hex()) 753 } 754 parentSeq := parentSeqI.(*types.Sequencer) 755 confirmBatch, err := newConfirmBatch(seq, dag.db, parentSeq.StateRoot) 756 if err != nil { 757 return nil, err 758 } 759 760 // store the tx and update the state 761 receipts := make(ReceiptSet) 762 for _, txi := range pushBatch.Txs { 763 txi.GetBase().Height = seq.Height 764 receipt, err := dag.processTransaction(confirmBatch.db, seq, txi) 765 if err != nil { 766 return nil, err 767 } 768 confirmBatch.addTx(txi) 769 receipts[txi.GetTxHash().HashKey()] = receipt 770 log.WithField("tx", txi).Tracef("successfully process tx") 771 } 772 // process sequencer 773 seqReceipt, err := dag.processTransaction(confirmBatch.db, seq, seq) 774 if err != nil { 775 return nil, err 776 } 777 778 confirmBatch.txReceipts = receipts 779 confirmBatch.seqReceipt = seqReceipt 780 781 // commit statedb's changes to trie and triedb 782 _, err = confirmBatch.db.Commit() 783 if err != nil { 784 return nil, fmt.Errorf("can't Commit statedb, err: %v", err) 785 } 786 confirmBatch.db.ClearJournalAndRefund() 787 788 return confirmBatch, nil 789 } 790 791 func (dag *Dag) flushAllToDB(confirmBatch *ConfirmBatch) (err error) { 792 dbBatch := dag.accessor.NewBatch() 793 794 // write txs 795 var txHashes []ogTypes.Hash 796 for _, tx := range confirmBatch.elders { 797 err = dag.writeTransaction(dbBatch, tx) 798 if err != nil { 799 return err 800 } 801 txHashes = append(txHashes, tx.GetTxHash()) 802 } 803 // store the hashs of the txs confirmed by this sequencer. 804 if len(txHashes) > 0 { 805 dag.accessor.WriteIndexedTxHashs(dbBatch, confirmBatch.seq.Height, txHashes) 806 } 807 // write sequencer 808 err = dag.writeSequencer(dbBatch, confirmBatch.seq) 809 if err != nil { 810 return err 811 } 812 // write receipts 813 confirmBatch.txReceipts[confirmBatch.seq.GetTxHash().HashKey()] = confirmBatch.seqReceipt 814 err = dag.accessor.WriteReceipts(dbBatch, confirmBatch.seq.Height, confirmBatch.txReceipts) 815 if err != nil { 816 return err 817 } 818 819 err = dbBatch.Write() 820 if err != nil { 821 log.WithError(err).Warn("dbBatch write error") 822 return err 823 } 824 return nil 825 } 826 827 // writeTransaction write the tx or sequencer into ogdb. It first writes 828 // the latest nonce of the tx's sender, then write the ([address, nonce] -> hash) 829 // relation into db, finally write the tx itself. Data will be overwritten 830 // if it already exists in db. 831 func (dag *Dag) writeTransaction(putter *Putter, tx types.Txi) error { 832 // Write tx hash. This is aimed to allow users to query tx hash 833 // by sender address and tx nonce. 834 if tx.GetType() != types.TxBaseTypeArchive { 835 err := dag.accessor.WriteTxHashByNonce(putter, tx.Sender(), tx.GetNonce(), tx.GetTxHash()) 836 if err != nil { 837 return fmt.Errorf("write latest nonce err: %v", err) 838 } 839 } 840 841 // Write tx itself 842 err := dag.accessor.WriteTransaction(putter, tx) 843 if err != nil { 844 return err 845 } 846 847 //dag.txcached.add(tx) 848 return nil 849 } 850 851 func (dag *Dag) deleteTransaction(hash ogTypes.Hash) error { 852 return dag.accessor.DeleteTransaction(hash) 853 } 854 855 // processTransaction execute the tx and update the data in statedb. 856 func (dag *Dag) processTransaction(stateDB *state.StateDB, seq *types.Sequencer, tx types.Txi) (*Receipt, error) { 857 txReceipt, err := dag.txProcessor.Process(stateDB, tx) 858 if err != nil { 859 return txReceipt, err 860 } 861 862 if !dag.vmProcessor.CanProcess(tx) { 863 return txReceipt, nil 864 } 865 return dag.vmProcessor.Process(stateDB, tx, seq.Height) 866 } 867 868 // writeSequencer flushes sequencer into db indexed by seq hash and seq height 869 func (dag *Dag) writeSequencer(putter *Putter, seq *types.Sequencer) (err error) { 870 err = dag.writeTransaction(putter, seq) 871 if err != nil { 872 return err 873 } 874 err = dag.accessor.WriteSequencerByHeight(putter, seq) 875 if err != nil { 876 return err 877 } 878 // set latest sequencer 879 err = dag.accessor.WriteLatestConfirmedSeq(nil, seq) 880 if err != nil { 881 return err 882 } 883 return nil 884 } 885 886 // CallContract calls contract but disallow any modifications on 887 // statedb. This method will call ovm.StaticCall() to satisfy this. 888 func (dag *Dag) CallContract(addr ogTypes.Address20, data []byte) ([]byte, error) { 889 // create ovm object. 890 // 891 // TODO gaslimit not implemented yet. 892 vmContext := ovm.NewOVMContext(&ovm.DefaultChainContext{}, DefaultCoinbase, dag.latestStateDB) 893 txContext := &ovm.TxContext{ 894 From: DefaultCoinbase, 895 Value: math.NewBigInt(0), 896 Data: data, 897 GasPrice: math.NewBigInt(0), 898 GasLimit: DefaultGasLimit, 899 Coinbase: DefaultCoinbase, 900 SequenceID: dag.latestSequencer.Height, 901 } 902 // TODO more interpreters should be initialized, here only evm. 903 evmInterpreter := evm.NewEVMInterpreter(vmContext, txContext, 904 &evm.InterpreterConfig{ 905 Debug: false, 906 }) 907 ovmconf := &ovm.OVMConfig{ 908 NoRecursion: false, 909 } 910 ogvm := ovm.NewOVM(vmContext, []ovm.Interpreter{evmInterpreter}, ovmconf) 911 912 ret, _, err := ogvm.StaticCall(vmtypes.AccountRef(*txContext.From), addr, txContext.Data, txContext.GasLimit) 913 return ret, err 914 } 915 916 func (dag *Dag) revert(snapShotID int) { 917 dag.latestStateDB.RevertToSnapshot(snapShotID) 918 } 919 920 type txcached struct { 921 maxsize int 922 order []ogTypes.Hash 923 txs map[ogTypes.HashKey]types.Txi 924 } 925 926 func newTxcached(maxsize int) *txcached { 927 return &txcached{ 928 maxsize: maxsize, 929 order: make([]ogTypes.Hash, 0), 930 txs: make(map[ogTypes.HashKey]types.Txi), 931 } 932 } 933 934 func (tc *txcached) get(hash ogTypes.Hash) types.Txi { 935 return tc.txs[hash.HashKey()] 936 } 937 938 func (tc *txcached) add(tx types.Txi) { 939 if tx == nil { 940 return 941 } 942 if _, ok := tc.txs[tx.GetTxHash().HashKey()]; ok { 943 return 944 } 945 if len(tc.order) >= tc.maxsize { 946 fstHash := tc.order[0] 947 delete(tc.txs, fstHash.HashKey()) 948 tc.order = tc.order[1:] 949 } 950 tc.order = append(tc.order, tx.GetTxHash()) 951 tc.txs[tx.GetTxHash().HashKey()] = tx 952 } 953 954 type PushBatch struct { 955 Seq *types.Sequencer 956 Txs types.Txis 957 } 958 959 func (c *PushBatch) String() string { 960 return fmt.Sprintf("seq: %s, txs: [%s]", c.Seq.String(), c.Txs.String()) 961 }