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  }