github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/examples/chaincode/go/utxo/util/utxo_test.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package util 18 19 import ( 20 "encoding/base64" 21 "encoding/hex" 22 "fmt" 23 "io/ioutil" 24 "strings" 25 "sync" 26 "testing" 27 28 "github.com/golang/protobuf/proto" 29 "github.com/hyperledger/fabric/examples/chaincode/go/utxo/consensus" 30 ) 31 32 // func TestMain(m *testing.M) { 33 // // viper.Set("ledger.blockchain.deploy-system-chaincode", "false") 34 // 35 // os.Exit(m.Run()) 36 // } 37 38 const txFileHashes = "./Hashes_for_first_500_transactions_on_testnet3.txt" 39 const txFile = "./First_500_transactions_base64_encoded_on_testnet3.txt" 40 41 const consensusScriptVerifyTx = "01000000017d01943c40b7f3d8a00a2d62fa1d560bf739a2368c180615b0a7937c0e883e7c000000006b4830450221008f66d188c664a8088893ea4ddd9689024ea5593877753ecc1e9051ed58c15168022037109f0d06e6068b7447966f751de8474641ad2b15ec37f4a9d159b02af68174012103e208f5403383c77d5832a268c9f71480f6e7bfbdfa44904becacfad66163ea31ffffffff01c8af0000000000001976a91458b7a60f11a904feef35a639b6048de8dd4d9f1c88ac00000000" 42 const consensusScriptVerifyPreviousOutputScript = "76a914c564c740c6900b93afc9f1bdaef0a9d466adf6ee88ac" 43 44 type block struct { 45 transactions []string 46 } 47 48 func makeBlock() *block { 49 //return &block{transactions: make([]string, 0)} 50 return &block{} 51 } 52 53 func (b *block) addTxAsBase64String(txAsString string) error { 54 b.transactions = append(b.transactions, txAsString) 55 return nil 56 } 57 58 //getTransactionsAsUTXOBytes returns a readonly channel of the transactions within this block as UTXO []byte 59 func (b *block) getTransactionsAsUTXOBytes() <-chan []byte { 60 resChannel := make(chan []byte) 61 go func() { 62 defer close(resChannel) 63 for _, txAsText := range b.transactions { 64 data, err := base64.StdEncoding.DecodeString(txAsText) 65 if err != nil { 66 panic(fmt.Errorf("Could not decode transaction (%s) into bytes use base64 decoding: %s\n", txAsText, err)) 67 } 68 resChannel <- data 69 } 70 }() 71 return resChannel 72 } 73 74 var blocksFromFile []*block 75 var once sync.Once 76 77 // getBlocks returns the blocks parsed from txFile, but only parses once. 78 func getBlocks() ([]*block, error) { 79 var err error 80 once.Do(func() { 81 contents, err := ioutil.ReadFile(txFile) 82 if err != nil { 83 return 84 } 85 lines := strings.Split(string(contents), string('\n')) 86 var currBlock *block 87 for _, line := range lines { 88 if strings.HasPrefix(line, "Block") { 89 currBlock = makeBlock() 90 blocksFromFile = append(blocksFromFile, currBlock) 91 } else { 92 // Trim out the 'Transacion XX:' part 93 //currBlock.addTxAsBase64String(strings.Split(line, ": ")[1]) 94 currBlock.addTxAsBase64String(line) 95 } 96 } 97 }) 98 99 return blocksFromFile, err 100 } 101 102 func TestVerifyScript_InvalidTranscation(t *testing.T) { 103 arg1 := []byte("arg1") 104 arg2 := int64(4) 105 arg3 := []byte("arg2") 106 arg4 := int64(4) 107 arg5 := uint(100) 108 arg6 := uint(1) 109 //func Verify_script(arg1 *byte, arg2 int64, arg3 *byte, arg4 int64, arg5 uint, arg6 uint) (_swig_ret LibbitcoinConsensusVerify_result_type) 110 result := consensus.Verify_script(&arg1[0], arg2, &arg3[0], arg4, arg5, arg6) 111 t.Log(result) 112 t.Log(consensus.Verify_result_tx_invalid) 113 if result != consensus.Verify_result_tx_invalid { 114 t.Fatalf("Should have failed to verify transaction") 115 } 116 } 117 118 func TestParse_GetBlocksFromFile(t *testing.T) { 119 blocks, err := getBlocks() 120 if err != nil { 121 t.Fatalf("Error getting blocks from tx file: %s", err) 122 } 123 for index, b := range blocks { 124 t.Logf("block %d has len transactions = %d", index, len(b.transactions)) 125 } 126 t.Logf("Number of blocks = %d from file %s", len(blocks), txFile) 127 } 128 129 //TestBlocks_GetTransactionsAsUTXOBytes will range over blocks and then transactions in UTXO bytes form. 130 func TestBlocks_GetTransactionsAsUTXOBytes(t *testing.T) { 131 blocks, err := getBlocks() 132 if err != nil { 133 t.Fatalf("Error getting blocks from tx file: %s", err) 134 } 135 // Loop through the blocks and then range over their transactions in UTXO bytes form. 136 for index, b := range blocks { 137 t.Logf("block %d has len transactions = %d", index, len(b.transactions)) 138 for txAsUTXOBytes := range b.getTransactionsAsUTXOBytes() { 139 //t.Logf("Tx as bytes = %v", txAsUTXOBytes) 140 _ = len(txAsUTXOBytes) 141 } 142 } 143 } 144 145 func TestParse_UTXOTransactionBytes(t *testing.T) { 146 blocks, err := getBlocks() 147 if err != nil { 148 t.Fatalf("Error getting blocks from tx file: %s", err) 149 } 150 utxo := MakeUTXO(MakeInMemoryStore()) 151 // Loop through the blocks and then range over their transactions in UTXO bytes form. 152 for index, b := range blocks { 153 t.Logf("block %d has len transactions = %d", index, len(b.transactions)) 154 for txAsUTXOBytes := range b.getTransactionsAsUTXOBytes() { 155 156 newTX := ParseUTXOBytes(txAsUTXOBytes) 157 t.Logf("Block = %d, txInputCount = %d, outputCount=%d", index, len(newTX.Txin), len(newTX.Txout)) 158 159 // Now store the HEX of txHASH 160 execResult, err := utxo.Execute(txAsUTXOBytes) 161 if err != nil { 162 t.Fatalf("Error executing TX: %s", err) 163 } 164 if execResult.IsCoinbase == false { 165 if execResult.SumCurrentOutputs > execResult.SumPriorOutputs { 166 t.Fatalf("sumOfCurrentOutputs > sumOfPriorOutputs: sumOfCurrentOutputs = %d, sumOfPriorOutputs = %d", execResult.SumCurrentOutputs, execResult.SumPriorOutputs) 167 } 168 } 169 170 txHash := utxo.GetTransactionHash(txAsUTXOBytes) 171 retrievedTx := utxo.Query(hex.EncodeToString(txHash)) 172 if !proto.Equal(newTX, retrievedTx) { 173 t.Fatal("Expected TX to be equal. ") 174 } 175 } 176 } 177 178 } 179 180 func TestParse_LibbitconTX(t *testing.T) { 181 txData, err := hex.DecodeString(consensusScriptVerifyTx) 182 if err != nil { 183 t.Fatalf("Error decoding HEX tx from libbitcoin: %s", err) 184 return 185 } 186 187 prevTxScript, err := hex.DecodeString(consensusScriptVerifyPreviousOutputScript) 188 if err != nil { 189 t.Fatalf("Error decoding HEX tx from libbitcoin: %s", err) 190 return 191 } 192 193 t.Logf("TX data from libbitcoin: %v", txData) 194 195 tx := ParseUTXOBytes(txData) 196 197 // Call Verify_script 198 txInputIndex := uint(0) 199 result := consensus.Verify_script(&txData[0], int64(len(txData)), &prevTxScript[0], int64(len(prevTxScript)), txInputIndex, uint(consensus.Verify_flags_p2sh)) 200 if result != consensus.Verify_result_eval_true { 201 t.Fatalf("Unexpected result from verify_script, expected %d, got %d", consensus.Verify_result_eval_true, result) 202 } 203 t.Log(result) 204 t.Log(consensus.Verify_result_eval_true) 205 t.Logf("TX from %v", tx) 206 }