Skip to content
New issue

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

3.0 发生交易回滚没有回滚所有写操作 #3629

Closed
jdkuangxx opened this issue May 10, 2023 · 2 comments
Closed

3.0 发生交易回滚没有回滚所有写操作 #3629

jdkuangxx opened this issue May 10, 2023 · 2 comments

Comments

@jdkuangxx
Copy link
Collaborator

Bug描述:交易回滚无法正常执行。在一笔交易中对两张表进行插入,发生回滚后(Receipt message为Revert instruction),一张表插入成功,另一张表插入失败

环境信息

  • OS: CentOS 7.5
  • FISCO BCOS Version: Release-3.3.0 [二进制来源 https://osp-1257653870.cos.ap-guangzhou.myqcloud.com/FISCO-BCOS/FISCO-BCOS/releases/v3.3.0/fisco-bcos-linux-x86_64.tar.gz]

测试合约

// 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;
    }
}

复现步骤及现象:

  1. 使用build_chain.sh搭建一条全新的链

  2. 打开控制台查询区块高度

    [group0]: /apps> getBlockNumber 
    0
  3. 部署上述合约

    [group0]: /apps> deploy TableTransactionTest 
    transaction hash: 0x0c92310dcfa2645ab79abc7c3850d6487cfe5b696b9aaeb2f8efcee12d9a0d43
    contract address: 0x6849f21d1e455e9f0712b1e99fa4fcd23758e8f1
    currentAccount: 0x8bdf73480154937a462e52d517b2757cc530288b
  4. 调用insert接口发送一笔交易

    [group0]: /apps> call TableTransactionTest 0x6849f21d1e455e9f0712b1e99fa4fcd23758e8f1 insert 0 xx 00
    transaction hash: 0x703426d7bfdb35d2756fc15ae4b430fa0c467daa0ec021cc62b75df1af8ee865
    ---------------------------------------------------------------------------------------------
    transaction status: 16
    ---------------------------------------------------------------------------------------------
    Receipt message: Revert instruction
    Return message: Revert instruction
    ---------------------------------------------------------------------------------------------
  5. 在insert方法中,先后对t_testV320x和t_testV320x1进行插入,其中t_testV320x可以执行成功,在对t_testV320x1插入时故意引起Revert instruction。理论上对t_testV320x和t_testV320x1的插入都应该失败,即在查询两张表时都不应当查询到数据。但实际上,t_testV320x中是可以查询到刚刚插入的数据。

    # 可以查询到数据
    [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:(, )
    ---------------------------------------------------------------------------------------------
  6. 此时查询区块高度,发现区块高度为2 = 1(deploy) + 1(insert)

    [group0]: /apps> getBlockNumber 
    2
@kyonRay
Copy link
Member

kyonRay commented May 11, 2023

确认是bug,问题在于执行第一段成功后把创建出来的excutive都析构了,第二段触发回滚后,不能回滚到第一段的数据。这个问题我们会在将来的版本解决。

@kyonRay kyonRay changed the title 交易回滚无法正常执行 3.0 发生交易回滚没有回滚所有写操作 May 11, 2023
JimmyShi22 added a commit to JimmyShi22/FISCO-BCOS that referenced this issue May 11, 2023
JimmyShi22 added a commit to JimmyShi22/FISCO-BCOS that referenced this issue May 11, 2023
@JimmyShi22
Copy link
Member

Fix at this PR #3620

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants