如果Fabric的智能合约函数陷入死循环会怎么样

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

大家好我是powervip今天和大家一起探讨一下如果Fabric的智能合约函数陷入死循环会怎么样

先看一段合约函数代码

func (t *SimpleChaincode) Test(stub shim.ChaincodeStubInterface, args []string) pb.Response {

// 选择商品价格在1元到100元之间的商品名称和数量

s := "{\"fields\": [\"GoodsName\", \"GoodsCount\"], \"selector\":{ \"$and\": [{\"GoodPrice\":{\"$gte\": 1}}, {\"GoodPrice\":{\"$lte\": 100}}] }}"

resultsIterator, err := stub.GetQueryResult(q)

defer resultsIterator.Close()

if err != nil {

return shim.Error(err.Error())

}

var count uint64

for resultsIterator.HasNext() {

count++

// resultsIterator.Next() // 注释掉该语句函数将陷入死循环

fmt.Println("count=", count)

}

msg := fmt.Sprintf("count: %d", count)

return shim.Success([]byte(msg))

}

上面的代码由于把 resultsIterator.Next() 这行代码注释掉返回的数据集如果包含有1条记录或以上游标就会一直停留在第一条数据记录上导致 resultsIterator.HasNext() 永远为true从而陷入死循环。

合约函数陷入死循环后由于Fabric一般默认的智能合约函数调用时长最长为30秒超过30秒后Fabric会返回类似于下面的超时提示

Error: endorsement failure during invoke. response: status:500 message:"failed to execute transaction 81f3c7715ae5f6678c711238571bb1c778c274bc505287da3f857465835832d6: error sending: timeout expired while executing transaction"

你以为合约函数调用就这样结束了No如果你attach上peer节点具体命令是docker attach c5841e55155ac5841e55155a为该节点的CONTAINER ID你会发现peer节点的log会不断地打印出类似下面的信息

count= 10000

count= 10001

count= 10002

count= 10003

count= 10004

count= 10005

count= 10006

count= 10007

count= 10008

count= 10009

...

表明合约函数还在不断地执行死循环代码。

如果这时候你想在客户端执行其它的合约函数得到的结果都是超时因为智能合约在上次调用中陷入死循环后没办法执行新的函数调用了。后果真的很严重需要认真注意合约函数会引起死循环的代码

要如何结束死循环目前来看只有重启peer节点了。如果你有更好的方法欢迎提出来讨论。

------------------------------------------------------------------------------

我是powervip

我的公众号区块链战斗机

我的知乎powervip - 知乎

我的学习笔记www.study.win

原创作品版权所有侵权必究商业转载请联系作者获得授权非商业转载需保留作者署名信息注明出处并保留原文链接。

如果你觉得这篇文章写得还可以请帮忙点个赞谢谢

你的鼓励我的动力 

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6