mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-20 09:21:11 +00:00
[beta] Stricter uint256 RLP decoding. Update consensus tests to 10.1 (#3089)
* Clean up test runners. Don't run legacy tests * Cherry pick https://github.com/ethereum/go-ethereum/pull/22927 * Tests update 10.1: Transaction Tests * Port decodeBigInt changes to decodeUint256 * Introduce (*Stream) Uint256Bytes * Temporarily disable stTransactionTest/HighGasPrice * linter * ttWrongRLP transaction tests pass now * Fix stTransactionTest/HighGasPrice Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
parent
3f34dee475
commit
759fb00593
@ -203,12 +203,21 @@ func (st *StateTransition) to() common.Address {
|
|||||||
func (st *StateTransition) buyGas(gasBailout bool) error {
|
func (st *StateTransition) buyGas(gasBailout bool) error {
|
||||||
mgval := st.sharedBuyGas
|
mgval := st.sharedBuyGas
|
||||||
mgval.SetUint64(st.msg.Gas())
|
mgval.SetUint64(st.msg.Gas())
|
||||||
mgval = mgval.Mul(mgval, st.gasPrice)
|
mgval, overflow := mgval.MulOverflow(mgval, st.gasPrice)
|
||||||
|
if overflow {
|
||||||
|
return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex())
|
||||||
|
}
|
||||||
balanceCheck := mgval
|
balanceCheck := mgval
|
||||||
if st.gasFeeCap != nil {
|
if st.gasFeeCap != nil {
|
||||||
balanceCheck = st.sharedBuyGasBalance.SetUint64(st.msg.Gas())
|
balanceCheck = st.sharedBuyGasBalance.SetUint64(st.msg.Gas())
|
||||||
balanceCheck = balanceCheck.Mul(balanceCheck, st.gasFeeCap)
|
balanceCheck, overflow = balanceCheck.MulOverflow(balanceCheck, st.gasFeeCap)
|
||||||
balanceCheck.Add(balanceCheck, st.value)
|
if overflow {
|
||||||
|
return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex())
|
||||||
|
}
|
||||||
|
balanceCheck, overflow = balanceCheck.AddOverflow(balanceCheck, st.value)
|
||||||
|
if overflow {
|
||||||
|
return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 {
|
if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 {
|
||||||
if !gasBailout {
|
if !gasBailout {
|
||||||
|
@ -465,22 +465,16 @@ func (tx *AccessListTx) DecodeRLP(s *rlp.Stream) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var b []byte
|
var b []byte
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read ChainID: %w", err)
|
return fmt.Errorf("read ChainID: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for ChainID: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.ChainID = new(uint256.Int).SetBytes(b)
|
tx.ChainID = new(uint256.Int).SetBytes(b)
|
||||||
if tx.Nonce, err = s.Uint(); err != nil {
|
if tx.Nonce, err = s.Uint(); err != nil {
|
||||||
return fmt.Errorf("read Nonce: %w", err)
|
return fmt.Errorf("read Nonce: %w", err)
|
||||||
}
|
}
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read GasPrice: %w", err)
|
return fmt.Errorf("read GasPrice: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for GasPrice: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.GasPrice = new(uint256.Int).SetBytes(b)
|
tx.GasPrice = new(uint256.Int).SetBytes(b)
|
||||||
if tx.Gas, err = s.Uint(); err != nil {
|
if tx.Gas, err = s.Uint(); err != nil {
|
||||||
return fmt.Errorf("read Gas: %w", err)
|
return fmt.Errorf("read Gas: %w", err)
|
||||||
@ -495,12 +489,9 @@ func (tx *AccessListTx) DecodeRLP(s *rlp.Stream) error {
|
|||||||
tx.To = &common.Address{}
|
tx.To = &common.Address{}
|
||||||
copy((*tx.To)[:], b)
|
copy((*tx.To)[:], b)
|
||||||
}
|
}
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read Value: %w", err)
|
return fmt.Errorf("read Value: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for Value: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.Value = new(uint256.Int).SetBytes(b)
|
tx.Value = new(uint256.Int).SetBytes(b)
|
||||||
if tx.Data, err = s.Bytes(); err != nil {
|
if tx.Data, err = s.Bytes(); err != nil {
|
||||||
return fmt.Errorf("read Data: %w", err)
|
return fmt.Errorf("read Data: %w", err)
|
||||||
@ -511,26 +502,17 @@ func (tx *AccessListTx) DecodeRLP(s *rlp.Stream) error {
|
|||||||
return fmt.Errorf("read AccessList: %w", err)
|
return fmt.Errorf("read AccessList: %w", err)
|
||||||
}
|
}
|
||||||
// decode V
|
// decode V
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read V: %w", err)
|
return fmt.Errorf("read V: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for V: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.V.SetBytes(b)
|
tx.V.SetBytes(b)
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read R: %w", err)
|
return fmt.Errorf("read R: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for R: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.R.SetBytes(b)
|
tx.R.SetBytes(b)
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read S: %w", err)
|
return fmt.Errorf("read S: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for S: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.S.SetBytes(b)
|
tx.S.SetBytes(b)
|
||||||
if err := s.ListEnd(); err != nil {
|
if err := s.ListEnd(); err != nil {
|
||||||
return fmt.Errorf("close AccessListTx: %w", err)
|
return fmt.Errorf("close AccessListTx: %w", err)
|
||||||
|
@ -486,19 +486,13 @@ func (h *Header) DecodeRLP(s *rlp.Stream) error {
|
|||||||
return fmt.Errorf("wrong size for Bloom: %d", len(b))
|
return fmt.Errorf("wrong size for Bloom: %d", len(b))
|
||||||
}
|
}
|
||||||
copy(h.Bloom[:], b)
|
copy(h.Bloom[:], b)
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read Difficulty: %w", err)
|
return fmt.Errorf("read Difficulty: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for Difficulty: %d", len(b))
|
|
||||||
}
|
|
||||||
h.Difficulty = new(big.Int).SetBytes(b)
|
h.Difficulty = new(big.Int).SetBytes(b)
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read Number: %w", err)
|
return fmt.Errorf("read Number: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for Number: %d", len(b))
|
|
||||||
}
|
|
||||||
h.Number = new(big.Int).SetBytes(b)
|
h.Number = new(big.Int).SetBytes(b)
|
||||||
if h.GasLimit, err = s.Uint(); err != nil {
|
if h.GasLimit, err = s.Uint(); err != nil {
|
||||||
return fmt.Errorf("read GasLimit: %w", err)
|
return fmt.Errorf("read GasLimit: %w", err)
|
||||||
@ -536,7 +530,7 @@ func (h *Header) DecodeRLP(s *rlp.Stream) error {
|
|||||||
return fmt.Errorf("wrong size for Nonce: %d", len(b))
|
return fmt.Errorf("wrong size for Nonce: %d", len(b))
|
||||||
}
|
}
|
||||||
copy(h.Nonce[:], b)
|
copy(h.Nonce[:], b)
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
if errors.Is(err, rlp.EOL) {
|
if errors.Is(err, rlp.EOL) {
|
||||||
h.BaseFee = nil
|
h.BaseFee = nil
|
||||||
h.Eip1559 = false
|
h.Eip1559 = false
|
||||||
@ -547,9 +541,6 @@ func (h *Header) DecodeRLP(s *rlp.Stream) error {
|
|||||||
}
|
}
|
||||||
return fmt.Errorf("read BaseFee: %w", err)
|
return fmt.Errorf("read BaseFee: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for BaseFee: %d", len(b))
|
|
||||||
}
|
|
||||||
h.Eip1559 = true
|
h.Eip1559 = true
|
||||||
h.BaseFee = new(big.Int).SetBytes(b)
|
h.BaseFee = new(big.Int).SetBytes(b)
|
||||||
}
|
}
|
||||||
|
@ -378,29 +378,20 @@ func (tx *DynamicFeeTransaction) DecodeRLP(s *rlp.Stream) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var b []byte
|
var b []byte
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for ChainID: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.ChainID = new(uint256.Int).SetBytes(b)
|
tx.ChainID = new(uint256.Int).SetBytes(b)
|
||||||
if tx.Nonce, err = s.Uint(); err != nil {
|
if tx.Nonce, err = s.Uint(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for MaxPriorityFeePerGas: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.Tip = new(uint256.Int).SetBytes(b)
|
tx.Tip = new(uint256.Int).SetBytes(b)
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for MaxFeePerGas: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.FeeCap = new(uint256.Int).SetBytes(b)
|
tx.FeeCap = new(uint256.Int).SetBytes(b)
|
||||||
if tx.Gas, err = s.Uint(); err != nil {
|
if tx.Gas, err = s.Uint(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -415,12 +406,9 @@ func (tx *DynamicFeeTransaction) DecodeRLP(s *rlp.Stream) error {
|
|||||||
tx.To = &common.Address{}
|
tx.To = &common.Address{}
|
||||||
copy((*tx.To)[:], b)
|
copy((*tx.To)[:], b)
|
||||||
}
|
}
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for Value: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.Value = new(uint256.Int).SetBytes(b)
|
tx.Value = new(uint256.Int).SetBytes(b)
|
||||||
if tx.Data, err = s.Bytes(); err != nil {
|
if tx.Data, err = s.Bytes(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -431,26 +419,17 @@ func (tx *DynamicFeeTransaction) DecodeRLP(s *rlp.Stream) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// decode V
|
// decode V
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for V: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.V.SetBytes(b)
|
tx.V.SetBytes(b)
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for R: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.R.SetBytes(b)
|
tx.R.SetBytes(b)
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for S: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.S.SetBytes(b)
|
tx.S.SetBytes(b)
|
||||||
return s.ListEnd()
|
return s.ListEnd()
|
||||||
|
|
||||||
|
@ -369,12 +369,9 @@ func (tx *LegacyTx) DecodeRLP(s *rlp.Stream, encodingSize uint64) error {
|
|||||||
return fmt.Errorf("read Nonce: %w", err)
|
return fmt.Errorf("read Nonce: %w", err)
|
||||||
}
|
}
|
||||||
var b []byte
|
var b []byte
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read GasPrice: %w", err)
|
return fmt.Errorf("read GasPrice: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for GasPrice: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.GasPrice = new(uint256.Int).SetBytes(b)
|
tx.GasPrice = new(uint256.Int).SetBytes(b)
|
||||||
if tx.Gas, err = s.Uint(); err != nil {
|
if tx.Gas, err = s.Uint(); err != nil {
|
||||||
return fmt.Errorf("read Gas: %w", err)
|
return fmt.Errorf("read Gas: %w", err)
|
||||||
@ -389,36 +386,24 @@ func (tx *LegacyTx) DecodeRLP(s *rlp.Stream, encodingSize uint64) error {
|
|||||||
tx.To = &common.Address{}
|
tx.To = &common.Address{}
|
||||||
copy((*tx.To)[:], b)
|
copy((*tx.To)[:], b)
|
||||||
}
|
}
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read Value: %w", err)
|
return fmt.Errorf("read Value: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for Value: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.Value = new(uint256.Int).SetBytes(b)
|
tx.Value = new(uint256.Int).SetBytes(b)
|
||||||
if tx.Data, err = s.Bytes(); err != nil {
|
if tx.Data, err = s.Bytes(); err != nil {
|
||||||
return fmt.Errorf("read Data: %w", err)
|
return fmt.Errorf("read Data: %w", err)
|
||||||
}
|
}
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read V: %w", err)
|
return fmt.Errorf("read V: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for V: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.V.SetBytes(b)
|
tx.V.SetBytes(b)
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read R: %w", err)
|
return fmt.Errorf("read R: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for R: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.R.SetBytes(b)
|
tx.R.SetBytes(b)
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read S: %w", err)
|
return fmt.Errorf("read S: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for S: %d", len(b))
|
|
||||||
}
|
|
||||||
tx.S.SetBytes(b)
|
tx.S.SetBytes(b)
|
||||||
if err = s.ListEnd(); err != nil {
|
if err = s.ListEnd(); err != nil {
|
||||||
return fmt.Errorf("close tx struct: %w", err)
|
return fmt.Errorf("close tx struct: %w", err)
|
||||||
|
@ -373,12 +373,9 @@ func (nbp *NewBlockPacket) DecodeRLP(s *rlp.Stream) error {
|
|||||||
}
|
}
|
||||||
// decode TD
|
// decode TD
|
||||||
var b []byte
|
var b []byte
|
||||||
if b, err = s.Bytes(); err != nil {
|
if b, err = s.Uint256Bytes(); err != nil {
|
||||||
return fmt.Errorf("read TD: %w", err)
|
return fmt.Errorf("read TD: %w", err)
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return fmt.Errorf("wrong size for TD: %d", len(b))
|
|
||||||
}
|
|
||||||
nbp.TD = new(big.Int).SetBytes(b)
|
nbp.TD = new(big.Int).SetBytes(b)
|
||||||
if err = s.ListEnd(); err != nil {
|
if err = s.ListEnd(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -242,19 +242,17 @@ func decodeBigIntNoPtr(s *Stream, val reflect.Value) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func decodeBigInt(s *Stream, val reflect.Value) error {
|
func decodeBigInt(s *Stream, val reflect.Value) error {
|
||||||
b, err := s.Bytes()
|
b, err := s.bigIntBytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrapStreamError(err, val.Type())
|
return wrapStreamError(err, val.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the integer bytes.
|
||||||
i := val.Interface().(*big.Int)
|
i := val.Interface().(*big.Int)
|
||||||
if i == nil {
|
if i == nil {
|
||||||
i = new(big.Int)
|
i = new(big.Int)
|
||||||
val.Set(reflect.ValueOf(i))
|
val.Set(reflect.ValueOf(i))
|
||||||
}
|
}
|
||||||
// Reject leading zero bytes
|
|
||||||
if len(b) > 0 && b[0] == 0 {
|
|
||||||
return wrapStreamError(ErrCanonInt, val.Type())
|
|
||||||
}
|
|
||||||
i.SetBytes(b)
|
i.SetBytes(b)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -264,22 +262,17 @@ func decodeUint256NoPtr(s *Stream, val reflect.Value) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func decodeUint256(s *Stream, val reflect.Value) error {
|
func decodeUint256(s *Stream, val reflect.Value) error {
|
||||||
b, err := s.Bytes()
|
b, err := s.Uint256Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrapStreamError(err, val.Type())
|
return wrapStreamError(err, val.Type())
|
||||||
}
|
}
|
||||||
if len(b) > 32 {
|
|
||||||
return wrapStreamError(errUintOverflow, val.Type())
|
// Set the integer bytes.
|
||||||
}
|
|
||||||
i := val.Interface().(*uint256.Int)
|
i := val.Interface().(*uint256.Int)
|
||||||
if i == nil {
|
if i == nil {
|
||||||
i = new(uint256.Int)
|
i = new(uint256.Int)
|
||||||
val.Set(reflect.ValueOf(i))
|
val.Set(reflect.ValueOf(i))
|
||||||
}
|
}
|
||||||
// Reject leading zero bytes
|
|
||||||
if len(b) > 0 && b[0] == 0 {
|
|
||||||
return wrapStreamError(ErrCanonInt, val.Type())
|
|
||||||
}
|
|
||||||
i.SetBytes(b)
|
i.SetBytes(b)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -599,7 +592,7 @@ type Stream struct {
|
|||||||
limited bool
|
limited bool
|
||||||
|
|
||||||
// auxiliary buffer for integer decoding
|
// auxiliary buffer for integer decoding
|
||||||
uintbuf []byte
|
uintbuf [32]byte
|
||||||
|
|
||||||
kind Kind // kind of value ahead
|
kind Kind // kind of value ahead
|
||||||
size uint64 // size of value ahead
|
size uint64 // size of value ahead
|
||||||
@ -734,6 +727,59 @@ func (s *Stream) uint(maxbits int) (uint64, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Stream) Uint256Bytes() ([]byte, error) {
|
||||||
|
b, err := s.bigIntBytes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(b) > 32 {
|
||||||
|
return nil, errUintOverflow
|
||||||
|
}
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stream) bigIntBytes() ([]byte, error) {
|
||||||
|
var buffer []byte
|
||||||
|
kind, size, err := s.Kind()
|
||||||
|
switch {
|
||||||
|
case err != nil:
|
||||||
|
return nil, err
|
||||||
|
case kind == List:
|
||||||
|
return nil, ErrExpectedString
|
||||||
|
case kind == Byte:
|
||||||
|
buffer = s.uintbuf[:1]
|
||||||
|
buffer[0] = s.byteval
|
||||||
|
s.kind = -1 // re-arm Kind
|
||||||
|
case size == 0:
|
||||||
|
// Avoid zero-length read.
|
||||||
|
s.kind = -1
|
||||||
|
case size <= uint64(len(s.uintbuf)):
|
||||||
|
// For integers smaller than s.uintbuf, allocating a buffer
|
||||||
|
// can be avoided.
|
||||||
|
buffer = s.uintbuf[:size]
|
||||||
|
if err := s.readFull(buffer); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Reject inputs where single byte encoding should have been used.
|
||||||
|
if size == 1 && buffer[0] < 128 {
|
||||||
|
return nil, ErrCanonSize
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// For large integers, a temporary buffer is needed.
|
||||||
|
buffer = make([]byte, size)
|
||||||
|
if err := s.readFull(buffer); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reject leading zero bytes.
|
||||||
|
if len(buffer) > 0 && buffer[0] == 0 {
|
||||||
|
return nil, ErrCanonInt
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Bool reads an RLP string of up to 1 byte and returns its contents
|
// Bool reads an RLP string of up to 1 byte and returns its contents
|
||||||
// as a boolean. If the input does not contain an RLP string, the
|
// as a boolean. If the input does not contain an RLP string, the
|
||||||
// returned error will be ErrExpectedString.
|
// returned error will be ErrExpectedString.
|
||||||
@ -856,9 +902,7 @@ func (s *Stream) Reset(r io.Reader, inputLimit uint64) {
|
|||||||
s.size = 0
|
s.size = 0
|
||||||
s.kind = -1
|
s.kind = -1
|
||||||
s.kinderr = nil
|
s.kinderr = nil
|
||||||
if s.uintbuf == nil {
|
s.uintbuf = [32]byte{}
|
||||||
s.uintbuf = make([]byte, 8)
|
|
||||||
}
|
|
||||||
s.byteval = 0
|
s.byteval = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -977,20 +1021,20 @@ func (s *Stream) readUint(size byte) (uint64, error) {
|
|||||||
b, err := s.readByte()
|
b, err := s.readByte()
|
||||||
return uint64(b), err
|
return uint64(b), err
|
||||||
default:
|
default:
|
||||||
start := int(8 - size)
|
buffer := s.uintbuf[:8]
|
||||||
for i := 0; i < start; i++ {
|
for i := range buffer {
|
||||||
s.uintbuf[i] = 0
|
buffer[i] = 0
|
||||||
}
|
}
|
||||||
if err := s.readFull(s.uintbuf[start:]); err != nil {
|
start := int(8 - size)
|
||||||
|
if err := s.readFull(buffer[start:]); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if s.uintbuf[start] == 0 {
|
if buffer[start] == 0 {
|
||||||
// Note: readUint is also used to decode integer
|
// Note: readUint is also used to decode integer values.
|
||||||
// values. The error needs to be adjusted to become
|
// The error needs to be adjusted to become ErrCanonInt in this case.
|
||||||
// ErrCanonInt in this case.
|
|
||||||
return 0, ErrCanonSize
|
return 0, ErrCanonSize
|
||||||
}
|
}
|
||||||
return binary.BigEndian.Uint64(s.uintbuf), nil
|
return binary.BigEndian.Uint64(buffer), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,6 +327,11 @@ type recstruct struct {
|
|||||||
Child *recstruct `rlp:"nil"`
|
Child *recstruct `rlp:"nil"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type bigIntStruct struct {
|
||||||
|
I *big.Int
|
||||||
|
B string
|
||||||
|
}
|
||||||
|
|
||||||
type invalidNilTag struct {
|
type invalidNilTag struct {
|
||||||
X []byte `rlp:"nil"`
|
X []byte `rlp:"nil"`
|
||||||
}
|
}
|
||||||
@ -375,6 +380,7 @@ var (
|
|||||||
uint256.NewInt(0xFFFF),
|
uint256.NewInt(0xFFFF),
|
||||||
)
|
)
|
||||||
realBigInt = big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000"))
|
realBigInt = big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000"))
|
||||||
|
veryVeryBigInt = new(big.Int).Exp(veryBigInt.ToBig(), big.NewInt(8), nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
type hasIgnoredField struct {
|
type hasIgnoredField struct {
|
||||||
@ -451,13 +457,16 @@ var decodeTests = []decodeTest{
|
|||||||
{input: "C0", ptr: new(string), error: "rlp: expected input string or byte for string"},
|
{input: "C0", ptr: new(string), error: "rlp: expected input string or byte for string"},
|
||||||
|
|
||||||
// big ints
|
// big ints
|
||||||
|
{input: "80", ptr: new(*big.Int), value: big.NewInt(0)},
|
||||||
{input: "01", ptr: new(*big.Int), value: big.NewInt(1)},
|
{input: "01", ptr: new(*big.Int), value: big.NewInt(1)},
|
||||||
{input: "89FFFFFFFFFFFFFFFFFF", ptr: new(*big.Int), value: veryBigInt.ToBig()},
|
{input: "89FFFFFFFFFFFFFFFFFF", ptr: new(*big.Int), value: veryBigInt.ToBig()},
|
||||||
{input: "A1010000000000000000000000000000000000000000000000000000000000000000", ptr: new(*big.Int), value: realBigInt},
|
{input: "A1010000000000000000000000000000000000000000000000000000000000000000", ptr: new(*big.Int), value: realBigInt},
|
||||||
|
{input: "B848FFFFFFFFFFFFFFFFF800000000000000001BFFFFFFFFFFFFFFFFC8000000000000000045FFFFFFFFFFFFFFFFC800000000000000001BFFFFFFFFFFFFFFFFF8000000000000000001", ptr: new(*big.Int), value: veryVeryBigInt},
|
||||||
{input: "10", ptr: new(big.Int), value: *big.NewInt(16)}, // non-pointer also works
|
{input: "10", ptr: new(big.Int), value: *big.NewInt(16)}, // non-pointer also works
|
||||||
{input: "C0", ptr: new(*big.Int), error: "rlp: expected input string or byte for *big.Int"},
|
{input: "C0", ptr: new(*big.Int), error: "rlp: expected input string or byte for *big.Int"},
|
||||||
{input: "820001", ptr: new(big.Int), error: "rlp: non-canonical integer (leading zero bytes) for *big.Int"},
|
{input: "00", ptr: new(*big.Int), error: "rlp: non-canonical integer (leading zero bytes) for *big.Int"},
|
||||||
{input: "8105", ptr: new(big.Int), error: "rlp: non-canonical size information for *big.Int"},
|
{input: "820001", ptr: new(*big.Int), error: "rlp: non-canonical integer (leading zero bytes) for *big.Int"},
|
||||||
|
{input: "8105", ptr: new(*big.Int), error: "rlp: non-canonical size information for *big.Int"},
|
||||||
|
|
||||||
// uint256
|
// uint256
|
||||||
{input: "01", ptr: new(*uint256.Int), value: uint256.NewInt(1)},
|
{input: "01", ptr: new(*uint256.Int), value: uint256.NewInt(1)},
|
||||||
@ -479,6 +488,13 @@ var decodeTests = []decodeTest{
|
|||||||
ptr: new(recstruct),
|
ptr: new(recstruct),
|
||||||
value: recstruct{1, &recstruct{2, &recstruct{3, nil}}},
|
value: recstruct{1, &recstruct{2, &recstruct{3, nil}}},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// This checks that empty big.Int works correctly in struct context. It's easy to
|
||||||
|
// miss the update of s.kind for this case, so it needs its own test.
|
||||||
|
input: "C58083343434",
|
||||||
|
ptr: new(bigIntStruct),
|
||||||
|
value: bigIntStruct{new(big.Int), "444"},
|
||||||
|
},
|
||||||
|
|
||||||
// struct errors
|
// struct errors
|
||||||
{
|
{
|
||||||
|
@ -134,6 +134,14 @@ var encTests = []encTest{
|
|||||||
val: big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000")),
|
val: big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000")),
|
||||||
output: "A1010000000000000000000000000000000000000000000000000000000000000000",
|
output: "A1010000000000000000000000000000000000000000000000000000000000000000",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
val: veryBigInt,
|
||||||
|
output: "89FFFFFFFFFFFFFFFFFF",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
val: veryVeryBigInt,
|
||||||
|
output: "B848FFFFFFFFFFFFFFFFF800000000000000001BFFFFFFFFFFFFFFFFC8000000000000000045FFFFFFFFFFFFFFFFC800000000000000001BFFFFFFFFFFFFFFFFF8000000000000000001",
|
||||||
|
},
|
||||||
|
|
||||||
// non-pointer big.Int
|
// non-pointer big.Int
|
||||||
{val: *big.NewInt(0), output: "80"},
|
{val: *big.NewInt(0), output: "80"},
|
||||||
|
@ -32,33 +32,8 @@ func TestBlockchain(t *testing.T) {
|
|||||||
|
|
||||||
bt := new(testMatcher)
|
bt := new(testMatcher)
|
||||||
// General state tests are 'exported' as blockchain tests, but we can run them natively.
|
// General state tests are 'exported' as blockchain tests, but we can run them natively.
|
||||||
// For speedier CI-runs, the line below can be uncommented, so those are skipped.
|
// For speedier CI-runs those are skipped.
|
||||||
// For now, in hardfork-times (Berlin), we run the tests both as StateTests and
|
bt.skipLoad(`^GeneralStateTests/`)
|
||||||
// as blockchain tests, since the latter also covers things like receipt root
|
|
||||||
//bt.skipLoad(`^GeneralStateTests/`)
|
|
||||||
|
|
||||||
// Skip random failures due to selfish mining test
|
|
||||||
bt.skipLoad(`.*bcForgedTest/bcForkUncle\.json`)
|
|
||||||
|
|
||||||
// Slow tests
|
|
||||||
bt.slow(`.*bcExploitTest/DelegateCallSpam.json`)
|
|
||||||
bt.slow(`.*bcExploitTest/ShanghaiLove.json`)
|
|
||||||
bt.slow(`.*bcExploitTest/SuicideIssue.json`)
|
|
||||||
bt.slow(`.*/bcForkStressTest/`)
|
|
||||||
bt.slow(`.*/bcGasPricerTest/RPC_API_Test.json`)
|
|
||||||
bt.slow(`.*/bcWalletTest/`)
|
|
||||||
|
|
||||||
// Very slow test
|
|
||||||
bt.skipLoad(`.*/stTimeConsuming/.*`)
|
|
||||||
|
|
||||||
// test takes a lot for time and goes easily OOM because of sha3 calculation on a huge range,
|
|
||||||
// using 4.6 TGas
|
|
||||||
bt.skipLoad(`.*randomStatetest94.json.*`)
|
|
||||||
|
|
||||||
bt.fails(`(?m)^TestBlockchain/InvalidBlocks/bcInvalidHeaderTest/wrongReceiptTrie.json/wrongReceiptTrie_EIP150`, "No receipt validation before Byzantium")
|
|
||||||
bt.fails(`(?m)^TestBlockchain/InvalidBlocks/bcInvalidHeaderTest/wrongReceiptTrie.json/wrongReceiptTrie_EIP158`, "No receipt validation before Byzantium")
|
|
||||||
bt.fails(`(?m)^TestBlockchain/InvalidBlocks/bcInvalidHeaderTest/wrongReceiptTrie.json/wrongReceiptTrie_Frontier`, "No receipt validation before Byzantium")
|
|
||||||
bt.fails(`(?m)^TestBlockchain/InvalidBlocks/bcInvalidHeaderTest/wrongReceiptTrie.json/wrongReceiptTrie_Homestead`, "No receipt validation before Byzantium")
|
|
||||||
|
|
||||||
bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) {
|
bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) {
|
||||||
// import pre accounts & construct test genesis block & state root
|
// import pre accounts & construct test genesis block & state root
|
||||||
@ -66,8 +41,4 @@ func TestBlockchain(t *testing.T) {
|
|||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// There is also a LegacyTests folder, containing blockchain tests generated
|
|
||||||
// prior to Istanbul. However, they are all derived from GeneralStateTests,
|
|
||||||
// which run natively, so there's no reason to run them here.
|
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,6 @@ var (
|
|||||||
baseDir = filepath.Join(".", "testdata")
|
baseDir = filepath.Join(".", "testdata")
|
||||||
blockTestDir = filepath.Join(baseDir, "BlockchainTests")
|
blockTestDir = filepath.Join(baseDir, "BlockchainTests")
|
||||||
stateTestDir = filepath.Join(baseDir, "GeneralStateTests")
|
stateTestDir = filepath.Join(baseDir, "GeneralStateTests")
|
||||||
legacyStateTestDir = filepath.Join(baseDir, "LegacyTests", "Constantinople", "GeneralStateTests")
|
|
||||||
vmTestDir = filepath.Join(baseDir, "LegacyTests", "Constantinople", "VMTests")
|
|
||||||
transactionTestDir = filepath.Join(baseDir, "TransactionTests")
|
transactionTestDir = filepath.Join(baseDir, "TransactionTests")
|
||||||
rlpTestDir = filepath.Join(baseDir, "RLPTests")
|
rlpTestDir = filepath.Join(baseDir, "RLPTests")
|
||||||
difficultyTestDir = filepath.Join(baseDir, "BasicTests")
|
difficultyTestDir = filepath.Join(baseDir, "BasicTests")
|
||||||
|
@ -39,21 +39,10 @@ func TestState(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
st := new(testMatcher)
|
st := new(testMatcher)
|
||||||
// Long tests:
|
|
||||||
st.slow(`^stAttackTest/ContractCreationSpam`)
|
|
||||||
st.slow(`^stBadOpcode/badOpcodes`)
|
|
||||||
st.slow(`^stPreCompiledContracts/modexp`)
|
|
||||||
st.slow(`^stQuadraticComplexityTest/`)
|
|
||||||
st.slow(`^stStaticCall/static_Call50000`)
|
|
||||||
st.slow(`^stStaticCall/static_Return50000`)
|
|
||||||
st.slow(`^stSystemOperationsTest/CallRecursiveBomb`)
|
|
||||||
st.slow(`^stTransactionTest/Opcodes_TransactionInit`)
|
|
||||||
|
|
||||||
// Very time consuming
|
// Very time consuming
|
||||||
st.skipLoad(`^stTimeConsuming/`)
|
st.skipLoad(`^stTimeConsuming/`)
|
||||||
|
st.skipLoad(`.*vmPerformance/loop.*`)
|
||||||
// Uses 1GB RAM per tested fork
|
|
||||||
st.skipLoad(`^stStaticCall/static_Call1MB`)
|
|
||||||
|
|
||||||
// Broken tests:
|
// Broken tests:
|
||||||
st.skipLoad(`^stCreate2/create2collisionStorage.json`)
|
st.skipLoad(`^stCreate2/create2collisionStorage.json`)
|
||||||
@ -61,20 +50,10 @@ func TestState(t *testing.T) {
|
|||||||
st.skipLoad(`^stSStoreTest/InitCollision.json`)
|
st.skipLoad(`^stSStoreTest/InitCollision.json`)
|
||||||
st.skipLoad(`^stEIP1559/typeTwoBerlin.json`)
|
st.skipLoad(`^stEIP1559/typeTwoBerlin.json`)
|
||||||
|
|
||||||
// Expected failures:
|
// https://github.com/ethereum/tests/issues/1001
|
||||||
//st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/Byzantium/0`, "bug in test")
|
st.skipLoad(`^stTransactionTest/ValueOverflow.json`)
|
||||||
//st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/Byzantium/3`, "bug in test")
|
|
||||||
//st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/Constantinople/0`, "bug in test")
|
|
||||||
//st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/Constantinople/3`, "bug in test")
|
|
||||||
//st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/ConstantinopleFix/0`, "bug in test")
|
|
||||||
//st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/ConstantinopleFix/3`, "bug in test")
|
|
||||||
|
|
||||||
// For Istanbul, older tests were moved into LegacyTests
|
st.walk(t, stateTestDir, func(t *testing.T, name string, test *StateTest) {
|
||||||
for _, dir := range []string{
|
|
||||||
stateTestDir,
|
|
||||||
legacyStateTestDir,
|
|
||||||
} {
|
|
||||||
st.walk(t, dir, func(t *testing.T, name string, test *StateTest) {
|
|
||||||
db := memdb.NewTestDB(t)
|
db := memdb.NewTestDB(t)
|
||||||
for _, subtest := range test.Subtests() {
|
for _, subtest := range test.Subtests() {
|
||||||
subtest := subtest
|
subtest := subtest
|
||||||
@ -99,7 +78,6 @@ func TestState(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Transactions with gasLimit above this value will not get a VM trace on failure.
|
// Transactions with gasLimit above this value will not get a VM trace on failure.
|
||||||
const traceErrorLimit = 400000
|
const traceErrorLimit = 400000
|
||||||
|
@ -230,13 +230,6 @@ func (t *StateTest) RunNoVerify(rules params.Rules, tx kv.RwTx, subtest StateSub
|
|||||||
statedb.RevertToSnapshot(snapshot)
|
statedb.RevertToSnapshot(snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
// And _now_ get the state root
|
|
||||||
// Add 0-value mining reward. This only makes a difference in the cases
|
|
||||||
// where
|
|
||||||
// - the coinbase suicided, or
|
|
||||||
// - there are only 'bad' transactions, which aren't executed. In those cases,
|
|
||||||
// the coinbase gets no txfee, so isn't created, and thus needs to be touched
|
|
||||||
statedb.AddBalance(block.Coinbase(), new(uint256.Int))
|
|
||||||
if err = statedb.FinalizeTx(evm.ChainRules, w); err != nil {
|
if err = statedb.FinalizeTx(evm.ChainRules, w); err != nil {
|
||||||
return nil, common.Hash{}, err
|
return nil, common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 52cb3b3e724d13943bd8a457ed70929f98b9b8bf
|
Subproject commit fbff6fee061ade2358280a8d6f98f67b4ae2b60e
|
@ -26,25 +26,16 @@ func TestTransaction(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
txt := new(testMatcher)
|
txt := new(testMatcher)
|
||||||
// These can't be parsed, invalid hex in RLP
|
|
||||||
txt.skipLoad("^ttWrongRLP/.*")
|
|
||||||
// We don't allow more than uint64 in gas amount
|
// We don't allow more than uint64 in gas amount
|
||||||
// This is a pseudo-consensus vulnerability, but not in practice
|
// This is a pseudo-consensus vulnerability, but not in practice
|
||||||
// because of the gas limit
|
// because of the gas limit
|
||||||
txt.skipLoad("^ttGasLimit/TransactionWithGasLimitxPriceOverflow.json")
|
txt.skipLoad("^ttGasLimit/TransactionWithGasLimitxPriceOverflow.json")
|
||||||
// We _do_ allow more than uint64 in gas price, as opposed to the tests
|
|
||||||
// This is also not a concern, as long as tx.Cost() uses big.Int for
|
|
||||||
// calculating the final cozt
|
|
||||||
txt.skipLoad(".*TransactionWithGasPriceOverflow.*")
|
|
||||||
|
|
||||||
// The nonce is too large for uint64. Not a concern, it means geth won't
|
// The nonce is too large for uint64. Not a concern, it means geth won't
|
||||||
// accept transactions at a certain point in the distant future
|
// accept transactions at a certain point in the distant future
|
||||||
txt.skipLoad("^ttNonce/TransactionWithHighNonce256.json")
|
txt.skipLoad("^ttNonce/TransactionWithHighNonce256.json")
|
||||||
|
|
||||||
// The value is larger than uint64, which according to the test is invalid.
|
|
||||||
// Geth accepts it, which is not a consensus issue since we use big.Int's
|
|
||||||
// internally to calculate the cost
|
|
||||||
txt.skipLoad("^ttValue/TransactionWithHighValueOverflow.json")
|
|
||||||
txt.walk(t, transactionTestDir, func(t *testing.T, name string, test *TransactionTest) {
|
txt.walk(t, transactionTestDir, func(t *testing.T, name string, test *TransactionTest) {
|
||||||
cfg := params.MainnetChainConfig
|
cfg := params.MainnetChainConfig
|
||||||
if err := txt.checkFailure(t, test.Run(cfg)); err != nil {
|
if err := txt.checkFailure(t, test.Run(cfg)); err != nil {
|
||||||
|
@ -30,19 +30,27 @@ import (
|
|||||||
|
|
||||||
// TransactionTest checks RLP decoding and sender derivation of transactions.
|
// TransactionTest checks RLP decoding and sender derivation of transactions.
|
||||||
type TransactionTest struct {
|
type TransactionTest struct {
|
||||||
RLP hexutil.Bytes `json:"rlp"`
|
RLP hexutil.Bytes `json:"txbytes"`
|
||||||
|
Forks ttForks `json:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ttForks struct {
|
||||||
|
Berlin ttFork
|
||||||
Byzantium ttFork
|
Byzantium ttFork
|
||||||
Constantinople ttFork
|
Constantinople ttFork
|
||||||
Istanbul ttFork
|
ConstantinopleFix ttFork
|
||||||
EIP150 ttFork
|
EIP150 ttFork
|
||||||
EIP158 ttFork
|
EIP158 ttFork
|
||||||
Frontier ttFork
|
Frontier ttFork
|
||||||
Homestead ttFork
|
Homestead ttFork
|
||||||
|
Istanbul ttFork
|
||||||
|
London ttFork
|
||||||
}
|
}
|
||||||
|
|
||||||
type ttFork struct {
|
type ttFork struct {
|
||||||
Sender common.UnprefixedAddress `json:"sender"`
|
Exception string `json:"exception"`
|
||||||
Hash common.UnprefixedHash `json:"hash"`
|
Sender common.Address `json:"sender"`
|
||||||
|
Hash common.Hash `json:"hash"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tt *TransactionTest) Run(config *params.ChainConfig) error {
|
func (tt *TransactionTest) Run(config *params.ChainConfig) error {
|
||||||
@ -74,19 +82,22 @@ func (tt *TransactionTest) Run(config *params.ChainConfig) error {
|
|||||||
isHomestead bool
|
isHomestead bool
|
||||||
isIstanbul bool
|
isIstanbul bool
|
||||||
}{
|
}{
|
||||||
{"Frontier", types.MakeFrontierSigner(), tt.Frontier, false, false},
|
{"Frontier", types.MakeFrontierSigner(), tt.Forks.Frontier, false, false},
|
||||||
{"Homestead", types.LatestSignerForChainID(nil), tt.Homestead, true, false},
|
{"Homestead", types.LatestSignerForChainID(nil), tt.Forks.Homestead, true, false},
|
||||||
{"EIP150", types.LatestSignerForChainID(nil), tt.EIP150, true, false},
|
{"EIP150", types.LatestSignerForChainID(nil), tt.Forks.EIP150, true, false},
|
||||||
{"EIP158", types.LatestSignerForChainID(config.ChainID), tt.EIP158, true, false},
|
{"EIP158", types.LatestSignerForChainID(config.ChainID), tt.Forks.EIP158, true, false},
|
||||||
{"Byzantium", types.LatestSignerForChainID(config.ChainID), tt.Byzantium, true, false},
|
{"Byzantium", types.LatestSignerForChainID(config.ChainID), tt.Forks.Byzantium, true, false},
|
||||||
{"Constantinople", types.LatestSignerForChainID(config.ChainID), tt.Constantinople, true, false},
|
{"Constantinople", types.LatestSignerForChainID(config.ChainID), tt.Forks.Constantinople, true, false},
|
||||||
{"Istanbul", types.LatestSignerForChainID(config.ChainID), tt.Istanbul, true, true},
|
{"ConstantinopleFix", types.LatestSignerForChainID(config.ChainID), tt.Forks.ConstantinopleFix, true, false},
|
||||||
|
{"Istanbul", types.LatestSignerForChainID(config.ChainID), tt.Forks.Istanbul, true, true},
|
||||||
|
{"Berlin", types.LatestSignerForChainID(config.ChainID), tt.Forks.Berlin, true, true},
|
||||||
|
{"London", types.LatestSignerForChainID(config.ChainID), tt.Forks.London, true, true},
|
||||||
} {
|
} {
|
||||||
sender, txhash, err := validateTx(tt.RLP, *testcase.signer, testcase.isHomestead, testcase.isIstanbul)
|
sender, txhash, err := validateTx(tt.RLP, *testcase.signer, testcase.isHomestead, testcase.isIstanbul)
|
||||||
|
|
||||||
if testcase.fork.Sender == (common.UnprefixedAddress{}) {
|
if testcase.fork.Exception != "" {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return fmt.Errorf("expected error, got none (address %v)[%v]", sender.String(), testcase.name)
|
return fmt.Errorf("expected error %v, got none [%v]", testcase.fork.Exception, testcase.name)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
// Copyright 2014 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package tests
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/ledgerwatch/erigon-lib/kv/memdb"
|
|
||||||
"github.com/ledgerwatch/erigon/core/vm"
|
|
||||||
"github.com/ledgerwatch/log/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVM(t *testing.T) {
|
|
||||||
defer log.Root().SetHandler(log.Root().GetHandler())
|
|
||||||
log.Root().SetHandler(log.LvlFilterHandler(log.LvlError, log.StderrHandler))
|
|
||||||
t.Parallel()
|
|
||||||
vmt := new(testMatcher)
|
|
||||||
vmt.slow("^vmPerformance")
|
|
||||||
vmt.fails("^vmSystemOperationsTest.json/createNameRegistrator$", "fails without parallel execution")
|
|
||||||
|
|
||||||
db := memdb.NewTestDB(t)
|
|
||||||
|
|
||||||
vmt.walk(t, vmTestDir, func(t *testing.T, name string, test *VMTest) {
|
|
||||||
withTrace(t, test.json.Exec.GasLimit, func(vmconfig vm.Config) error {
|
|
||||||
tx, err := db.BeginRw(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer tx.Rollback()
|
|
||||||
return vmt.checkFailure(t, test.Run(tx, vmconfig, 0))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user