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
|
// 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)
|
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("could not sign tx: %v", err)
|
t.Errorf("could not sign tx: %v", err)
|
||||||
@ -281,7 +281,7 @@ func TestSimulatedBackend_SendTransaction(t *testing.T) {
|
|||||||
bgCtx := context.Background()
|
bgCtx := context.Background()
|
||||||
|
|
||||||
// create a signed transaction to send
|
// 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)
|
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("could not sign tx: %v", err)
|
t.Errorf("could not sign tx: %v", err)
|
||||||
@ -316,7 +316,7 @@ func TestSimulatedBackend_TransactionByHash(t *testing.T) {
|
|||||||
bgCtx := context.Background()
|
bgCtx := context.Background()
|
||||||
|
|
||||||
// create a signed transaction to send
|
// 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)
|
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("could not sign tx: %v", err)
|
t.Errorf("could not sign tx: %v", err)
|
||||||
@ -481,7 +481,7 @@ func TestSimulatedBackend_TransactionCount(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create a signed transaction to send
|
// 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)
|
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("could not sign tx: %v", err)
|
t.Errorf("could not sign tx: %v", err)
|
||||||
@ -540,7 +540,7 @@ func TestSimulatedBackend_TransactionInBlock(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create a signed transaction to send
|
// 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)
|
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("could not sign tx: %v", err)
|
t.Errorf("could not sign tx: %v", err)
|
||||||
@ -599,7 +599,7 @@ func TestSimulatedBackend_PendingNonceAt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create a signed transaction to send
|
// 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)
|
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("could not sign tx: %v", err)
|
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
|
// 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)
|
signedTx, err = types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("could not sign tx: %v", err)
|
t.Errorf("could not sign tx: %v", err)
|
||||||
@ -655,7 +655,7 @@ func TestSimulatedBackend_TransactionReceipt(t *testing.T) {
|
|||||||
bgCtx := context.Background()
|
bgCtx := context.Background()
|
||||||
|
|
||||||
// create a signed transaction to send
|
// 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)
|
signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("could not sign tx: %v", err)
|
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 {
|
if contract == nil {
|
||||||
rawTx = types.NewContractCreation(nonce, value, gasLimit, gasPrice, input, nil, nil)
|
rawTx = types.NewContractCreation(nonce, value, gasLimit, gasPrice, input, nil, nil)
|
||||||
} else {
|
} 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 {
|
if opts.Signer == nil {
|
||||||
return nil, errors.New("no signer to authorize the transaction with")
|
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).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))
|
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)
|
signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f.lock.Unlock()
|
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
|
// 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.
|
// first one. The last is needs a state change again to force a reorg.
|
||||||
if i != 1 {
|
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 {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
|
|||||||
toaddr := common.Address{}
|
toaddr := common.Address{}
|
||||||
data := make([]byte, nbytes)
|
data := make([]byte, nbytes)
|
||||||
gas, _ := IntrinsicGas(data, false, false, false)
|
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)
|
gen.AddTx(tx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
to := (from + 1) % naccounts
|
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])
|
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, ringKeys[from])
|
||||||
gen.AddTx(tx)
|
gen.AddTx(tx)
|
||||||
from = to
|
from = to
|
||||||
|
@ -1221,6 +1221,9 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
|
|||||||
rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body())
|
rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body())
|
||||||
rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i])
|
rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i])
|
||||||
rawdb.WriteTxLookupEntries(batch, block)
|
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
|
// Write everything belongs to the blocks into the database. So that
|
||||||
// we can ensure all components of body is completed(body, receipts,
|
// 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()
|
blockBatch := bc.db.NewBatch()
|
||||||
rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd)
|
rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd)
|
||||||
rawdb.WriteBlock(blockBatch, block)
|
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.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts)
|
||||||
rawdb.WritePreimages(blockBatch, state.Preimages())
|
rawdb.WritePreimages(blockBatch, state.Preimages())
|
||||||
if err := blockBatch.Write(); err != nil {
|
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 the block number is multiple of 3, send a few bonus transactions to the miner
|
||||||
if i%3 == 2 {
|
if i%3 == 2 {
|
||||||
for j := 0; j < i%4+1; j++ {
|
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 {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -840,8 +840,8 @@ func TestChainTxReorgs(t *testing.T) {
|
|||||||
// Create two transactions shared between the chains:
|
// Create two transactions shared between the chains:
|
||||||
// - postponed: transaction included at a later block in the forked chain
|
// - postponed: transaction included at a later block in the forked chain
|
||||||
// - swapped: transaction included at the same block number 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)
|
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), 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:
|
// Create two transactions that will be dropped by the forked chain:
|
||||||
// - pastDrop: transaction dropped retroactively from a past block
|
// - 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) {
|
chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
|
||||||
switch i {
|
switch i {
|
||||||
case 0:
|
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(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
|
gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
|
||||||
|
|
||||||
case 2:
|
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(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
|
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) {
|
chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
|
||||||
switch i {
|
switch i {
|
||||||
case 0:
|
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
|
gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
|
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
|
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
|
gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
|
||||||
|
|
||||||
case 3:
|
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
|
gen.AddTx(futureAdd) // This transaction will be added after a full reorg
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1340,7 +1340,7 @@ func TestEIP155Transition(t *testing.T) {
|
|||||||
tx *types.Transaction
|
tx *types.Transaction
|
||||||
err error
|
err error
|
||||||
basicTx = func(signer types.Signer) (*types.Transaction, 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 {
|
switch i {
|
||||||
@ -1403,7 +1403,7 @@ func TestEIP155Transition(t *testing.T) {
|
|||||||
tx *types.Transaction
|
tx *types.Transaction
|
||||||
err error
|
err error
|
||||||
basicTx = func(signer types.Signer) (*types.Transaction, 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 {
|
if i == 0 {
|
||||||
@ -1453,11 +1453,11 @@ func TestEIP161AccountRemoval(t *testing.T) {
|
|||||||
)
|
)
|
||||||
switch i {
|
switch i {
|
||||||
case 0:
|
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:
|
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:
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -2166,7 +2166,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
|
|||||||
for txi := 0; txi < numTxs; txi++ {
|
for txi := 0; txi < numTxs; txi++ {
|
||||||
uniq := uint64(i*numTxs + txi)
|
uniq := uint64(i*numTxs + txi)
|
||||||
recipient := recipientFn(uniq)
|
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 {
|
if err != nil {
|
||||||
b.Error(err)
|
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) {
|
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
|
||||||
b.SetCoinbase(common.Address{1})
|
b.SetCoinbase(common.Address{1})
|
||||||
// One transaction to AAAA
|
// 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)
|
b.AddTx(tx)
|
||||||
// One transaction to BBBB
|
// 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)
|
b.AddTx(tx)
|
||||||
})
|
})
|
||||||
// Import the canonical chain
|
// 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.
|
// 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 {
|
func ReadTdRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
|
||||||
// First try to look up the data in ancient database. Extra hash
|
// First try to look up the data in ancient database. Extra hash
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/core/types"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
@ -273,8 +274,8 @@ func TestBlockReceiptStorage(t *testing.T) {
|
|||||||
db := NewMemoryDatabase()
|
db := NewMemoryDatabase()
|
||||||
|
|
||||||
// Create a live block since we need metadata to reconstruct the receipt
|
// 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)
|
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)
|
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}}
|
body := &types.Body{Transactions: types.Transactions{tx1, tx2}}
|
||||||
|
|
||||||
@ -424,3 +425,49 @@ func TestAncientStorage(t *testing.T) {
|
|||||||
t.Fatalf("invalid td returned")
|
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 {
|
for txIndex, tx := range body.Transactions {
|
||||||
if tx.Hash() == hash {
|
if tx.Hash() == hash {
|
||||||
|
txMeta := ReadTransactionMeta(db, hash)
|
||||||
|
if txMeta != nil {
|
||||||
|
tx.SetTransactionMeta(txMeta)
|
||||||
|
}
|
||||||
|
|
||||||
return tx, blockHash, *blockNumber, uint64(txIndex)
|
return tx, blockHash, *blockNumber, uint64(txIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,9 +74,9 @@ func TestLookupStorage(t *testing.T) {
|
|||||||
l1RollupTxId1 := hexutil.Uint64(1)
|
l1RollupTxId1 := hexutil.Uint64(1)
|
||||||
l1RollupTxId2 := hexutil.Uint64(2)
|
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)
|
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)
|
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)
|
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}
|
txs := []*types.Transaction{tx1, tx2, tx3}
|
||||||
|
|
||||||
block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil)
|
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
|
txLookupPrefix = []byte("l") // txLookupPrefix + hash -> transaction/receipt lookup metadata
|
||||||
bloomBitsPrefix = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits
|
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
|
preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage
|
||||||
configPrefix = []byte("ethereum-config-") // config prefix for the db
|
configPrefix = []byte("ethereum-config-") // config prefix for the db
|
||||||
|
|
||||||
@ -145,6 +148,11 @@ func txLookupKey(hash common.Hash) []byte {
|
|||||||
return append(txLookupPrefix, hash.Bytes()...)
|
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
|
// bloomBitsKey = bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash
|
||||||
func bloomBitsKey(bit uint, section uint64, hash common.Hash) []byte {
|
func bloomBitsKey(bit uint, section uint64, hash common.Hash) []byte {
|
||||||
key := append(append(bloomBitsPrefix, make([]byte, 10)...), hash.Bytes()...)
|
key := append(append(bloomBitsPrefix, make([]byte, 10)...), hash.Bytes()...)
|
||||||
|
@ -271,7 +271,7 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block
|
|||||||
config: config,
|
config: config,
|
||||||
chainconfig: chainconfig,
|
chainconfig: chainconfig,
|
||||||
chain: chain,
|
chain: chain,
|
||||||
signer: types.NewEIP155Signer(chainconfig.ChainID),
|
signer: types.NewOVMSigner(chainconfig.ChainID),
|
||||||
pending: make(map[common.Address]*txList),
|
pending: make(map[common.Address]*txList),
|
||||||
queue: make(map[common.Address]*txList),
|
queue: make(map[common.Address]*txList),
|
||||||
beats: make(map[common.Address]time.Time),
|
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 {
|
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
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key
|
|||||||
data := make([]byte, bytes)
|
data := make([]byte, bytes)
|
||||||
rand.Read(data)
|
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
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ func TestTransactionNegativeValue(t *testing.T) {
|
|||||||
pool, key := setupTxPool()
|
pool, key := setupTxPool()
|
||||||
defer pool.Stop()
|
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)
|
from, _ := deriveSender(tx)
|
||||||
pool.currentState.AddBalance(from, big.NewInt(1))
|
pool.currentState.AddBalance(from, big.NewInt(1))
|
||||||
if err := pool.AddRemote(tx); err != ErrNegativeValue {
|
if err := pool.AddRemote(tx); err != ErrNegativeValue {
|
||||||
@ -383,9 +383,9 @@ func TestTransactionDoubleNonce(t *testing.T) {
|
|||||||
resetState()
|
resetState()
|
||||||
|
|
||||||
signer := types.HomesteadSigner{}
|
signer := types.HomesteadSigner{}
|
||||||
tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 100000, 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), 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), 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
|
// Add the first two transaction, ensure higher priced stays only
|
||||||
if replace, err := pool.add(tx1, false); err != nil || replace {
|
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("Time", block.Time(), uint64(1426516743))
|
||||||
check("Size", block.Size(), common.StorageSize(len(blockEnc)))
|
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"))
|
tx1, _ = tx1.WithSignature(HomesteadSigner{}, common.Hex2Bytes("9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b100"))
|
||||||
check("len(Transactions)", len(block.Transactions()), 1)
|
check("len(Transactions)", len(block.Transactions()), 1)
|
||||||
check("Transactions[0].Hash", block.Transactions()[0].Hash(), tx1.Hash())
|
check("Transactions[0].Hash", block.Transactions()[0].Hash(), tx1.Hash())
|
||||||
|
@ -13,9 +13,9 @@ import (
|
|||||||
|
|
||||||
var _ = (*txdataMarshaling)(nil)
|
var _ = (*txdataMarshaling)(nil)
|
||||||
|
|
||||||
// MarshalJSON marshals as JSON.
|
// TransactionMarshalJSON marshals as JSON.
|
||||||
func (t txdata) MarshalJSON() ([]byte, error) {
|
func TransactionMarshalJSON(t *Transaction) ([]byte, error) {
|
||||||
type txdata struct {
|
type txnjson struct {
|
||||||
AccountNonce hexutil.Uint64 `json:"nonce" gencodec:"required"`
|
AccountNonce hexutil.Uint64 `json:"nonce" gencodec:"required"`
|
||||||
Price *hexutil.Big `json:"gasPrice" gencodec:"required"`
|
Price *hexutil.Big `json:"gasPrice" gencodec:"required"`
|
||||||
GasLimit hexutil.Uint64 `json:"gas" gencodec:"required"`
|
GasLimit hexutil.Uint64 `json:"gas" gencodec:"required"`
|
||||||
@ -28,26 +28,30 @@ func (t txdata) MarshalJSON() ([]byte, error) {
|
|||||||
Hash *common.Hash `json:"hash" rlp:"-"`
|
Hash *common.Hash `json:"hash" rlp:"-"`
|
||||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty" rlp:"nil,?"`
|
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty" rlp:"nil,?"`
|
||||||
L1MessageSender *common.Address `json:"l1MessageSender,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)
|
var enc txnjson
|
||||||
enc.Price = (*hexutil.Big)(t.Price)
|
enc.AccountNonce = hexutil.Uint64(t.data.AccountNonce)
|
||||||
enc.GasLimit = hexutil.Uint64(t.GasLimit)
|
enc.Price = (*hexutil.Big)(t.data.Price)
|
||||||
enc.Recipient = t.Recipient
|
enc.GasLimit = hexutil.Uint64(t.data.GasLimit)
|
||||||
enc.L1MessageSender = t.L1MessageSender
|
enc.Recipient = t.data.Recipient
|
||||||
enc.L1RollupTxId = t.L1RollupTxId
|
enc.L1MessageSender = t.meta.L1MessageSender
|
||||||
enc.Amount = (*hexutil.Big)(t.Amount)
|
enc.L1RollupTxId = t.meta.L1RollupTxId
|
||||||
enc.Payload = t.Payload
|
enc.SignatureHashType = t.meta.SignatureHashType
|
||||||
enc.V = (*hexutil.Big)(t.V)
|
enc.Amount = (*hexutil.Big)(t.data.Amount)
|
||||||
enc.R = (*hexutil.Big)(t.R)
|
enc.Payload = t.data.Payload
|
||||||
enc.S = (*hexutil.Big)(t.S)
|
enc.V = (*hexutil.Big)(t.data.V)
|
||||||
enc.Hash = t.Hash
|
enc.R = (*hexutil.Big)(t.data.R)
|
||||||
|
enc.S = (*hexutil.Big)(t.data.S)
|
||||||
|
hash := t.Hash()
|
||||||
|
enc.Hash = &hash
|
||||||
return json.Marshal(&enc)
|
return json.Marshal(&enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON unmarshals from JSON.
|
// UnmarshalJSON unmarshals from JSON.
|
||||||
func (t *txdata) UnmarshalJSON(input []byte) error {
|
func TransactionUnmarshalJSON(input []byte) (*Transaction, error) {
|
||||||
type txdata struct {
|
type txnjson struct {
|
||||||
AccountNonce *hexutil.Uint64 `json:"nonce" gencodec:"required"`
|
AccountNonce *hexutil.Uint64 `json:"nonce" gencodec:"required"`
|
||||||
Price *hexutil.Big `json:"gasPrice" gencodec:"required"`
|
Price *hexutil.Big `json:"gasPrice" gencodec:"required"`
|
||||||
GasLimit *hexutil.Uint64 `json:"gas" gencodec:"required"`
|
GasLimit *hexutil.Uint64 `json:"gas" gencodec:"required"`
|
||||||
@ -58,56 +62,62 @@ func (t *txdata) UnmarshalJSON(input []byte) error {
|
|||||||
R *hexutil.Big `json:"r" gencodec:"required"`
|
R *hexutil.Big `json:"r" gencodec:"required"`
|
||||||
S *hexutil.Big `json:"s" gencodec:"required"`
|
S *hexutil.Big `json:"s" gencodec:"required"`
|
||||||
Hash *common.Hash `json:"hash" rlp:"-"`
|
Hash *common.Hash `json:"hash" rlp:"-"`
|
||||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty" rlp:"nil,?"`
|
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty"`
|
||||||
L1MessageSender *common.Address `json:"l1MessageSender,omitempty" rlp:"nil,?"`
|
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 {
|
if err := json.Unmarshal(input, &dec); err != nil {
|
||||||
return err
|
return &Transaction{}, err
|
||||||
}
|
}
|
||||||
if dec.AccountNonce == nil {
|
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 {
|
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 {
|
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 {
|
if dec.Recipient != nil {
|
||||||
t.Recipient = dec.Recipient
|
t.data.Recipient = dec.Recipient
|
||||||
}
|
}
|
||||||
if dec.L1MessageSender != nil {
|
if dec.L1MessageSender != nil {
|
||||||
t.L1MessageSender = dec.L1MessageSender
|
t.meta.L1MessageSender = dec.L1MessageSender
|
||||||
}
|
}
|
||||||
if dec.L1RollupTxId != nil {
|
if dec.L1RollupTxId != nil {
|
||||||
t.L1RollupTxId = dec.L1RollupTxId
|
t.meta.L1RollupTxId = dec.L1RollupTxId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.meta.SignatureHashType = dec.SignatureHashType
|
||||||
|
|
||||||
if dec.Amount == nil {
|
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 {
|
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 {
|
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 {
|
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 {
|
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 {
|
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{
|
receipt := &Receipt{
|
||||||
Status: ReceiptStatusFailed,
|
Status: ReceiptStatusFailed,
|
||||||
CumulativeGasUsed: 1,
|
CumulativeGasUsed: 1,
|
||||||
@ -156,7 +156,7 @@ func TestDeriveFields(t *testing.T) {
|
|||||||
// Create a few transactions to have receipts for
|
// Create a few transactions to have receipts for
|
||||||
txs := Transactions{
|
txs := Transactions{
|
||||||
NewContractCreation(1, big.NewInt(1), 1, big.NewInt(1), nil, nil, nil),
|
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
|
// Create the corresponding receipts
|
||||||
receipts := Receipts{
|
receipts := Receipts{
|
||||||
|
@ -36,8 +36,16 @@ var (
|
|||||||
ErrInvalidSig = errors.New("invalid transaction v, r, s values")
|
ErrInvalidSig = errors.New("invalid transaction v, r, s values")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type SignatureHashType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
SighashEIP155 SignatureHashType = 0
|
||||||
|
SighashEthSign SignatureHashType = 1
|
||||||
|
)
|
||||||
|
|
||||||
type Transaction struct {
|
type Transaction struct {
|
||||||
data txdata
|
data txdata
|
||||||
|
meta TransactionMeta
|
||||||
// caches
|
// caches
|
||||||
hash atomic.Value
|
hash atomic.Value
|
||||||
size atomic.Value
|
size atomic.Value
|
||||||
@ -59,8 +67,6 @@ type txdata struct {
|
|||||||
|
|
||||||
// This is only used when marshaling to JSON.
|
// This is only used when marshaling to JSON.
|
||||||
Hash *common.Hash `json:"hash" rlp:"-"`
|
Hash *common.Hash `json:"hash" rlp:"-"`
|
||||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty" rlp:"nil,?"`
|
|
||||||
L1MessageSender *common.Address `json:"l1MessageSender,omitempty" rlp:"nil,?"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type txdataMarshaling struct {
|
type txdataMarshaling struct {
|
||||||
@ -74,23 +80,28 @@ type txdataMarshaling struct {
|
|||||||
S *hexutil.Big
|
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 {
|
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)
|
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 {
|
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 {
|
if len(data) > 0 {
|
||||||
data = common.CopyBytes(data)
|
data = common.CopyBytes(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meta := TransactionMeta{
|
||||||
|
L1RollupTxId: l1RollupTxId,
|
||||||
|
L1MessageSender: l1MessageSender,
|
||||||
|
SignatureHashType: sighashType,
|
||||||
|
}
|
||||||
|
|
||||||
d := txdata{
|
d := txdata{
|
||||||
AccountNonce: nonce,
|
AccountNonce: nonce,
|
||||||
Recipient: to,
|
Recipient: to,
|
||||||
L1MessageSender: l1MessageSender,
|
|
||||||
L1RollupTxId: l1RollupTxId,
|
|
||||||
Payload: data,
|
Payload: data,
|
||||||
Amount: new(big.Int),
|
Amount: new(big.Int),
|
||||||
GasLimit: gasLimit,
|
GasLimit: gasLimit,
|
||||||
@ -106,7 +117,21 @@ func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit
|
|||||||
d.Price.Set(gasPrice)
|
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
|
// Appends the provided 64-bit nonce to this Transaction's calldata as the last 4 bytes
|
||||||
@ -169,34 +194,31 @@ func (tx *Transaction) DecodeRLP(s *rlp.Stream) error {
|
|||||||
|
|
||||||
// MarshalJSON encodes the web3 RPC transaction format.
|
// MarshalJSON encodes the web3 RPC transaction format.
|
||||||
func (tx *Transaction) MarshalJSON() ([]byte, error) {
|
func (tx *Transaction) MarshalJSON() ([]byte, error) {
|
||||||
hash := tx.Hash()
|
return TransactionMarshalJSON(tx)
|
||||||
data := tx.data
|
|
||||||
data.Hash = &hash
|
|
||||||
return data.MarshalJSON()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON decodes the web3 RPC transaction format.
|
// UnmarshalJSON decodes the web3 RPC transaction format.
|
||||||
func (tx *Transaction) UnmarshalJSON(input []byte) error {
|
func (tx *Transaction) UnmarshalJSON(input []byte) error {
|
||||||
var dec txdata
|
dec, err := TransactionUnmarshalJSON(input)
|
||||||
if err := dec.UnmarshalJSON(input); err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
if withSignature {
|
||||||
var V byte
|
var V byte
|
||||||
if isProtectedV(dec.V) {
|
if isProtectedV(dec.data.V) {
|
||||||
chainID := deriveChainId(dec.V).Uint64()
|
chainID := deriveChainId(dec.data.V).Uint64()
|
||||||
V = byte(dec.V.Uint64() - 35 - 2*chainID)
|
V = byte(dec.data.V.Uint64() - 35 - 2*chainID)
|
||||||
} else {
|
} 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
|
return ErrInvalidSig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*tx = Transaction{data: dec}
|
*tx = *dec
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,6 +228,15 @@ func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Pri
|
|||||||
func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) }
|
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) Nonce() uint64 { return tx.data.AccountNonce }
|
||||||
func (tx *Transaction) CheckNonce() bool { return true }
|
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.
|
// To returns the recipient address of the transaction.
|
||||||
// It returns nil if the transaction is a contract creation.
|
// 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.
|
// 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.
|
// It returns nil if this transaction was not from an L1 contract.
|
||||||
func (tx *Transaction) L1MessageSender() *common.Address {
|
func (tx *Transaction) L1MessageSender() *common.Address {
|
||||||
if tx.data.L1MessageSender == nil {
|
if tx.meta.L1MessageSender == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
l1MessageSender := *tx.data.L1MessageSender
|
l1MessageSender := *tx.meta.L1MessageSender
|
||||||
return &l1MessageSender
|
return &l1MessageSender
|
||||||
}
|
}
|
||||||
|
|
||||||
// L1RollupTxId returns the L1 Rollup Tx Id of the transaction if one exists.
|
// 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.
|
// It returns nil if this transaction was not generated from a transaction received on L1.
|
||||||
func (tx *Transaction) L1RollupTxId() *hexutil.Uint64 {
|
func (tx *Transaction) L1RollupTxId() *hexutil.Uint64 {
|
||||||
if tx.data.L1RollupTxId == nil {
|
if tx.meta.L1RollupTxId == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
l1RolupTxId := *tx.data.L1RollupTxId
|
l1RolupTxId := *tx.meta.L1RollupTxId
|
||||||
return &l1RolupTxId
|
return &l1RolupTxId
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,20 +275,7 @@ func (tx *Transaction) Hash() common.Hash {
|
|||||||
return 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)
|
v := rlpHash(tx)
|
||||||
|
|
||||||
if tx != nil {
|
|
||||||
tx.data.L1MessageSender = sender
|
|
||||||
tx.data.L1RollupTxId = l1RollupTxId
|
|
||||||
}
|
|
||||||
tx.hash.Store(v)
|
tx.hash.Store(v)
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
@ -285,8 +303,9 @@ func (tx *Transaction) AsMessage(s Signer) (Message, error) {
|
|||||||
gasLimit: tx.data.GasLimit,
|
gasLimit: tx.data.GasLimit,
|
||||||
gasPrice: new(big.Int).Set(tx.data.Price),
|
gasPrice: new(big.Int).Set(tx.data.Price),
|
||||||
to: tx.data.Recipient,
|
to: tx.data.Recipient,
|
||||||
l1MessageSender: tx.data.L1MessageSender,
|
l1MessageSender: tx.meta.L1MessageSender,
|
||||||
l1RollupTxId: tx.data.L1RollupTxId,
|
l1RollupTxId: tx.meta.L1RollupTxId,
|
||||||
|
signatureHashType: tx.meta.SignatureHashType,
|
||||||
amount: tx.data.Amount,
|
amount: tx.data.Amount,
|
||||||
data: tx.data.Payload,
|
data: tx.data.Payload,
|
||||||
checkNonce: true,
|
checkNonce: true,
|
||||||
@ -304,7 +323,7 @@ func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
cpy.data.R, cpy.data.S, cpy.data.V = r, s, v
|
||||||
return cpy, nil
|
return cpy, nil
|
||||||
}
|
}
|
||||||
@ -402,6 +421,8 @@ func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transa
|
|||||||
// Initialize a price based heap with the head transactions
|
// Initialize a price based heap with the head transactions
|
||||||
heads := make(TxByPrice, 0, len(txs))
|
heads := make(TxByPrice, 0, len(txs))
|
||||||
for from, accTxs := range txs {
|
for from, accTxs := range txs {
|
||||||
|
// This prevents a panic, not ideal.
|
||||||
|
if len(accTxs) > 0 {
|
||||||
heads = append(heads, accTxs[0])
|
heads = append(heads, accTxs[0])
|
||||||
// Ensure the sender address is from the signer
|
// Ensure the sender address is from the signer
|
||||||
acc, _ := Sender(signer, accTxs[0])
|
acc, _ := Sender(signer, accTxs[0])
|
||||||
@ -410,6 +431,7 @@ func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transa
|
|||||||
delete(txs, from)
|
delete(txs, from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
heap.Init(&heads)
|
heap.Init(&heads)
|
||||||
|
|
||||||
// Assemble and return the transaction set
|
// Assemble and return the transaction set
|
||||||
@ -453,6 +475,7 @@ type Message struct {
|
|||||||
to *common.Address
|
to *common.Address
|
||||||
l1MessageSender *common.Address
|
l1MessageSender *common.Address
|
||||||
l1RollupTxId *hexutil.Uint64
|
l1RollupTxId *hexutil.Uint64
|
||||||
|
signatureHashType SignatureHashType
|
||||||
from common.Address
|
from common.Address
|
||||||
nonce uint64
|
nonce uint64
|
||||||
amount *big.Int
|
amount *big.Int
|
||||||
@ -462,7 +485,7 @@ type Message struct {
|
|||||||
checkNonce bool
|
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{
|
return Message{
|
||||||
from: from,
|
from: from,
|
||||||
to: to,
|
to: to,
|
||||||
@ -474,6 +497,7 @@ func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *b
|
|||||||
checkNonce: checkNonce,
|
checkNonce: checkNonce,
|
||||||
l1RollupTxId: l1RollupTxId,
|
l1RollupTxId: l1RollupTxId,
|
||||||
l1MessageSender: l1MessageSender,
|
l1MessageSender: l1MessageSender,
|
||||||
|
signatureHashType: signatureHashType,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,6 +505,7 @@ func (m Message) From() common.Address { return m.from }
|
|||||||
func (m Message) To() *common.Address { return m.to }
|
func (m Message) To() *common.Address { return m.to }
|
||||||
func (m Message) L1MessageSender() *common.Address { return m.l1MessageSender }
|
func (m Message) L1MessageSender() *common.Address { return m.l1MessageSender }
|
||||||
func (m Message) L1RollupTxId() *hexutil.Uint64 { return m.l1RollupTxId }
|
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) GasPrice() *big.Int { return m.gasPrice }
|
||||||
func (m Message) Value() *big.Int { return m.amount }
|
func (m Message) Value() *big.Int { return m.amount }
|
||||||
func (m Message) Gas() uint64 { return m.gasLimit }
|
func (m Message) Gas() uint64 { return m.gasLimit }
|
||||||
|
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
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
@ -25,6 +27,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -40,16 +43,7 @@ type sigCache struct {
|
|||||||
|
|
||||||
// MakeSigner returns a Signer based on the given chain config and block number.
|
// MakeSigner returns a Signer based on the given chain config and block number.
|
||||||
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
|
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
|
||||||
var signer Signer
|
return NewOVMSigner(config.ChainID)
|
||||||
switch {
|
|
||||||
case config.IsEIP155(blockNumber):
|
|
||||||
signer = NewEIP155Signer(config.ChainID)
|
|
||||||
case config.IsHomestead(blockNumber):
|
|
||||||
signer = HomesteadSigner{}
|
|
||||||
default:
|
|
||||||
signer = FrontierSigner{}
|
|
||||||
}
|
|
||||||
return signer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignTx signs the transaction using the given signer and private key
|
// SignTx signs the transaction using the given signer and private key
|
||||||
@ -102,6 +96,102 @@ type Signer interface {
|
|||||||
Equal(Signer) bool
|
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.
|
// EIP155Transaction implements Signer using the EIP155 rules.
|
||||||
type EIP155Signer struct {
|
type EIP155Signer struct {
|
||||||
chainId, chainIdMul *big.Int
|
chainId, chainIdMul *big.Int
|
||||||
|
@ -30,7 +30,7 @@ func TestEIP155Signing(t *testing.T) {
|
|||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
|
|
||||||
signer := NewEIP155Signer(big.NewInt(18))
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -49,7 +49,7 @@ func TestEIP155ChainId(t *testing.T) {
|
|||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
|
|
||||||
signer := NewEIP155Signer(big.NewInt(18))
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ func TestEIP155ChainId(t *testing.T) {
|
|||||||
t.Error("expected chainId to be", signer.chainId, "got", tx.ChainId())
|
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)
|
tx, err = SignTx(tx, HomesteadSigner{}, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -118,7 +118,7 @@ func TestEIP155SigningVitalik(t *testing.T) {
|
|||||||
func TestChainId(t *testing.T) {
|
func TestChainId(t *testing.T) {
|
||||||
key, _ := defaultTestKey()
|
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
|
var err error
|
||||||
tx, err = SignTx(tx, NewEIP155Signer(big.NewInt(1)), key)
|
tx, err = SignTx(tx, NewEIP155Signer(big.NewInt(1)), key)
|
||||||
@ -136,3 +136,94 @@ func TestChainId(t *testing.T) {
|
|||||||
t.Error("expected no error")
|
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 (
|
var (
|
||||||
sender = common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87")
|
sender = common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87")
|
||||||
l1RollupTxId = hexutil.Uint64(1)
|
l1RollupTxId = hexutil.Uint64(1)
|
||||||
emptyTx = NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(0), 0, big.NewInt(0), nil, &sender, 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)
|
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{},
|
HomesteadSigner{},
|
||||||
common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a301"),
|
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{},
|
HomesteadSigner{},
|
||||||
common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a301"),
|
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{},
|
HomesteadSigner{},
|
||||||
common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a301"),
|
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) {
|
func TestTransactionSigHash(t *testing.T) {
|
||||||
@ -78,16 +80,29 @@ func TestTransactionEncode(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("encode error: %v", err)
|
t.Fatalf("encode error: %v", err)
|
||||||
}
|
}
|
||||||
if bytes.Equal(txc, should) {
|
if !bytes.Equal(txc, should) {
|
||||||
t.Errorf("RLP encoding with L1MessageSender should be different than without. Got %x", txc)
|
t.Errorf("RLP encoding with L1MessageSender should be the same. Got %x", txc)
|
||||||
}
|
}
|
||||||
|
|
||||||
txd, err := rlp.EncodeToBytes(rightvrsTxWithL1RollupTxId)
|
txd, err := rlp.EncodeToBytes(rightvrsTxWithL1RollupTxId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("encode error: %v", err)
|
t.Fatalf("encode error: %v", err)
|
||||||
}
|
}
|
||||||
if bytes.Equal(txd, should) {
|
if !bytes.Equal(txd, should) {
|
||||||
t.Errorf("RLP encoding with L1MessageSender should be different than without. Got %x", txd)
|
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 {
|
for start, key := range keys {
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
for i := 0; i < 25; i++ {
|
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)
|
groups[addr] = append(groups[addr], tx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,14 +212,14 @@ func TestTransactionJSON(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("could not generate key: %v", err)
|
t.Fatalf("could not generate key: %v", err)
|
||||||
}
|
}
|
||||||
signer := NewEIP155Signer(common.Big1)
|
signer := NewOVMSigner(common.Big1)
|
||||||
|
|
||||||
transactions := make([]*Transaction, 0, 50)
|
transactions := make([]*Transaction, 0, 50)
|
||||||
for i := uint64(0); i < 25; i++ {
|
for i := uint64(0); i < 25; i++ {
|
||||||
var tx *Transaction
|
var tx *Transaction
|
||||||
switch i % 2 {
|
switch i % 2 {
|
||||||
case 0:
|
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:
|
case 1:
|
||||||
tx = NewContractCreation(i, common.Big0, 1, common.Big2, []byte("abcdef"), nil, nil)
|
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
|
// Tests that OVM metadata has no impact on hash
|
||||||
func TestL1MessageSenderHash(t *testing.T) {
|
func TestOVMMetaDataHash(t *testing.T) {
|
||||||
if rightvrsTx.Hash() != rightvrsTxWithL1Sender.Hash() {
|
if rightvrsTx.Hash() != rightvrsTxWithL1Sender.Hash() {
|
||||||
t.Errorf("L1MessageSender, should not affect the hash, want %x, got %x with L1MessageSender", 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() {
|
if emptyTx.Hash() != emptyTxEmptyL1Sender.Hash() {
|
||||||
t.Errorf("L1MessageSender, should not affect the hash, want %x, got %x with L1MessageSender", 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())
|
signer := types.MakeSigner(params.TestChainConfig, block.Number())
|
||||||
l1Sender := common.Address{seed}
|
l1Sender := common.Address{seed}
|
||||||
l1RollupTxId := hexutil.Uint64(22)
|
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 {
|
if err != nil {
|
||||||
panic(err)
|
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 the block number is multiple of 3, send a bonus transaction to the miner
|
||||||
if parent == genesis && i%3 == 0 {
|
if parent == genesis && i%3 == 0 {
|
||||||
signer := types.MakeSigner(params.TestChainConfig, block.Number())
|
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 {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -218,11 +218,11 @@ func TestPendingTxFilter(t *testing.T) {
|
|||||||
api = NewPublicFilterAPI(backend, false)
|
api = NewPublicFilterAPI(backend, false)
|
||||||
|
|
||||||
transactions = []*types.Transaction{
|
transactions = []*types.Transaction{
|
||||||
types.NewTransaction(0, 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.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.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.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.NewTransaction(4, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil, nil, nil, types.SighashEIP155),
|
||||||
}
|
}
|
||||||
|
|
||||||
hashes []common.Hash
|
hashes []common.Hash
|
||||||
|
@ -127,7 +127,7 @@ func TestFilters(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
gen.AddUncheckedReceipt(receipt)
|
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:
|
case 2:
|
||||||
receipt := types.NewReceipt(nil, false, 0)
|
receipt := types.NewReceipt(nil, false, 0)
|
||||||
receipt.Logs = []*types.Log{
|
receipt.Logs = []*types.Log{
|
||||||
@ -137,7 +137,7 @@ func TestFilters(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
gen.AddUncheckedReceipt(receipt)
|
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:
|
case 998:
|
||||||
receipt := types.NewReceipt(nil, false, 0)
|
receipt := types.NewReceipt(nil, false, 0)
|
||||||
@ -148,7 +148,7 @@ func TestFilters(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
gen.AddUncheckedReceipt(receipt)
|
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:
|
case 999:
|
||||||
receipt := types.NewReceipt(nil, false, 0)
|
receipt := types.NewReceipt(nil, false, 0)
|
||||||
receipt.Logs = []*types.Log{
|
receipt.Logs = []*types.Log{
|
||||||
@ -158,7 +158,7 @@ func TestFilters(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
gen.AddUncheckedReceipt(receipt)
|
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 {
|
for i, block := range chain {
|
||||||
|
@ -290,13 +290,13 @@ func testGetNodeData(t *testing.T, protocol int) {
|
|||||||
switch i {
|
switch i {
|
||||||
case 0:
|
case 0:
|
||||||
// In block 1, the test bank sends account #1 some ether.
|
// 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)
|
block.AddTx(tx)
|
||||||
case 1:
|
case 1:
|
||||||
// In block 2, the test bank sends some more ether to account #1.
|
// In block 2, the test bank sends some more ether to account #1.
|
||||||
// acc1Addr passes it on to account #2.
|
// 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)
|
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), signer, acc1Key)
|
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(tx1)
|
||||||
block.AddTx(tx2)
|
block.AddTx(tx2)
|
||||||
case 2:
|
case 2:
|
||||||
@ -389,13 +389,13 @@ func testGetReceipt(t *testing.T, protocol int) {
|
|||||||
switch i {
|
switch i {
|
||||||
case 0:
|
case 0:
|
||||||
// In block 1, the test bank sends account #1 some ether.
|
// 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)
|
block.AddTx(tx)
|
||||||
case 1:
|
case 1:
|
||||||
// In block 2, the test bank sends some more ether to account #1.
|
// In block 2, the test bank sends some more ether to account #1.
|
||||||
// acc1Addr passes it on to account #2.
|
// 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)
|
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), signer, acc1Key)
|
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(tx1)
|
||||||
block.AddTx(tx2)
|
block.AddTx(tx2)
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -134,7 +134,7 @@ func (p *testTxPool) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subs
|
|||||||
|
|
||||||
// newTestTransaction create a new dummy transaction.
|
// newTestTransaction create a new dummy transaction.
|
||||||
func newTestTransaction(from *ecdsa.PrivateKey, nonce uint64, datasize int) *types.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)
|
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, from)
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ type callTracerTest struct {
|
|||||||
func TestPrestateTracerCreate2(t *testing.T) {
|
func TestPrestateTracerCreate2(t *testing.T) {
|
||||||
t.Skip("OVM breaks this with `cannot read property` error, probably related to state manager.")
|
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)
|
privateKeyECDSA, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -830,7 +830,7 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.Blo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create new call message
|
// 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
|
// Setup context so it may be cancelled the call has completed
|
||||||
// or, in case of unmetered gas, setup a context with a timeout.
|
// 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
|
// newRPCTransaction returns a transaction that will serialize to the RPC
|
||||||
// representation, with the given location metadata set (if available).
|
// representation, with the given location metadata set (if available).
|
||||||
func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) *RPCTransaction {
|
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{}
|
var signer types.Signer = types.FrontierSigner{}
|
||||||
if tx.Protected() {
|
if tx.Protected() {
|
||||||
signer = types.NewEIP155Signer(tx.ChainId())
|
signer = types.NewOVMSigner(tx.ChainId())
|
||||||
}
|
}
|
||||||
from, _ := types.Sender(signer, tx)
|
from, _ := types.Sender(signer, tx)
|
||||||
v, r, s := tx.RawSignatureValues()
|
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) {
|
func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) {
|
||||||
// Try to return an already finalized transaction
|
// Try to return an already finalized transaction
|
||||||
tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash)
|
tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1318,7 +1320,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha
|
|||||||
|
|
||||||
var signer types.Signer = types.FrontierSigner{}
|
var signer types.Signer = types.FrontierSigner{}
|
||||||
if tx.Protected() {
|
if tx.Protected() {
|
||||||
signer = types.NewEIP155Signer(tx.ChainId())
|
signer = types.NewOVMSigner(tx.ChainId())
|
||||||
}
|
}
|
||||||
from, _ := types.Sender(signer, tx)
|
from, _ := types.Sender(signer, tx)
|
||||||
|
|
||||||
@ -1377,8 +1379,9 @@ type SendTxArgs struct {
|
|||||||
// newer name and should be preferred by clients.
|
// newer name and should be preferred by clients.
|
||||||
Data *hexutil.Bytes `json:"data"`
|
Data *hexutil.Bytes `json:"data"`
|
||||||
Input *hexutil.Bytes `json:"input"`
|
Input *hexutil.Bytes `json:"input"`
|
||||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty" rlp:"nil,?"`
|
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty"`
|
||||||
L1MessageSender *common.Address `json:"l1MessageSender,omitempty" rlp:"nil,?"`
|
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.
|
// 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 {
|
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.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 {
|
type RollupTransaction struct {
|
||||||
@ -1471,7 +1474,7 @@ func (r *RollupTransaction) toTransaction(txNonce uint64) *types.Transaction {
|
|||||||
if r.Target == nil {
|
if r.Target == nil {
|
||||||
tx = types.NewContractCreation(txNonce, big.NewInt(0), uint64(*r.GasLimit), big.NewInt(0), c, r.Sender, r.L1RollupTxId)
|
tx = types.NewContractCreation(txNonce, big.NewInt(0), uint64(*r.GasLimit), big.NewInt(0), c, r.Sender, r.L1RollupTxId)
|
||||||
} else {
|
} 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))
|
tx.AddNonceToWrappedTransaction(uint64(*r.Nonce))
|
||||||
return tx
|
return tx
|
||||||
@ -1561,7 +1564,21 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encod
|
|||||||
return SubmitTransaction(ctx, s.b, tx)
|
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.
|
// * Verify the batches are signed by the RollupTransaction sender.
|
||||||
// * Update the Geth timestamp to the provided timestamp
|
// * Update the Geth timestamp to the provided timestamp
|
||||||
// * handle the provided batch of RollupTransactions atomically
|
// * handle the provided batch of RollupTransactions atomically
|
||||||
@ -1680,7 +1697,7 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err
|
|||||||
for _, tx := range pending {
|
for _, tx := range pending {
|
||||||
var signer types.Signer = types.HomesteadSigner{}
|
var signer types.Signer = types.HomesteadSigner{}
|
||||||
if tx.Protected() {
|
if tx.Protected() {
|
||||||
signer = types.NewEIP155Signer(tx.ChainId())
|
signer = types.NewOVMSigner(tx.ChainId())
|
||||||
}
|
}
|
||||||
from, _ := types.Sender(signer, tx)
|
from, _ := types.Sender(signer, tx)
|
||||||
if _, exists := accounts[from]; exists {
|
if _, exists := accounts[from]; exists {
|
||||||
@ -1708,7 +1725,7 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxAr
|
|||||||
for _, p := range pending {
|
for _, p := range pending {
|
||||||
var signer types.Signer = types.HomesteadSigner{}
|
var signer types.Signer = types.HomesteadSigner{}
|
||||||
if p.Protected() {
|
if p.Protected() {
|
||||||
signer = types.NewEIP155Signer(p.ChainId())
|
signer = types.NewOVMSigner(p.ChainId())
|
||||||
}
|
}
|
||||||
wantSigHash := signer.Hash(matchTx)
|
wantSigHash := signer.Hash(matchTx)
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ func (b *benchmarkTxSend) init(h *serverHandler, count int) error {
|
|||||||
for i := range b.txs {
|
for i := range b.txs {
|
||||||
data := make([]byte, txSizeCostLimit)
|
data := make([]byte, txSizeCostLimit)
|
||||||
rand.Read(data)
|
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 {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -556,16 +556,16 @@ func testTransactionStatus(t *testing.T, protocol int) {
|
|||||||
signer := types.HomesteadSigner{}
|
signer := types.HomesteadSigner{}
|
||||||
|
|
||||||
// test error status by sending an underpriced transaction
|
// 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()})
|
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, 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}) // send valid processable tx, should return pending
|
||||||
test(tx1, true, light.TxStatus{Status: core.TxStatusPending}) // adding it again should not return an error
|
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)
|
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), 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
|
// send transactions in the wrong order, tx3 should be queued
|
||||||
test(tx3, true, light.TxStatus{Status: core.TxStatusQueued})
|
test(tx3, true, light.TxStatus{Status: core.TxStatusQueued})
|
||||||
test(tx2, true, light.TxStatus{Status: core.TxStatusPending})
|
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 := statedb.GetOrNewStateObject(bankAddr)
|
||||||
from.SetBalance(math.MaxBig256)
|
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)
|
context := core.NewEVMContext(msg, header, bc, nil)
|
||||||
vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
|
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)
|
header := lc.GetHeaderByHash(bhash)
|
||||||
state := light.NewState(ctx, header, lc.Odr())
|
state := light.NewState(ctx, header, lc.Odr())
|
||||||
state.SetBalance(bankAddr, math.MaxBig256)
|
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)
|
context := core.NewEVMContext(msg, header, lc, nil)
|
||||||
vmenv := vm.NewEVM(context, state, config, vm.Config{})
|
vmenv := vm.NewEVM(context, state, config, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
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))
|
registrarAddr, _, _, _ = contract.DeployCheckpointOracle(bind.NewKeyedTransactor(bankKey), backend, []common.Address{signerAddr}, sectionSize, processConfirms, big.NewInt(1))
|
||||||
// bankUser transfers some ether to user1
|
// bankUser transfers some ether to user1
|
||||||
nonce, _ := backend.PendingNonceAt(ctx, bankAddr)
|
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)
|
backend.SendTransaction(ctx, tx)
|
||||||
case 1:
|
case 1:
|
||||||
bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
|
bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
|
||||||
userNonce1, _ := backend.PendingNonceAt(ctx, userAddr1)
|
userNonce1, _ := backend.PendingNonceAt(ctx, userAddr1)
|
||||||
|
|
||||||
// bankUser transfers more ether to user1
|
// 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)
|
backend.SendTransaction(ctx, tx1)
|
||||||
|
|
||||||
// user1 relays ether to user2
|
// 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)
|
backend.SendTransaction(ctx, tx2)
|
||||||
|
|
||||||
// user1 deploys a test contract
|
// user1 deploys a test contract
|
||||||
@ -137,18 +137,18 @@ func prepare(n int, backend *backends.SimulatedBackend) {
|
|||||||
case 2:
|
case 2:
|
||||||
// bankUser transfer some ether to signer
|
// bankUser transfer some ether to signer
|
||||||
bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
|
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)
|
backend.SendTransaction(ctx, tx1)
|
||||||
|
|
||||||
// invoke test contract
|
// invoke test contract
|
||||||
data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001")
|
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)
|
backend.SendTransaction(ctx, tx2)
|
||||||
case 3:
|
case 3:
|
||||||
// invoke test contract
|
// invoke test contract
|
||||||
bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
|
bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
|
||||||
data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002")
|
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.SendTransaction(ctx, tx)
|
||||||
}
|
}
|
||||||
backend.Commit()
|
backend.Commit()
|
||||||
|
@ -194,7 +194,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
|||||||
|
|
||||||
// Perform read-only call.
|
// Perform read-only call.
|
||||||
st.SetBalance(testBankAddress, math.MaxBig256)
|
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)
|
context := core.NewEVMContext(msg, header, chain, nil)
|
||||||
vmenv := vm.NewEVM(context, st, config, vm.Config{})
|
vmenv := vm.NewEVM(context, st, config, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
@ -212,15 +212,15 @@ func testChainGen(i int, block *core.BlockGen) {
|
|||||||
switch i {
|
switch i {
|
||||||
case 0:
|
case 0:
|
||||||
// In block 1, the test bank sends account #1 some ether.
|
// 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)
|
block.AddTx(tx)
|
||||||
case 1:
|
case 1:
|
||||||
// In block 2, the test bank sends some more ether to account #1.
|
// In block 2, the test bank sends some more ether to account #1.
|
||||||
// acc1Addr passes it on to account #2.
|
// acc1Addr passes it on to account #2.
|
||||||
// acc1Addr creates a test contract.
|
// 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)
|
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++
|
nonce++
|
||||||
tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 1000000, big.NewInt(0), testContractCode, nil, nil), signer, acc1Key)
|
tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 1000000, big.NewInt(0), testContractCode, nil, nil), signer, acc1Key)
|
||||||
testContractAddr = crypto.CreateAddress(acc1Addr, nonce)
|
testContractAddr = crypto.CreateAddress(acc1Addr, nonce)
|
||||||
@ -232,7 +232,7 @@ func testChainGen(i int, block *core.BlockGen) {
|
|||||||
block.SetCoinbase(acc2Addr)
|
block.SetCoinbase(acc2Addr)
|
||||||
block.SetExtra([]byte("yeehaw"))
|
block.SetExtra([]byte("yeehaw"))
|
||||||
data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001")
|
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)
|
block.AddTx(tx)
|
||||||
case 3:
|
case 3:
|
||||||
// Block 4 includes blocks 2 and 3 as uncle headers (with modified extra data).
|
// 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")
|
b3.Extra = []byte("foo")
|
||||||
block.AddUncle(b3)
|
block.AddUncle(b3)
|
||||||
data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002")
|
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)
|
block.AddTx(tx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ func txPoolTestChainGen(i int, block *core.BlockGen) {
|
|||||||
|
|
||||||
func TestTxPool(t *testing.T) {
|
func TestTxPool(t *testing.T) {
|
||||||
for i := range testTx {
|
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 (
|
var (
|
||||||
|
@ -82,9 +82,9 @@ func init() {
|
|||||||
Period: 10,
|
Period: 10,
|
||||||
Epoch: 30000,
|
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)
|
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)
|
newTxs = append(newTxs, tx2)
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
}
|
}
|
||||||
@ -171,7 +171,7 @@ func (b *testWorkerBackend) newRandomTx(creation bool) *types.Transaction {
|
|||||||
if creation {
|
if creation {
|
||||||
tx, _ = types.SignTx(types.NewContractCreation(b.txPool.Nonce(testBankAddress), big.NewInt(0), testGas, nil, common.FromHex(testCode), nil, nil), types.HomesteadSigner{}, testBankKey)
|
tx, _ = types.SignTx(types.NewContractCreation(b.txPool.Nonce(testBankAddress), big.NewInt(0), testGas, nil, common.FromHex(testCode), nil, nil), types.HomesteadSigner{}, testBankKey)
|
||||||
} else {
|
} 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
|
return tx
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ func NewTransaction(nonce int64, to *Address, amount *BigInt, gasLimit int64, ga
|
|||||||
if to == nil {
|
if to == nil {
|
||||||
return &Transaction{types.NewContractCreation(uint64(nonce), amount.bigint, uint64(gasLimit), gasPrice.bigint, common.CopyBytes(data), nil, 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.
|
// 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))}
|
header := &types.Header{Number: big.NewInt(int64(i + startIndex))}
|
||||||
txs := make(types.Transactions, 0)
|
txs := make(types.Transactions, 0)
|
||||||
if withTx {
|
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)
|
txs = append(txs, tx)
|
||||||
}
|
}
|
||||||
block := types.NewBlock(header, txs, make([]*types.Header, 0), make([]*types.Receipt, 0))
|
block := types.NewBlock(header, txs, make([]*types.Header, 0), make([]*types.Receipt, 0))
|
||||||
|
@ -76,8 +76,9 @@ type SendTxArgs struct {
|
|||||||
// We accept "data" and "input" for backwards-compatibility reasons.
|
// We accept "data" and "input" for backwards-compatibility reasons.
|
||||||
Data *hexutil.Bytes `json:"data"`
|
Data *hexutil.Bytes `json:"data"`
|
||||||
Input *hexutil.Bytes `json:"input,omitempty"`
|
Input *hexutil.Bytes `json:"input,omitempty"`
|
||||||
L1MessageSender *common.MixedcaseAddress `json:"l1MessageSender,omitempty" rlp:"nil,?"`
|
L1MessageSender *common.MixedcaseAddress `json:"l1MessageSender,omitempty"`
|
||||||
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty" rlp:"nil,?"`
|
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId,omitempty"`
|
||||||
|
SignatureHashType types.SignatureHashType `json:"signatureHashType,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (args SendTxArgs) String() string {
|
func (args SendTxArgs) String() string {
|
||||||
@ -105,5 +106,6 @@ func (args *SendTxArgs) toTransaction() *types.Transaction {
|
|||||||
l1RollupTxId = new(hexutil.Uint64)
|
l1RollupTxId = new(hexutil.Uint64)
|
||||||
*l1RollupTxId = *args.L1RollupTxId
|
*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)
|
gas := uint64(21000)
|
||||||
gasPrice := big.NewInt(2000000)
|
gasPrice := big.NewInt(2000000)
|
||||||
data := make([]byte, 0)
|
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) {
|
func TestLimitWindow(t *testing.T) {
|
||||||
|
@ -241,6 +241,7 @@ func applyMessageToState(currentState *state.StateDB, from common.Address, to co
|
|||||||
false,
|
false,
|
||||||
&ZERO_ADDRESS,
|
&ZERO_ADDRESS,
|
||||||
nil,
|
nil,
|
||||||
|
0,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// Otherwise we actually use the `to` field!
|
// Otherwise we actually use the `to` field!
|
||||||
@ -255,6 +256,7 @@ func applyMessageToState(currentState *state.StateDB, from common.Address, to co
|
|||||||
false,
|
false,
|
||||||
&ZERO_ADDRESS,
|
&ZERO_ADDRESS,
|
||||||
nil,
|
nil,
|
||||||
|
0,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ func (tx *stTransaction) toMessage(ps stPostState) (core.Message, error) {
|
|||||||
return nil, fmt.Errorf("invalid tx data %q", dataHex)
|
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
|
return msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user