eth-sign like signature hash (#15)
* eth-sign: initial implementation * sighash: pre-refactor * sighash: refactor, all old tests pass * sighash: test ovmsigner code paths for eip155 and eth_sign * sighash: tx serialization tests * sighash: refactor to sign bytes * common/varbytes: use varbytes serialization from btcd * transactionmeta: implement and test * rawdb: add new index * types/transaction: use txmeta * blockchain: index tx meta on new block * rpc: fix sendrawethsigntransaction docstring * meta test: remove dead code * ethapi: clean up comment * lint: fix * txmeta: clean up compares * ethapi: remove rlp tag * signer: remove rlp encoding tags from struct * types: use factory pattern for getting sighash type * sighash: migrate to using const * tx pool: use ovmsigner for tx validation * tx signing: fix eth_sign serialization * sighash: new version * sighash: commit to chainid * sighash: bugfixes * core/types: prevent panic on tx sort * core/types: rename to transaction_meta * core/blockchain: index txmeta * sighash: no native value * ethapi: use ovm signer * sighash: move chainid
This commit is contained in:
parent
538ddf8fc0
commit
680b4f874b
@ -246,7 +246,7 @@ func TestSimulatedBackend_NonceAt(t *testing.T) {
|
||||
}
|
||||
|
||||
// create a signed transaction to send
|
||||
tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil)
|
||||
tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil, types.SighashEIP155)
|
||||
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||
if err != nil {
|
||||
t.Errorf("could not sign tx: %v", err)
|
||||
@ -281,7 +281,7 @@ func TestSimulatedBackend_SendTransaction(t *testing.T) {
|
||||
bgCtx := context.Background()
|
||||
|
||||
// create a signed transaction to send
|
||||
tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil)
|
||||
tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil, types.SighashEIP155)
|
||||
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||
if err != nil {
|
||||
t.Errorf("could not sign tx: %v", err)
|
||||
@ -316,7 +316,7 @@ func TestSimulatedBackend_TransactionByHash(t *testing.T) {
|
||||
bgCtx := context.Background()
|
||||
|
||||
// create a signed transaction to send
|
||||
tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil)
|
||||
tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil, types.SighashEIP155)
|
||||
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||
if err != nil {
|
||||
t.Errorf("could not sign tx: %v", err)
|
||||
@ -481,7 +481,7 @@ func TestSimulatedBackend_TransactionCount(t *testing.T) {
|
||||
}
|
||||
|
||||
// create a signed transaction to send
|
||||
tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil)
|
||||
tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil, types.SighashEIP155)
|
||||
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||
if err != nil {
|
||||
t.Errorf("could not sign tx: %v", err)
|
||||
@ -540,7 +540,7 @@ func TestSimulatedBackend_TransactionInBlock(t *testing.T) {
|
||||
}
|
||||
|
||||
// create a signed transaction to send
|
||||
tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil)
|
||||
tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil, types.SighashEIP155)
|
||||
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||
if err != nil {
|
||||
t.Errorf("could not sign tx: %v", err)
|
||||
@ -599,7 +599,7 @@ func TestSimulatedBackend_PendingNonceAt(t *testing.T) {
|
||||
}
|
||||
|
||||
// create a signed transaction to send
|
||||
tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil)
|
||||
tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil, types.SighashEIP155)
|
||||
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||
if err != nil {
|
||||
t.Errorf("could not sign tx: %v", err)
|
||||
@ -622,7 +622,7 @@ func TestSimulatedBackend_PendingNonceAt(t *testing.T) {
|
||||
}
|
||||
|
||||
// make a new transaction with a nonce of 1
|
||||
tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil)
|
||||
tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil, types.SighashEIP155)
|
||||
signedTx, err = types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||
if err != nil {
|
||||
t.Errorf("could not sign tx: %v", err)
|
||||
@ -655,7 +655,7 @@ func TestSimulatedBackend_TransactionReceipt(t *testing.T) {
|
||||
bgCtx := context.Background()
|
||||
|
||||
// create a signed transaction to send
|
||||
tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil)
|
||||
tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil, nil, nil, types.SighashEIP155)
|
||||
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||
if err != nil {
|
||||
t.Errorf("could not sign tx: %v", err)
|
||||
|
@ -229,7 +229,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
|
||||
if contract == nil {
|
||||
rawTx = types.NewContractCreation(nonce, value, gasLimit, gasPrice, input, nil, nil)
|
||||
} else {
|
||||
rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input, nil, nil)
|
||||
rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input, nil, nil, types.SighashEIP155)
|
||||
}
|
||||
if opts.Signer == nil {
|
||||
return nil, errors.New("no signer to authorize the transaction with")
|
||||
|
@ -490,7 +490,7 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) {
|
||||
amount = new(big.Int).Mul(amount, new(big.Int).Exp(big.NewInt(5), big.NewInt(int64(msg.Tier)), nil))
|
||||
amount = new(big.Int).Div(amount, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(msg.Tier)), nil))
|
||||
|
||||
tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, 21000, f.price, nil, nil, nil)
|
||||
tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, 21000, f.price, nil, nil, nil, types.SighashEIP155)
|
||||
signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainID)
|
||||
if err != nil {
|
||||
f.lock.Unlock()
|
||||
|
383
common/varbytes.go
Normal file
383
common/varbytes.go
Normal file
@ -0,0 +1,383 @@
|
||||
// Copyright (c) 2013-2016 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
)
|
||||
|
||||
const (
|
||||
// MaxVarIntPayload is the maximum payload size for a variable length integer.
|
||||
MaxVarIntPayload = 9
|
||||
|
||||
// binaryFreeListMaxItems is the number of buffers to keep in the free
|
||||
// list to use for binary serialization and deserialization.
|
||||
binaryFreeListMaxItems = 1024
|
||||
)
|
||||
|
||||
var (
|
||||
// littleEndian is a convenience variable since binary.LittleEndian is
|
||||
// quite long.
|
||||
littleEndian = binary.LittleEndian
|
||||
)
|
||||
|
||||
// binaryFreeList defines a concurrent safe free list of byte slices (up to the
|
||||
// maximum number defined by the binaryFreeListMaxItems constant) that have a
|
||||
// cap of 8 (thus it supports up to a uint64). It is used to provide temporary
|
||||
// buffers for serializing and deserializing primitive numbers to and from their
|
||||
// binary encoding in order to greatly reduce the number of allocations
|
||||
// required.
|
||||
//
|
||||
// For convenience, functions are provided for each of the primitive unsigned
|
||||
// integers that automatically obtain a buffer from the free list, perform the
|
||||
// necessary binary conversion, read from or write to the given io.Reader or
|
||||
// io.Writer, and return the buffer to the free list.
|
||||
type binaryFreeList chan []byte
|
||||
|
||||
// Borrow returns a byte slice from the free list with a length of 8. A new
|
||||
// buffer is allocated if there are not any available on the free list.
|
||||
func (l binaryFreeList) Borrow() []byte {
|
||||
var buf []byte
|
||||
select {
|
||||
case buf = <-l:
|
||||
default:
|
||||
buf = make([]byte, 8)
|
||||
}
|
||||
return buf[:8]
|
||||
}
|
||||
|
||||
// Return puts the provided byte slice back on the free list. The buffer MUST
|
||||
// have been obtained via the Borrow function and therefore have a cap of 8.
|
||||
func (l binaryFreeList) Return(buf []byte) {
|
||||
select {
|
||||
case l <- buf:
|
||||
default:
|
||||
// Let it go to the garbage collector.
|
||||
}
|
||||
}
|
||||
|
||||
// Uint8 reads a single byte from the provided reader using a buffer from the
|
||||
// free list and returns it as a uint8.
|
||||
func (l binaryFreeList) Uint8(r io.Reader) (uint8, error) {
|
||||
buf := l.Borrow()[:1]
|
||||
if _, err := io.ReadFull(r, buf); err != nil {
|
||||
l.Return(buf)
|
||||
return 0, err
|
||||
}
|
||||
rv := buf[0]
|
||||
l.Return(buf)
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
// Uint16 reads two bytes from the provided reader using a buffer from the
|
||||
// free list, converts it to a number using the provided byte order, and returns
|
||||
// the resulting uint16.
|
||||
func (l binaryFreeList) Uint16(r io.Reader, byteOrder binary.ByteOrder) (uint16, error) {
|
||||
buf := l.Borrow()[:2]
|
||||
if _, err := io.ReadFull(r, buf); err != nil {
|
||||
l.Return(buf)
|
||||
return 0, err
|
||||
}
|
||||
rv := byteOrder.Uint16(buf)
|
||||
l.Return(buf)
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
// Uint32 reads four bytes from the provided reader using a buffer from the
|
||||
// free list, converts it to a number using the provided byte order, and returns
|
||||
// the resulting uint32.
|
||||
func (l binaryFreeList) Uint32(r io.Reader, byteOrder binary.ByteOrder) (uint32, error) {
|
||||
buf := l.Borrow()[:4]
|
||||
if _, err := io.ReadFull(r, buf); err != nil {
|
||||
l.Return(buf)
|
||||
return 0, err
|
||||
}
|
||||
rv := byteOrder.Uint32(buf)
|
||||
l.Return(buf)
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
// Uint64 reads eight bytes from the provided reader using a buffer from the
|
||||
// free list, converts it to a number using the provided byte order, and returns
|
||||
// the resulting uint64.
|
||||
func (l binaryFreeList) Uint64(r io.Reader, byteOrder binary.ByteOrder) (uint64, error) {
|
||||
buf := l.Borrow()[:8]
|
||||
if _, err := io.ReadFull(r, buf); err != nil {
|
||||
l.Return(buf)
|
||||
return 0, err
|
||||
}
|
||||
rv := byteOrder.Uint64(buf)
|
||||
l.Return(buf)
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
// PutUint8 copies the provided uint8 into a buffer from the free list and
|
||||
// writes the resulting byte to the given writer.
|
||||
func (l binaryFreeList) PutUint8(w io.Writer, val uint8) error {
|
||||
buf := l.Borrow()[:1]
|
||||
buf[0] = val
|
||||
_, err := w.Write(buf)
|
||||
l.Return(buf)
|
||||
return err
|
||||
}
|
||||
|
||||
// PutUint16 serializes the provided uint16 using the given byte order into a
|
||||
// buffer from the free list and writes the resulting two bytes to the given
|
||||
// writer.
|
||||
func (l binaryFreeList) PutUint16(w io.Writer, byteOrder binary.ByteOrder, val uint16) error {
|
||||
buf := l.Borrow()[:2]
|
||||
byteOrder.PutUint16(buf, val)
|
||||
_, err := w.Write(buf)
|
||||
l.Return(buf)
|
||||
return err
|
||||
}
|
||||
|
||||
// PutUint32 serializes the provided uint32 using the given byte order into a
|
||||
// buffer from the free list and writes the resulting four bytes to the given
|
||||
// writer.
|
||||
func (l binaryFreeList) PutUint32(w io.Writer, byteOrder binary.ByteOrder, val uint32) error {
|
||||
buf := l.Borrow()[:4]
|
||||
byteOrder.PutUint32(buf, val)
|
||||
_, err := w.Write(buf)
|
||||
l.Return(buf)
|
||||
return err
|
||||
}
|
||||
|
||||
// PutUint64 serializes the provided uint64 using the given byte order into a
|
||||
// buffer from the free list and writes the resulting eight bytes to the given
|
||||
// writer.
|
||||
func (l binaryFreeList) PutUint64(w io.Writer, byteOrder binary.ByteOrder, val uint64) error {
|
||||
buf := l.Borrow()[:8]
|
||||
byteOrder.PutUint64(buf, val)
|
||||
_, err := w.Write(buf)
|
||||
l.Return(buf)
|
||||
return err
|
||||
}
|
||||
|
||||
// binarySerializer provides a free list of buffers to use for serializing and
|
||||
// deserializing primitive integer values to and from io.Readers and io.Writers.
|
||||
var binarySerializer binaryFreeList = make(chan []byte, binaryFreeListMaxItems)
|
||||
|
||||
// errNonCanonicalVarInt is the common format string used for non-canonically
|
||||
// encoded variable length integer errors.
|
||||
var errNonCanonicalVarInt = "non-canonical varint %x - discriminant %x must " +
|
||||
"encode a value greater than %x"
|
||||
|
||||
// ReadVarInt reads a variable length integer from r and returns it as a uint64.
|
||||
func ReadVarInt(r io.Reader, pver uint32) (uint64, error) {
|
||||
discriminant, err := binarySerializer.Uint8(r)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var rv uint64
|
||||
switch discriminant {
|
||||
case 0xff:
|
||||
sv, err := binarySerializer.Uint64(r, littleEndian)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv = sv
|
||||
|
||||
// The encoding is not canonical if the value could have been
|
||||
// encoded using fewer bytes.
|
||||
min := uint64(0x100000000)
|
||||
if rv < min {
|
||||
return 0, messageError("ReadVarInt", fmt.Sprintf(
|
||||
errNonCanonicalVarInt, rv, discriminant, min))
|
||||
}
|
||||
|
||||
case 0xfe:
|
||||
sv, err := binarySerializer.Uint32(r, littleEndian)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv = uint64(sv)
|
||||
|
||||
// The encoding is not canonical if the value could have been
|
||||
// encoded using fewer bytes.
|
||||
min := uint64(0x10000)
|
||||
if rv < min {
|
||||
return 0, messageError("ReadVarInt", fmt.Sprintf(
|
||||
errNonCanonicalVarInt, rv, discriminant, min))
|
||||
}
|
||||
|
||||
case 0xfd:
|
||||
sv, err := binarySerializer.Uint16(r, littleEndian)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv = uint64(sv)
|
||||
|
||||
// The encoding is not canonical if the value could have been
|
||||
// encoded using fewer bytes.
|
||||
min := uint64(0xfd)
|
||||
if rv < min {
|
||||
return 0, messageError("ReadVarInt", fmt.Sprintf(
|
||||
errNonCanonicalVarInt, rv, discriminant, min))
|
||||
}
|
||||
|
||||
default:
|
||||
rv = uint64(discriminant)
|
||||
}
|
||||
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
// WriteVarInt serializes val to w using a variable number of bytes depending
|
||||
// on its value.
|
||||
func WriteVarInt(w io.Writer, pver uint32, val uint64) error {
|
||||
if val < 0xfd {
|
||||
return binarySerializer.PutUint8(w, uint8(val))
|
||||
}
|
||||
|
||||
if val <= math.MaxUint16 {
|
||||
err := binarySerializer.PutUint8(w, 0xfd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return binarySerializer.PutUint16(w, littleEndian, uint16(val))
|
||||
}
|
||||
|
||||
if val <= math.MaxUint32 {
|
||||
err := binarySerializer.PutUint8(w, 0xfe)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return binarySerializer.PutUint32(w, littleEndian, uint32(val))
|
||||
}
|
||||
|
||||
err := binarySerializer.PutUint8(w, 0xff)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return binarySerializer.PutUint64(w, littleEndian, val)
|
||||
}
|
||||
|
||||
// VarIntSerializeSize returns the number of bytes it would take to serialize
|
||||
// val as a variable length integer.
|
||||
func VarIntSerializeSize(val uint64) int {
|
||||
// The value is small enough to be represented by itself, so it's
|
||||
// just 1 byte.
|
||||
if val < 0xfd {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Discriminant 1 byte plus 2 bytes for the uint16.
|
||||
if val <= math.MaxUint16 {
|
||||
return 3
|
||||
}
|
||||
|
||||
// Discriminant 1 byte plus 4 bytes for the uint32.
|
||||
if val <= math.MaxUint32 {
|
||||
return 5
|
||||
}
|
||||
|
||||
// Discriminant 1 byte plus 8 bytes for the uint64.
|
||||
return 9
|
||||
}
|
||||
|
||||
// ReadVarString reads a variable length string from r and returns it as a Go
|
||||
// string. A variable length string is encoded as a variable length integer
|
||||
// containing the length of the string followed by the bytes that represent the
|
||||
// string itself.
|
||||
func ReadVarString(r io.Reader, pver uint32) (string, error) {
|
||||
count, err := ReadVarInt(r, pver)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
buf := make([]byte, count)
|
||||
_, err = io.ReadFull(r, buf)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(buf), nil
|
||||
}
|
||||
|
||||
// WriteVarString serializes str to w as a variable length integer containing
|
||||
// the length of the string followed by the bytes that represent the string
|
||||
// itself.
|
||||
func WriteVarString(w io.Writer, pver uint32, str string) error {
|
||||
err := WriteVarInt(w, pver, uint64(len(str)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write([]byte(str))
|
||||
return err
|
||||
}
|
||||
|
||||
// ReadVarBytes reads a variable length byte array. A byte array is encoded
|
||||
// as a varInt containing the length of the array followed by the bytes
|
||||
// themselves. An error is returned if the length is greater than the
|
||||
// passed maxAllowed parameter which helps protect against memory exhaustion
|
||||
// attacks and forced panics through malformed messages. The fieldName
|
||||
// parameter is only used for the error message so it provides more context in
|
||||
// the error.
|
||||
func ReadVarBytes(r io.Reader, pver uint32, maxAllowed uint32,
|
||||
fieldName string) ([]byte, error) {
|
||||
|
||||
count, err := ReadVarInt(r, pver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Prevent byte array larger than the max message size. It would
|
||||
// be possible to cause memory exhaustion and panics without a sane
|
||||
// upper bound on this count.
|
||||
if count > uint64(maxAllowed) {
|
||||
str := fmt.Sprintf("%s is larger than the max allowed size "+
|
||||
"[count %d, max %d]", fieldName, count, maxAllowed)
|
||||
return nil, messageError("ReadVarBytes", str)
|
||||
}
|
||||
|
||||
b := make([]byte, count)
|
||||
_, err = io.ReadFull(r, b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// WriteVarBytes serializes a variable length byte array to w as a varInt
|
||||
// containing the number of bytes, followed by the bytes themselves.
|
||||
func WriteVarBytes(w io.Writer, pver uint32, bytes []byte) error {
|
||||
slen := uint64(len(bytes))
|
||||
err := WriteVarInt(w, pver, slen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = w.Write(bytes)
|
||||
return err
|
||||
}
|
||||
|
||||
// MessageError describes an issue with a message.
|
||||
// An example of some potential issues are messages from the wrong bitcoin
|
||||
// network, invalid commands, mismatched checksums, and exceeding max payloads.
|
||||
//
|
||||
// This provides a mechanism for the caller to type assert the error to
|
||||
// differentiate between general io errors such as io.EOF and issues that
|
||||
// resulted from malformed messages.
|
||||
type MessageError struct {
|
||||
Func string // Function name
|
||||
Description string // Human readable description of the issue
|
||||
}
|
||||
|
||||
// Error satisfies the error interface and prints human-readable errors.
|
||||
func (e *MessageError) Error() string {
|
||||
if e.Func != "" {
|
||||
return fmt.Sprintf("%v: %v", e.Func, e.Description)
|
||||
}
|
||||
return e.Description
|
||||
}
|
||||
|
||||
// messageError creates an error for the given function and description.
|
||||
func messageError(f string, desc string) *MessageError {
|
||||
return &MessageError{Func: f, Description: desc}
|
||||
}
|
@ -65,7 +65,7 @@ func TestReimportMirroredState(t *testing.T) {
|
||||
// We want to simulate an empty middle block, having the same state as the
|
||||
// first one. The last is needs a state change again to force a reorg.
|
||||
if i != 1 {
|
||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(addr), common.Address{0x00}, new(big.Int), params.TxGas, nil, nil, nil, nil), signer, key)
|
||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(addr), common.Address{0x00}, new(big.Int), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
|
||||
toaddr := common.Address{}
|
||||
data := make([]byte, nbytes)
|
||||
gas, _ := IntrinsicGas(data, false, false, false)
|
||||
tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(benchRootAddr), toaddr, big.NewInt(1), gas, nil, data, nil, nil), types.HomesteadSigner{}, benchRootKey)
|
||||
tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(benchRootAddr), toaddr, big.NewInt(1), gas, nil, data, nil, nil, types.SighashEIP155), types.HomesteadSigner{}, benchRootKey)
|
||||
gen.AddTx(tx)
|
||||
}
|
||||
}
|
||||
@ -119,7 +119,7 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
|
||||
break
|
||||
}
|
||||
to := (from + 1) % naccounts
|
||||
tx := types.NewTransaction(gen.TxNonce(ringAddrs[from]), ringAddrs[to], benchRootFunds, params.TxGas, nil, nil, nil, nil)
|
||||
tx := types.NewTransaction(gen.TxNonce(ringAddrs[from]), ringAddrs[to], benchRootFunds, params.TxGas, nil, nil, nil, nil, types.SighashEIP155)
|
||||
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, ringKeys[from])
|
||||
gen.AddTx(tx)
|
||||
from = to
|
||||
|
@ -1221,6 +1221,9 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
|
||||
rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body())
|
||||
rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i])
|
||||
rawdb.WriteTxLookupEntries(batch, block)
|
||||
for _, tx := range block.Transactions() {
|
||||
rawdb.WriteTransactionMeta(batch, tx.Hash(), tx.GetMeta())
|
||||
}
|
||||
|
||||
// Write everything belongs to the blocks into the database. So that
|
||||
// we can ensure all components of body is completed(body, receipts,
|
||||
@ -1343,6 +1346,9 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
||||
blockBatch := bc.db.NewBatch()
|
||||
rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd)
|
||||
rawdb.WriteBlock(blockBatch, block)
|
||||
for _, tx := range block.Transactions() {
|
||||
rawdb.WriteTransactionMeta(blockBatch, tx.Hash(), tx.GetMeta())
|
||||
}
|
||||
rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts)
|
||||
rawdb.WritePreimages(blockBatch, state.Preimages())
|
||||
if err := blockBatch.Write(); err != nil {
|
||||
|
@ -607,7 +607,7 @@ func TestFastVsFullChains(t *testing.T) {
|
||||
// If the block number is multiple of 3, send a few bonus transactions to the miner
|
||||
if i%3 == 2 {
|
||||
for j := 0; j < i%4+1; j++ {
|
||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, key)
|
||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -840,8 +840,8 @@ func TestChainTxReorgs(t *testing.T) {
|
||||
// Create two transactions shared between the chains:
|
||||
// - postponed: transaction included at a later block in the forked chain
|
||||
// - swapped: transaction included at the same block number in the forked chain
|
||||
postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, key1)
|
||||
swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, key1)
|
||||
postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, key1)
|
||||
swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, key1)
|
||||
|
||||
// Create two transactions that will be dropped by the forked chain:
|
||||
// - pastDrop: transaction dropped retroactively from a past block
|
||||
@ -857,13 +857,13 @@ func TestChainTxReorgs(t *testing.T) {
|
||||
chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
|
||||
switch i {
|
||||
case 0:
|
||||
pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, key2)
|
||||
pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, key2)
|
||||
|
||||
gen.AddTx(pastDrop) // This transaction will be dropped in the fork from below the split point
|
||||
gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
|
||||
|
||||
case 2:
|
||||
freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, key2)
|
||||
freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, key2)
|
||||
|
||||
gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
|
||||
gen.AddTx(swapped) // This transaction will be swapped out at the exact height
|
||||
@ -882,18 +882,18 @@ func TestChainTxReorgs(t *testing.T) {
|
||||
chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
|
||||
switch i {
|
||||
case 0:
|
||||
pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, key3)
|
||||
pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, key3)
|
||||
gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
|
||||
|
||||
case 2:
|
||||
gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
|
||||
gen.AddTx(swapped) // This transaction was swapped from the exact current spot in the original chain
|
||||
|
||||
freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, key3)
|
||||
freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, key3)
|
||||
gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
|
||||
|
||||
case 3:
|
||||
futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, key3)
|
||||
futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, key3)
|
||||
gen.AddTx(futureAdd) // This transaction will be added after a full reorg
|
||||
}
|
||||
})
|
||||
@ -1340,7 +1340,7 @@ func TestEIP155Transition(t *testing.T) {
|
||||
tx *types.Transaction
|
||||
err error
|
||||
basicTx = func(signer types.Signer) (*types.Transaction, error) {
|
||||
return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil, nil, nil), signer, key)
|
||||
return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil, nil, nil, types.SighashEIP155), signer, key)
|
||||
}
|
||||
)
|
||||
switch i {
|
||||
@ -1403,7 +1403,7 @@ func TestEIP155Transition(t *testing.T) {
|
||||
tx *types.Transaction
|
||||
err error
|
||||
basicTx = func(signer types.Signer) (*types.Transaction, error) {
|
||||
return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil, nil, nil), signer, key)
|
||||
return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil, nil, nil, types.SighashEIP155), signer, key)
|
||||
}
|
||||
)
|
||||
if i == 0 {
|
||||
@ -1453,11 +1453,11 @@ func TestEIP161AccountRemoval(t *testing.T) {
|
||||
)
|
||||
switch i {
|
||||
case 0:
|
||||
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil, nil, nil), signer, key)
|
||||
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil, nil, nil, types.SighashEIP155), signer, key)
|
||||
case 1:
|
||||
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil, nil, nil), signer, key)
|
||||
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil, nil, nil, types.SighashEIP155), signer, key)
|
||||
case 2:
|
||||
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil, nil, nil), signer, key)
|
||||
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil, nil, nil, types.SighashEIP155), signer, key)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -2166,7 +2166,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
|
||||
for txi := 0; txi < numTxs; txi++ {
|
||||
uniq := uint64(i*numTxs + txi)
|
||||
recipient := recipientFn(uniq)
|
||||
tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil, nil, nil), signer, testBankKey)
|
||||
tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil, nil, nil, types.SighashEIP155), signer, testBankKey)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
@ -2346,10 +2346,10 @@ func TestDeleteCreateRevert(t *testing.T) {
|
||||
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
|
||||
b.SetCoinbase(common.Address{1})
|
||||
// One transaction to AAAA
|
||||
tx, _ := types.SignTx(types.NewTransaction(0, aa, big.NewInt(0), 50000, big.NewInt(1), nil, nil, nil), types.HomesteadSigner{}, key)
|
||||
tx, _ := types.SignTx(types.NewTransaction(0, aa, big.NewInt(0), 50000, big.NewInt(1), nil, nil, nil, types.SighashEIP155), types.HomesteadSigner{}, key)
|
||||
b.AddTx(tx)
|
||||
// One transaction to BBBB
|
||||
tx, _ = types.SignTx(types.NewTransaction(1, bb, big.NewInt(0), 100000, big.NewInt(1), nil, nil, nil), types.HomesteadSigner{}, key)
|
||||
tx, _ = types.SignTx(types.NewTransaction(1, bb, big.NewInt(0), 100000, big.NewInt(1), nil, nil, nil, types.SighashEIP155), types.HomesteadSigner{}, key)
|
||||
b.AddTx(tx)
|
||||
})
|
||||
// Import the canonical chain
|
||||
|
@ -338,6 +338,53 @@ func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
|
||||
}
|
||||
}
|
||||
|
||||
// ReadTransactionMeta returns the transaction metadata associated with a
|
||||
// transaction hash.
|
||||
func ReadTransactionMeta(db ethdb.Reader, hash common.Hash) *types.TransactionMeta {
|
||||
data := ReadTransactionMetaRaw(db, hash)
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
meta, err := types.TxMetaDecode(data)
|
||||
if err != nil {
|
||||
log.Error("Invalid raw tx meta ", "hash", hash, "err", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return meta
|
||||
}
|
||||
|
||||
// ReadTransactionMetaRaw returns the raw transaction metadata associated with a
|
||||
// transaction hash.
|
||||
func ReadTransactionMetaRaw(db ethdb.Reader, hash common.Hash) []byte {
|
||||
data, _ := db.Get(txMetaKey(hash))
|
||||
if len(data) > 0 {
|
||||
return data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteTransactionMeta writes the TransactionMeta to disk by hash.
|
||||
func WriteTransactionMeta(db ethdb.KeyValueWriter, hash common.Hash, meta *types.TransactionMeta) {
|
||||
data := types.TxMetaEncode(meta)
|
||||
WriteTransactionMetaRaw(db, hash, data)
|
||||
}
|
||||
|
||||
// WriteTransactionMetaRaw writes the raw transaction metadata bytes to disk.
|
||||
func WriteTransactionMetaRaw(db ethdb.KeyValueWriter, hash common.Hash, data []byte) {
|
||||
if err := db.Put(txMetaKey(hash), data); err != nil {
|
||||
log.Crit("Failed to store transaction meta", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteTransactionMeta removes the transaction metadata associated with a hash
|
||||
func DeleteTransactionMeta(db ethdb.KeyValueWriter, hash common.Hash) {
|
||||
if err := db.Delete(txMetaKey(hash)); err != nil {
|
||||
log.Crit("Failed to delete transaction meta", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
// ReadTdRLP retrieves a block's total difficulty corresponding to the hash in RLP encoding.
|
||||
func ReadTdRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
|
||||
// First try to look up the data in ancient database. Extra hash
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
@ -273,8 +274,8 @@ func TestBlockReceiptStorage(t *testing.T) {
|
||||
db := NewMemoryDatabase()
|
||||
|
||||
// Create a live block since we need metadata to reconstruct the receipt
|
||||
tx1 := types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil, nil, nil)
|
||||
tx2 := types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil, nil, nil)
|
||||
tx1 := types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil, nil, nil, types.SighashEIP155)
|
||||
tx2 := types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil, nil, nil, types.SighashEIP155)
|
||||
|
||||
body := &types.Body{Transactions: types.Transactions{tx1, tx2}}
|
||||
|
||||
@ -424,3 +425,49 @@ func TestAncientStorage(t *testing.T) {
|
||||
t.Fatalf("invalid td returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlockMetaStorage(t *testing.T) {
|
||||
db := NewMemoryDatabase()
|
||||
|
||||
tx1 := types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil, nil, nil, types.SighashEIP155)
|
||||
|
||||
WriteTransactionMeta(db, tx1.Hash(), tx1.GetMeta())
|
||||
meta := ReadTransactionMeta(db, tx1.Hash())
|
||||
|
||||
if meta.L1MessageSender != nil {
|
||||
t.Fatalf("Could not recover L1MessageSender")
|
||||
}
|
||||
if meta.L1RollupTxId != nil {
|
||||
t.Fatalf("Could not recover L1RollupTxId")
|
||||
}
|
||||
|
||||
if meta.SignatureHashType != types.SighashEIP155 {
|
||||
t.Fatalf("Could not recover sighash type")
|
||||
}
|
||||
|
||||
DeleteTransactionMeta(db, tx1.Hash())
|
||||
postDelete := ReadTransactionMeta(db, tx1.Hash())
|
||||
|
||||
if postDelete != nil {
|
||||
t.Fatalf("Delete did not work")
|
||||
}
|
||||
|
||||
addr := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87")
|
||||
txid := hexutil.Uint64(777)
|
||||
|
||||
tx2 := types.NewTransaction(2, common.HexToAddress("0x02"), big.NewInt(2), 2, big.NewInt(2), nil, &addr, &txid, types.SighashEthSign)
|
||||
|
||||
WriteTransactionMeta(db, tx2.Hash(), tx2.GetMeta())
|
||||
meta2 := ReadTransactionMeta(db, tx2.Hash())
|
||||
|
||||
if !bytes.Equal(meta2.L1MessageSender.Bytes(), addr.Bytes()) {
|
||||
t.Fatalf("Could not recover L1MessageSender")
|
||||
}
|
||||
|
||||
if *meta2.L1RollupTxId != txid {
|
||||
t.Fatalf("Could not recover L1RollupTxId")
|
||||
}
|
||||
if meta2.SignatureHashType != types.SighashEthSign {
|
||||
t.Fatalf("Could not recover sighash type")
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,11 @@ func ReadTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, com
|
||||
}
|
||||
for txIndex, tx := range body.Transactions {
|
||||
if tx.Hash() == hash {
|
||||
txMeta := ReadTransactionMeta(db, hash)
|
||||
if txMeta != nil {
|
||||
tx.SetTransactionMeta(txMeta)
|
||||
}
|
||||
|
||||
return tx, blockHash, *blockNumber, uint64(txIndex)
|
||||
}
|
||||
}
|
||||
|
@ -74,9 +74,9 @@ func TestLookupStorage(t *testing.T) {
|
||||
l1RollupTxId1 := hexutil.Uint64(1)
|
||||
l1RollupTxId2 := hexutil.Uint64(2)
|
||||
|
||||
tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11}, &sender1, &l1RollupTxId1)
|
||||
tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22}, &sender2, &l1RollupTxId2)
|
||||
tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}, nil, &l1RollupTxId1)
|
||||
tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11}, &sender1, &l1RollupTxId1, types.SighashEIP155)
|
||||
tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22}, &sender2, &l1RollupTxId2, types.SighashEIP155)
|
||||
tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}, nil, &l1RollupTxId1, types.SighashEIP155)
|
||||
txs := []*types.Transaction{tx1, tx2, tx3}
|
||||
|
||||
block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil)
|
||||
|
@ -53,6 +53,9 @@ var (
|
||||
txLookupPrefix = []byte("l") // txLookupPrefix + hash -> transaction/receipt lookup metadata
|
||||
bloomBitsPrefix = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits
|
||||
|
||||
// Optmism specific
|
||||
txMetaPrefix = []byte("x") // txMetaPrefix + hash -> transaction metadata
|
||||
|
||||
preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage
|
||||
configPrefix = []byte("ethereum-config-") // config prefix for the db
|
||||
|
||||
@ -145,6 +148,11 @@ func txLookupKey(hash common.Hash) []byte {
|
||||
return append(txLookupPrefix, hash.Bytes()...)
|
||||
}
|
||||
|
||||
// txMetaKey = txMetaPrefix + hash
|
||||
func txMetaKey(hash common.Hash) []byte {
|
||||
return append(txMetaPrefix, hash.Bytes()...)
|
||||
}
|
||||
|
||||
// bloomBitsKey = bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash
|
||||
func bloomBitsKey(bit uint, section uint64, hash common.Hash) []byte {
|
||||
key := append(append(bloomBitsPrefix, make([]byte, 10)...), hash.Bytes()...)
|
||||
|
@ -271,7 +271,7 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block
|
||||
config: config,
|
||||
chainconfig: chainconfig,
|
||||
chain: chain,
|
||||
signer: types.NewEIP155Signer(chainconfig.ChainID),
|
||||
signer: types.NewOVMSigner(chainconfig.ChainID),
|
||||
pending: make(map[common.Address]*txList),
|
||||
queue: make(map[common.Address]*txList),
|
||||
beats: make(map[common.Address]time.Time),
|
||||
|
@ -73,7 +73,7 @@ func transaction(nonce uint64, gaslimit uint64, key *ecdsa.PrivateKey) *types.Tr
|
||||
}
|
||||
|
||||
func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction {
|
||||
tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, gasprice, nil, nil, nil), types.HomesteadSigner{}, key)
|
||||
tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, gasprice, nil, nil, nil, types.SighashEIP155), types.HomesteadSigner{}, key)
|
||||
return tx
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key
|
||||
data := make([]byte, bytes)
|
||||
rand.Read(data)
|
||||
|
||||
tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data, nil, nil), types.HomesteadSigner{}, key)
|
||||
tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data, nil, nil, types.SighashEIP155), types.HomesteadSigner{}, key)
|
||||
return tx
|
||||
}
|
||||
|
||||
@ -329,7 +329,7 @@ func TestTransactionNegativeValue(t *testing.T) {
|
||||
pool, key := setupTxPool()
|
||||
defer pool.Stop()
|
||||
|
||||
tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), 100, big.NewInt(1), nil, nil, nil), types.HomesteadSigner{}, key)
|
||||
tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), 100, big.NewInt(1), nil, nil, nil, types.SighashEIP155), types.HomesteadSigner{}, key)
|
||||
from, _ := deriveSender(tx)
|
||||
pool.currentState.AddBalance(from, big.NewInt(1))
|
||||
if err := pool.AddRemote(tx); err != ErrNegativeValue {
|
||||
@ -383,9 +383,9 @@ func TestTransactionDoubleNonce(t *testing.T) {
|
||||
resetState()
|
||||
|
||||
signer := types.HomesteadSigner{}
|
||||
tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 100000, big.NewInt(1), nil, nil, nil), signer, key)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(2), nil, nil, nil), signer, key)
|
||||
tx3, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(1), nil, nil, nil), signer, key)
|
||||
tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 100000, big.NewInt(1), nil, nil, nil, types.SighashEIP155), signer, key)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(2), nil, nil, nil, types.SighashEIP155), signer, key)
|
||||
tx3, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(1), nil, nil, nil, types.SighashEIP155), signer, key)
|
||||
|
||||
// Add the first two transaction, ensure higher priced stays only
|
||||
if replace, err := pool.add(tx1, false); err != nil || replace {
|
||||
|
@ -50,7 +50,7 @@ func TestBlockEncoding(t *testing.T) {
|
||||
check("Time", block.Time(), uint64(1426516743))
|
||||
check("Size", block.Size(), common.StorageSize(len(blockEnc)))
|
||||
|
||||
tx1 := NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), 50000, big.NewInt(10), nil, nil, nil)
|
||||
tx1 := NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), 50000, big.NewInt(10), nil, nil, nil, SighashEIP155)
|
||||
tx1, _ = tx1.WithSignature(HomesteadSigner{}, common.Hex2Bytes("9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b100"))
|
||||
check("len(Transactions)", len(block.Transactions()), 1)
|
||||
check("Transactions[0].Hash", block.Transactions()[0].Hash(), tx1.Hash())
|
||||
|
@ -13,101 +13,111 @@ import (
|
||||
|
||||
var _ = (*txdataMarshaling)(nil)
|
||||
|
||||
// MarshalJSON marshals as JSON.
|
||||
func (t txdata) MarshalJSON() ([]byte, error) {
|
||||
type txdata struct {
|
||||
AccountNonce hexutil.Uint64 `json:"nonce" gencodec:"required"`
|
||||
Price *hexutil.Big `json:"gasPrice" gencodec:"required"`
|
||||
GasLimit hexutil.Uint64 `json:"gas" gencodec:"required"`
|
||||
Recipient *common.Address `json:"to" rlp:"nil"`
|
||||
Amount *hexutil.Big `json:"value" gencodec:"required"`
|
||||
Payload hexutil.Bytes `json:"input" gencodec:"required"`
|
||||
V *hexutil.Big `json:"v" gencodec:"required"`
|
||||
R *hexutil.Big `json:"r" gencodec:"required"`
|
||||
S *hexutil.Big `json:"s" gencodec:"required"`
|
||||
Hash *common.Hash `json:"hash" rlp:"-"`
|
||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty" rlp:"nil,?"`
|
||||
L1MessageSender *common.Address `json:"l1MessageSender,omitempty" rlp:"nil,?"`
|
||||
// TransactionMarshalJSON marshals as JSON.
|
||||
func TransactionMarshalJSON(t *Transaction) ([]byte, error) {
|
||||
type txnjson struct {
|
||||
AccountNonce hexutil.Uint64 `json:"nonce" gencodec:"required"`
|
||||
Price *hexutil.Big `json:"gasPrice" gencodec:"required"`
|
||||
GasLimit hexutil.Uint64 `json:"gas" gencodec:"required"`
|
||||
Recipient *common.Address `json:"to" rlp:"nil"`
|
||||
Amount *hexutil.Big `json:"value" gencodec:"required"`
|
||||
Payload hexutil.Bytes `json:"input" gencodec:"required"`
|
||||
V *hexutil.Big `json:"v" gencodec:"required"`
|
||||
R *hexutil.Big `json:"r" gencodec:"required"`
|
||||
S *hexutil.Big `json:"s" gencodec:"required"`
|
||||
Hash *common.Hash `json:"hash" rlp:"-"`
|
||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty" rlp:"nil,?"`
|
||||
L1MessageSender *common.Address `json:"l1MessageSender,omitempty" rlp:"nil,?"`
|
||||
SignatureHashType SignatureHashType `json:"signatureHashType,omitempty" rlp:"nil,?"`
|
||||
}
|
||||
var enc txdata
|
||||
enc.AccountNonce = hexutil.Uint64(t.AccountNonce)
|
||||
enc.Price = (*hexutil.Big)(t.Price)
|
||||
enc.GasLimit = hexutil.Uint64(t.GasLimit)
|
||||
enc.Recipient = t.Recipient
|
||||
enc.L1MessageSender = t.L1MessageSender
|
||||
enc.L1RollupTxId = t.L1RollupTxId
|
||||
enc.Amount = (*hexutil.Big)(t.Amount)
|
||||
enc.Payload = t.Payload
|
||||
enc.V = (*hexutil.Big)(t.V)
|
||||
enc.R = (*hexutil.Big)(t.R)
|
||||
enc.S = (*hexutil.Big)(t.S)
|
||||
enc.Hash = t.Hash
|
||||
|
||||
var enc txnjson
|
||||
enc.AccountNonce = hexutil.Uint64(t.data.AccountNonce)
|
||||
enc.Price = (*hexutil.Big)(t.data.Price)
|
||||
enc.GasLimit = hexutil.Uint64(t.data.GasLimit)
|
||||
enc.Recipient = t.data.Recipient
|
||||
enc.L1MessageSender = t.meta.L1MessageSender
|
||||
enc.L1RollupTxId = t.meta.L1RollupTxId
|
||||
enc.SignatureHashType = t.meta.SignatureHashType
|
||||
enc.Amount = (*hexutil.Big)(t.data.Amount)
|
||||
enc.Payload = t.data.Payload
|
||||
enc.V = (*hexutil.Big)(t.data.V)
|
||||
enc.R = (*hexutil.Big)(t.data.R)
|
||||
enc.S = (*hexutil.Big)(t.data.S)
|
||||
hash := t.Hash()
|
||||
enc.Hash = &hash
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals from JSON.
|
||||
func (t *txdata) UnmarshalJSON(input []byte) error {
|
||||
type txdata struct {
|
||||
AccountNonce *hexutil.Uint64 `json:"nonce" gencodec:"required"`
|
||||
Price *hexutil.Big `json:"gasPrice" gencodec:"required"`
|
||||
GasLimit *hexutil.Uint64 `json:"gas" gencodec:"required"`
|
||||
Recipient *common.Address `json:"to" rlp:"nil"`
|
||||
Amount *hexutil.Big `json:"value" gencodec:"required"`
|
||||
Payload *hexutil.Bytes `json:"input" gencodec:"required"`
|
||||
V *hexutil.Big `json:"v" gencodec:"required"`
|
||||
R *hexutil.Big `json:"r" gencodec:"required"`
|
||||
S *hexutil.Big `json:"s" gencodec:"required"`
|
||||
Hash *common.Hash `json:"hash" rlp:"-"`
|
||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty" rlp:"nil,?"`
|
||||
L1MessageSender *common.Address `json:"l1MessageSender,omitempty" rlp:"nil,?"`
|
||||
func TransactionUnmarshalJSON(input []byte) (*Transaction, error) {
|
||||
type txnjson struct {
|
||||
AccountNonce *hexutil.Uint64 `json:"nonce" gencodec:"required"`
|
||||
Price *hexutil.Big `json:"gasPrice" gencodec:"required"`
|
||||
GasLimit *hexutil.Uint64 `json:"gas" gencodec:"required"`
|
||||
Recipient *common.Address `json:"to" rlp:"nil"`
|
||||
Amount *hexutil.Big `json:"value" gencodec:"required"`
|
||||
Payload *hexutil.Bytes `json:"input" gencodec:"required"`
|
||||
V *hexutil.Big `json:"v" gencodec:"required"`
|
||||
R *hexutil.Big `json:"r" gencodec:"required"`
|
||||
S *hexutil.Big `json:"s" gencodec:"required"`
|
||||
Hash *common.Hash `json:"hash" rlp:"-"`
|
||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty"`
|
||||
L1MessageSender *common.Address `json:"l1MessageSender,omitempty"`
|
||||
SignatureHashType SignatureHashType `json:"signatureHashType"`
|
||||
}
|
||||
var dec txdata
|
||||
|
||||
var t Transaction
|
||||
var dec txnjson
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
return err
|
||||
return &Transaction{}, err
|
||||
}
|
||||
if dec.AccountNonce == nil {
|
||||
return errors.New("missing required field 'nonce' for txdata")
|
||||
return &Transaction{}, errors.New("missing required field 'nonce' for txdata")
|
||||
}
|
||||
t.AccountNonce = uint64(*dec.AccountNonce)
|
||||
t.data.AccountNonce = uint64(*dec.AccountNonce)
|
||||
if dec.Price == nil {
|
||||
return errors.New("missing required field 'gasPrice' for txdata")
|
||||
return &Transaction{}, errors.New("missing required field 'gasPrice' for txdata")
|
||||
}
|
||||
t.Price = (*big.Int)(dec.Price)
|
||||
t.data.Price = (*big.Int)(dec.Price)
|
||||
if dec.GasLimit == nil {
|
||||
return errors.New("missing required field 'gas' for txdata")
|
||||
return &Transaction{}, errors.New("missing required field 'gas' for txdata")
|
||||
}
|
||||
t.GasLimit = uint64(*dec.GasLimit)
|
||||
t.data.GasLimit = uint64(*dec.GasLimit)
|
||||
if dec.Recipient != nil {
|
||||
t.Recipient = dec.Recipient
|
||||
t.data.Recipient = dec.Recipient
|
||||
}
|
||||
if dec.L1MessageSender != nil {
|
||||
t.L1MessageSender = dec.L1MessageSender
|
||||
t.meta.L1MessageSender = dec.L1MessageSender
|
||||
}
|
||||
if dec.L1RollupTxId != nil {
|
||||
t.L1RollupTxId = dec.L1RollupTxId
|
||||
t.meta.L1RollupTxId = dec.L1RollupTxId
|
||||
}
|
||||
|
||||
t.meta.SignatureHashType = dec.SignatureHashType
|
||||
|
||||
if dec.Amount == nil {
|
||||
return errors.New("missing required field 'value' for txdata")
|
||||
return &Transaction{}, errors.New("missing required field 'value' for txdata")
|
||||
}
|
||||
t.Amount = (*big.Int)(dec.Amount)
|
||||
t.data.Amount = (*big.Int)(dec.Amount)
|
||||
if dec.Payload == nil {
|
||||
return errors.New("missing required field 'input' for txdata")
|
||||
return &Transaction{}, errors.New("missing required field 'input' for txdata")
|
||||
}
|
||||
t.Payload = *dec.Payload
|
||||
t.data.Payload = *dec.Payload
|
||||
if dec.V == nil {
|
||||
return errors.New("missing required field 'v' for txdata")
|
||||
return &Transaction{}, errors.New("missing required field 'v' for txdata")
|
||||
}
|
||||
t.V = (*big.Int)(dec.V)
|
||||
t.data.V = (*big.Int)(dec.V)
|
||||
if dec.R == nil {
|
||||
return errors.New("missing required field 'r' for txdata")
|
||||
return &Transaction{}, errors.New("missing required field 'r' for txdata")
|
||||
}
|
||||
t.R = (*big.Int)(dec.R)
|
||||
t.data.R = (*big.Int)(dec.R)
|
||||
if dec.S == nil {
|
||||
return errors.New("missing required field 's' for txdata")
|
||||
return &Transaction{}, errors.New("missing required field 's' for txdata")
|
||||
}
|
||||
t.S = (*big.Int)(dec.S)
|
||||
t.data.S = (*big.Int)(dec.S)
|
||||
if dec.Hash != nil {
|
||||
t.Hash = dec.Hash
|
||||
t.data.Hash = dec.Hash
|
||||
}
|
||||
return nil
|
||||
return &t, nil
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ func TestLegacyReceiptDecoding(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
tx := NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil, nil, nil)
|
||||
tx := NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil, nil, nil, SighashEIP155)
|
||||
receipt := &Receipt{
|
||||
Status: ReceiptStatusFailed,
|
||||
CumulativeGasUsed: 1,
|
||||
@ -156,7 +156,7 @@ func TestDeriveFields(t *testing.T) {
|
||||
// Create a few transactions to have receipts for
|
||||
txs := Transactions{
|
||||
NewContractCreation(1, big.NewInt(1), 1, big.NewInt(1), nil, nil, nil),
|
||||
NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil, nil, nil),
|
||||
NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil, nil, nil, SighashEIP155),
|
||||
}
|
||||
// Create the corresponding receipts
|
||||
receipts := Receipts{
|
||||
|
@ -36,8 +36,16 @@ var (
|
||||
ErrInvalidSig = errors.New("invalid transaction v, r, s values")
|
||||
)
|
||||
|
||||
type SignatureHashType uint8
|
||||
|
||||
const (
|
||||
SighashEIP155 SignatureHashType = 0
|
||||
SighashEthSign SignatureHashType = 1
|
||||
)
|
||||
|
||||
type Transaction struct {
|
||||
data txdata
|
||||
meta TransactionMeta
|
||||
// caches
|
||||
hash atomic.Value
|
||||
size atomic.Value
|
||||
@ -58,9 +66,7 @@ type txdata struct {
|
||||
S *big.Int `json:"s" gencodec:"required"`
|
||||
|
||||
// This is only used when marshaling to JSON.
|
||||
Hash *common.Hash `json:"hash" rlp:"-"`
|
||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty" rlp:"nil,?"`
|
||||
L1MessageSender *common.Address `json:"l1MessageSender,omitempty" rlp:"nil,?"`
|
||||
Hash *common.Hash `json:"hash" rlp:"-"`
|
||||
}
|
||||
|
||||
type txdataMarshaling struct {
|
||||
@ -74,30 +80,35 @@ type txdataMarshaling struct {
|
||||
S *hexutil.Big
|
||||
}
|
||||
|
||||
func NewTransaction(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, l1MessageSender *common.Address, l1RollupTxId *hexutil.Uint64) *Transaction {
|
||||
return newTransaction(nonce, &to, amount, gasLimit, gasPrice, data, l1MessageSender, l1RollupTxId)
|
||||
func NewTransaction(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, l1MessageSender *common.Address, l1RollupTxId *hexutil.Uint64, sighashType SignatureHashType) *Transaction {
|
||||
return newTransaction(nonce, &to, amount, gasLimit, gasPrice, data, l1MessageSender, l1RollupTxId, sighashType)
|
||||
}
|
||||
|
||||
func NewContractCreation(nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, l1MessageSender *common.Address, l1RollupTxId *hexutil.Uint64) *Transaction {
|
||||
return newTransaction(nonce, nil, amount, gasLimit, gasPrice, data, l1MessageSender, l1RollupTxId)
|
||||
return newTransaction(nonce, nil, amount, gasLimit, gasPrice, data, l1MessageSender, l1RollupTxId, SighashEIP155)
|
||||
}
|
||||
|
||||
func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, l1MessageSender *common.Address, l1RollupTxId *hexutil.Uint64) *Transaction {
|
||||
func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, l1MessageSender *common.Address, l1RollupTxId *hexutil.Uint64, sighashType SignatureHashType) *Transaction {
|
||||
if len(data) > 0 {
|
||||
data = common.CopyBytes(data)
|
||||
}
|
||||
|
||||
meta := TransactionMeta{
|
||||
L1RollupTxId: l1RollupTxId,
|
||||
L1MessageSender: l1MessageSender,
|
||||
SignatureHashType: sighashType,
|
||||
}
|
||||
|
||||
d := txdata{
|
||||
AccountNonce: nonce,
|
||||
Recipient: to,
|
||||
L1MessageSender: l1MessageSender,
|
||||
L1RollupTxId: l1RollupTxId,
|
||||
Payload: data,
|
||||
Amount: new(big.Int),
|
||||
GasLimit: gasLimit,
|
||||
Price: new(big.Int),
|
||||
V: new(big.Int),
|
||||
R: new(big.Int),
|
||||
S: new(big.Int),
|
||||
AccountNonce: nonce,
|
||||
Recipient: to,
|
||||
Payload: data,
|
||||
Amount: new(big.Int),
|
||||
GasLimit: gasLimit,
|
||||
Price: new(big.Int),
|
||||
V: new(big.Int),
|
||||
R: new(big.Int),
|
||||
S: new(big.Int),
|
||||
}
|
||||
if amount != nil {
|
||||
d.Amount.Set(amount)
|
||||
@ -106,7 +117,21 @@ func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit
|
||||
d.Price.Set(gasPrice)
|
||||
}
|
||||
|
||||
return &Transaction{data: d}
|
||||
return &Transaction{data: d, meta: meta}
|
||||
}
|
||||
|
||||
func (t *Transaction) SetTransactionMeta(meta *TransactionMeta) {
|
||||
if meta == nil {
|
||||
return
|
||||
}
|
||||
t.meta = *meta
|
||||
}
|
||||
|
||||
func (t *Transaction) GetMeta() *TransactionMeta {
|
||||
if &t.meta == nil {
|
||||
return &TransactionMeta{}
|
||||
}
|
||||
return &t.meta
|
||||
}
|
||||
|
||||
// Appends the provided 64-bit nonce to this Transaction's calldata as the last 4 bytes
|
||||
@ -169,43 +194,49 @@ func (tx *Transaction) DecodeRLP(s *rlp.Stream) error {
|
||||
|
||||
// MarshalJSON encodes the web3 RPC transaction format.
|
||||
func (tx *Transaction) MarshalJSON() ([]byte, error) {
|
||||
hash := tx.Hash()
|
||||
data := tx.data
|
||||
data.Hash = &hash
|
||||
return data.MarshalJSON()
|
||||
return TransactionMarshalJSON(tx)
|
||||
}
|
||||
|
||||
// UnmarshalJSON decodes the web3 RPC transaction format.
|
||||
func (tx *Transaction) UnmarshalJSON(input []byte) error {
|
||||
var dec txdata
|
||||
if err := dec.UnmarshalJSON(input); err != nil {
|
||||
dec, err := TransactionUnmarshalJSON(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
withSignature := dec.V.Sign() != 0 || dec.R.Sign() != 0 || dec.S.Sign() != 0
|
||||
withSignature := dec.data.V.Sign() != 0 || dec.data.R.Sign() != 0 || dec.data.S.Sign() != 0
|
||||
if withSignature {
|
||||
var V byte
|
||||
if isProtectedV(dec.V) {
|
||||
chainID := deriveChainId(dec.V).Uint64()
|
||||
V = byte(dec.V.Uint64() - 35 - 2*chainID)
|
||||
if isProtectedV(dec.data.V) {
|
||||
chainID := deriveChainId(dec.data.V).Uint64()
|
||||
V = byte(dec.data.V.Uint64() - 35 - 2*chainID)
|
||||
} else {
|
||||
V = byte(dec.V.Uint64() - 27)
|
||||
V = byte(dec.data.V.Uint64() - 27)
|
||||
}
|
||||
if !crypto.ValidateSignatureValues(V, dec.R, dec.S, false) {
|
||||
if !crypto.ValidateSignatureValues(V, dec.data.R, dec.data.S, false) {
|
||||
return ErrInvalidSig
|
||||
}
|
||||
}
|
||||
|
||||
*tx = Transaction{data: dec}
|
||||
*tx = *dec
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) }
|
||||
func (tx *Transaction) Gas() uint64 { return tx.data.GasLimit }
|
||||
func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) }
|
||||
func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) }
|
||||
func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce }
|
||||
func (tx *Transaction) CheckNonce() bool { return true }
|
||||
func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) }
|
||||
func (tx *Transaction) Gas() uint64 { return tx.data.GasLimit }
|
||||
func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) }
|
||||
func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) }
|
||||
func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce }
|
||||
func (tx *Transaction) CheckNonce() bool { return true }
|
||||
func (tx *Transaction) SignatureHashType() SignatureHashType { return tx.meta.SignatureHashType }
|
||||
|
||||
func (tx *Transaction) SetSignatureHashType(sighashType SignatureHashType) {
|
||||
tx.meta.SignatureHashType = sighashType
|
||||
}
|
||||
|
||||
func (tx *Transaction) IsEthSignSighash() bool {
|
||||
return tx.SignatureHashType() == SighashEthSign
|
||||
}
|
||||
|
||||
// To returns the recipient address of the transaction.
|
||||
// It returns nil if the transaction is a contract creation.
|
||||
@ -220,20 +251,20 @@ func (tx *Transaction) To() *common.Address {
|
||||
// L1MessageSender returns the L1 message sender address of the transaction if one exists.
|
||||
// It returns nil if this transaction was not from an L1 contract.
|
||||
func (tx *Transaction) L1MessageSender() *common.Address {
|
||||
if tx.data.L1MessageSender == nil {
|
||||
if tx.meta.L1MessageSender == nil {
|
||||
return nil
|
||||
}
|
||||
l1MessageSender := *tx.data.L1MessageSender
|
||||
l1MessageSender := *tx.meta.L1MessageSender
|
||||
return &l1MessageSender
|
||||
}
|
||||
|
||||
// L1RollupTxId returns the L1 Rollup Tx Id of the transaction if one exists.
|
||||
// It returns nil if this transaction was not generated from a transaction received on L1.
|
||||
func (tx *Transaction) L1RollupTxId() *hexutil.Uint64 {
|
||||
if tx.data.L1RollupTxId == nil {
|
||||
if tx.meta.L1RollupTxId == nil {
|
||||
return nil
|
||||
}
|
||||
l1RolupTxId := *tx.data.L1RollupTxId
|
||||
l1RolupTxId := *tx.meta.L1RollupTxId
|
||||
return &l1RolupTxId
|
||||
}
|
||||
|
||||
@ -244,20 +275,7 @@ func (tx *Transaction) Hash() common.Hash {
|
||||
return hash.(common.Hash)
|
||||
}
|
||||
|
||||
var sender *common.Address
|
||||
var l1RollupTxId *hexutil.Uint64
|
||||
if tx != nil {
|
||||
sender = tx.data.L1MessageSender
|
||||
tx.data.L1MessageSender = nil
|
||||
l1RollupTxId = tx.data.L1RollupTxId
|
||||
tx.data.L1RollupTxId = nil
|
||||
}
|
||||
v := rlpHash(tx)
|
||||
|
||||
if tx != nil {
|
||||
tx.data.L1MessageSender = sender
|
||||
tx.data.L1RollupTxId = l1RollupTxId
|
||||
}
|
||||
tx.hash.Store(v)
|
||||
return v
|
||||
}
|
||||
@ -281,15 +299,16 @@ func (tx *Transaction) Size() common.StorageSize {
|
||||
// XXX Rename message to something less arbitrary?
|
||||
func (tx *Transaction) AsMessage(s Signer) (Message, error) {
|
||||
msg := Message{
|
||||
nonce: tx.data.AccountNonce,
|
||||
gasLimit: tx.data.GasLimit,
|
||||
gasPrice: new(big.Int).Set(tx.data.Price),
|
||||
to: tx.data.Recipient,
|
||||
l1MessageSender: tx.data.L1MessageSender,
|
||||
l1RollupTxId: tx.data.L1RollupTxId,
|
||||
amount: tx.data.Amount,
|
||||
data: tx.data.Payload,
|
||||
checkNonce: true,
|
||||
nonce: tx.data.AccountNonce,
|
||||
gasLimit: tx.data.GasLimit,
|
||||
gasPrice: new(big.Int).Set(tx.data.Price),
|
||||
to: tx.data.Recipient,
|
||||
l1MessageSender: tx.meta.L1MessageSender,
|
||||
l1RollupTxId: tx.meta.L1RollupTxId,
|
||||
signatureHashType: tx.meta.SignatureHashType,
|
||||
amount: tx.data.Amount,
|
||||
data: tx.data.Payload,
|
||||
checkNonce: true,
|
||||
}
|
||||
|
||||
var err error
|
||||
@ -304,7 +323,7 @@ func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, e
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cpy := &Transaction{data: tx.data}
|
||||
cpy := &Transaction{data: tx.data, meta: tx.meta}
|
||||
cpy.data.R, cpy.data.S, cpy.data.V = r, s, v
|
||||
return cpy, nil
|
||||
}
|
||||
@ -402,12 +421,15 @@ func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transa
|
||||
// Initialize a price based heap with the head transactions
|
||||
heads := make(TxByPrice, 0, len(txs))
|
||||
for from, accTxs := range txs {
|
||||
heads = append(heads, accTxs[0])
|
||||
// Ensure the sender address is from the signer
|
||||
acc, _ := Sender(signer, accTxs[0])
|
||||
txs[acc] = accTxs[1:]
|
||||
if from != acc {
|
||||
delete(txs, from)
|
||||
// This prevents a panic, not ideal.
|
||||
if len(accTxs) > 0 {
|
||||
heads = append(heads, accTxs[0])
|
||||
// Ensure the sender address is from the signer
|
||||
acc, _ := Sender(signer, accTxs[0])
|
||||
txs[acc] = accTxs[1:]
|
||||
if from != acc {
|
||||
delete(txs, from)
|
||||
}
|
||||
}
|
||||
}
|
||||
heap.Init(&heads)
|
||||
@ -450,40 +472,43 @@ func (t *TransactionsByPriceAndNonce) Pop() {
|
||||
//
|
||||
// NOTE: In a future PR this will be removed.
|
||||
type Message struct {
|
||||
to *common.Address
|
||||
l1MessageSender *common.Address
|
||||
l1RollupTxId *hexutil.Uint64
|
||||
from common.Address
|
||||
nonce uint64
|
||||
amount *big.Int
|
||||
gasLimit uint64
|
||||
gasPrice *big.Int
|
||||
data []byte
|
||||
checkNonce bool
|
||||
to *common.Address
|
||||
l1MessageSender *common.Address
|
||||
l1RollupTxId *hexutil.Uint64
|
||||
signatureHashType SignatureHashType
|
||||
from common.Address
|
||||
nonce uint64
|
||||
amount *big.Int
|
||||
gasLimit uint64
|
||||
gasPrice *big.Int
|
||||
data []byte
|
||||
checkNonce bool
|
||||
}
|
||||
|
||||
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool, l1MessageSender *common.Address, l1RollupTxId *hexutil.Uint64) Message {
|
||||
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool, l1MessageSender *common.Address, l1RollupTxId *hexutil.Uint64, signatureHashType SignatureHashType) Message {
|
||||
return Message{
|
||||
from: from,
|
||||
to: to,
|
||||
nonce: nonce,
|
||||
amount: amount,
|
||||
gasLimit: gasLimit,
|
||||
gasPrice: gasPrice,
|
||||
data: data,
|
||||
checkNonce: checkNonce,
|
||||
l1RollupTxId: l1RollupTxId,
|
||||
l1MessageSender: l1MessageSender,
|
||||
from: from,
|
||||
to: to,
|
||||
nonce: nonce,
|
||||
amount: amount,
|
||||
gasLimit: gasLimit,
|
||||
gasPrice: gasPrice,
|
||||
data: data,
|
||||
checkNonce: checkNonce,
|
||||
l1RollupTxId: l1RollupTxId,
|
||||
l1MessageSender: l1MessageSender,
|
||||
signatureHashType: signatureHashType,
|
||||
}
|
||||
}
|
||||
|
||||
func (m Message) From() common.Address { return m.from }
|
||||
func (m Message) To() *common.Address { return m.to }
|
||||
func (m Message) L1MessageSender() *common.Address { return m.l1MessageSender }
|
||||
func (m Message) L1RollupTxId() *hexutil.Uint64 { return m.l1RollupTxId }
|
||||
func (m Message) GasPrice() *big.Int { return m.gasPrice }
|
||||
func (m Message) Value() *big.Int { return m.amount }
|
||||
func (m Message) Gas() uint64 { return m.gasLimit }
|
||||
func (m Message) Nonce() uint64 { return m.nonce }
|
||||
func (m Message) Data() []byte { return m.data }
|
||||
func (m Message) CheckNonce() bool { return m.checkNonce }
|
||||
func (m Message) From() common.Address { return m.from }
|
||||
func (m Message) To() *common.Address { return m.to }
|
||||
func (m Message) L1MessageSender() *common.Address { return m.l1MessageSender }
|
||||
func (m Message) L1RollupTxId() *hexutil.Uint64 { return m.l1RollupTxId }
|
||||
func (m Message) SignatureHashType() SignatureHashType { return m.signatureHashType }
|
||||
func (m Message) GasPrice() *big.Int { return m.gasPrice }
|
||||
func (m Message) Value() *big.Int { return m.amount }
|
||||
func (m Message) Gas() uint64 { return m.gasLimit }
|
||||
func (m Message) Nonce() uint64 { return m.nonce }
|
||||
func (m Message) Data() []byte { return m.data }
|
||||
func (m Message) CheckNonce() bool { return m.checkNonce }
|
||||
|
104
core/types/transaction_meta.go
Normal file
104
core/types/transaction_meta.go
Normal file
@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Optimism 2020 Copyright
|
||||
*/
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
type TransactionMeta struct {
|
||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId"`
|
||||
L1MessageSender *common.Address `json:"l1MessageSender"`
|
||||
SignatureHashType SignatureHashType `json:"signatureHashType"`
|
||||
}
|
||||
|
||||
func NewTransactionMeta(L1RollupTxId *hexutil.Uint64, L1MessageSender *common.Address, sighashType SignatureHashType) *TransactionMeta {
|
||||
return &TransactionMeta{L1RollupTxId: L1RollupTxId, L1MessageSender: L1MessageSender, SignatureHashType: sighashType}
|
||||
}
|
||||
|
||||
// TxMetaDecode deserializes bytes as a TransactionMeta struct.
|
||||
// The schema is:
|
||||
// varbytes(SignatureHashType) || varbytes(L1RollupTxId) || varbytes(L1MessageSender)
|
||||
func TxMetaDecode(input []byte) (*TransactionMeta, error) {
|
||||
var err error
|
||||
meta := TransactionMeta{}
|
||||
|
||||
b := bytes.NewReader(input)
|
||||
|
||||
sb, err := common.ReadVarBytes(b, 0, 1024, "SignatureHashType")
|
||||
if err != nil {
|
||||
return &TransactionMeta{}, err
|
||||
}
|
||||
|
||||
var sighashType SignatureHashType
|
||||
binary.Read(bytes.NewReader(sb), binary.LittleEndian, &sighashType)
|
||||
meta.SignatureHashType = sighashType
|
||||
|
||||
lb, err := common.ReadVarBytes(b, 0, 1024, "L1RollupTxId")
|
||||
if err != nil {
|
||||
return &TransactionMeta{}, err
|
||||
}
|
||||
|
||||
if !isNullValue(lb) {
|
||||
var l1RollupTxId hexutil.Uint64
|
||||
binary.Read(bytes.NewReader(lb), binary.LittleEndian, &l1RollupTxId)
|
||||
meta.L1RollupTxId = &l1RollupTxId
|
||||
}
|
||||
|
||||
mb, err := common.ReadVarBytes(b, 0, 1024, "L1MessageSender")
|
||||
if err != nil {
|
||||
return &TransactionMeta{}, err
|
||||
}
|
||||
|
||||
if !isNullValue(mb) {
|
||||
var l1MessageSender common.Address
|
||||
binary.Read(bytes.NewReader(mb), binary.LittleEndian, &l1MessageSender)
|
||||
meta.L1MessageSender = &l1MessageSender
|
||||
}
|
||||
|
||||
return &meta, nil
|
||||
}
|
||||
|
||||
// TxMetaEncode serializes the TransactionMeta as bytes.
|
||||
func TxMetaEncode(meta *TransactionMeta) []byte {
|
||||
b := new(bytes.Buffer)
|
||||
|
||||
s := new(bytes.Buffer)
|
||||
binary.Write(s, binary.LittleEndian, &meta.SignatureHashType)
|
||||
common.WriteVarBytes(b, 0, s.Bytes())
|
||||
|
||||
L1RollupTxId := meta.L1RollupTxId
|
||||
if L1RollupTxId == nil {
|
||||
common.WriteVarBytes(b, 0, getNullValue())
|
||||
} else {
|
||||
l := new(bytes.Buffer)
|
||||
binary.Write(l, binary.LittleEndian, *L1RollupTxId)
|
||||
common.WriteVarBytes(b, 0, l.Bytes())
|
||||
}
|
||||
|
||||
L1MessageSender := meta.L1MessageSender
|
||||
if L1MessageSender == nil {
|
||||
common.WriteVarBytes(b, 0, getNullValue())
|
||||
} else {
|
||||
l := new(bytes.Buffer)
|
||||
binary.Write(l, binary.LittleEndian, *L1MessageSender)
|
||||
common.WriteVarBytes(b, 0, l.Bytes())
|
||||
}
|
||||
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
func isNullValue(b []byte) bool {
|
||||
nullValue := []byte{0x00}
|
||||
return bytes.Equal(b, nullValue)
|
||||
}
|
||||
|
||||
func getNullValue() []byte {
|
||||
return []byte{0x00}
|
||||
}
|
110
core/types/transaction_meta_test.go
Normal file
110
core/types/transaction_meta_test.go
Normal file
@ -0,0 +1,110 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
var (
|
||||
addr = common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87")
|
||||
txid = hexutil.Uint64(0)
|
||||
|
||||
txMetaSerializationTests = []struct {
|
||||
txid *hexutil.Uint64
|
||||
msgSender *common.Address
|
||||
sighashType SignatureHashType
|
||||
}{
|
||||
{
|
||||
txid: &txid,
|
||||
msgSender: &addr,
|
||||
sighashType: SighashEthSign,
|
||||
},
|
||||
{
|
||||
txid: nil,
|
||||
msgSender: &addr,
|
||||
sighashType: SighashEthSign,
|
||||
},
|
||||
{
|
||||
txid: &txid,
|
||||
msgSender: nil,
|
||||
sighashType: SighashEthSign,
|
||||
},
|
||||
}
|
||||
|
||||
txMetaSighashEncodeTests = []struct {
|
||||
input SignatureHashType
|
||||
output SignatureHashType
|
||||
}{
|
||||
{
|
||||
input: SighashEIP155,
|
||||
output: SighashEIP155,
|
||||
},
|
||||
{
|
||||
input: SighashEthSign,
|
||||
output: SighashEthSign,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func TestTransactionMetaEncode(t *testing.T) {
|
||||
for _, test := range txMetaSerializationTests {
|
||||
txmeta := NewTransactionMeta(test.txid, test.msgSender, test.sighashType)
|
||||
encoded := TxMetaEncode(txmeta)
|
||||
decoded, err := TxMetaDecode(encoded)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !isTxMetaEqual(txmeta, decoded) {
|
||||
t.Fatal("Encoding/decoding mismatch")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransactionSighashEncode(t *testing.T) {
|
||||
for _, test := range txMetaSighashEncodeTests {
|
||||
txmeta := NewTransactionMeta(&txid, &addr, test.input)
|
||||
encoded := TxMetaEncode(txmeta)
|
||||
decoded, err := TxMetaDecode(encoded)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if decoded.SignatureHashType != test.output {
|
||||
t.Fatal("SighashTypes do not match")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isTxMetaEqual(meta1 *TransactionMeta, meta2 *TransactionMeta) bool {
|
||||
if meta1.L1MessageSender == nil || meta2.L1MessageSender == nil {
|
||||
if meta1.L1MessageSender != meta2.L1MessageSender {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if !bytes.Equal(meta1.L1MessageSender.Bytes(), meta2.L1MessageSender.Bytes()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if meta1.L1RollupTxId == nil || meta2.L1RollupTxId == nil {
|
||||
if meta1.L1RollupTxId != meta2.L1RollupTxId {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if *meta1.L1RollupTxId != *meta2.L1RollupTxId {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if meta1.SignatureHashType != meta2.SignatureHashType {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
@ -17,7 +17,9 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
@ -25,6 +27,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -40,16 +43,7 @@ type sigCache struct {
|
||||
|
||||
// MakeSigner returns a Signer based on the given chain config and block number.
|
||||
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
|
||||
var signer Signer
|
||||
switch {
|
||||
case config.IsEIP155(blockNumber):
|
||||
signer = NewEIP155Signer(config.ChainID)
|
||||
case config.IsHomestead(blockNumber):
|
||||
signer = HomesteadSigner{}
|
||||
default:
|
||||
signer = FrontierSigner{}
|
||||
}
|
||||
return signer
|
||||
return NewOVMSigner(config.ChainID)
|
||||
}
|
||||
|
||||
// SignTx signs the transaction using the given signer and private key
|
||||
@ -102,6 +96,102 @@ type Signer interface {
|
||||
Equal(Signer) bool
|
||||
}
|
||||
|
||||
// OVMSigner implements Signers using the EIP155 rules along with a new
|
||||
// `eth_sign` based signature hash.
|
||||
type OVMSigner struct {
|
||||
EIP155Signer
|
||||
}
|
||||
|
||||
func NewOVMSigner(chainId *big.Int) OVMSigner {
|
||||
signer := NewEIP155Signer(chainId)
|
||||
return OVMSigner{signer}
|
||||
}
|
||||
|
||||
func (s OVMSigner) Equal(s2 Signer) bool {
|
||||
ovm, ok := s2.(OVMSigner)
|
||||
return ok && ovm.chainId.Cmp(s.chainId) == 0
|
||||
}
|
||||
|
||||
// Hash returns the hash to be signed by the sender.
|
||||
// It does not uniquely identify the transaction.
|
||||
func (s OVMSigner) Hash(tx *Transaction) common.Hash {
|
||||
if tx.IsEthSignSighash() {
|
||||
msg := s.OVMSignerTemplateSighashPreimage(tx)
|
||||
|
||||
hasher := sha3.NewLegacyKeccak256()
|
||||
hasher.Write(msg)
|
||||
digest := hasher.Sum(nil)
|
||||
|
||||
return common.BytesToHash(digest)
|
||||
}
|
||||
|
||||
return rlpHash([]interface{}{
|
||||
tx.data.AccountNonce,
|
||||
tx.data.Price,
|
||||
tx.data.GasLimit,
|
||||
tx.data.Recipient,
|
||||
tx.data.Amount,
|
||||
tx.data.Payload,
|
||||
s.chainId, uint(0), uint(0),
|
||||
})
|
||||
}
|
||||
|
||||
func (s OVMSigner) Sender(tx *Transaction) (common.Address, error) {
|
||||
if !tx.Protected() {
|
||||
return HomesteadSigner{}.Sender(tx)
|
||||
}
|
||||
if tx.ChainId().Cmp(s.chainId) != 0 {
|
||||
return common.Address{}, ErrInvalidChainId
|
||||
}
|
||||
V := new(big.Int).Sub(tx.data.V, s.chainIdMul)
|
||||
V.Sub(V, big8)
|
||||
return recoverPlain(s.Hash(tx), tx.data.R, tx.data.S, V, true)
|
||||
}
|
||||
|
||||
// OVMSignerTemplateSighashPreimage creates the preimage for the `eth_sign` like
|
||||
// signature hash. The transaction is `ABI.encodePacked`.
|
||||
func (s OVMSigner) OVMSignerTemplateSighashPreimage(tx *Transaction) []byte {
|
||||
// Pad the nonce to 32 bytes
|
||||
n := new(bytes.Buffer)
|
||||
binary.Write(n, binary.BigEndian, tx.data.AccountNonce)
|
||||
nonce := common.LeftPadBytes(n.Bytes(), 32)
|
||||
|
||||
// Pad the gas limit to 32 bytes
|
||||
g := new(bytes.Buffer)
|
||||
binary.Write(g, binary.BigEndian, tx.data.GasLimit)
|
||||
gasLimit := common.LeftPadBytes(g.Bytes(), 32)
|
||||
|
||||
p := new(bytes.Buffer)
|
||||
binary.Write(p, binary.BigEndian, tx.data.Price.Bytes())
|
||||
gasPrice := common.LeftPadBytes(p.Bytes(), 32)
|
||||
|
||||
chainId := common.LeftPadBytes(s.chainId.Bytes(), 32)
|
||||
|
||||
// This should always be 20 bytes
|
||||
to := tx.data.Recipient.Bytes()
|
||||
|
||||
// The signature hash commits to the nonce, gas limit,
|
||||
// recipient and data
|
||||
b := new(bytes.Buffer)
|
||||
binary.Write(b, binary.BigEndian, nonce)
|
||||
binary.Write(b, binary.BigEndian, gasLimit)
|
||||
binary.Write(b, binary.BigEndian, gasPrice)
|
||||
binary.Write(b, binary.BigEndian, chainId)
|
||||
binary.Write(b, binary.BigEndian, to)
|
||||
binary.Write(b, binary.BigEndian, tx.data.Payload)
|
||||
|
||||
hasher := sha3.NewLegacyKeccak256()
|
||||
hasher.Write(b.Bytes())
|
||||
digest := hasher.Sum(nil)
|
||||
|
||||
preimage := new(bytes.Buffer)
|
||||
prefix := []byte("\x19Ethereum Signed Message:\n32")
|
||||
binary.Write(preimage, binary.BigEndian, prefix)
|
||||
binary.Write(preimage, binary.BigEndian, digest)
|
||||
|
||||
return preimage.Bytes()
|
||||
}
|
||||
|
||||
// EIP155Transaction implements Signer using the EIP155 rules.
|
||||
type EIP155Signer struct {
|
||||
chainId, chainIdMul *big.Int
|
||||
|
@ -30,7 +30,7 @@ func TestEIP155Signing(t *testing.T) {
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
|
||||
signer := NewEIP155Signer(big.NewInt(18))
|
||||
tx, err := SignTx(NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil, nil, nil), signer, key)
|
||||
tx, err := SignTx(NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil, nil, nil, SighashEIP155), signer, key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -49,7 +49,7 @@ func TestEIP155ChainId(t *testing.T) {
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
|
||||
signer := NewEIP155Signer(big.NewInt(18))
|
||||
tx, err := SignTx(NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil, nil, nil), signer, key)
|
||||
tx, err := SignTx(NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil, nil, nil, SighashEIP155), signer, key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -61,7 +61,7 @@ func TestEIP155ChainId(t *testing.T) {
|
||||
t.Error("expected chainId to be", signer.chainId, "got", tx.ChainId())
|
||||
}
|
||||
|
||||
tx = NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil, nil, nil)
|
||||
tx = NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil, nil, nil, SighashEIP155)
|
||||
tx, err = SignTx(tx, HomesteadSigner{}, key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -118,7 +118,7 @@ func TestEIP155SigningVitalik(t *testing.T) {
|
||||
func TestChainId(t *testing.T) {
|
||||
key, _ := defaultTestKey()
|
||||
|
||||
tx := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil, nil, nil)
|
||||
tx := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil, nil, nil, SighashEIP155)
|
||||
|
||||
var err error
|
||||
tx, err = SignTx(tx, NewEIP155Signer(big.NewInt(1)), key)
|
||||
@ -136,3 +136,94 @@ func TestChainId(t *testing.T) {
|
||||
t.Error("expected no error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOVMSigner(t *testing.T) {
|
||||
key, _ := defaultTestKey()
|
||||
|
||||
tx := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil, nil, nil, SighashEthSign)
|
||||
|
||||
var err error
|
||||
tx, err = SignTx(tx, NewOVMSigner(big.NewInt(1)), key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = Sender(NewOVMSigner(big.NewInt(2)), tx)
|
||||
if err != ErrInvalidChainId {
|
||||
t.Error("expected error:", ErrInvalidChainId)
|
||||
}
|
||||
|
||||
_, err = Sender(NewOVMSigner(big.NewInt(1)), tx)
|
||||
if err != nil {
|
||||
t.Error("expected no error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOVMSignerHash(t *testing.T) {
|
||||
signer := NewOVMSigner(big.NewInt(1))
|
||||
|
||||
txNil := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil, nil, nil, SighashEIP155)
|
||||
txEIP155 := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil, nil, nil, SighashEIP155)
|
||||
|
||||
hashNil := signer.Hash(txNil)
|
||||
hashEIP155 := signer.Hash(txEIP155)
|
||||
if hashNil != hashEIP155 {
|
||||
t.Errorf("Signature hashes should be equal: %s != %s", hashNil.Hex(), hashEIP155.Hex())
|
||||
}
|
||||
|
||||
// The signature hash should be different when using `SighashEthSign`
|
||||
txEthSign := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil, nil, nil, SighashEthSign)
|
||||
|
||||
hashEthSign := signer.Hash(txEthSign)
|
||||
if hashEIP155 == hashEthSign {
|
||||
t.Errorf("Signature hashes should not be equal: %s == %s", hashEIP155.Hex(), hashEthSign.Hex())
|
||||
}
|
||||
}
|
||||
|
||||
func TestOVMSignerSender(t *testing.T) {
|
||||
// Create a keypair to sign transactions with and the corresponding address
|
||||
// from the public key.
|
||||
key, _ := crypto.GenerateKey()
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
|
||||
// This test makes sure that both the EIP155 and EthSign signature hash
|
||||
// codepaths work when using the OVMSigner.
|
||||
signer := NewOVMSigner(big.NewInt(1))
|
||||
var err error
|
||||
|
||||
// Create a transaction with EIP155 signature hash, sign the transaction,
|
||||
// recover the address and assert that the address matches the key.
|
||||
txEIP155 := NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil, nil, nil, SighashEIP155)
|
||||
|
||||
txEIP155, err = SignTx(txEIP155, signer, key)
|
||||
if err != nil {
|
||||
t.Errorf("No error expected")
|
||||
}
|
||||
|
||||
recEIP155, err := signer.Sender(txEIP155)
|
||||
if err != nil {
|
||||
t.Errorf("No error expected")
|
||||
}
|
||||
|
||||
if addr != recEIP155 {
|
||||
t.Errorf("Recovered address doesn't match. Got %s, expected %s", recEIP155.Hex(), addr.Hex())
|
||||
}
|
||||
|
||||
// Create a transaction with EthSign signature hash, sign the transaction,
|
||||
// recover the address and assert that the address matches the key.
|
||||
txEthSign := NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil, nil, nil, SighashEthSign)
|
||||
|
||||
txEthSign, err = SignTx(txEthSign, signer, key)
|
||||
if err != nil {
|
||||
t.Errorf("No error expected")
|
||||
}
|
||||
|
||||
recEthSign, err := signer.Sender(txEthSign)
|
||||
if err != nil {
|
||||
t.Errorf("No error expected")
|
||||
}
|
||||
|
||||
if addr != recEthSign {
|
||||
t.Errorf("Recovered address doesn't match. Got %s, expected %s", recEthSign.Hex(), addr.Hex())
|
||||
}
|
||||
}
|
||||
|
@ -35,23 +35,25 @@ import (
|
||||
var (
|
||||
sender = common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87")
|
||||
l1RollupTxId = hexutil.Uint64(1)
|
||||
emptyTx = NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(0), 0, big.NewInt(0), nil, &sender, nil)
|
||||
emptyTxEmptyL1Sender = NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(0), 0, big.NewInt(0), nil, nil, nil)
|
||||
emptyTx = NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(0), 0, big.NewInt(0), nil, &sender, nil, SighashEIP155)
|
||||
emptyTxEmptyL1Sender = NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(0), 0, big.NewInt(0), nil, nil, nil, SighashEIP155)
|
||||
|
||||
rightvrsTx, _ = NewTransaction(3, common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"), big.NewInt(10), 2000, big.NewInt(1), common.FromHex("5544"), nil, nil).WithSignature(
|
||||
rightvrsTx, _ = NewTransaction(3, common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"), big.NewInt(10), 2000, big.NewInt(1), common.FromHex("5544"), nil, nil, SighashEIP155).WithSignature(
|
||||
HomesteadSigner{},
|
||||
common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a301"),
|
||||
)
|
||||
|
||||
rightvrsTxWithL1Sender, _ = NewTransaction(3, common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"), big.NewInt(10), 2000, big.NewInt(1), common.FromHex("5544"), &sender, nil).WithSignature(
|
||||
rightvrsTxWithL1Sender, _ = NewTransaction(3, common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"), big.NewInt(10), 2000, big.NewInt(1), common.FromHex("5544"), &sender, nil, SighashEIP155).WithSignature(
|
||||
HomesteadSigner{},
|
||||
common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a301"),
|
||||
)
|
||||
|
||||
rightvrsTxWithL1RollupTxId, _ = NewTransaction(3, common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"), big.NewInt(10), 2000, big.NewInt(1), common.FromHex("5544"), nil, &l1RollupTxId).WithSignature(
|
||||
rightvrsTxWithL1RollupTxId, _ = NewTransaction(3, common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"), big.NewInt(10), 2000, big.NewInt(1), common.FromHex("5544"), nil, &l1RollupTxId, SighashEIP155).WithSignature(
|
||||
HomesteadSigner{},
|
||||
common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a301"),
|
||||
)
|
||||
|
||||
emptyTxSighashEthSign = NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(0), 0, big.NewInt(0), nil, &sender, nil, SighashEthSign)
|
||||
)
|
||||
|
||||
func TestTransactionSigHash(t *testing.T) {
|
||||
@ -78,16 +80,29 @@ func TestTransactionEncode(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("encode error: %v", err)
|
||||
}
|
||||
if bytes.Equal(txc, should) {
|
||||
t.Errorf("RLP encoding with L1MessageSender should be different than without. Got %x", txc)
|
||||
if !bytes.Equal(txc, should) {
|
||||
t.Errorf("RLP encoding with L1MessageSender should be the same. Got %x", txc)
|
||||
}
|
||||
|
||||
txd, err := rlp.EncodeToBytes(rightvrsTxWithL1RollupTxId)
|
||||
if err != nil {
|
||||
t.Fatalf("encode error: %v", err)
|
||||
}
|
||||
if bytes.Equal(txd, should) {
|
||||
t.Errorf("RLP encoding with L1MessageSender should be different than without. Got %x", txd)
|
||||
if !bytes.Equal(txd, should) {
|
||||
t.Errorf("RLP encoding with L1MessageSender should be the same. Got %x", txd)
|
||||
}
|
||||
|
||||
txe, err := rlp.EncodeToBytes(emptyTx)
|
||||
if err != nil {
|
||||
t.Fatalf("encode error: %v", err)
|
||||
}
|
||||
|
||||
txf, err := rlp.EncodeToBytes(emptyTxSighashEthSign)
|
||||
if err != nil {
|
||||
t.Fatalf("encode error: %v", err)
|
||||
}
|
||||
if !bytes.Equal(txe, txf) {
|
||||
t.Error("RLP encoding with SighashEthSign should be the same")
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +168,7 @@ func TestTransactionPriceNonceSort(t *testing.T) {
|
||||
for start, key := range keys {
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
for i := 0; i < 25; i++ {
|
||||
tx, _ := SignTx(NewTransaction(uint64(start+i), common.Address{}, big.NewInt(100), 100, big.NewInt(int64(start+i)), nil, nil, nil), signer, key)
|
||||
tx, _ := SignTx(NewTransaction(uint64(start+i), common.Address{}, big.NewInt(100), 100, big.NewInt(int64(start+i)), nil, nil, nil, SighashEIP155), signer, key)
|
||||
groups[addr] = append(groups[addr], tx)
|
||||
}
|
||||
}
|
||||
@ -197,14 +212,14 @@ func TestTransactionJSON(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("could not generate key: %v", err)
|
||||
}
|
||||
signer := NewEIP155Signer(common.Big1)
|
||||
signer := NewOVMSigner(common.Big1)
|
||||
|
||||
transactions := make([]*Transaction, 0, 50)
|
||||
for i := uint64(0); i < 25; i++ {
|
||||
var tx *Transaction
|
||||
switch i % 2 {
|
||||
case 0:
|
||||
tx = NewTransaction(i, common.Address{1}, common.Big0, 1, common.Big2, []byte("abcdef"), &sender, &l1RollupTxId)
|
||||
tx = NewTransaction(i, common.Address{1}, common.Big0, 1, common.Big2, []byte("abcdef"), &sender, &l1RollupTxId, SighashEIP155)
|
||||
case 1:
|
||||
tx = NewContractCreation(i, common.Big0, 1, common.Big2, []byte("abcdef"), nil, nil)
|
||||
}
|
||||
@ -245,8 +260,8 @@ func TestTransactionJSON(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that L1MessageSender has no impact on hash
|
||||
func TestL1MessageSenderHash(t *testing.T) {
|
||||
// Tests that OVM metadata has no impact on hash
|
||||
func TestOVMMetaDataHash(t *testing.T) {
|
||||
if rightvrsTx.Hash() != rightvrsTxWithL1Sender.Hash() {
|
||||
t.Errorf("L1MessageSender, should not affect the hash, want %x, got %x with L1MessageSender", rightvrsTx.Hash(), rightvrsTxWithL1Sender.Hash())
|
||||
}
|
||||
@ -258,4 +273,8 @@ func TestL1MessageSenderHash(t *testing.T) {
|
||||
if emptyTx.Hash() != emptyTxEmptyL1Sender.Hash() {
|
||||
t.Errorf("L1MessageSender, should not affect the hash, want %x, got %x with L1MessageSender", emptyTx.Hash(), emptyTxEmptyL1Sender.Hash())
|
||||
}
|
||||
|
||||
if emptyTx.Hash() != emptyTxSighashEthSign.Hash() {
|
||||
t.Errorf("SignatureHashType, should not affect the hash, want %x, got %x with SighashEthSign", emptyTx.Hash(), emptyTxSighashEthSign.Hash())
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ func (tc *testChain) generate(n int, seed byte, parent *types.Block, heavy bool)
|
||||
signer := types.MakeSigner(params.TestChainConfig, block.Number())
|
||||
l1Sender := common.Address{seed}
|
||||
l1RollupTxId := hexutil.Uint64(22)
|
||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil, &l1Sender, &l1RollupTxId), signer, testKey)
|
||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil, &l1Sender, &l1RollupTxId, types.SighashEIP155), signer, testKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ func makeChain(n int, seed byte, parent *types.Block) ([]common.Hash, map[common
|
||||
// If the block number is multiple of 3, send a bonus transaction to the miner
|
||||
if parent == genesis && i%3 == 0 {
|
||||
signer := types.MakeSigner(params.TestChainConfig, block.Number())
|
||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, testKey)
|
||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, testKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -218,11 +218,11 @@ func TestPendingTxFilter(t *testing.T) {
|
||||
api = NewPublicFilterAPI(backend, false)
|
||||
|
||||
transactions = []*types.Transaction{
|
||||
types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil, nil, nil),
|
||||
types.NewTransaction(1, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil, nil, nil),
|
||||
types.NewTransaction(2, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil, nil, nil),
|
||||
types.NewTransaction(3, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil, nil, nil),
|
||||
types.NewTransaction(4, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil, nil, nil),
|
||||
types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil, nil, nil, types.SighashEIP155),
|
||||
types.NewTransaction(1, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil, nil, nil, types.SighashEIP155),
|
||||
types.NewTransaction(2, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil, nil, nil, types.SighashEIP155),
|
||||
types.NewTransaction(3, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil, nil, nil, types.SighashEIP155),
|
||||
types.NewTransaction(4, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil, nil, nil, types.SighashEIP155),
|
||||
}
|
||||
|
||||
hashes []common.Hash
|
||||
|
@ -127,7 +127,7 @@ func TestFilters(t *testing.T) {
|
||||
},
|
||||
}
|
||||
gen.AddUncheckedReceipt(receipt)
|
||||
gen.AddUncheckedTx(types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil, nil, nil))
|
||||
gen.AddUncheckedTx(types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil, nil, nil, types.SighashEIP155))
|
||||
case 2:
|
||||
receipt := types.NewReceipt(nil, false, 0)
|
||||
receipt.Logs = []*types.Log{
|
||||
@ -137,7 +137,7 @@ func TestFilters(t *testing.T) {
|
||||
},
|
||||
}
|
||||
gen.AddUncheckedReceipt(receipt)
|
||||
gen.AddUncheckedTx(types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil, nil, nil))
|
||||
gen.AddUncheckedTx(types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil, nil, nil, types.SighashEIP155))
|
||||
|
||||
case 998:
|
||||
receipt := types.NewReceipt(nil, false, 0)
|
||||
@ -148,7 +148,7 @@ func TestFilters(t *testing.T) {
|
||||
},
|
||||
}
|
||||
gen.AddUncheckedReceipt(receipt)
|
||||
gen.AddUncheckedTx(types.NewTransaction(998, common.HexToAddress("0x998"), big.NewInt(998), 998, big.NewInt(998), nil, nil, nil))
|
||||
gen.AddUncheckedTx(types.NewTransaction(998, common.HexToAddress("0x998"), big.NewInt(998), 998, big.NewInt(998), nil, nil, nil, types.SighashEIP155))
|
||||
case 999:
|
||||
receipt := types.NewReceipt(nil, false, 0)
|
||||
receipt.Logs = []*types.Log{
|
||||
@ -158,7 +158,7 @@ func TestFilters(t *testing.T) {
|
||||
},
|
||||
}
|
||||
gen.AddUncheckedReceipt(receipt)
|
||||
gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, big.NewInt(999), nil, nil, nil))
|
||||
gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, big.NewInt(999), nil, nil, nil, types.SighashEIP155))
|
||||
}
|
||||
})
|
||||
for i, block := range chain {
|
||||
|
@ -290,13 +290,13 @@ func testGetNodeData(t *testing.T, protocol int) {
|
||||
switch i {
|
||||
case 0:
|
||||
// In block 1, the test bank sends account #1 some ether.
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil, nil, nil), signer, testBankKey)
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, testBankKey)
|
||||
block.AddTx(tx)
|
||||
case 1:
|
||||
// In block 2, the test bank sends some more ether to account #1.
|
||||
// acc1Addr passes it on to account #2.
|
||||
tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, testBankKey)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, acc1Key)
|
||||
tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, testBankKey)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, acc1Key)
|
||||
block.AddTx(tx1)
|
||||
block.AddTx(tx2)
|
||||
case 2:
|
||||
@ -389,13 +389,13 @@ func testGetReceipt(t *testing.T, protocol int) {
|
||||
switch i {
|
||||
case 0:
|
||||
// In block 1, the test bank sends account #1 some ether.
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil, nil, nil), signer, testBankKey)
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, testBankKey)
|
||||
block.AddTx(tx)
|
||||
case 1:
|
||||
// In block 2, the test bank sends some more ether to account #1.
|
||||
// acc1Addr passes it on to account #2.
|
||||
tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, testBankKey)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, acc1Key)
|
||||
tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, testBankKey)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, acc1Key)
|
||||
block.AddTx(tx1)
|
||||
block.AddTx(tx2)
|
||||
case 2:
|
||||
|
@ -134,7 +134,7 @@ func (p *testTxPool) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subs
|
||||
|
||||
// newTestTransaction create a new dummy transaction.
|
||||
func newTestTransaction(from *ecdsa.PrivateKey, nonce uint64, datasize int) *types.Transaction {
|
||||
tx := types.NewTransaction(nonce, common.Address{}, big.NewInt(0), 100000, big.NewInt(0), make([]byte, datasize), nil, nil)
|
||||
tx := types.NewTransaction(nonce, common.Address{}, big.NewInt(0), 100000, big.NewInt(0), make([]byte, datasize), nil, nil, types.SighashEIP155)
|
||||
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, from)
|
||||
return tx
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ type callTracerTest struct {
|
||||
func TestPrestateTracerCreate2(t *testing.T) {
|
||||
t.Skip("OVM breaks this with `cannot read property` error, probably related to state manager.")
|
||||
|
||||
unsignedTx := types.NewTransaction(1, common.HexToAddress("0x00000000000000000000000000000000deadbeef"), new(big.Int), 5000000, big.NewInt(1), []byte{}, nil, nil)
|
||||
unsignedTx := types.NewTransaction(1, common.HexToAddress("0x00000000000000000000000000000000deadbeef"), new(big.Int), 5000000, big.NewInt(1), []byte{}, nil, nil, types.SighashEIP155)
|
||||
|
||||
privateKeyECDSA, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader)
|
||||
if err != nil {
|
||||
|
@ -830,7 +830,7 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.Blo
|
||||
}
|
||||
|
||||
// Create new call message
|
||||
msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, data, false, nil, nil)
|
||||
msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, data, false, nil, nil, 0)
|
||||
|
||||
// Setup context so it may be cancelled the call has completed
|
||||
// or, in case of unmetered gas, setup a context with a timeout.
|
||||
@ -1117,9 +1117,10 @@ type RPCTransaction struct {
|
||||
// newRPCTransaction returns a transaction that will serialize to the RPC
|
||||
// representation, with the given location metadata set (if available).
|
||||
func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) *RPCTransaction {
|
||||
// TODO(mark): the transaction must be protected
|
||||
var signer types.Signer = types.FrontierSigner{}
|
||||
if tx.Protected() {
|
||||
signer = types.NewEIP155Signer(tx.ChainId())
|
||||
signer = types.NewOVMSigner(tx.ChainId())
|
||||
}
|
||||
from, _ := types.Sender(signer, tx)
|
||||
v, r, s := tx.RawSignatureValues()
|
||||
@ -1269,6 +1270,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, addr
|
||||
func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) {
|
||||
// Try to return an already finalized transaction
|
||||
tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1318,7 +1320,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha
|
||||
|
||||
var signer types.Signer = types.FrontierSigner{}
|
||||
if tx.Protected() {
|
||||
signer = types.NewEIP155Signer(tx.ChainId())
|
||||
signer = types.NewOVMSigner(tx.ChainId())
|
||||
}
|
||||
from, _ := types.Sender(signer, tx)
|
||||
|
||||
@ -1375,10 +1377,11 @@ type SendTxArgs struct {
|
||||
Nonce *hexutil.Uint64 `json:"nonce"`
|
||||
// We accept "data" and "input" for backwards-compatibility reasons. "input" is the
|
||||
// newer name and should be preferred by clients.
|
||||
Data *hexutil.Bytes `json:"data"`
|
||||
Input *hexutil.Bytes `json:"input"`
|
||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty" rlp:"nil,?"`
|
||||
L1MessageSender *common.Address `json:"l1MessageSender,omitempty" rlp:"nil,?"`
|
||||
Data *hexutil.Bytes `json:"data"`
|
||||
Input *hexutil.Bytes `json:"input"`
|
||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty"`
|
||||
L1MessageSender *common.Address `json:"l1MessageSender,omitempty"`
|
||||
SignatureHashType types.SignatureHashType `json:"signatureHashType,omitempty"`
|
||||
}
|
||||
|
||||
// setDefaults is a helper function that fills in default values for unspecified tx fields.
|
||||
@ -1451,7 +1454,7 @@ func (args *SendTxArgs) toTransaction() *types.Transaction {
|
||||
if args.To == nil {
|
||||
return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input, nil, args.L1RollupTxId)
|
||||
}
|
||||
return types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input, args.L1MessageSender, args.L1RollupTxId)
|
||||
return types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input, args.L1MessageSender, args.L1RollupTxId, args.SignatureHashType)
|
||||
}
|
||||
|
||||
type RollupTransaction struct {
|
||||
@ -1471,7 +1474,7 @@ func (r *RollupTransaction) toTransaction(txNonce uint64) *types.Transaction {
|
||||
if r.Target == nil {
|
||||
tx = types.NewContractCreation(txNonce, big.NewInt(0), uint64(*r.GasLimit), big.NewInt(0), c, r.Sender, r.L1RollupTxId)
|
||||
} else {
|
||||
tx = types.NewTransaction(txNonce, *r.Target, big.NewInt(0), uint64(*r.GasLimit), big.NewInt(0), c, r.Sender, r.L1RollupTxId)
|
||||
tx = types.NewTransaction(txNonce, *r.Target, big.NewInt(0), uint64(*r.GasLimit), big.NewInt(0), c, r.Sender, r.L1RollupTxId, types.SighashEIP155)
|
||||
}
|
||||
tx.AddNonceToWrappedTransaction(uint64(*r.Nonce))
|
||||
return tx
|
||||
@ -1561,7 +1564,21 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encod
|
||||
return SubmitTransaction(ctx, s.b, tx)
|
||||
}
|
||||
|
||||
// SendBlockBatches will:
|
||||
// SendRawEthSignTransaction will add the signed transaction to the mempool.
|
||||
// The signature hash was computed with `eth_sign`, meaning that the
|
||||
// `abi.encodedPacked` transaction was prefixed with the string
|
||||
// "Ethereum Signed Message".
|
||||
func (s *PublicTransactionPoolAPI) SendRawEthSignTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) {
|
||||
tx := new(types.Transaction)
|
||||
if err := rlp.DecodeBytes(encodedTx, tx); err != nil {
|
||||
return common.Hash{}, err
|
||||
}
|
||||
|
||||
tx.SetSignatureHashType(types.SighashEthSign)
|
||||
return SubmitTransaction(ctx, s.b, tx)
|
||||
}
|
||||
|
||||
// SendRollupTransactions will:
|
||||
// * Verify the batches are signed by the RollupTransaction sender.
|
||||
// * Update the Geth timestamp to the provided timestamp
|
||||
// * handle the provided batch of RollupTransactions atomically
|
||||
@ -1680,7 +1697,7 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err
|
||||
for _, tx := range pending {
|
||||
var signer types.Signer = types.HomesteadSigner{}
|
||||
if tx.Protected() {
|
||||
signer = types.NewEIP155Signer(tx.ChainId())
|
||||
signer = types.NewOVMSigner(tx.ChainId())
|
||||
}
|
||||
from, _ := types.Sender(signer, tx)
|
||||
if _, exists := accounts[from]; exists {
|
||||
@ -1708,7 +1725,7 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxAr
|
||||
for _, p := range pending {
|
||||
var signer types.Signer = types.HomesteadSigner{}
|
||||
if p.Protected() {
|
||||
signer = types.NewEIP155Signer(p.ChainId())
|
||||
signer = types.NewOVMSigner(p.ChainId())
|
||||
}
|
||||
wantSigHash := signer.Hash(matchTx)
|
||||
|
||||
|
@ -180,7 +180,7 @@ func (b *benchmarkTxSend) init(h *serverHandler, count int) error {
|
||||
for i := range b.txs {
|
||||
data := make([]byte, txSizeCostLimit)
|
||||
rand.Read(data)
|
||||
tx, err := types.SignTx(types.NewTransaction(0, addr, new(big.Int), 0, new(big.Int), data, nil, nil), signer, key)
|
||||
tx, err := types.SignTx(types.NewTransaction(0, addr, new(big.Int), 0, new(big.Int), data, nil, nil, types.SighashEIP155), signer, key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -556,16 +556,16 @@ func testTransactionStatus(t *testing.T, protocol int) {
|
||||
signer := types.HomesteadSigner{}
|
||||
|
||||
// test error status by sending an underpriced transaction
|
||||
tx0, _ := types.SignTx(types.NewTransaction(0, userAddr1, big.NewInt(10000), params.TxGas, nil, nil, nil, nil), signer, bankKey)
|
||||
tx0, _ := types.SignTx(types.NewTransaction(0, userAddr1, big.NewInt(10000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, bankKey)
|
||||
test(tx0, true, light.TxStatus{Status: core.TxStatusUnknown, Error: core.ErrUnderpriced.Error()})
|
||||
|
||||
tx1, _ := types.SignTx(types.NewTransaction(0, userAddr1, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil, nil, nil), signer, bankKey)
|
||||
tx1, _ := types.SignTx(types.NewTransaction(0, userAddr1, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil, nil, nil, types.SighashEIP155), signer, bankKey)
|
||||
test(tx1, false, light.TxStatus{Status: core.TxStatusUnknown}) // query before sending, should be unknown
|
||||
test(tx1, true, light.TxStatus{Status: core.TxStatusPending}) // send valid processable tx, should return pending
|
||||
test(tx1, true, light.TxStatus{Status: core.TxStatusPending}) // adding it again should not return an error
|
||||
|
||||
tx2, _ := types.SignTx(types.NewTransaction(1, userAddr1, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil, nil, nil), signer, bankKey)
|
||||
tx3, _ := types.SignTx(types.NewTransaction(2, userAddr1, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil, nil, nil), signer, bankKey)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(1, userAddr1, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil, nil, nil, types.SighashEIP155), signer, bankKey)
|
||||
tx3, _ := types.SignTx(types.NewTransaction(2, userAddr1, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil, nil, nil, types.SighashEIP155), signer, bankKey)
|
||||
// send transactions in the wrong order, tx3 should be queued
|
||||
test(tx3, true, light.TxStatus{Status: core.TxStatusQueued})
|
||||
test(tx2, true, light.TxStatus{Status: core.TxStatusPending})
|
||||
|
@ -160,7 +160,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||
from := statedb.GetOrNewStateObject(bankAddr)
|
||||
from.SetBalance(math.MaxBig256)
|
||||
|
||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false, nil, nil)}
|
||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false, nil, nil, 0)}
|
||||
|
||||
context := core.NewEVMContext(msg, header, bc, nil)
|
||||
vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
|
||||
@ -174,7 +174,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||
header := lc.GetHeaderByHash(bhash)
|
||||
state := light.NewState(ctx, header, lc.Odr())
|
||||
state.SetBalance(bankAddr, math.MaxBig256)
|
||||
msg := callmsg{types.NewMessage(bankAddr, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false, nil, nil)}
|
||||
msg := callmsg{types.NewMessage(bankAddr, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), data, false, nil, nil, 0)}
|
||||
context := core.NewEVMContext(msg, header, lc, nil)
|
||||
vmenv := vm.NewEVM(context, state, config, vm.Config{})
|
||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||
|
@ -112,18 +112,18 @@ func prepare(n int, backend *backends.SimulatedBackend) {
|
||||
registrarAddr, _, _, _ = contract.DeployCheckpointOracle(bind.NewKeyedTransactor(bankKey), backend, []common.Address{signerAddr}, sectionSize, processConfirms, big.NewInt(1))
|
||||
// bankUser transfers some ether to user1
|
||||
nonce, _ := backend.PendingNonceAt(ctx, bankAddr)
|
||||
tx, _ := types.SignTx(types.NewTransaction(nonce, userAddr1, big.NewInt(10000), params.TxGas, nil, nil, nil, nil), signer, bankKey)
|
||||
tx, _ := types.SignTx(types.NewTransaction(nonce, userAddr1, big.NewInt(10000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, bankKey)
|
||||
backend.SendTransaction(ctx, tx)
|
||||
case 1:
|
||||
bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
|
||||
userNonce1, _ := backend.PendingNonceAt(ctx, userAddr1)
|
||||
|
||||
// bankUser transfers more ether to user1
|
||||
tx1, _ := types.SignTx(types.NewTransaction(bankNonce, userAddr1, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, bankKey)
|
||||
tx1, _ := types.SignTx(types.NewTransaction(bankNonce, userAddr1, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, bankKey)
|
||||
backend.SendTransaction(ctx, tx1)
|
||||
|
||||
// user1 relays ether to user2
|
||||
tx2, _ := types.SignTx(types.NewTransaction(userNonce1, userAddr2, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, userKey1)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(userNonce1, userAddr2, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, userKey1)
|
||||
backend.SendTransaction(ctx, tx2)
|
||||
|
||||
// user1 deploys a test contract
|
||||
@ -137,18 +137,18 @@ func prepare(n int, backend *backends.SimulatedBackend) {
|
||||
case 2:
|
||||
// bankUser transfer some ether to signer
|
||||
bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
|
||||
tx1, _ := types.SignTx(types.NewTransaction(bankNonce, signerAddr, big.NewInt(1000000000), params.TxGas, nil, nil, nil, nil), signer, bankKey)
|
||||
tx1, _ := types.SignTx(types.NewTransaction(bankNonce, signerAddr, big.NewInt(1000000000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, bankKey)
|
||||
backend.SendTransaction(ctx, tx1)
|
||||
|
||||
// invoke test contract
|
||||
data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001")
|
||||
tx2, _ := types.SignTx(types.NewTransaction(bankNonce+1, testContractAddr, big.NewInt(0), 100000, nil, data, nil, nil), signer, bankKey)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(bankNonce+1, testContractAddr, big.NewInt(0), 100000, nil, data, nil, nil, types.SighashEIP155), signer, bankKey)
|
||||
backend.SendTransaction(ctx, tx2)
|
||||
case 3:
|
||||
// invoke test contract
|
||||
bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
|
||||
data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002")
|
||||
tx, _ := types.SignTx(types.NewTransaction(bankNonce, testContractAddr, big.NewInt(0), 100000, nil, data, nil, nil), signer, bankKey)
|
||||
tx, _ := types.SignTx(types.NewTransaction(bankNonce, testContractAddr, big.NewInt(0), 100000, nil, data, nil, nil, types.SighashEIP155), signer, bankKey)
|
||||
backend.SendTransaction(ctx, tx)
|
||||
}
|
||||
backend.Commit()
|
||||
|
@ -194,7 +194,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
||||
|
||||
// Perform read-only call.
|
||||
st.SetBalance(testBankAddress, math.MaxBig256)
|
||||
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), data, false, nil, nil)}
|
||||
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), data, false, nil, nil, 0)}
|
||||
context := core.NewEVMContext(msg, header, chain, nil)
|
||||
vmenv := vm.NewEVM(context, st, config, vm.Config{})
|
||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||
@ -212,15 +212,15 @@ func testChainGen(i int, block *core.BlockGen) {
|
||||
switch i {
|
||||
case 0:
|
||||
// In block 1, the test bank sends account #1 some ether.
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil, nil, nil), signer, testBankKey)
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, testBankKey)
|
||||
block.AddTx(tx)
|
||||
case 1:
|
||||
// In block 2, the test bank sends some more ether to account #1.
|
||||
// acc1Addr passes it on to account #2.
|
||||
// acc1Addr creates a test contract.
|
||||
tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, testBankKey)
|
||||
tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, testBankKey)
|
||||
nonce := block.TxNonce(acc1Addr)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), signer, acc1Key)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), signer, acc1Key)
|
||||
nonce++
|
||||
tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 1000000, big.NewInt(0), testContractCode, nil, nil), signer, acc1Key)
|
||||
testContractAddr = crypto.CreateAddress(acc1Addr, nonce)
|
||||
@ -232,7 +232,7 @@ func testChainGen(i int, block *core.BlockGen) {
|
||||
block.SetCoinbase(acc2Addr)
|
||||
block.SetExtra([]byte("yeehaw"))
|
||||
data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001")
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), 100000, nil, data, nil, nil), signer, testBankKey)
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), 100000, nil, data, nil, nil, types.SighashEIP155), signer, testBankKey)
|
||||
block.AddTx(tx)
|
||||
case 3:
|
||||
// Block 4 includes blocks 2 and 3 as uncle headers (with modified extra data).
|
||||
@ -243,7 +243,7 @@ func testChainGen(i int, block *core.BlockGen) {
|
||||
b3.Extra = []byte("foo")
|
||||
block.AddUncle(b3)
|
||||
data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002")
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), 100000, nil, data, nil, nil), signer, testBankKey)
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), 100000, nil, data, nil, nil, types.SighashEIP155), signer, testBankKey)
|
||||
block.AddTx(tx)
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ func txPoolTestChainGen(i int, block *core.BlockGen) {
|
||||
|
||||
func TestTxPool(t *testing.T) {
|
||||
for i := range testTx {
|
||||
testTx[i], _ = types.SignTx(types.NewTransaction(uint64(i), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil, nil, nil), types.HomesteadSigner{}, testBankKey)
|
||||
testTx[i], _ = types.SignTx(types.NewTransaction(uint64(i), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), types.HomesteadSigner{}, testBankKey)
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -82,9 +82,9 @@ func init() {
|
||||
Period: 10,
|
||||
Epoch: 30000,
|
||||
}
|
||||
tx1, _ := types.SignTx(types.NewTransaction(0, testUserAddress, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), types.HomesteadSigner{}, testBankKey)
|
||||
tx1, _ := types.SignTx(types.NewTransaction(0, testUserAddress, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), types.HomesteadSigner{}, testBankKey)
|
||||
pendingTxs = append(pendingTxs, tx1)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(1, testUserAddress, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), types.HomesteadSigner{}, testBankKey)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(1, testUserAddress, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), types.HomesteadSigner{}, testBankKey)
|
||||
newTxs = append(newTxs, tx2)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
@ -171,7 +171,7 @@ func (b *testWorkerBackend) newRandomTx(creation bool) *types.Transaction {
|
||||
if creation {
|
||||
tx, _ = types.SignTx(types.NewContractCreation(b.txPool.Nonce(testBankAddress), big.NewInt(0), testGas, nil, common.FromHex(testCode), nil, nil), types.HomesteadSigner{}, testBankKey)
|
||||
} else {
|
||||
tx, _ = types.SignTx(types.NewTransaction(b.txPool.Nonce(testBankAddress), testUserAddress, big.NewInt(1000), params.TxGas, nil, nil, nil, nil), types.HomesteadSigner{}, testBankKey)
|
||||
tx, _ = types.SignTx(types.NewTransaction(b.txPool.Nonce(testBankAddress), testUserAddress, big.NewInt(1000), params.TxGas, nil, nil, nil, nil, types.SighashEIP155), types.HomesteadSigner{}, testBankKey)
|
||||
}
|
||||
return tx
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ func NewTransaction(nonce int64, to *Address, amount *BigInt, gasLimit int64, ga
|
||||
if to == nil {
|
||||
return &Transaction{types.NewContractCreation(uint64(nonce), amount.bigint, uint64(gasLimit), gasPrice.bigint, common.CopyBytes(data), nil, nil)}
|
||||
}
|
||||
return &Transaction{types.NewTransaction(uint64(nonce), to.address, amount.bigint, uint64(gasLimit), gasPrice.bigint, common.CopyBytes(data), nil, nil)}
|
||||
return &Transaction{types.NewTransaction(uint64(nonce), to.address, amount.bigint, uint64(gasLimit), gasPrice.bigint, common.CopyBytes(data), nil, nil, types.SighashEIP155)}
|
||||
}
|
||||
|
||||
// NewTransactionFromRLP parses a transaction from an RLP data dump.
|
||||
|
@ -78,7 +78,7 @@ func createBlocks(number int, startIndex int, withTx bool) types.Blocks {
|
||||
header := &types.Header{Number: big.NewInt(int64(i + startIndex))}
|
||||
txs := make(types.Transactions, 0)
|
||||
if withTx {
|
||||
tx, _ := types.SignTx(types.NewTransaction(uint64(i), testUserAddress, big.NewInt(1), params.TxGas, big.NewInt(0), nil, &testUserAddress, &testRollupTxId), types.HomesteadSigner{}, testBankKey)
|
||||
tx, _ := types.SignTx(types.NewTransaction(uint64(i), testUserAddress, big.NewInt(1), params.TxGas, big.NewInt(0), nil, &testUserAddress, &testRollupTxId, types.SighashEIP155), types.HomesteadSigner{}, testBankKey)
|
||||
txs = append(txs, tx)
|
||||
}
|
||||
block := types.NewBlock(header, txs, make([]*types.Header, 0), make([]*types.Receipt, 0))
|
||||
|
@ -74,10 +74,11 @@ type SendTxArgs struct {
|
||||
Value hexutil.Big `json:"value"`
|
||||
Nonce hexutil.Uint64 `json:"nonce"`
|
||||
// We accept "data" and "input" for backwards-compatibility reasons.
|
||||
Data *hexutil.Bytes `json:"data"`
|
||||
Input *hexutil.Bytes `json:"input,omitempty"`
|
||||
L1MessageSender *common.MixedcaseAddress `json:"l1MessageSender,omitempty" rlp:"nil,?"`
|
||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty" rlp:"nil,?"`
|
||||
Data *hexutil.Bytes `json:"data"`
|
||||
Input *hexutil.Bytes `json:"input,omitempty"`
|
||||
L1MessageSender *common.MixedcaseAddress `json:"l1MessageSender,omitempty"`
|
||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty"`
|
||||
SignatureHashType types.SignatureHashType `json:"signatureHashType,omitempty"`
|
||||
}
|
||||
|
||||
func (args SendTxArgs) String() string {
|
||||
@ -105,5 +106,6 @@ func (args *SendTxArgs) toTransaction() *types.Transaction {
|
||||
l1RollupTxId = new(hexutil.Uint64)
|
||||
*l1RollupTxId = *args.L1RollupTxId
|
||||
}
|
||||
return types.NewTransaction(uint64(args.Nonce), args.To.Address(), (*big.Int)(&args.Value), (uint64)(args.Gas), (*big.Int)(&args.GasPrice), input, l1MessageSender, l1RollupTxId)
|
||||
|
||||
return types.NewTransaction(uint64(args.Nonce), args.To.Address(), (*big.Int)(&args.Value), (uint64)(args.Gas), (*big.Int)(&args.GasPrice), input, l1MessageSender, l1RollupTxId, args.SignatureHashType)
|
||||
}
|
||||
|
@ -458,7 +458,7 @@ func dummySigned(value *big.Int) *types.Transaction {
|
||||
gas := uint64(21000)
|
||||
gasPrice := big.NewInt(2000000)
|
||||
data := make([]byte, 0)
|
||||
return types.NewTransaction(3, to, value, gas, gasPrice, data, nil, nil)
|
||||
return types.NewTransaction(3, to, value, gas, gasPrice, data, nil, nil, types.SighashEIP155)
|
||||
}
|
||||
|
||||
func TestLimitWindow(t *testing.T) {
|
||||
|
@ -241,6 +241,7 @@ func applyMessageToState(currentState *state.StateDB, from common.Address, to co
|
||||
false,
|
||||
&ZERO_ADDRESS,
|
||||
nil,
|
||||
0,
|
||||
)
|
||||
} else {
|
||||
// Otherwise we actually use the `to` field!
|
||||
@ -255,6 +256,7 @@ func applyMessageToState(currentState *state.StateDB, from common.Address, to co
|
||||
false,
|
||||
&ZERO_ADDRESS,
|
||||
nil,
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ func (tx *stTransaction) toMessage(ps stPostState) (core.Message, error) {
|
||||
return nil, fmt.Errorf("invalid tx data %q", dataHex)
|
||||
}
|
||||
|
||||
msg := types.NewMessage(from, to, tx.Nonce, value, gasLimit, tx.GasPrice, data, true, nil, nil)
|
||||
msg := types.NewMessage(from, to, tx.Nonce, value, gasLimit, tx.GasPrice, data, true, nil, nil, 0)
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user