fixes EIP2718/EIP2930 misinterpretation

the new Tx format (txType || txPayload) needs envelope
encoding at EthBlock level, not at the Tx level itself.
This commit is contained in:
jangko 2021-05-16 12:03:29 +07:00
parent 343d4f25e1
commit ef49a6f50a
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
2 changed files with 52 additions and 34 deletions

View File

@ -154,7 +154,7 @@ type
EthBlock* = object EthBlock* = object
header*: BlockHeader header*: BlockHeader
txs* : seq[Transaction] txs* {.rlpCustomSerialization.}: seq[Transaction]
uncles*: seq[BlockHeader] uncles*: seq[BlockHeader]
CollationHeader* = object CollationHeader* = object
@ -355,28 +355,47 @@ proc append*(rlpWriter: var RlpWriter, tx: Transaction) =
if tx.txType == LegacyTxType: if tx.txType == LegacyTxType:
rlpWriter.append(tx.legacyTx) rlpWriter.append(tx.legacyTx)
else: else:
var rw = initRlpWriter() # EIP 2718/2930
rw.append(1) rlpWriter.append(1)
rw.append(tx.accessListTx) rlpWriter.append(tx.accessListTx)
rlpWriter.append(rw.finish())
proc read*(rlp: var Rlp, T: type Transaction): T = proc read*(rlp: var Rlp, T: type Transaction): T =
if rlp.isList: if rlp.isList:
result = Transaction( return Transaction(
txType: LegacyTxType, txType: LegacyTxType,
legacyTx: rlp.read(LegacyTx) legacyTx: rlp.read(LegacyTx)
) )
else:
let bytes = rlp.read(Blob) # EIP 2718/2930
var rr = rlpFromBytes(bytes) let txType = rlp.read(int)
let txType = rr.read(int) if txType != 1:
if txType != 1: raise newException(UnsupportedRlpError,
raise newException(UnsupportedRlpError, "TxType expect 1 got " & $txType)
"TxType expect 1 got " & $txType) return Transaction(
result = Transaction( txType: AccessListTxType,
txType: AccessListTxType, accessListTx: rlp.read(AccessListTx)
accessListTx: rr.read(AccessListTx) )
)
proc read*(rlp: var Rlp, t: var EthBlock, _: type seq[Transaction]): seq[Transaction] {.inline.} =
# EIP 2718/2930: we have to override this field
# for reasons described below in `append` proc
for tx in rlp:
if tx.isList:
result.add tx.read(Transaction)
else:
let bytes = rlp.read(Blob)
var rr = rlpFromBytes(bytes)
result.add rr.read(Transaction)
proc append*(rlpWriter: var RlpWriter, blk: EthBlock, txs: seq[Transaction]) {.inline.} =
# EIP 2718/2930: the new Tx is rlp(txType || txPlayload) -> one blob/one list elem
# not rlp(txType, txPayload) -> two list elem, wrong!
rlpWriter.startList(txs.len)
for tx in txs:
if tx.txType == LegacyTxType:
rlpWriter.append(tx)
else:
rlpWriter.append(rlp.encode(tx))
proc read*(rlp: var Rlp, T: type HashOrStatus): T {.inline.} = proc read*(rlp: var Rlp, T: type HashOrStatus): T {.inline.} =
if rlp.isBlob() and (rlp.blobLen() == 32 or rlp.blobLen() == 1): if rlp.isBlob() and (rlp.blobLen() == 32 or rlp.blobLen() == 1):
@ -416,28 +435,26 @@ proc append*(rlpWriter: var RlpWriter, rec: Receipt) =
if rec.receiptType == LegacyReceiptType: if rec.receiptType == LegacyReceiptType:
rlpWriter.append(rec.legacyReceipt) rlpWriter.append(rec.legacyReceipt)
else: else:
var rw = initRlpWriter() # EIP 2718/2930
rw.append(1) rlpWriter.append(1)
rw.append(rec.accessListReceipt) rlpWriter.append(rec.accessListReceipt)
rlpWriter.append(rw.finish())
proc read*(rlp: var Rlp, T: type Receipt): T = proc read*(rlp: var Rlp, T: type Receipt): T =
if rlp.isList: if rlp.isList:
result = Receipt( return Receipt(
receiptType: LegacyReceiptType, receiptType: LegacyReceiptType,
legacyReceipt: rlp.read(LegacyReceipt) legacyReceipt: rlp.read(LegacyReceipt)
) )
else:
let bytes = rlp.read(Blob) # EIP 2718/2930
var rr = rlpFromBytes(bytes) let recType = rlp.read(int)
let recType = rr.read(int) if recType != 1:
if recType != 1: raise newException(UnsupportedRlpError,
raise newException(UnsupportedRlpError, "TxType expect 1 got " & $recType)
"TxType expect 1 got " & $recType) return Receipt(
result = Receipt( receiptType: AccessListReceiptType,
receiptType: AccessListReceiptType, accessListReceipt: rlp.read(AccessListReceipt)
accessListReceipt: rr.read(AccessListReceipt) )
)
proc read*(rlp: var Rlp, T: type Time): T {.inline.} = proc read*(rlp: var Rlp, T: type Time): T {.inline.} =
result = fromUnix(rlp.read(int64)) result = fromUnix(rlp.read(int64))

View File

@ -88,6 +88,7 @@ func rlpEncodeEIP155*(tx: LegacyTx): auto =
)) ))
func rlpEncode*(tx: AccessListTx): auto = func rlpEncode*(tx: AccessListTx): auto =
# EIP 2718/2930
let unsignedTx = AccessListUnsignedTx( let unsignedTx = AccessListUnsignedTx(
chainId: tx.chainId, chainId: tx.chainId,
nonce: tx.nonce, nonce: tx.nonce,
@ -102,7 +103,7 @@ func rlpEncode*(tx: AccessListTx): auto =
var rw = initRlpWriter() var rw = initRlpWriter()
rw.append(1) rw.append(1)
rw.append(unsignedTx) rw.append(unsignedTx)
rlp.encode(rw.finish()) rw.finish()
func txHashNoSignature*(tx: LegacyTx): Hash256 = func txHashNoSignature*(tx: LegacyTx): Hash256 =
# Hash transaction without signature # Hash transaction without signature