Developers Forum for XinFin XDC Network

Daniel Liu
Daniel Liu

Posted on

Why roll back testnet

Why roll back the testnet

The function DeriveSha computes the transactionsRoot and receiptsRoot fields in each block. And it calls the function EncodeIndex for each item in the transactions list or receipts list during execution.

Our current code is as follows:

func (s Transactions) EncodeIndex(i int, w *bytes.Buffer) {
    tx := s[i]
    if tx.Type() == LegacyTxType {
        rlp.Encode(w, tx.inner)
    } else {
        rlp.Encode(w, tx)
    }
}

func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) {
    r := rs[i]
    if r.Type == LegacyTxType {
        data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs}
        rlp.Encode(w, data)
    } else {
        rlp.Encode(w, r)
    }
}
Enter fullscreen mode Exit fullscreen mode

But the corresponding code in geth is as follows:

func (s Transactions) EncodeIndex(i int, w *bytes.Buffer) {
    tx := s[i]
    if tx.Type() == LegacyTxType {
        rlp.Encode(w, tx.inner)
    } else {
        tx.encodeTyped(w)
    }
}

func (tx *Transaction) encodeTyped(w *bytes.Buffer) error {
    w.WriteByte(tx.Type())
    return rlp.Encode(w, tx.inner)
}

func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) {
    r := rs[i]
    data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs}
    switch r.Type {
    case LegacyTxType:
        rlp.Encode(w, data)
    case AccessListTxType:
        w.WriteByte(AccessListTxType)
        rlp.Encode(w, data)
    case DynamicFeeTxType:
        w.WriteByte(DynamicFeeTxType)
        rlp.Encode(w, data)
    default:
    }
}
Enter fullscreen mode Exit fullscreen mode

The above different codes will result in different root hashes. To avoid future accidents, we should use geth code to produce the same value. But the EIP-1559 feature has been actived on testnet from block number 71550000. That is to say, the transactionsRoot and receiptsRoot are inconsistent with geth algorithm from block number 71550000. Although we can introduce a block number parameter to identify old and new blocks, such as:

func (s Transactions) EncodeIndex(i int, w *bytes.Buffer, number *big.Int) {
    tx := s[i]
    if tx.Type() == LegacyTxType {
        rlp.Encode(w, tx.inner)
    } else {
        if number != nil && common.Eip1559TxHashBlock != nil && number.Cmp(common.Eip1559TxHashBlock) < 0 {
            rlp.Encode(w, tx)
        } else {
            tx.encodeTyped(w)
        }
    }
 }
Enter fullscreen mode Exit fullscreen mode

We need to modify 21 files to complete similar modifications. The complex code can increase the risk of bugs. Additionally, since EIP-1559 has not been activated on the mainnet, these code changes are not actually required on the mainnet. So we suggest:

  • release a new version:
    • change cancunBlock from 73425600 to 71550000 for testnet
    • pick some commits about hash from PR #933
  • test new version on devnet
  • roll back the testnet to 71550000 or less
  • recreate snapshot for testnet after roll back

Discussion (0)