We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug描述:交易回滚无法正常执行。在一笔交易中对两张表进行插入,发生回滚后(Receipt message为Revert instruction),一张表插入成功,另一张表插入失败
环境信息
测试合约
// SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.6.10 <0.8.20; pragma experimental ABIEncoderV2; import "./Table.sol"; import "./Cast.sol"; contract TableTransactionTest { event CreateResult(int256 count); event InsertResult(int256 count); event UpdateResult(int256 count); event RemoveResult(int256 count); Cast constant cast = Cast(address(0x100f)); TableManager constant tm = TableManager(address(0x1002)); Table table; Table table1; string constant TABLE_NAME = "t_testV320x"; string constant TABLE_NAME1 = "t_testV320x1"; constructor () public { // create table string[] memory columnNames = new string[](3); columnNames[0] = "name"; columnNames[1] = "age"; columnNames[2] = "status"; TableInfo memory tf = TableInfo(KeyOrder.Lexicographic ,"id", columnNames); tm.createTable(TABLE_NAME, tf); address t_address = tm.openTable(TABLE_NAME); require(t_address!=address(0x0),""); table = Table(t_address); TableInfo memory tf1 = TableInfo(KeyOrder.Lexicographic ,"id", columnNames); tm.createTable(TABLE_NAME1, tf1); address t_address1 = tm.openTable(TABLE_NAME1); require(t_address1!=address(0x0),""); table1 = Table(t_address1); } function selectTable(int64 id) public view returns (string memory, string memory) { Entry memory entry = table.select(cast.s64ToString(id)); string memory name; string memory age; if(entry.fields.length == 3){ name = entry.fields[0]; age = entry.fields[1]; } return (name, age); } function selectTable1(int64 id) public view returns (string memory, string memory) { Entry memory entry = table1.select(cast.s64ToString(id)); string memory name; string memory age; if(entry.fields.length == 3){ name = entry.fields[0]; age = entry.fields[1]; } return (name, age); } function insert(int64 id, string memory name, string memory age) public returns (int32){ Entry memory entry = Entry(cast.s64ToString(id), new string[](3)); entry.fields[0] = name; entry.fields[1] = age; entry.fields[2] = "init"; table.insert(entry); // 字段数不匹配导致Revert instruction, 理论上table的插入应当被回滚,但实际上通过selectTable可以查询到数据 // createTable时字段数为3,这里故意设置为4 Entry memory entry1 = Entry(cast.s64ToString(id), new string[](4)); entry1.fields[0] = name; entry1.fields[1] = age; entry1.fields[2] = "init"; int32 result1 = table1.insert(entry1); return result1; } }
复现步骤及现象:
使用build_chain.sh搭建一条全新的链
打开控制台查询区块高度
[group0]: /apps> getBlockNumber 0
部署上述合约
[group0]: /apps> deploy TableTransactionTest transaction hash: 0x0c92310dcfa2645ab79abc7c3850d6487cfe5b696b9aaeb2f8efcee12d9a0d43 contract address: 0x6849f21d1e455e9f0712b1e99fa4fcd23758e8f1 currentAccount: 0x8bdf73480154937a462e52d517b2757cc530288b
调用insert接口发送一笔交易
[group0]: /apps> call TableTransactionTest 0x6849f21d1e455e9f0712b1e99fa4fcd23758e8f1 insert 0 xx 00 transaction hash: 0x703426d7bfdb35d2756fc15ae4b430fa0c467daa0ec021cc62b75df1af8ee865 --------------------------------------------------------------------------------------------- transaction status: 16 --------------------------------------------------------------------------------------------- Receipt message: Revert instruction Return message: Revert instruction ---------------------------------------------------------------------------------------------
在insert方法中,先后对t_testV320x和t_testV320x1进行插入,其中t_testV320x可以执行成功,在对t_testV320x1插入时故意引起Revert instruction。理论上对t_testV320x和t_testV320x1的插入都应该失败,即在查询两张表时都不应当查询到数据。但实际上,t_testV320x中是可以查询到刚刚插入的数据。
t_testV320x和t_testV320x1
t_testV320x
t_testV320x1
# 可以查询到数据 [group0]: /apps> call TableTransactionTest 0x6849f21d1e455e9f0712b1e99fa4fcd23758e8f1 selectTable 0 --------------------------------------------------------------------------------------------- Return code: 0 description: transaction executed successfully Return message: Success --------------------------------------------------------------------------------------------- Return value size:2 Return types: (string, string) Return values:(xx, 00) --------------------------------------------------------------------------------------------- # 无法查询到数据 [group0]: /apps> call TableTransactionTest 0x6849f21d1e455e9f0712b1e99fa4fcd23758e8f1 selectTable1 0 --------------------------------------------------------------------------------------------- Return code: 0 description: transaction executed successfully Return message: Success --------------------------------------------------------------------------------------------- Return value size:2 Return types: (string, string) Return values:(, ) ---------------------------------------------------------------------------------------------
此时查询区块高度,发现区块高度为2 = 1(deploy) + 1(insert)
2 = 1(deploy) + 1(insert)
[group0]: /apps> getBlockNumber 2
The text was updated successfully, but these errors were encountered:
确认是bug,问题在于执行第一段成功后把创建出来的excutive都析构了,第二段触发回滚后,不能回滚到第一段的数据。这个问题我们会在将来的版本解决。
Sorry, something went wrong.
fix revert without children bug for issue FISCO-BCOS#3629
8293c60
01920c6
Fix at this PR #3620
<fix>(Executive): Fix revert without children bug for issue #3629 (#3620
b4b2e92
)
JimmyShi22
No branches or pull requests
Bug描述:交易回滚无法正常执行。在一笔交易中对两张表进行插入,发生回滚后(Receipt message为Revert instruction),一张表插入成功,另一张表插入失败
环境信息
测试合约
复现步骤及现象:
使用build_chain.sh搭建一条全新的链
打开控制台查询区块高度
[group0]: /apps> getBlockNumber 0
部署上述合约
[group0]: /apps> deploy TableTransactionTest transaction hash: 0x0c92310dcfa2645ab79abc7c3850d6487cfe5b696b9aaeb2f8efcee12d9a0d43 contract address: 0x6849f21d1e455e9f0712b1e99fa4fcd23758e8f1 currentAccount: 0x8bdf73480154937a462e52d517b2757cc530288b
调用insert接口发送一笔交易
[group0]: /apps> call TableTransactionTest 0x6849f21d1e455e9f0712b1e99fa4fcd23758e8f1 insert 0 xx 00 transaction hash: 0x703426d7bfdb35d2756fc15ae4b430fa0c467daa0ec021cc62b75df1af8ee865 --------------------------------------------------------------------------------------------- transaction status: 16 --------------------------------------------------------------------------------------------- Receipt message: Revert instruction Return message: Revert instruction ---------------------------------------------------------------------------------------------
在insert方法中,先后对
t_testV320x和t_testV320x1
进行插入,其中t_testV320x
可以执行成功,在对t_testV320x1
插入时故意引起Revert instruction。理论上对t_testV320x和t_testV320x1
的插入都应该失败,即在查询两张表时都不应当查询到数据。但实际上,t_testV320x
中是可以查询到刚刚插入的数据。此时查询区块高度,发现区块高度为
2 = 1(deploy) + 1(insert)
[group0]: /apps> getBlockNumber 2
The text was updated successfully, but these errors were encountered: