github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/core/ledger/kvledger/example/main/example.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 main 18 19 import ( 20 "fmt" 21 "os" 22 23 "github.com/hyperledger/fabric/core/ledger" 24 "github.com/hyperledger/fabric/core/ledger/kvledger/example" 25 "github.com/hyperledger/fabric/core/ledger/ledgerconfig" 26 "github.com/hyperledger/fabric/core/ledger/ledgermgmt" 27 "github.com/hyperledger/fabric/core/ledger/testutil" 28 "github.com/hyperledger/fabric/core/ledger/util" 29 "github.com/hyperledger/fabric/protos/common" 30 logging "github.com/op/go-logging" 31 ) 32 33 var logger = logging.MustGetLogger("main") 34 35 const ( 36 ledgerID = "Default" 37 ) 38 39 var peerLedger ledger.PeerLedger 40 var app *example.App 41 var committer *example.Committer 42 var consenter *example.Consenter 43 44 var accounts = []string{"account1", "account2", "account3", "account4"} 45 46 func init() { 47 48 //call a helper method to load the core.yaml 49 testutil.SetupCoreYAMLConfig("./../../../../../peer") 50 51 // Initialization will get a handle to the ledger at the specified path 52 // Note, if subledgers are supported in the future, 53 // the various ledgers could be created/managed at this level 54 cleanup() 55 ledgermgmt.Initialize() 56 var err error 57 peerLedger, err = ledgermgmt.CreateLedger(ledgerID) 58 if err != nil { 59 panic(fmt.Errorf("Error in NewKVLedger(): %s", err)) 60 } 61 app = example.ConstructAppInstance(peerLedger) 62 committer = example.ConstructCommitter(peerLedger) 63 consenter = example.ConstructConsenter() 64 } 65 66 func main() { 67 defer ledgermgmt.Close() 68 69 // Each of the functions here will emulate endorser, orderer, 70 // and committer by calling ledger APIs to similate the proposal, 71 // get simulation results, create a transaction, add it to a block, 72 // and then commit the block. 73 74 // Initialize account balances by setting each account to 100 75 initApp() 76 77 printBalances() 78 79 // Transfer money between accounts. Exercises happy path. 80 transferFunds() 81 82 printBalances() 83 84 // Attempt to transfer more money than account balance 85 // Exercises simulation failure 86 tryInvalidTransfer() 87 88 // Attempt two transactions, the first one will have sufficient funds, 89 // the second one should fail since the account balance was updated 90 // (by the first tran) since simulation time. This exercises the MVCC check. 91 tryDoubleSpend() 92 93 printBalances() 94 } 95 96 func initApp() { 97 logger.Debug("Entering initApp()") 98 tx, err := app.Init(map[string]int{ 99 accounts[0]: 100, 100 accounts[1]: 100, 101 accounts[2]: 100, 102 accounts[3]: 100}) 103 handleError(err, true) 104 rawBlock := consenter.ConstructBlock(tx) 105 err = committer.Commit(rawBlock) 106 handleError(err, true) 107 printBlocksInfo(rawBlock) 108 logger.Debug("Exiting initApp()") 109 } 110 111 func transferFunds() { 112 logger.Debug("Entering transferFunds()") 113 tx1, err := app.TransferFunds("account1", "account2", 50) 114 handleError(err, true) 115 tx2, err := app.TransferFunds("account3", "account4", 50) 116 handleError(err, true) 117 118 // act as ordering service (consenter) to create a Raw Block from the Transaction 119 rawBlock := consenter.ConstructBlock(tx1, tx2) 120 121 // act as committing peer to commit the Raw Block 122 err = committer.Commit(rawBlock) 123 handleError(err, true) 124 printBlocksInfo(rawBlock) 125 logger.Debug("Exiting transferFunds") 126 } 127 128 func tryInvalidTransfer() { 129 logger.Debug("Entering tryInvalidTransfer()") 130 _, err := app.TransferFunds("account1", "account2", 60) 131 handleError(err, false) 132 logger.Debug("Exiting tryInvalidTransfer()") 133 } 134 135 func tryDoubleSpend() { 136 logger.Debug("Entering tryDoubleSpend()") 137 tx1, err := app.TransferFunds("account1", "account2", 50) 138 handleError(err, true) 139 tx2, err := app.TransferFunds("account1", "account4", 50) 140 handleError(err, true) 141 rawBlock := consenter.ConstructBlock(tx1, tx2) 142 err = committer.Commit(rawBlock) 143 handleError(err, true) 144 printBlocksInfo(rawBlock) 145 logger.Debug("Exiting tryDoubleSpend()") 146 } 147 148 func printBlocksInfo(block *common.Block) { 149 logger.Debug("Entering printBlocksInfo()") 150 // Read invalid transactions filter 151 txsFltr := util.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) 152 numOfInvalid := 0 153 // Count how many transaction indeed invalid 154 for i := 0; i < len(block.Data.Data); i++ { 155 if txsFltr.IsInvalid(i) { 156 numOfInvalid++ 157 } 158 } 159 fmt.Printf("Num txs in rawBlock = [%d], num invalidTxs = [%d]\n", 160 len(block.Data.Data), numOfInvalid) 161 logger.Debug("Exiting printBlocksInfo()") 162 } 163 164 func printBalances() { 165 logger.Debug("Entering printBalances()") 166 balances, err := app.QueryBalances(accounts) 167 handleError(err, true) 168 for i := 0; i < len(accounts); i++ { 169 fmt.Printf("[%s] = [%d]\n", accounts[i], balances[i]) 170 } 171 logger.Debug("Exiting printBalances()") 172 } 173 174 func handleError(err error, quit bool) { 175 if err != nil { 176 if quit { 177 panic(fmt.Errorf("Error: %s\n", err)) 178 } else { 179 fmt.Printf("Error: %s\n", err) 180 } 181 } 182 } 183 184 func cleanup() { 185 ledgerRootPath := ledgerconfig.GetRootPath() 186 os.RemoveAll(ledgerRootPath) 187 }