Conflux-Chain / CIPs

Conflux Improvement Proposals (CIPs)
MIT License
26 stars 30 forks source link

Update internal transaction trace. #88

Closed ChenxingLi closed 2 years ago

ChenxingLi commented 2 years ago

A recent PR changes the trace of transaction trace. The changes are described as follows.

中文摘要

The "valid" field

If the inner message call triggers an error and the error is caught by the outside contract, the whole transaction could also succeed, but the effects of the inner message call are reverted. The traces of the reverted message call will also be retained for debugging usage.

Here, we add a new field "valid" to indicate whether the corresponding trace is reverted.

Trace for gas payment.

Any transaction bumping nonce during execution will generate one or two traces with type "internal_transfer_action" to indicate gas payment and gas refund.

Consider a transaction has gas limit 40000 and gas price 3 Drip.

For gas payment, if the transaction is sponsored, the trace will be

{
    "action": {
        "from": <contract_address>,
        "fromPocket": "sponsor_balance_for_gas",
        "to": <zero_address>,
        "toPocket": "gas_payment",
        "value": 120000, 
    }
    "type": "internal_transfer_action"
    ......
}

If the transaction is not sponsored, the trace will be

{
    "action": {
        "from": <sender_address>,
        "fromPocket": "balance",
        "to": <zero_address>,
        "toPocket": "gas_payment",
        "value": 120000, 
    }
    "type": "internal_transfer_action"
    ......
}

This should be the first trace of most transactions.

After execution, if this transaction costs 25000 gas, up to 1/4 of gas limit, i.e., 10000 gas (30000 Drip when gas price = 3) will be refunded, then it will generate a trace

{
    "action": {
        "from": <zero_address>,
        "fromPocket": "gas_payment",
        "to": ...,
        "toPocket": ...,
        "value": 30000, 
    },
    "type": "internal_transfer_action",
    ...
}

Trace for storage collateral.

Consider a transaction collateralize 10 Drip (it can not happen in a real Conflux system, just for example).

If the transaction is sponsored,

{
    "action": {
        "from": <contract_address>,
        "fromPocket": "sponsor_balance_for_collateral",
        "to": <contract_address>,
        "toPocket": "storage_collateral",
        "value": 10, 
    },
    "type": "internal_transfer_action",
    ...
}

If the transaction is not sponsored,

{
    "action": {
        "from": <sender_address>,
        "fromPocket": "balance",
        "to": <sender_address>,
        "toPocket": "storage_collateral",
        "value": 10, 
    },
    "type": "internal_transfer_action",
    ...
}

When releasing storage, the value will be returned to the same route.

Changes in the sponsorship (example)

When a user adds sponsor balance for gas for a contract, the trace will be

Before change

{
    "action": {
        "from": <sender_address>,
        "to": <internal_contract_for_sponsorship>, // 0x088800...01
        "value": ...,
        ...
    },
    "type": "call",
    ...
}

After change

{
    "action": {
         // call type trace has no fromPocket and toPocket field. Because the pocket is always "balance". 
        "from": <sender_address>,
        "to": <internal_contract_for_sponsorship>, // 0x088800...01
        "value": ...,
        ...
    },
    "type": "call",
    ...
}
{
    "action": {
        "from": <internal_contract_for_sponsorship>, // 0x088800...01
        "fromPocket": "balance",
        "to": <contract_address>,
        "toPocket": "sponsor_balance_for_gas"
        "value": ...,
        ...
    },
    "type": "internal_transfer_action",
    ...
}

Now you can know which contract is sponsored from the trace.

Changes in the staking (example)

When a user stakes, the trace will be

Before change

{
    "action": {
        "from": <sender_address>,
        "to": <internal_contract_for_staking>, // 0x088800...02
        "value": ...,
        ...
    },
    "type": "internal_transfer_action",
    ...
}

After change

{
    "action": {
        "from": <sender_address>,
        "fromPocket": "balance",
        "to": <sender_address>, 
        "toPocket": "staking_balance",
        "value": ...,
        ...
    },
    "type": "internal_transfer_action",
    ...
}

Indicator for kill contract

Each time a contract is killed, it will produce such a trace,

{
    "action": {
        "from": <contract_address>,
        "fromPocket": "balance",
        "to": <zero_address>, 
        "toPocket": "mint_burn",
        "value": ...,
        ...
    },
    "type": "internal_transfer_action",
    ...
}

Changes in integrity constraints

Before change

After change

Specification for pocket

In Conflux, each account could have several pockets to store CFX.

The fromPocket field and toPocket field could be one of them.

Besides these five values, the "pocket" could be two special values "mint_burn" and "gas_payment".

wangdayong228 commented 2 years ago

Reference:

Paragraph of Changes in integrity constraints -> After change

The staking balance/collateral balance/sponsor balance for gas/sponsor balance for collateral increasing (or decreasing) of an address during transaction execution corresponds to an internal_transfer type trace whose "to" (or "from") is this address and "toPocket" (or "fromPocket") is "sponsor_balance"/"storage_collateral"/"sponsor_balance_for_gas"/"sponsor_balance_for_gas".

Comment: Should the last word sponsor_balance_for_gas be sponsor_balance_for_collateral ?

ChenxingLi commented 2 years ago

Fixed