{"content":{"title":"如果Fabric的智能合约函数陷入死循环会怎么样","body":"大家好，我是powervip！今天和大家一起探讨一下：如果Fabric的智能合约函数陷入死循环会怎么样\r\n\r\n## 先看一段合约函数代码：\r\n```\r\nfunc (t *SimpleChaincode) Test(stub shim.ChaincodeStubInterface, args []string) pb.Response  {\r\n   // 选择商品价格在1元到100元之间的商品名称和数量\r\n    s := \"{\\\"fields\\\": [\\\"GoodsName\\\", \\\"GoodsCount\\\"], \\\"selector\\\":{ \\\"$and\\\": [{\\\"GoodPrice\\\":{\\\"$gte\\\": 1}}, {\\\"GoodPrice\\\":{\\\"$lte\\\": 100}}] }}\"\r\n\r\n    resultsIterator, err := stub.GetQueryResult(q)\r\n    defer resultsIterator.Close()\r\n    \r\n    if err != nil {\r\n        return shim.Error(err.Error())\r\n    }\r\n\r\n    var count uint64 \r\n    for resultsIterator.HasNext() {\r\n        count++\r\n        // resultsIterator.Next()    // 注释掉该语句，函数将陷入死循环\r\n\r\n        fmt.Println(\"count=\", count)\r\n    }\r\n\r\n    msg := fmt.Sprintf(\"count: %d\", count)\r\n    return shim.Success([]byte(msg))\r\n}\r\n```\r\n\r\n上面的代码由于把 resultsIterator.Next() 这行代码注释掉，返回的数据集如果包含有1条记录或以上，游标就会一直停留在第一条数据记录上，导致 resultsIterator.HasNext() 永远为true，从而陷入死循环。\r\n\r\n合约函数陷入死循环后，由于Fabric一般默认的智能合约函数调用时长最长为30秒，超过30秒后，Fabric会返回类似于下面的超时提示：\r\n\r\nError: endorsement failure during invoke. response: status:500 message:\"failed to execute transaction 81f3c7715ae5f6678c711238571bb1c778c274bc505287da3f857465835832d6: error sending: timeout expired while executing transaction\"\r\n\r\n\r\n你以为合约函数调用就这样结束了？No！如果你attach上peer节点（具体命令是：docker attach c5841e55155a，c5841e55155a为该节点的CONTAINER ID），你会发现，peer节点的log会不断地打印出类似下面的信息：\r\n\r\ncount= 10000\r\ncount= 10001\r\ncount= 10002\r\ncount= 10003\r\ncount= 10004\r\ncount= 10005\r\ncount= 10006\r\ncount= 10007\r\ncount= 10008\r\ncount= 10009\r\n...\r\n\r\n表明合约函数还在不断地执行死循环代码。\r\n\r\n如果这时候，你想在客户端执行其它的合约函数，得到的结果都是超时，因为智能合约在上次调用中陷入死循环后，没办法执行新的函数调用了。后果真的很严重，需要认真注意合约函数会引起死循环的代码！\r\n\r\n要如何结束死循环，目前来看只有重启peer节点了。如果你有更好的方法，欢迎提出来讨论。\r\n\r\n\r\n------------------------------------------------------------------------------\r\n我是powervip\r\n我的公众号：区块链战斗机\r\n我的知乎：https://www.zhihu.com/people/powervip\r\n我的学习笔记：www.study.win\r\n\r\n原创作品，版权所有，侵权必究！商业转载请联系作者获得授权；非商业转载需保留作者署名信息，注明出处并保留原文链接。\r\n\r\n如果你觉得这篇文章写得还可以，请帮忙点个赞，谢谢！\r\n你的鼓励，我的动力！"},"author":{"user":"https://learnblockchain.cn/people/5018","address":null},"history":"QmVqKNbmXcxFnKocgbPKw9AmmQ82tWYPLdhhsVmCyAGpPj","timestamp":1668763930,"version":1}