Skip to content

Commit

Permalink
Use SHA256 TXID instead of UUID
Browse files Browse the repository at this point in the history
This squashed changeset does the following:
 - It renames UUID to TXID in the code (Go/Java), in tests,
   in proto files, in all chaincode related files
 - It uses all the arguments of the chaincode to
   generate the TXID

Change-Id: Iae6f1fb45c12c2652d9ad18451e75ea1f91fe9a3
Signed-off-by: Gabor Hosszu <gabor@digitalasset.com>
  • Loading branch information
gaborh-da committed Aug 8, 2016
1 parent f062bd5 commit c950903
Show file tree
Hide file tree
Showing 43 changed files with 718 additions and 670 deletions.
14 changes: 7 additions & 7 deletions bddtests/peer_basic.feature
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ Feature: Network of Peers
# @doNotDecompose
# @wip
# Arg[0] = a, base64 = 'YQ=='
# sha256 = 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb'
# sha256 = 'acfb280369a87a57b1954210081d78943f1a0adb5368184984e8852a42c14df8'
# calculated using all the args
Scenario: chaincode map single peer content generated ID
Given we compose "docker-compose-1.yml"
When requesting "/chain" from "vp0"
Expand All @@ -361,12 +362,12 @@ Feature: Network of Peers
Then I should have received a chaincode name
Then I wait up to "60" seconds for transaction to be committed to all peers

When I invoke chaincode "map" function name "put" on "vp0" with "sha256base64"
When I invoke chaincode "map" function name "put" on "vp0" with "sha256"
| arg1 |arg2|
| YQ== | 10 |
Then I should have received a transactionID
Then I wait up to "25" seconds for transaction to be committed to all peers
Then I check the transaction ID if it is "ca978112-ca1b-bdca-fac2-31b39a23dc4d"
Then I check the transaction ID if it is "acfb280369a87a57b1954210081d78943f1a0adb5368184984e8852a42c14df8"

Scenario: chaincode example 01 single peer rejection message
Given we compose "docker-compose-1-exp.yml"
Expand Down Expand Up @@ -1106,7 +1107,7 @@ Feature: Network of Peers


@issue_1942
#@doNotDecompose
# @doNotDecompose
Scenario: chaincode example02 with 4 peers, stop and start alternates, reverse
Given we compose "docker-compose-4-consensus-batch.yml"
And I register with CA supplying username "binhn" and secret "7avZQLwcUe9q" on peers:
Expand Down Expand Up @@ -1152,15 +1153,14 @@ Scenario: chaincode example02 with 4 peers, stop and start alternates, reverse

Given I start peers:
| vp2 |
And I wait "30" seconds

And I wait "30" seconds
Given I stop peers:
| vp1 |
When I invoke chaincode "example2" function name "invoke" on "vp3" "20" times
|arg1|arg2|arg3|
| a | b | 1 |
Then I should have received a transactionID
Then I wait up to "300" seconds for transaction to be committed to peers:
Then I wait up to "300" seconds for transactions to be committed to peers:
| vp0 | vp2 | vp3 |

When I query chaincode "example2" function name "query" with value "a" on peers:
Expand Down
49 changes: 49 additions & 0 deletions bddtests/steps/peer_basic_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,12 @@ def step_impl(context, chaincodeName, functionName, containerName, idGenAlg):
@when(u'I invoke chaincode "{chaincodeName}" function name "{functionName}" on "{containerName}" "{times}" times')
def step_impl(context, chaincodeName, functionName, containerName, times):
assert 'chaincodeSpec' in context, "chaincodeSpec not found in context"
ipAddress = bdd_test_util.ipFromContainerNamePart(containerName, context.compose_containers)
request_url = buildUrl(context, ipAddress, "/chain")
resp = requests.get(request_url, headers={'Accept': 'application/json'}, verify=False)
assert resp.status_code == 200, "Failed to get chain height %s: %s" % (request_url,resp.text)
context.chainheight = getAttributeFromJSON("height", resp.json(), "Height not found in response.")
context.txcount = times
for i in range(int(times)):
invokeChaincode(context, "invoke", functionName, containerName)

Expand Down Expand Up @@ -577,6 +583,49 @@ def step_impl(context, seconds):
print("Result of request to all peers = {0}".format(respMap))
print("")

@then(u'I wait up to "{seconds}" seconds for transactions to be committed to peers')
def step_impl(context, seconds):
assert 'chainheight' in context, "chainheight not found in context"
assert 'txcount' in context, "txcount not found in context"
assert 'compose_containers' in context, "compose_containers not found in context"
assert 'table' in context, "table (of peers) not found in context"

aliases = context.table.headings
containerDataList = bdd_test_util.getContainerDataValuesFromContext(context, aliases, lambda containerData: containerData)

# Build map of "containerName" : resp.statusCode
respMap = {container.containerName:0 for container in containerDataList}

# Set the max time before stopping attempts
maxTime = datetime.now() + timedelta(seconds = int(seconds))
for container in containerDataList:
ipAddress = container.ipAddress
request_url = buildUrl(context, ipAddress, "/chain")

# Loop unless failure or time exceeded
while (datetime.now() < maxTime):
print("{0} GETing path = {1}".format(currentTime(), request_url))
resp = requests.get(request_url, headers={'Accept': 'application/json'}, verify=False)
if resp.status_code == 404:
# Pause then try again
respMap[container.containerName] = 404
time.sleep(1)
continue
elif resp.status_code == 200:
height = getAttributeFromJSON("height", resp.json(), "Height not found in response.")
if height >= int(context.chainheight) + int(context.txcount):
# Success, continue
respMap[container.containerName] = 200
break
else:
continue
else:
raise Exception("Error requesting {0}, returned result code = {1}".format(request_url, resp.status_code))
else:
raise Exception("Max time exceeded waiting for transactions with current response map = {0}".format(respMap))
print("Result of request to all peers = {0}".format(respMap))
print("")


@then(u'I should get a rejection message in the listener after stopping it')
def step_impl(context):
Expand Down
4 changes: 2 additions & 2 deletions bddtests/syschaincode/noop/chaincode.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
var logger = shim.NewLogger("noop")

type ledgerHandler interface {
GetTransactionByUUID(txUUID string) (*protos.Transaction, error)
GetTransactionByID(txID string) (*protos.Transaction, error)
}

// SystemChaincode is type representing the chaincode
Expand Down Expand Up @@ -86,7 +86,7 @@ func (t *SystemChaincode) Query(stub *shim.ChaincodeStub, function string, args
logger.Infof("--> %x", args[0])

var txHashHex = args[0]
var tx, txerr = t.getLedger().GetTransactionByUUID(txHashHex)
var tx, txerr = t.getLedger().GetTransactionByID(txHashHex)
if nil != txerr || nil == tx {
return nil, txerr
}
Expand Down
4 changes: 2 additions & 2 deletions bddtests/syschaincode/noop/chaincode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ func TestQueryGetTranExisting(t *testing.T) {
type mockLedger struct {
}

func (ml mockLedger) GetTransactionByUUID(txUUID string) (*protos.Transaction, error) {
if txUUID == "noSuchTX" {
func (ml mockLedger) GetTransactionByID(txID string) (*protos.Transaction, error) {
if txID == "noSuchTX" {
return nil, fmt.Errorf("Some error")
}
newCCIS := &protos.ChaincodeInvocationSpec{ChaincodeSpec: &protos.ChaincodeSpec{CtorMsg: &protos.ChaincodeInput{Function: "execute", Args: []string{something}}}}
Expand Down
2 changes: 1 addition & 1 deletion consensus/helper/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (eng *EngineImpl) ProcessTransactionMsg(msg *pb.Message, tx *pb.Transaction
}
} else {
// Chaincode Transaction
response = &pb.Response{Status: pb.Response_SUCCESS, Msg: []byte(tx.Uuid)}
response = &pb.Response{Status: pb.Response_SUCCESS, Msg: []byte(tx.Txid)}

//TODO: Do we need to verify security, or can we supply a flag on the invoke ot this functions
// If we fail to marshal or verify the tx, don't send it to consensus plugin
Expand Down
4 changes: 2 additions & 2 deletions consensus/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,9 @@ func (h *Helper) ExecTxs(id interface{}, txs []*pb.Transaction) ([]byte, error)
for i, e := range txerrs {
//NOTE- it'll be nice if we can have error values. For now success == 0, error == 1
if txerrs[i] != nil {
txresults[i] = &pb.TransactionResult{Uuid: txs[i].Uuid, Error: e.Error(), ErrorCode: 1, ChaincodeEvent: ccevents[i]}
txresults[i] = &pb.TransactionResult{Txid: txs[i].Txid, Error: e.Error(), ErrorCode: 1, ChaincodeEvent: ccevents[i]}
} else {
txresults[i] = &pb.TransactionResult{Uuid: txs[i].Uuid, ChaincodeEvent: ccevents[i]}
txresults[i] = &pb.TransactionResult{Txid: txs[i].Txid, ChaincodeEvent: ccevents[i]}
}
}
h.curBatchErrs = append(h.curBatchErrs, txresults...) // TODO, remove after issue 579
Expand Down
2 changes: 1 addition & 1 deletion consensus/noops/noops.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (i *Noops) RecvMsg(msg *pb.Message, senderHandle *pb.PeerID) error {
return err
}
if logger.IsEnabledFor(logging.DEBUG) {
logger.Debugf("Sending to channel tx uuid: %s", tx.Uuid)
logger.Debugf("Sending to channel tx uuid: %s", tx.Txid)
}
i.channel <- tx
}
Expand Down
6 changes: 3 additions & 3 deletions consensus/pbft/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ func (op *obcBatch) execute(seqNo uint64, reqBatch *RequestBatch) {
logger.Warningf("Batch replica %d could not unmarshal transaction %s", op.pbft.id, err)
continue
}
logger.Debugf("Batch replica %d executing request with transaction %s from outstandingReqs, seqNo=%d", op.pbft.id, tx.Uuid, seqNo)
logger.Debugf("Batch replica %d executing request with transaction %s from outstandingReqs, seqNo=%d", op.pbft.id, tx.Txid, seqNo)
if outstanding, pending := op.reqStore.remove(req); !outstanding || !pending {
logger.Debugf("Batch replica %d missing transaction %s outstanding=%v, pending=%v", op.pbft.id, tx.Uuid, outstanding, pending)
logger.Debugf("Batch replica %d missing transaction %s outstanding=%v, pending=%v", op.pbft.id, tx.Txid, outstanding, pending)
}
txs = append(txs, tx)
op.deduplicator.Execute(req)
Expand Down Expand Up @@ -314,7 +314,7 @@ func (op *obcBatch) logAddTxFromRequest(req *Request) {
if err != nil {
logger.Errorf("Replica %d was sent a transaction which did not unmarshal: %s", op.pbft.id, err)
} else {
logger.Debugf("Replica %d adding request from %d with transaction %s into outstandingReqs", op.pbft.id, req.ReplicaId, tx.Uuid)
logger.Debugf("Replica %d adding request from %d with transaction %s into outstandingReqs", op.pbft.id, req.ReplicaId, tx.Txid)
}
}
}
Expand Down
30 changes: 15 additions & 15 deletions core/chaincode/chaincode_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func (chaincodeSupport *ChaincodeSupport) registerHandler(chaincodehandler *Hand

//now we are ready to receive messages and send back responses
chaincodehandler.txCtxs = make(map[string]*transactionContext)
chaincodehandler.uuidMap = make(map[string]bool)
chaincodehandler.txidMap = make(map[string]bool)
chaincodehandler.isTransaction = make(map[string]bool)

chaincodeLogger.Debugf("registered handler complete for chaincode %s", key)
Expand Down Expand Up @@ -243,7 +243,7 @@ func (chaincodeSupport *ChaincodeSupport) deregisterHandler(chaincodehandler *Ha
}

// Based on state of chaincode send either init or ready to move to ready state
func (chaincodeSupport *ChaincodeSupport) sendInitOrReady(context context.Context, uuid string, chaincode string, f *string, initArgs []string, timeout time.Duration, tx *pb.Transaction, depTx *pb.Transaction) error {
func (chaincodeSupport *ChaincodeSupport) sendInitOrReady(context context.Context, txid string, chaincode string, f *string, initArgs []string, timeout time.Duration, tx *pb.Transaction, depTx *pb.Transaction) error {
chaincodeSupport.runningChaincodes.Lock()
//if its in the map, there must be a connected stream...nothing to do
var chrte *chaincodeRTEnv
Expand All @@ -257,7 +257,7 @@ func (chaincodeSupport *ChaincodeSupport) sendInitOrReady(context context.Contex

var notfy chan *pb.ChaincodeMessage
var err error
if notfy, err = chrte.handler.initOrReady(uuid, f, initArgs, tx, depTx); err != nil {
if notfy, err = chrte.handler.initOrReady(txid, f, initArgs, tx, depTx); err != nil {
return fmt.Errorf("Error sending %s: %s", pb.ChaincodeMessage_INIT, err)
}
if notfy != nil {
Expand All @@ -272,7 +272,7 @@ func (chaincodeSupport *ChaincodeSupport) sendInitOrReady(context context.Contex
}

//if initOrReady succeeded, our responsibility to delete the context
chrte.handler.deleteTxContext(uuid)
chrte.handler.deleteTxContext(txid)

return err
}
Expand Down Expand Up @@ -309,7 +309,7 @@ func (chaincodeSupport *ChaincodeSupport) getArgsAndEnv(cID *pb.ChaincodeID, cLa
}

// launchAndWaitForRegister will launch container if not already running. Use the targz to create the image if not found
func (chaincodeSupport *ChaincodeSupport) launchAndWaitForRegister(ctxt context.Context, cds *pb.ChaincodeDeploymentSpec, cID *pb.ChaincodeID, uuid string, cLang pb.ChaincodeSpec_Type, targz io.Reader) (bool, error) {
func (chaincodeSupport *ChaincodeSupport) launchAndWaitForRegister(ctxt context.Context, cds *pb.ChaincodeDeploymentSpec, cID *pb.ChaincodeID, txid string, cLang pb.ChaincodeSpec_Type, targz io.Reader) (bool, error) {
chaincode := cID.Name
if chaincode == "" {
return false, fmt.Errorf("chaincode name not set")
Expand Down Expand Up @@ -359,10 +359,10 @@ func (chaincodeSupport *ChaincodeSupport) launchAndWaitForRegister(ctxt context.
select {
case ok := <-notfy:
if !ok {
err = fmt.Errorf("registration failed for %s(networkid:%s,peerid:%s,tx:%s)", chaincode, chaincodeSupport.peerNetworkID, chaincodeSupport.peerID, uuid)
err = fmt.Errorf("registration failed for %s(networkid:%s,peerid:%s,tx:%s)", chaincode, chaincodeSupport.peerNetworkID, chaincodeSupport.peerID, txid)
}
case <-time.After(chaincodeSupport.ccStartupTimeout):
err = fmt.Errorf("Timeout expired while starting chaincode %s(networkid:%s,peerid:%s,tx:%s)", chaincode, chaincodeSupport.peerNetworkID, chaincodeSupport.peerID, uuid)
err = fmt.Errorf("Timeout expired while starting chaincode %s(networkid:%s,peerid:%s,tx:%s)", chaincode, chaincodeSupport.peerNetworkID, chaincodeSupport.peerID, txid)
}
if err != nil {
chaincodeLogger.Debugf("stopping due to error while launching %s", err)
Expand Down Expand Up @@ -486,7 +486,7 @@ func (chaincodeSupport *ChaincodeSupport) Launch(context context.Context, t *pb.
}

//hopefully we are restarting from existing image and the deployed transaction exists
depTx, ledgerErr = ledger.GetTransactionByUUID(chaincode)
depTx, ledgerErr = ledger.GetTransactionByID(chaincode)
if ledgerErr != nil {
return cID, cMsg, fmt.Errorf("Could not get deployment transaction for %s - %s", chaincode, ledgerErr)
}
Expand Down Expand Up @@ -514,7 +514,7 @@ func (chaincodeSupport *ChaincodeSupport) Launch(context context.Context, t *pb.
//launch container if it is a System container or not in dev mode
if (!chaincodeSupport.userRunsCC || cds.ExecEnv == pb.ChaincodeDeploymentSpec_SYSTEM) && (chrte == nil || chrte.handler == nil) {
var targz io.Reader = bytes.NewBuffer(cds.CodePackage)
_, err = chaincodeSupport.launchAndWaitForRegister(context, cds, cID, t.Uuid, cLang, targz)
_, err = chaincodeSupport.launchAndWaitForRegister(context, cds, cID, t.Txid, cLang, targz)
if err != nil {
chaincodeLogger.Errorf("launchAndWaitForRegister failed %s", err)
return cID, cMsg, err
Expand All @@ -523,7 +523,7 @@ func (chaincodeSupport *ChaincodeSupport) Launch(context context.Context, t *pb.

if err == nil {
//send init (if (f,args)) and wait for ready state
err = chaincodeSupport.sendInitOrReady(context, t.Uuid, chaincode, f, initargs, chaincodeSupport.ccStartupTimeout, t, depTx)
err = chaincodeSupport.sendInitOrReady(context, t.Txid, chaincode, f, initargs, chaincodeSupport.ccStartupTimeout, t, depTx)
if err != nil {
chaincodeLogger.Errorf("sending init failed(%s)", err)
err = fmt.Errorf("Failed to init chaincode(%s)", err)
Expand Down Expand Up @@ -615,22 +615,22 @@ func (chaincodeSupport *ChaincodeSupport) Register(stream pb.ChaincodeSupport_Re
}

// createTransactionMessage creates a transaction message.
func createTransactionMessage(uuid string, cMsg *pb.ChaincodeInput) (*pb.ChaincodeMessage, error) {
func createTransactionMessage(txid string, cMsg *pb.ChaincodeInput) (*pb.ChaincodeMessage, error) {
payload, err := proto.Marshal(cMsg)
if err != nil {
fmt.Printf(err.Error())
return nil, err
}
return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Uuid: uuid}, nil
return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSACTION, Payload: payload, Txid: txid}, nil
}

// createQueryMessage creates a query message.
func createQueryMessage(uuid string, cMsg *pb.ChaincodeInput) (*pb.ChaincodeMessage, error) {
func createQueryMessage(txid string, cMsg *pb.ChaincodeInput) (*pb.ChaincodeMessage, error) {
payload, err := proto.Marshal(cMsg)
if err != nil {
return nil, err
}
return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY, Payload: payload, Uuid: uuid}, nil
return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY, Payload: payload, Txid: txid}, nil
}

// Execute executes a transaction and waits for it to complete until a timeout value.
Expand Down Expand Up @@ -660,7 +660,7 @@ func (chaincodeSupport *ChaincodeSupport) Execute(ctxt context.Context, chaincod
}

//our responsibility to delete transaction context if sendExecuteMessage succeeded
chrte.handler.deleteTxContext(msg.Uuid)
chrte.handler.deleteTxContext(msg.Txid)

return ccresp, err
}
18 changes: 9 additions & 9 deletions core/chaincode/exectransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,12 @@ func Execute(ctxt context.Context, chain *ChaincodeSupport, t *pb.Transaction) (

var ccMsg *pb.ChaincodeMessage
if t.Type == pb.Transaction_CHAINCODE_INVOKE {
ccMsg, err = createTransactionMessage(t.Uuid, cMsg)
ccMsg, err = createTransactionMessage(t.Txid, cMsg)
if err != nil {
return nil, nil, fmt.Errorf("Failed to transaction message(%s)", err)
}
} else {
ccMsg, err = createQueryMessage(t.Uuid, cMsg)
ccMsg, err = createQueryMessage(t.Txid, cMsg)
if err != nil {
return nil, nil, fmt.Errorf("Failed to query message(%s)", err)
}
Expand All @@ -106,11 +106,11 @@ func Execute(ctxt context.Context, chain *ChaincodeSupport, t *pb.Transaction) (
} else if resp == nil {
// Rollback transaction
markTxFinish(ledger, t, false)
return nil, nil, fmt.Errorf("Failed to receive a response for (%s)", t.Uuid)
return nil, nil, fmt.Errorf("Failed to receive a response for (%s)", t.Txid)
} else {
if resp.ChaincodeEvent != nil {
resp.ChaincodeEvent.ChaincodeID = chaincode
resp.ChaincodeEvent.TxID = t.Uuid
resp.ChaincodeEvent.TxID = t.Txid
}

if resp.Type == pb.ChaincodeMessage_COMPLETED || resp.Type == pb.ChaincodeMessage_QUERY_COMPLETED {
Expand All @@ -123,7 +123,7 @@ func Execute(ctxt context.Context, chain *ChaincodeSupport, t *pb.Transaction) (
return nil, resp.ChaincodeEvent, fmt.Errorf("Transaction or query returned with failure: %s", string(resp.Payload))
}
markTxFinish(ledger, t, false)
return resp.Payload, nil, fmt.Errorf("receive a response for (%s) but in invalid state(%d)", t.Uuid, resp.Type)
return resp.Payload, nil, fmt.Errorf("receive a response for (%s) but in invalid state(%d)", t.Txid, resp.Type)
}

} else {
Expand Down Expand Up @@ -184,9 +184,9 @@ func getTimeout(cID *pb.ChaincodeID) (time.Duration, error) {
ledger, err := ledger.GetLedger()
if err == nil {
chaincodeID := cID.Name
txUUID, err := ledger.GetState(chaincodeID, "github.com_openblockchain_obc-peer_chaincode_id", true)
txID, err := ledger.GetState(chaincodeID, "github.com_openblockchain_obc-peer_chaincode_id", true)
if err == nil {
tx, err := ledger.GetTransactionByUUID(string(txUUID))
tx, err := ledger.GetTransactionByID(string(txID))
if err == nil {
chaincodeDeploymentSpec := &pb.ChaincodeDeploymentSpec{}
proto.Unmarshal(tx.Payload, chaincodeDeploymentSpec)
Expand All @@ -204,14 +204,14 @@ func markTxBegin(ledger *ledger.Ledger, t *pb.Transaction) {
if t.Type == pb.Transaction_CHAINCODE_QUERY {
return
}
ledger.TxBegin(t.Uuid)
ledger.TxBegin(t.Txid)
}

func markTxFinish(ledger *ledger.Ledger, t *pb.Transaction, successful bool) {
if t.Type == pb.Transaction_CHAINCODE_QUERY {
return
}
ledger.TxFinished(t.Uuid, successful)
ledger.TxFinished(t.Txid, successful)
}

func sendTxRejectedEvent(tx *pb.Transaction, errorMsg string) {
Expand Down
Loading

0 comments on commit c950903

Please sign in to comment.