aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/blocktest.go22
-rw-r--r--tests/transaction_test.go58
-rw-r--r--tests/transaction_test_util.go134
3 files changed, 211 insertions, 3 deletions
diff --git a/tests/blocktest.go b/tests/blocktest.go
index 6b8ee9d4a..84b70678d 100644
--- a/tests/blocktest.go
+++ b/tests/blocktest.go
@@ -81,7 +81,7 @@ type BlockTest struct {
// LoadBlockTests loads a block test JSON file.
func LoadBlockTests(file string) (map[string]*BlockTest, error) {
bt := make(map[string]*btJSON)
- if err := loadJSON(file, &bt); err != nil {
+ if err := LoadJSON(file, &bt); err != nil {
return nil, err
}
out := make(map[string]*BlockTest)
@@ -250,6 +250,14 @@ func mustConvertBigInt10(in string) *big.Int {
return out
}
+func mustConvertBigIntHex(in string) *big.Int {
+ out, ok := new(big.Int).SetString(in, 16)
+ if !ok {
+ panic(fmt.Errorf("invalid integer: %q", in))
+ }
+ return out
+}
+
func mustConvertUint(in string) uint64 {
out, err := strconv.ParseUint(in, 0, 64)
if err != nil {
@@ -258,8 +266,16 @@ func mustConvertUint(in string) uint64 {
return out
}
-// loadJSON reads the given file and unmarshals its content.
-func loadJSON(file string, val interface{}) error {
+func mustConvertUintHex(in string) uint64 {
+ out, err := strconv.ParseUint(in, 16, 64)
+ if err != nil {
+ panic(fmt.Errorf("invalid integer: %q", in))
+ }
+ return out
+}
+
+// LoadJSON reads the given file and unmarshals its content.
+func LoadJSON(file string, val interface{}) error {
content, err := ioutil.ReadFile(file)
if err != nil {
return err
diff --git a/tests/transaction_test.go b/tests/transaction_test.go
new file mode 100644
index 000000000..5e903e4b4
--- /dev/null
+++ b/tests/transaction_test.go
@@ -0,0 +1,58 @@
+package tests
+
+import (
+ "testing"
+)
+
+func TestTransactions(t *testing.T) {
+ notWorking := make(map[string]bool, 100)
+ // TODO: all commented out tests should work!
+
+ snafus := []string{
+ "AddressLessThan20Prefixed0",
+ "DataTest",
+ "EmptyTransaction",
+ "RightVRSTest",
+ "SenderTest",
+ "TransactionWithGasLimitxPriceOverflow",
+ "TransactionWithHihghGas",
+ "TransactionWithHihghGasPrice",
+ "TransactionWithHihghNonce",
+ "TransactionWithHihghValue",
+ "TransactionWithRvalueWrongSize",
+ "TransactionWithSvalueHigh",
+ "TransactionWithSvalueTooHigh",
+ "TransactionWithSvalueWrongSize",
+ "ValuesAsDec",
+ "ValuesAsHex",
+ "libsecp256k1test",
+ "unpadedRValue"}
+
+ for _, name := range snafus {
+ notWorking[name] = true
+ }
+
+ var err error
+ err = RunTransactionTests("./files/TransactionTests/ttTransactionTest.json",
+ notWorking)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestWrongRLPTransactions(t *testing.T) {
+ notWorking := make(map[string]bool, 100)
+ // TODO: all commented out tests should work!
+ notWorking[""] = true
+ notWorking[""] = true
+ notWorking[""] = true
+ notWorking[""] = true
+ notWorking[""] = true
+
+ var err error
+ err = RunTransactionTests("./files/TransactionTests/ttWrongRLPTransaction.json",
+ notWorking)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go
new file mode 100644
index 000000000..800891887
--- /dev/null
+++ b/tests/transaction_test_util.go
@@ -0,0 +1,134 @@
+package tests
+
+import (
+ "bytes"
+ "fmt"
+ "math/big"
+ "runtime"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/rlp"
+)
+
+// Transaction Test JSON Format
+type TtTransaction struct {
+ Data string
+ GasLimit string
+ GasPrice string
+ Nonce string
+ R string
+ S string
+ To string
+ V string
+ Value string
+}
+
+type TransactionTest struct {
+ Rlp string
+ Sender string
+ Transaction TtTransaction
+}
+
+func RunTransactionTests(file string, notWorking map[string]bool) error {
+ bt := make(map[string]TransactionTest)
+ if err := LoadJSON(file, &bt); err != nil {
+ return err
+ }
+ for name, in := range bt {
+ var err error
+ // TODO: remove this, we currently ignore some tests which are broken
+ if !notWorking[name] {
+ if err = runTest(in); err != nil {
+ return fmt.Errorf("bad test %s: %v", name, err)
+ }
+ fmt.Println("Test passed:", name)
+ }
+ }
+ return nil
+}
+
+func runTest(txTest TransactionTest) (err error) {
+ expectedSender, expectedTo, expectedData, rlpBytes, expectedGasLimit, expectedGasPrice, expectedValue, expectedR, expectedS, expectedNonce, expectedV, err := convertTestTypes(txTest)
+
+ if err != nil {
+ if txTest.Sender == "" { // tx is invalid and this is expected (test OK)
+ return nil
+ } else {
+ return err // tx is invalid and this is NOT expected (test FAIL)
+ }
+ }
+ tx := new(types.Transaction)
+ rlp.DecodeBytes(rlpBytes, tx)
+
+ sender, err := tx.From()
+ if err != nil {
+ return err
+ }
+
+ if expectedSender != sender {
+ return fmt.Errorf("Sender mismatch: %v %v", expectedSender, sender)
+ }
+ if !bytes.Equal(expectedData, tx.Payload) {
+ return fmt.Errorf("Tx input data mismatch: %#v %#v", expectedData, tx.Payload)
+ }
+ if expectedGasLimit.Cmp(tx.GasLimit) != 0 {
+ return fmt.Errorf("GasLimit mismatch: %v %v", expectedGasLimit, tx.GasLimit)
+ }
+ if expectedGasPrice.Cmp(tx.Price) != 0 {
+ return fmt.Errorf("GasPrice mismatch: %v %v", expectedGasPrice, tx.Price)
+ }
+ if expectedNonce != tx.AccountNonce {
+ return fmt.Errorf("Nonce mismatch: %v %v", expectedNonce, tx.AccountNonce)
+ }
+ if expectedR.Cmp(tx.R) != 0 {
+ return fmt.Errorf("R mismatch: %v %v", expectedR, tx.R)
+ }
+ if expectedS.Cmp(tx.S) != 0 {
+ return fmt.Errorf("S mismatch: %v %v", expectedS, tx.S)
+ }
+ if expectedV != uint64(tx.V) {
+ return fmt.Errorf("V mismatch: %v %v", expectedV, uint64(tx.V))
+ }
+ if expectedTo != *tx.Recipient {
+ return fmt.Errorf("To mismatch: %v %v", expectedTo, *tx.Recipient)
+ }
+ if expectedValue.Cmp(tx.Amount) != 0 {
+ return fmt.Errorf("Value mismatch: %v %v", expectedValue, tx.Amount)
+ }
+
+ return nil
+}
+
+func convertTestTypes(txTest TransactionTest) (sender, to common.Address,
+ txInputData, rlpBytes []byte,
+ gasLimit, gasPrice, value, r, s *big.Int,
+ nonce, v uint64,
+ err error) {
+
+ defer func() {
+ if recovered := recover(); recovered != nil {
+ buf := make([]byte, 64<<10)
+ buf = buf[:runtime.Stack(buf, false)]
+ err = fmt.Errorf("%v\n%s", recovered, buf)
+ }
+ }()
+
+ sender = mustConvertAddress(txTest.Sender)
+ to = mustConvertAddress(txTest.Transaction.To)
+
+ txInputData = mustConvertBytes(txTest.Transaction.Data)
+ rlpBytes = mustConvertBytes(txTest.Rlp)
+
+ gasLimit = mustConvertBigIntHex(txTest.Transaction.GasLimit)
+ gasPrice = mustConvertBigIntHex(txTest.Transaction.GasPrice)
+ value = mustConvertBigIntHex(txTest.Transaction.Value)
+
+ r = common.Bytes2Big(mustConvertBytes(txTest.Transaction.R))
+ s = common.Bytes2Big(mustConvertBytes(txTest.Transaction.S))
+
+ nonce = mustConvertUintHex(txTest.Transaction.Nonce)
+ v = mustConvertUintHex(txTest.Transaction.V)
+
+ return sender, to, txInputData, rlpBytes, gasLimit, gasPrice, value, r, s, nonce, v, nil
+}