这是indexloc提供的服务,不要输入任何密码
Skip to content
This repository was archived by the owner on Mar 30, 2018. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
<!--- Provide a general summary of your changes in the Title above -->
<!-- Provide a general summary of your changes in the Title above -->

## Description
<!--- Describe your changes in detail. -->
<!-- Describe your changes in detail. -->

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
<!-- Why is this change required? What problem does it solve? -->
<!-- If it fixes an open issue, please link to the issue here. -->
Fixes #

## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- If this PR does not contain a new test case, explain why. -->
<!-- If this PR does not contain a new test case, explain why. -->
<!-- Describe in detail how you tested your changes. -->

## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [] I have added a [Signed-off-by](https://github.com/hyperledger/fabric/blob/master/CONTRIBUTING.md#legal-stuff)
- [] Either no new documentation is required by this change, OR I added new documentation
- [] Either no new tests are required by this change, OR I added new tests
- [] I have run [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports), [go vet](https://golang.org/cmd/vet/), and [golint](https://github.com/golang/lint). I have cleaned up all valid errors and warnings in code I have added or modified. These tools may generate false positives. Don't be worried about ignoring some errors or warnings. The goal is clean, consistent, and readable code.
<!-- To check a box, and an 'x': [x] -->
<!-- To uncheck box, add a space: [ ] -->
<!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [] I have added a [Signed-off-by](https://github.com/hyperledger/fabric/blob/master/CONTRIBUTING.md#legal-stuff).
- [] I have either added documentation to cover my changes or this change requires no new documentation.
- [] I have either added unit tests to cover my changes or this change requires no new tests.
- [] I have run [golint](https://github.com/golang/lint) and have fixed valid warnings in code I have added or modified. This tool generates false positives so you may choose to ignore some warnings. The goal is clean, consistent, and readable code.

The continuous integration build process will run [make checks](https://github.com/hyperledger/fabric/blob/master/Makefile#L22) to confirm that tests pass and that code quality meets minimum standards. You may optionally run this locally as PRs will not be accepted until they pass.

Signed-off-by:
17 changes: 17 additions & 0 deletions core/chaincode/chaincode_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"bytes"
"fmt"
"io"
"strconv"
"sync"
"time"

Expand Down Expand Up @@ -129,6 +130,21 @@ func NewChaincodeSupport(chainname ChainName, getPeerEndpoint func() (*pb.PeerEn
s.peerTLSSvrHostOrd = viper.GetString("peer.tls.serverhostoverride")
}

kadef := 0
if ka := viper.GetString("chaincode.keepalive"); ka == "" {
s.keepalive = time.Duration(kadef) * time.Second
} else {
t, terr := strconv.Atoi(ka)
if terr != nil {
chaincodeLogger.Errorf("Invalid keepalive value %s (%s) defaulting to %d", ka, terr, kadef)
t = kadef
} else if t <= 0 {
chaincodeLogger.Debugf("Turn off keepalive(value %s)", ka)
t = kadef
}
s.keepalive = time.Duration(t) * time.Second
}

return s
}

Expand All @@ -153,6 +169,7 @@ type ChaincodeSupport struct {
peerTLSCertFile string
peerTLSKeyFile string
peerTLSSvrHostOrd string
keepalive time.Duration
}

// DuplicateChaincodeHandlerError returned if attempt to register same chaincodeID while a stream already exists.
Expand Down
5 changes: 5 additions & 0 deletions core/chaincode/chaincodetest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,11 @@ chaincode:
# the image
installpath: /opt/gopath/bin/

#keepalive in seconds. In situations where the communiction goes through a
#proxy that does not support keep-alive, this parameter will maintain connection
#between peer and chaincode.
#A value <= 0 turns keepalive off
keepalive: 1
###############################################################################
#
# Ledger section - ledger configuration encompases both the blockchain
Expand Down
3 changes: 3 additions & 0 deletions core/chaincode/exectransaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,9 @@ func TestExecuteInvokeTransaction(t *testing.T) {
//TLS is on by default. This is the ONLY test that does NOT use TLS
viper.Set("peer.tls.enabled", false)

//turn OFF keepalive. All other tests use keepalive
viper.Set("peer.chaincode.keepalive", "0")

if viper.GetBool("peer.tls.enabled") {
creds, err := credentials.NewServerTLSFromFile(viper.GetString("peer.tls.cert.file"), viper.GetString("peer.tls.key.file"))
if err != nil {
Expand Down
34 changes: 34 additions & 0 deletions core/chaincode/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,16 @@ func (handler *Handler) triggerNextState(msg *pb.ChaincodeMessage, send bool) {
handler.nextState <- &nextStateInfo{msg, send}
}

func (handler *Handler) waitForKeepaliveTimer() <-chan time.Time {
if handler.chaincodeSupport.keepalive > 0 {
c := time.After(handler.chaincodeSupport.keepalive)
return c
}
//no one will signal this channel, listner blocks forever
c := make(chan time.Time, 1)
return c
}

func (handler *Handler) processStream() error {
defer handler.deregister()
msgAvail := make(chan *pb.ChaincodeMessage)
Expand Down Expand Up @@ -307,6 +317,13 @@ func (handler *Handler) processStream() error {

// we can spin off another Recv again
recv = true

if in.Type == pb.ChaincodeMessage_KEEPALIVE {
chaincodeLogger.Debug("Received KEEPALIVE Response")
// Received a keep alive message, we don't do anything with it for now
// and it does not touch the state machine
continue
}
case nsInfo = <-handler.nextState:
in = nsInfo.msg
if in == nil {
Expand All @@ -315,12 +332,29 @@ func (handler *Handler) processStream() error {
return err
}
chaincodeLogger.Debugf("[%s]Move state message %s", shortuuid(in.Uuid), in.Type.String())
case <-handler.waitForKeepaliveTimer():
if handler.chaincodeSupport.keepalive <= 0 {
chaincodeLogger.Errorf("Invalid select: keepalive not on (keepalive=%d)", handler.chaincodeSupport.keepalive)
continue
}

//TODO we could use this to hook into container lifecycle (kill the chaincode if not in use, etc)
kaerr := handler.serialSend(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_KEEPALIVE})
if kaerr != nil {
chaincodeLogger.Errorf("Error sending keepalive, err=%s", kaerr)
} else {
chaincodeLogger.Debug("Sent KEEPALIVE request")
}
//keepalive message kicked in. just continue
continue
}

err = handler.HandleMessage(in)
if err != nil {
chaincodeLogger.Errorf("[%s]Error handling message, ending stream: %s", shortuuid(in.Uuid), err)
return fmt.Errorf("Error handling message, ending stream: %s", err)
}

if nsInfo != nil && nsInfo.sendToCC {
chaincodeLogger.Debugf("[%s]sending state message %s", shortuuid(in.Uuid), in.Type.String())
if err = handler.serialSend(in); err != nil {
Expand Down
11 changes: 9 additions & 2 deletions core/chaincode/shim/chaincode.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,14 @@ func chatWithPeer(chaincodename string, stream PeerChaincodeStream, cc Chaincode
err = fmt.Errorf("Error handling message: %s", err)
return
}
if nsInfo != nil && nsInfo.sendToCC {
chaincodeLogger.Debugf("[%s]send state message %s", shortuuid(in.Uuid), in.Type.String())

//keepalive messages are PONGs to the fabric's PINGs
if (nsInfo != nil && nsInfo.sendToCC) || (in.Type == pb.ChaincodeMessage_KEEPALIVE) {
if in.Type == pb.ChaincodeMessage_KEEPALIVE {
chaincodeLogger.Debug("Sending KEEPALIVE response")
} else {
chaincodeLogger.Debugf("[%s]send state message %s", shortuuid(in.Uuid), in.Type.String())
}
if err = handler.serialSend(in); err != nil {
err = fmt.Errorf("Error sending %s: %s", in.Type.String(), err)
return
Expand Down Expand Up @@ -832,6 +838,7 @@ func (stub *ChaincodeStub) insertRowInternal(tableName string, row Row, update b
}

// ------------- ChaincodeEvent API ----------------------

// SetEvent saves the event to be sent when a transaction is made part of a block
func (stub *ChaincodeStub) SetEvent(name string, payload []byte) error {
stub.chaincodeEvent = &pb.ChaincodeEvent{EventName: name, Payload: payload}
Expand Down
5 changes: 5 additions & 0 deletions core/chaincode/shim/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,11 @@ func (handler *Handler) handleQueryChaincode(chaincodeName string, function stri

// handleMessage message handles loop for shim side of chaincode/validator stream.
func (handler *Handler) handleMessage(msg *pb.ChaincodeMessage) error {
if msg.Type == pb.ChaincodeMessage_KEEPALIVE {
// Received a keep alive message, we don't do anything with it for now
// and it does not touch the state machine
return nil
}
chaincodeLogger.Debugf("[%s]Handling ChaincodeMessage of type: %s(state:%s)", shortuuid(msg.Uuid), msg.Type, handler.FSM.Current())
if handler.FSM.Cannot(msg.Type.String()) {
errStr := fmt.Sprintf("[%s]Chaincode handler FSM cannot handle message (%s) with payload size (%d) while in state: %s", msg.Uuid, msg.Type.String(), len(msg.Payload), handler.FSM.Current())
Expand Down
8 changes: 8 additions & 0 deletions peer/core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,14 @@ chaincode:
# the image
installpath: /opt/gopath/bin/

# keepalive in seconds. In situations where the communiction goes through a
# proxy that does not support keep-alive, this parameter will maintain connection
# between peer and chaincode.
# A value <= 0 turns keepalive off
keepalive: 0

###############################################################################
#
###############################################################################
#
# Ledger section - ledger configuration encompases both the blockchain
Expand Down
2 changes: 1 addition & 1 deletion protos/api.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions protos/chaincode.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions protos/chaincode.proto
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ message ChaincodeMessage {
RANGE_QUERY_STATE = 17;
RANGE_QUERY_STATE_NEXT = 18;
RANGE_QUERY_STATE_CLOSE = 19;
KEEPALIVE = 20;
}

Type type = 1;
Expand Down