github.com/klaytn/klaytn@v1.12.1/tests/transaction_test_util.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from tests/transaction_test_util.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package tests 22 23 import ( 24 "bytes" 25 "errors" 26 "fmt" 27 "math/big" 28 29 "github.com/klaytn/klaytn/blockchain/types" 30 "github.com/klaytn/klaytn/common" 31 "github.com/klaytn/klaytn/common/hexutil" 32 "github.com/klaytn/klaytn/common/math" 33 "github.com/klaytn/klaytn/params" 34 "github.com/klaytn/klaytn/rlp" 35 ) 36 37 // TransactionTest checks RLP decoding and sender derivation of transactions. 38 type TransactionTest struct { 39 json ttJSON 40 } 41 42 type ttJSON struct { 43 BlockNumber math.HexOrDecimal64 `json:"blockNumber"` 44 RLP hexutil.Bytes `json:"rlp"` 45 Sender hexutil.Bytes `json:"sender"` 46 Transaction *ttTransaction `json:"transaction"` 47 } 48 49 //go:generate gencodec -type ttTransaction -field-override ttTransactionMarshaling -out gen_tttransaction.go 50 51 type ttTransaction struct { 52 Data []byte `gencodec:"required"` 53 GasLimit uint64 `gencodec:"required"` 54 GasPrice *big.Int `gencodec:"required"` 55 Nonce uint64 `gencodec:"required"` 56 Value *big.Int `gencodec:"required"` 57 R *big.Int `gencodec:"required"` 58 S *big.Int `gencodec:"required"` 59 V *big.Int `gencodec:"required"` 60 To common.Address `gencodec:"required"` 61 } 62 63 type ttTransactionMarshaling struct { 64 Data hexutil.Bytes 65 GasLimit math.HexOrDecimal64 66 GasPrice *math.HexOrDecimal256 67 Nonce math.HexOrDecimal64 68 Value *math.HexOrDecimal256 69 R *math.HexOrDecimal256 70 S *math.HexOrDecimal256 71 V *math.HexOrDecimal256 72 } 73 74 func (tt *TransactionTest) Run(config *params.ChainConfig) error { 75 tx := new(types.Transaction) 76 if err := rlp.DecodeBytes(tt.json.RLP, tx); err != nil { 77 if tt.json.Transaction == nil { 78 return nil 79 } 80 return fmt.Errorf("RLP decoding failed: %v", err) 81 } 82 // Check sender derivation. 83 signer := types.MakeSigner(config, new(big.Int).SetUint64(uint64(tt.json.BlockNumber))) 84 sender, err := types.Sender(signer, tx) 85 if err != nil { 86 return err 87 } 88 if sender != common.BytesToAddress(tt.json.Sender) { 89 return fmt.Errorf("Sender mismatch: got %x, want %x", sender, tt.json.Sender) 90 } 91 // Check decoded fields. 92 err = tt.json.Transaction.verify(signer, tx) 93 if tt.json.Sender == nil && err == nil { 94 return errors.New("field validations succeeded but should fail") 95 } 96 if tt.json.Sender != nil && err != nil { 97 return fmt.Errorf("field validations failed after RLP decoding: %s", err) 98 } 99 return nil 100 } 101 102 func (tt *ttTransaction) verify(signer types.Signer, tx *types.Transaction) error { 103 if !bytes.Equal(tx.Data(), tt.Data) { 104 return fmt.Errorf("Tx input data mismatch: got %x want %x", tx.Data(), tt.Data) 105 } 106 if tx.Gas() != tt.GasLimit { 107 return fmt.Errorf("GasLimit mismatch: got %d, want %d", tx.Gas(), tt.GasLimit) 108 } 109 if tx.GasPrice().Cmp(tt.GasPrice) != 0 { 110 return fmt.Errorf("GasPrice mismatch: got %v, want %v", tx.GasPrice(), tt.GasPrice) 111 } 112 if tx.Nonce() != tt.Nonce { 113 return fmt.Errorf("Nonce mismatch: got %v, want %v", tx.Nonce(), tt.Nonce) 114 } 115 sigs := tx.RawSignatureValues() 116 v, r, s := sigs[0].V, sigs[1].R, sigs[2].S 117 if r.Cmp(tt.R) != 0 { 118 return fmt.Errorf("R mismatch: got %v, want %v", r, tt.R) 119 } 120 if s.Cmp(tt.S) != 0 { 121 return fmt.Errorf("S mismatch: got %v, want %v", s, tt.S) 122 } 123 if v.Cmp(tt.V) != 0 { 124 return fmt.Errorf("V mismatch: got %v, want %v", v, tt.V) 125 } 126 if tx.To() == nil { 127 if tt.To != (common.Address{}) { 128 return fmt.Errorf("To mismatch when recipient is nil (contract creation): %x", tt.To) 129 } 130 } else if *tx.To() != tt.To { 131 return fmt.Errorf("To mismatch: got %x, want %x", *tx.To(), tt.To) 132 } 133 if tx.Value().Cmp(tt.Value) != 0 { 134 return fmt.Errorf("Value mismatch: got %x, want %x", tx.Value(), tt.Value) 135 } 136 return nil 137 }