diff --git a/go-ethereum/core/types/access_list_tx.go b/go-ethereum/core/types/access_list_tx.go index aea26474..35f7f2f4 100644 --- a/go-ethereum/core/types/access_list_tx.go +++ b/go-ethereum/core/types/access_list_tx.go @@ -53,6 +53,9 @@ type AccessListTx struct { Data []byte // contract invocation input data AccessList AccessList // EIP-2930 access list V, R, S *big.Int // signature values + + // Optional Avalanche extension + From *common.Address } // copy creates a deep copy of the transaction data and initializes all fields. @@ -62,6 +65,7 @@ func (tx *AccessListTx) copy() TxData { To: copyAddressPtr(tx.To), Data: common.CopyBytes(tx.Data), Gas: tx.Gas, + From: copyAddressPtr(tx.From), // These are copied below. AccessList: make(AccessList, len(tx.AccessList)), Value: new(big.Int), diff --git a/go-ethereum/core/types/block.go b/go-ethereum/core/types/block.go index d8c270b8..d4fc4c66 100644 --- a/go-ethereum/core/types/block.go +++ b/go-ethereum/core/types/block.go @@ -64,6 +64,8 @@ func (n *BlockNonce) UnmarshalText(input []byte) error { // Header represents a block header in the Ethereum blockchain. type Header struct { + hash *common.Hash + ParentHash common.Hash `json:"parentHash" gencodec:"required"` UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` Coinbase common.Address `json:"miner"` @@ -84,13 +86,21 @@ type Header struct { BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"` // WithdrawalsHash was added by EIP-4895 and is ignored in legacy headers. - WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"` + WithdrawalsHash *common.Hash `json:"withdrawalsRoot,omitempty" rlp:"optional"` /* TODO (MariusVanDerWijden) Add this field once needed // Random was added during the merge and contains the BeaconState randomness Random common.Hash `json:"random" rlp:"optional"` */ + + // Optional Avalanche extension + ExtSize *uint64 `json:"size,omitempty" rlp:"optional"` + ExtTotalDifficulty *big.Int `json:"totalDifficulty,omitempty" rlp:"optional"` + ExtBlockExtraData []byte `json:"blockExtraData,omitempty" rlp:"optional"` + ExtBlockGasCost *uint64 `json:"blockGasCost,omitempty" rlp:"optional"` + ExtDataGasUsed *uint64 `json:"extDataGasUsed,omitempty" rlp:"optional"` + ExtDataHash *common.Hash `json:"extDataHash,omitempty" rlp:"optional"` } // field type overrides for gencodec @@ -103,6 +113,12 @@ type headerMarshaling struct { Extra hexutil.Bytes BaseFee *hexutil.Big Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON + + ExtSize *hexutil.Uint64 + ExtTotalDifficulty *hexutil.Big + ExtBlockExtraData hexutil.Bytes + ExtBlockGasCost *hexutil.Uint64 + ExtDataGasUsed *hexutil.Uint64 } // Hash returns the block hash of the header, which is simply the keccak256 hash of its @@ -123,6 +139,10 @@ func (h *Header) Hash() common.Hash { // computed block hash: 0xcfe3a3725b81644c8fd38ced1acbf2c74e000087477b151bfc73217e025104ba // real block hash: 0xfcbe02c3303094a6ef511ed6acb39931f24c70691a0afefa740b7a3aed678861 + if h.hash != nil { + return *h.hash + } + return rlpHash(h) } @@ -299,6 +319,29 @@ func CopyHeader(h *Header) *Header { cpy.WithdrawalsHash = new(common.Hash) *cpy.WithdrawalsHash = *h.WithdrawalsHash } + if h.ExtSize != nil { + cpy.ExtSize = new(uint64) + *cpy.ExtSize = *h.ExtSize + } + if h.ExtTotalDifficulty != nil { + cpy.ExtTotalDifficulty = new(big.Int).Set(h.ExtTotalDifficulty) + } + if len(h.ExtBlockExtraData) > 0 { + cpy.ExtBlockExtraData = make([]byte, len(h.ExtBlockExtraData)) + copy(cpy.ExtBlockExtraData, h.ExtBlockExtraData) + } + if h.ExtBlockGasCost != nil { + cpy.ExtBlockGasCost = new(uint64) + *cpy.ExtBlockGasCost = *h.ExtBlockGasCost + } + if h.ExtDataGasUsed != nil { + cpy.ExtDataGasUsed = new(uint64) + *cpy.ExtDataGasUsed = *h.ExtDataGasUsed + } + if h.ExtDataHash != nil { + cpy.ExtDataHash = new(common.Hash) + *cpy.ExtDataHash = *h.ExtDataHash + } return &cpy } @@ -441,6 +484,7 @@ func (b *Block) WithWithdrawals(withdrawals []*Withdrawal) *Block { // delete this code ASAP, this shouldn't be neccesary func (b *Block) SetHash(hash common.Hash) { b.hash.Store(hash) + b.header.hash = &hash } // Hash returns the keccak256 hash of b's header. diff --git a/go-ethereum/core/types/dynamic_fee_tx.go b/go-ethereum/core/types/dynamic_fee_tx.go index 8d3ff329..98f13a77 100644 --- a/go-ethereum/core/types/dynamic_fee_tx.go +++ b/go-ethereum/core/types/dynamic_fee_tx.go @@ -37,6 +37,9 @@ type DynamicFeeTx struct { V *big.Int `json:"v" gencodec:"required"` R *big.Int `json:"r" gencodec:"required"` S *big.Int `json:"s" gencodec:"required"` + + // Optional Avalanche extension + From *common.Address } // copy creates a deep copy of the transaction data and initializes all fields. @@ -46,6 +49,7 @@ func (tx *DynamicFeeTx) copy() TxData { To: copyAddressPtr(tx.To), Data: common.CopyBytes(tx.Data), Gas: tx.Gas, + From: copyAddressPtr(tx.From), // These are copied below. AccessList: make(AccessList, len(tx.AccessList)), Value: new(big.Int), diff --git a/go-ethereum/core/types/gen_header_json.go b/go-ethereum/core/types/gen_header_json.go index 85b151c3..89091781 100644 --- a/go-ethereum/core/types/gen_header_json.go +++ b/go-ethereum/core/types/gen_header_json.go @@ -16,24 +16,30 @@ var _ = (*headerMarshaling)(nil) // MarshalJSON marshals as JSON. func (h Header) MarshalJSON() ([]byte, error) { type Header struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner"` - Root common.Hash `json:"stateRoot" gencodec:"required"` - TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest common.Hash `json:"mixHash"` - Nonce BlockNonce `json:"nonce"` - BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` - WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"` - Hash common.Hash `json:"hash"` + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase common.Address `json:"miner"` + Root common.Hash `json:"stateRoot" gencodec:"required"` + TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest common.Hash `json:"mixHash"` + Nonce BlockNonce `json:"nonce"` + BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` + WithdrawalsHash *common.Hash `json:"withdrawalsRoot,omitempty" rlp:"optional"` + ExtSize *hexutil.Uint64 `json:"size,omitempty" rlp:"optional"` + ExtTotalDifficulty *hexutil.Big `json:"totalDifficulty,omitempty" rlp:"optional"` + ExtBlockExtraData hexutil.Bytes `json:"blockExtraData,omitempty" rlp:"optional"` + ExtBlockGasCost *hexutil.Uint64 `json:"blockGasCost,omitempty" rlp:"optional"` + ExtDataGasUsed *hexutil.Uint64 `json:"extDataGasUsed,omitempty" rlp:"optional"` + ExtDataHash *common.Hash `json:"extDataHash,omitempty" rlp:"optional"` + Hash common.Hash `json:"hash"` } var enc Header enc.ParentHash = h.ParentHash @@ -53,6 +59,12 @@ func (h Header) MarshalJSON() ([]byte, error) { enc.Nonce = h.Nonce enc.BaseFee = (*hexutil.Big)(h.BaseFee) enc.WithdrawalsHash = h.WithdrawalsHash + enc.ExtSize = (*hexutil.Uint64)(h.ExtSize) + enc.ExtTotalDifficulty = (*hexutil.Big)(h.ExtTotalDifficulty) + enc.ExtBlockExtraData = h.ExtBlockExtraData + enc.ExtBlockGasCost = (*hexutil.Uint64)(h.ExtBlockGasCost) + enc.ExtDataGasUsed = (*hexutil.Uint64)(h.ExtDataGasUsed) + enc.ExtDataHash = h.ExtDataHash enc.Hash = h.Hash() return json.Marshal(&enc) } @@ -60,23 +72,29 @@ func (h Header) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (h *Header) UnmarshalJSON(input []byte) error { type Header struct { - ParentHash *common.Hash `json:"parentHash" gencodec:"required"` - UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase *common.Address `json:"miner"` - Root *common.Hash `json:"stateRoot" gencodec:"required"` - TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom *Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest *common.Hash `json:"mixHash"` - Nonce *BlockNonce `json:"nonce"` - BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` - WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"` + ParentHash *common.Hash `json:"parentHash" gencodec:"required"` + UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase *common.Address `json:"miner"` + Root *common.Hash `json:"stateRoot" gencodec:"required"` + TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom *Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest *common.Hash `json:"mixHash"` + Nonce *BlockNonce `json:"nonce"` + BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` + WithdrawalsHash *common.Hash `json:"withdrawalsRoot,omitempty" rlp:"optional"` + ExtSize *hexutil.Uint64 `json:"size,omitempty" rlp:"optional"` + ExtTotalDifficulty *hexutil.Big `json:"totalDifficulty,omitempty" rlp:"optional"` + ExtBlockExtraData *hexutil.Bytes `json:"blockExtraData,omitempty" rlp:"optional"` + ExtBlockGasCost *hexutil.Uint64 `json:"blockGasCost,omitempty" rlp:"optional"` + ExtDataGasUsed *hexutil.Uint64 `json:"extDataGasUsed,omitempty" rlp:"optional"` + ExtDataHash *common.Hash `json:"extDataHash,omitempty" rlp:"optional"` } var dec Header if err := json.Unmarshal(input, &dec); err != nil { @@ -145,5 +163,23 @@ func (h *Header) UnmarshalJSON(input []byte) error { if dec.WithdrawalsHash != nil { h.WithdrawalsHash = dec.WithdrawalsHash } + if dec.ExtSize != nil { + h.ExtSize = (*uint64)(dec.ExtSize) + } + if dec.ExtTotalDifficulty != nil { + h.ExtTotalDifficulty = (*big.Int)(dec.ExtTotalDifficulty) + } + if dec.ExtBlockExtraData != nil { + h.ExtBlockExtraData = *dec.ExtBlockExtraData + } + if dec.ExtBlockGasCost != nil { + h.ExtBlockGasCost = (*uint64)(dec.ExtBlockGasCost) + } + if dec.ExtDataGasUsed != nil { + h.ExtDataGasUsed = (*uint64)(dec.ExtDataGasUsed) + } + if dec.ExtDataHash != nil { + h.ExtDataHash = dec.ExtDataHash + } return nil } diff --git a/go-ethereum/core/types/gen_header_rlp.go b/go-ethereum/core/types/gen_header_rlp.go index e566042a..8a72a00a 100644 --- a/go-ethereum/core/types/gen_header_rlp.go +++ b/go-ethereum/core/types/gen_header_rlp.go @@ -42,7 +42,13 @@ func (obj *Header) EncodeRLP(_w io.Writer) error { w.WriteBytes(obj.Nonce[:]) _tmp1 := obj.BaseFee != nil _tmp2 := obj.WithdrawalsHash != nil - if _tmp1 || _tmp2 { + _tmp3 := obj.ExtSize != nil + _tmp4 := obj.ExtTotalDifficulty != nil + _tmp5 := len(obj.ExtBlockExtraData) > 0 + _tmp6 := obj.ExtBlockGasCost != nil + _tmp7 := obj.ExtDataGasUsed != nil + _tmp8 := obj.ExtDataHash != nil + if _tmp1 || _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 || _tmp8 { if obj.BaseFee == nil { w.Write(rlp.EmptyString) } else { @@ -52,13 +58,54 @@ func (obj *Header) EncodeRLP(_w io.Writer) error { w.WriteBigInt(obj.BaseFee) } } - if _tmp2 { + if _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 || _tmp8 { if obj.WithdrawalsHash == nil { w.Write([]byte{0x80}) } else { w.WriteBytes(obj.WithdrawalsHash[:]) } } + if _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 || _tmp8 { + if obj.ExtSize == nil { + w.Write([]byte{0x80}) + } else { + w.WriteUint64((*obj.ExtSize)) + } + } + if _tmp4 || _tmp5 || _tmp6 || _tmp7 || _tmp8 { + if obj.ExtTotalDifficulty == nil { + w.Write(rlp.EmptyString) + } else { + if obj.ExtTotalDifficulty.Sign() == -1 { + return rlp.ErrNegativeBigInt + } + w.WriteBigInt(obj.ExtTotalDifficulty) + } + } + if _tmp5 || _tmp6 || _tmp7 || _tmp8 { + w.WriteBytes(obj.ExtBlockExtraData) + } + if _tmp6 || _tmp7 || _tmp8 { + if obj.ExtBlockGasCost == nil { + w.Write([]byte{0x80}) + } else { + w.WriteUint64((*obj.ExtBlockGasCost)) + } + } + if _tmp7 || _tmp8 { + if obj.ExtDataGasUsed == nil { + w.Write([]byte{0x80}) + } else { + w.WriteUint64((*obj.ExtDataGasUsed)) + } + } + if _tmp8 { + if obj.ExtDataHash == nil { + w.Write([]byte{0x80}) + } else { + w.WriteBytes(obj.ExtDataHash[:]) + } + } w.ListEnd(_tmp0) return w.Flush() } diff --git a/go-ethereum/core/types/legacy_tx.go b/go-ethereum/core/types/legacy_tx.go index 0b4442fe..90332df5 100644 --- a/go-ethereum/core/types/legacy_tx.go +++ b/go-ethereum/core/types/legacy_tx.go @@ -31,6 +31,10 @@ type LegacyTx struct { Value *big.Int // wei amount Data []byte // contract invocation input data V, R, S *big.Int // signature values + + // Optional Avalanche extension: + From *common.Address + ChainID *big.Int } // NewTransaction creates an unsigned legacy transaction. @@ -65,12 +69,14 @@ func (tx *LegacyTx) copy() TxData { To: copyAddressPtr(tx.To), Data: common.CopyBytes(tx.Data), Gas: tx.Gas, + From: copyAddressPtr(tx.From), // These are initialized below. Value: new(big.Int), GasPrice: new(big.Int), V: new(big.Int), R: new(big.Int), S: new(big.Int), + ChainID: new(big.Int), } if tx.Value != nil { cpy.Value.Set(tx.Value) @@ -87,6 +93,9 @@ func (tx *LegacyTx) copy() TxData { if tx.S != nil { cpy.S.Set(tx.S) } + if tx.ChainID != nil { + cpy.ChainID.Set(tx.ChainID) + } return cpy } diff --git a/go-ethereum/core/types/transaction_marshalling.go b/go-ethereum/core/types/transaction_marshalling.go index 40f63dea..ed98ae74 100644 --- a/go-ethereum/core/types/transaction_marshalling.go +++ b/go-ethereum/core/types/transaction_marshalling.go @@ -48,6 +48,9 @@ type txJSON struct { // Only used for encoding: Hash common.Hash `json:"hash"` + + // Optional Avalanche extension: + From *common.Address `json:"from,omitempty"` } // MarshalJSON marshals as JSON with a hash. @@ -86,6 +89,7 @@ func (t *Transaction) MarshalJSON() ([]byte, error) { enc.AccessList = &tx.AccessList enc.Nonce = (*hexutil.Uint64)(&tx.Nonce) enc.Gas = (*hexutil.Uint64)(&tx.Gas) + enc.GasPrice = (*hexutil.Big)(tx.gasPrice()) enc.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap) enc.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap) enc.Value = (*hexutil.Big)(tx.Value) @@ -152,6 +156,8 @@ func (t *Transaction) UnmarshalJSON(input []byte) error { return err } } + itx.ChainID = (*big.Int)(dec.ChainID) + itx.From = dec.From case AccessListTxType: var itx AccessListTx @@ -205,6 +211,7 @@ func (t *Transaction) UnmarshalJSON(input []byte) error { return err } } + itx.From = dec.From case DynamicFeeTxType: var itx DynamicFeeTx @@ -262,6 +269,7 @@ func (t *Transaction) UnmarshalJSON(input []byte) error { return err } } + itx.From = dec.From default: return ErrTxTypeNotSupported