github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/database/contract_view_test.go (about) 1 package database 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "os" 7 "testing" 8 9 "github.com/google/uuid" 10 11 "github.com/bytom/bytom/crypto/sha3pool" 12 dbm "github.com/bytom/bytom/database/leveldb" 13 "github.com/bytom/bytom/protocol/bc" 14 "github.com/bytom/bytom/protocol/state" 15 ) 16 17 var ( 18 program, _ = hex.DecodeString("6a4c04626372704c01014c2820e9108d3ca8049800727f6a3505b3a2710dc579405dde03c250f16d9a7e1e6e787403ae7cac00c0") 19 hash [32]byte 20 txID1 = &bc.Hash{V0: 1, V1: 1, V2: 1, V3: 1} 21 txID2 = &bc.Hash{V0: 2, V1: 2, V2: 2, V3: 2} 22 ) 23 24 func init() { 25 sha3pool.Sum256(hash[:], program) 26 } 27 28 // register contract by transaction 1 29 func registerContract(testDB dbm.DB) { 30 contractView := state.NewContractViewpoint() 31 contractView.AttachEntries[hash] = append(txID1.Bytes(), program...) 32 if err := setContractView(testDB, contractView); err != nil { 33 panic(err) 34 } 35 } 36 37 func setContractView(testDB dbm.DB, contractView *state.ContractViewpoint) error { 38 batch := testDB.NewBatch() 39 if err := deleteContractView(testDB, batch, contractView); err != nil { 40 return err 41 } 42 43 if err := saveContractView(testDB, batch, contractView); err != nil { 44 return err 45 } 46 47 batch.Write() 48 return nil 49 } 50 51 func assertDBContractData(testDB dbm.DB, txID *bc.Hash, t *testing.T) { 52 data := testDB.Get(CalcContractKey(hash)) 53 if data == nil { 54 t.Errorf("can't find the registered contract by contract hash %v", hash) 55 } 56 57 expect := append(txID.Bytes(), program...) 58 if !bytes.Equal(data, expect) { 59 t.Errorf("got contract data: %v, expect contract data: %v", data, expect) 60 } 61 } 62 63 func TestRollback(t *testing.T) { 64 dbName := uuid.New().String() 65 testDB := dbm.NewDB(dbName, "leveldb", dbName) 66 registerContract(testDB) 67 defer os.RemoveAll(dbName) 68 69 contractView := state.NewContractViewpoint() 70 // rollback 71 contractView.DetachEntries[hash] = append(txID1.Bytes(), program...) 72 if err := setContractView(testDB, contractView); err != nil { 73 t.Errorf("set contract view failed") 74 } 75 76 data := testDB.Get(CalcContractKey(hash)) 77 if data != nil { 78 t.Errorf("registered contract should be deleted") 79 } 80 } 81 82 func TestRollbackAndRegisterAgain(t *testing.T) { 83 dbName := uuid.New().String() 84 testDB := dbm.NewDB(dbName, "leveldb", dbName) 85 registerContract(testDB) 86 defer os.RemoveAll(dbName) 87 88 contractView := state.NewContractViewpoint() 89 // rollback 90 contractView.DetachEntries[hash] = append(txID1.Bytes(), program...) 91 // register again 92 contractView.AttachEntries[hash] = append(txID1.Bytes(), program...) 93 if err := setContractView(testDB, contractView); err != nil { 94 t.Errorf("set contract view failed") 95 } 96 97 assertDBContractData(testDB, txID1, t) 98 } 99 100 func TestRollbackAndRegisterByAnotherTx(t *testing.T) { 101 dbName := uuid.New().String() 102 testDB := dbm.NewDB(dbName, "leveldb", dbName) 103 registerContract(testDB) 104 defer os.RemoveAll(dbName) 105 106 contractView := state.NewContractViewpoint() 107 // rollback 108 contractView.DetachEntries[hash] = append(txID1.Bytes(), program...) 109 // register by another transaction 110 contractView.AttachEntries[hash] = append(txID2.Bytes(), program...) 111 if err := setContractView(testDB, contractView); err != nil { 112 t.Errorf("set contract view failed") 113 } 114 115 assertDBContractData(testDB, txID2, t) 116 } 117 118 func TestRepeatRegisterAndRollback(t *testing.T) { 119 dbName := uuid.New().String() 120 testDB := dbm.NewDB(dbName, "leveldb", dbName) 121 registerContract(testDB) 122 defer os.RemoveAll(dbName) 123 124 // repeat register 125 contractView := state.NewContractViewpoint() 126 contractView.AttachEntries[hash] = append(txID2.Bytes(), program...) 127 if err := setContractView(testDB, contractView); err != nil { 128 t.Errorf("set contract view failed") 129 } 130 131 assertDBContractData(testDB, txID1, t) 132 133 // rollback by repeat register transaction 134 contractView = state.NewContractViewpoint() 135 contractView.DetachEntries[hash] = append(txID2.Bytes(), program...) 136 if err := setContractView(testDB, contractView); err != nil { 137 t.Errorf("set contract view failed") 138 } 139 140 assertDBContractData(testDB, txID1, t) 141 }