core/types: copy tx recipient address (#23376)

This resolves a long-standing TODO. The point of copying the address is
to ensure that all data referenced by types.Transaction is independent of the
data passed into the constructor.

Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
aaronbuchwald 2021-10-06 07:12:52 -04:00 committed by GitHub
parent 57ff2dee06
commit 4e599ee469
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 13 additions and 12 deletions

@ -59,7 +59,7 @@ type AccessListTx struct {
func (tx *AccessListTx) copy() TxData { func (tx *AccessListTx) copy() TxData {
cpy := &AccessListTx{ cpy := &AccessListTx{
Nonce: tx.Nonce, Nonce: tx.Nonce,
To: tx.To, // TODO: copy pointed-to address To: copyAddressPtr(tx.To),
Data: common.CopyBytes(tx.Data), Data: common.CopyBytes(tx.Data),
Gas: tx.Gas, Gas: tx.Gas,
// These are copied below. // These are copied below.
@ -96,7 +96,6 @@ func (tx *AccessListTx) copy() TxData {
// accessors for innerTx. // accessors for innerTx.
func (tx *AccessListTx) txType() byte { return AccessListTxType } func (tx *AccessListTx) txType() byte { return AccessListTxType }
func (tx *AccessListTx) chainID() *big.Int { return tx.ChainID } func (tx *AccessListTx) chainID() *big.Int { return tx.ChainID }
func (tx *AccessListTx) protected() bool { return true }
func (tx *AccessListTx) accessList() AccessList { return tx.AccessList } func (tx *AccessListTx) accessList() AccessList { return tx.AccessList }
func (tx *AccessListTx) data() []byte { return tx.Data } func (tx *AccessListTx) data() []byte { return tx.Data }
func (tx *AccessListTx) gas() uint64 { return tx.Gas } func (tx *AccessListTx) gas() uint64 { return tx.Gas }

@ -43,7 +43,7 @@ type DynamicFeeTx struct {
func (tx *DynamicFeeTx) copy() TxData { func (tx *DynamicFeeTx) copy() TxData {
cpy := &DynamicFeeTx{ cpy := &DynamicFeeTx{
Nonce: tx.Nonce, Nonce: tx.Nonce,
To: tx.To, // TODO: copy pointed-to address To: copyAddressPtr(tx.To),
Data: common.CopyBytes(tx.Data), Data: common.CopyBytes(tx.Data),
Gas: tx.Gas, Gas: tx.Gas,
// These are copied below. // These are copied below.
@ -84,7 +84,6 @@ func (tx *DynamicFeeTx) copy() TxData {
// accessors for innerTx. // accessors for innerTx.
func (tx *DynamicFeeTx) txType() byte { return DynamicFeeTxType } func (tx *DynamicFeeTx) txType() byte { return DynamicFeeTxType }
func (tx *DynamicFeeTx) chainID() *big.Int { return tx.ChainID } func (tx *DynamicFeeTx) chainID() *big.Int { return tx.ChainID }
func (tx *DynamicFeeTx) protected() bool { return true }
func (tx *DynamicFeeTx) accessList() AccessList { return tx.AccessList } func (tx *DynamicFeeTx) accessList() AccessList { return tx.AccessList }
func (tx *DynamicFeeTx) data() []byte { return tx.Data } func (tx *DynamicFeeTx) data() []byte { return tx.Data }
func (tx *DynamicFeeTx) gas() uint64 { return tx.Gas } func (tx *DynamicFeeTx) gas() uint64 { return tx.Gas }

@ -62,7 +62,7 @@ func NewContractCreation(nonce uint64, amount *big.Int, gasLimit uint64, gasPric
func (tx *LegacyTx) copy() TxData { func (tx *LegacyTx) copy() TxData {
cpy := &LegacyTx{ cpy := &LegacyTx{
Nonce: tx.Nonce, Nonce: tx.Nonce,
To: tx.To, // TODO: copy pointed-to address To: copyAddressPtr(tx.To),
Data: common.CopyBytes(tx.Data), Data: common.CopyBytes(tx.Data),
Gas: tx.Gas, Gas: tx.Gas,
// These are initialized below. // These are initialized below.

@ -284,13 +284,7 @@ func (tx *Transaction) Nonce() uint64 { return tx.inner.nonce() }
// To returns the recipient address of the transaction. // To returns the recipient address of the transaction.
// For contract-creation transactions, To returns nil. // For contract-creation transactions, To returns nil.
func (tx *Transaction) To() *common.Address { func (tx *Transaction) To() *common.Address {
// Copy the pointed-to address. return copyAddressPtr(tx.inner.to())
ito := tx.inner.to()
if ito == nil {
return nil
}
cpy := *ito
return &cpy
} }
// Cost returns gas * gasPrice + value. // Cost returns gas * gasPrice + value.
@ -632,3 +626,12 @@ func (m Message) Nonce() uint64 { return m.nonce }
func (m Message) Data() []byte { return m.data } func (m Message) Data() []byte { return m.data }
func (m Message) AccessList() AccessList { return m.accessList } func (m Message) AccessList() AccessList { return m.accessList }
func (m Message) IsFake() bool { return m.isFake } func (m Message) IsFake() bool { return m.isFake }
// copyAddressPtr copies an address.
func copyAddressPtr(a *common.Address) *common.Address {
if a == nil {
return nil
}
cpy := *a
return &cpy
}