Skip to content

Commit

Permalink
Merge "Add timeout configuration for chaincode install"
Browse files Browse the repository at this point in the history
  • Loading branch information
mastersingh24 authored and Gerrit Code Review committed Nov 8, 2019
2 parents cd97bc3 + 54f2210 commit 9b266bd
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 3 deletions.
33 changes: 32 additions & 1 deletion core/chaincode/chaincode_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type ChaincodeSupport struct {
BuiltinSCCs scc.BuiltinSCCs
DeployedCCInfoProvider ledger.DeployedChaincodeInfoProvider
ExecuteTimeout time.Duration
InstallTimeout time.Duration
HandlerMetrics *HandlerMetrics
HandlerRegistry *HandlerRegistry
Keepalive time.Duration
Expand Down Expand Up @@ -264,14 +265,44 @@ func (cs *ChaincodeSupport) execute(cctyp pb.ChaincodeMessage_Type, txParams *cc
ChannelId: txParams.ChannelID,
}

ccresp, err := h.Execute(txParams, namespace, ccMsg, cs.ExecuteTimeout)
timeout := cs.executeTimeout(namespace, input)
ccresp, err := h.Execute(txParams, namespace, ccMsg, timeout)
if err != nil {
return nil, errors.WithMessage(err, "error sending")
}

return ccresp, nil
}

func (cs *ChaincodeSupport) executeTimeout(namespace string, input *pb.ChaincodeInput) time.Duration {
operation := chaincodeOperation(input.Args)
switch {
case namespace == "lscc" && operation == "install":
return maxDuration(cs.InstallTimeout, cs.ExecuteTimeout)
case namespace == lifecycle.LifecycleNamespace && operation == lifecycle.InstallChaincodeFuncName:
return maxDuration(cs.InstallTimeout, cs.ExecuteTimeout)
default:
return cs.ExecuteTimeout
}
}

func maxDuration(durations ...time.Duration) time.Duration {
var result time.Duration
for _, d := range durations {
if d > result {
result = d
}
}
return result
}

func chaincodeOperation(args [][]byte) string {
if len(args) == 0 {
return ""
}
return string(args[0])
}

func logDevModeError(userRunsCC bool) {
if userRunsCC {
chaincodeLogger.Error("You are attempting to perform an action other than Deploy on Chaincode that is not ready and you are in developer mode. Did you forget to Deploy your chaincode?")
Expand Down
102 changes: 101 additions & 1 deletion core/chaincode/chaincode_support_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,9 @@ func initMockPeer(channelIDs ...string) (*peer.Peer, *ChaincodeSupport, func(),
ca, _ := tlsgen.NewCA()
certGenerator := accesscontrol.NewAuthenticator(ca)
globalConfig := GlobalConfig()
globalConfig.StartupTimeout = 10 * time.Second
globalConfig.ExecuteTimeout = 1 * time.Second
globalConfig.InstallTimeout = 90 * time.Second
globalConfig.StartupTimeout = 10 * time.Second

buildRegistry := &container.BuildRegistry{}

Expand Down Expand Up @@ -252,6 +253,7 @@ func initMockPeer(channelIDs ...string) (*peer.Peer, *ChaincodeSupport, func(),
AppConfig: peerInstance,
DeployedCCInfoProvider: &ledgermock.DeployedChaincodeInfoProvider{},
ExecuteTimeout: globalConfig.ExecuteTimeout,
InstallTimeout: globalConfig.InstallTimeout,
HandlerMetrics: NewHandlerMetrics(metricsProviders),
HandlerRegistry: chaincodeHandlerRegistry,
Keepalive: globalConfig.Keepalive,
Expand Down Expand Up @@ -1191,3 +1193,101 @@ func TestCCFramework(t *testing.T) {

ccSide.Quit()
}

func TestExecuteTimeout(t *testing.T) {
_, cs, cleanup, err := initMockPeer("testchannel")
assert.NoError(t, err)
defer cleanup()

tests := []struct {
executeTimeout time.Duration
installTimeout time.Duration
namespace string
command string
expectedTimeout time.Duration
}{
{
executeTimeout: time.Second,
installTimeout: time.Minute,
namespace: "lscc",
command: "install",
expectedTimeout: time.Minute,
},
{
executeTimeout: time.Minute,
installTimeout: time.Second,
namespace: "lscc",
command: "install",
expectedTimeout: time.Minute,
},
{
executeTimeout: time.Second,
installTimeout: time.Minute,
namespace: "_lifecycle",
command: "InstallChaincode",
expectedTimeout: time.Minute,
},
{
executeTimeout: time.Minute,
installTimeout: time.Second,
namespace: "_lifecycle",
command: "InstallChaincode",
expectedTimeout: time.Minute,
},
{
executeTimeout: time.Second,
installTimeout: time.Minute,
namespace: "_lifecycle",
command: "anything",
expectedTimeout: time.Second,
},
{
executeTimeout: time.Second,
installTimeout: time.Minute,
namespace: "lscc",
command: "anything",
expectedTimeout: time.Second,
},
{
executeTimeout: time.Second,
installTimeout: time.Minute,
namespace: "anything",
command: "",
expectedTimeout: time.Second,
},
}
for _, tt := range tests {
t.Run(tt.namespace+"_"+tt.command, func(t *testing.T) {
cs.ExecuteTimeout = tt.executeTimeout
cs.InstallTimeout = tt.installTimeout
input := &pb.ChaincodeInput{Args: util.ToChaincodeArgs(tt.command)}

result := cs.executeTimeout(tt.namespace, input)
assert.Equalf(t, tt.expectedTimeout, result, "want %s, got %s", tt.expectedTimeout, result)
})
}
}

func TestMaxDuration(t *testing.T) {
tests := []struct {
durations []time.Duration
expected time.Duration
}{
{
durations: []time.Duration{},
expected: time.Duration(0),
},
{
durations: []time.Duration{time.Second, time.Hour, time.Minute},
expected: time.Hour,
},
{
durations: []time.Duration{-time.Second},
expected: time.Duration(0),
},
}
for _, tt := range tests {
result := maxDuration(tt.durations...)
assert.Equalf(t, tt.expected, result, "want %s got %s", tt.expected, result)
}
}
2 changes: 2 additions & 0 deletions core/chaincode/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type Config struct {
TLSEnabled bool
Keepalive time.Duration
ExecuteTimeout time.Duration
InstallTimeout time.Duration
StartupTimeout time.Duration
LogFormat string
LogLevel string
Expand All @@ -51,6 +52,7 @@ func (c *Config) load() {
if c.ExecuteTimeout < time.Second {
c.ExecuteTimeout = defaultExecutionTimeout
}
c.InstallTimeout = viper.GetDuration("chaincode.installTimeout")
c.StartupTimeout = viper.GetDuration("chaincode.startuptimeout")
if c.StartupTimeout < minimumStartupTimeout {
c.StartupTimeout = minimumStartupTimeout
Expand Down
2 changes: 2 additions & 0 deletions core/chaincode/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var _ = Describe("Config", func() {
viper.Set("peer.tls.enabled", "true")
viper.Set("chaincode.keepalive", "50")
viper.Set("chaincode.executetimeout", "20h")
viper.Set("chaincode.installTimeout", "30m")
viper.Set("chaincode.startuptimeout", "30h")
viper.Set("chaincode.logging.format", "test-chaincode-logging-format")
viper.Set("chaincode.logging.level", "warning")
Expand All @@ -40,6 +41,7 @@ var _ = Describe("Config", func() {
Expect(config.TLSEnabled).To(BeTrue())
Expect(config.Keepalive).To(Equal(50 * time.Second))
Expect(config.ExecuteTimeout).To(Equal(20 * time.Hour))
Expect(config.InstallTimeout).To(Equal(30 * time.Minute))
Expect(config.StartupTimeout).To(Equal(30 * time.Hour))
Expect(config.LogFormat).To(Equal("test-chaincode-logging-format"))
Expect(config.LogLevel).To(Equal("warn"))
Expand Down
1 change: 1 addition & 0 deletions integration/nwo/core_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ chaincode:
runtime: $(DOCKER_NS)/fabric-javaenv:latest
node:
runtime: $(DOCKER_NS)/fabric-nodeenv:latest
installTimeout: 300s
startuptimeout: 300s
executetimeout: 30s
mode: net
Expand Down
1 change: 1 addition & 0 deletions integration/nwo/fabricconfig/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ type Chaincode struct {
Golang *Golang `yaml:"golang,omitempty"`
Java *Java `yaml:"java,omitempty"`
Node *Node `yaml:"node,omitempty"`
InstallTimeout time.Duration `yaml:"installTimeout,omitempty"`
StartupTimeout time.Duration `yaml:"startupTimeout,omitempty"`
ExecuteTimeout time.Duration `yaml:"executeTimeout,omitempty"`
Mode string `yaml:"mode,omitempty"`
Expand Down
1 change: 1 addition & 0 deletions internal/peer/node/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,7 @@ func serve(args []string) error {
AppConfig: peerInstance,
DeployedCCInfoProvider: lifecycleValidatorCommitter,
ExecuteTimeout: chaincodeConfig.ExecuteTimeout,
InstallTimeout: chaincodeConfig.InstallTimeout,
HandlerRegistry: chaincodeHandlerRegistry,
HandlerMetrics: chaincode.NewHandlerMetrics(opsSystem.Provider),
Keepalive: chaincodeConfig.Keepalive,
Expand Down
6 changes: 5 additions & 1 deletion sampleconfig/core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,12 @@ chaincode:
# builders in the order specified below.
externalBuilders: []

# The maximum duration to wait for the chaincode build and install process
# to complete.
installTimeout: 300s

# Timeout duration for starting up a container and waiting for Register
# to come through. 1sec should be plenty for chaincode unit tests
# to come through.
startuptimeout: 300s

# Timeout duration for Invoke and Init calls to prevent runaway.
Expand Down

0 comments on commit 9b266bd

Please sign in to comment.