// NodeKey retrieves the currently configured private key of the node, checking // first any manually set key, falling back to the one found in the configured // data folder. If no key can be found, a new one is generated. func (c *Config) NodeKey() *ecdsa.PrivateKey { // Use any specifically configured key if c.PrivateKey != nil { return c.PrivateKey } // Generate ephemeral key if no datadir is being used if c.DataDir == "" { key, err := crypto.GenerateKey() if err != nil { glog.Fatalf("Failed to generate ephemeral node key: %v", err) } return key } // Fall back to persistent key from the data directory keyfile := filepath.Join(c.DataDir, datadirPrivateKey) if key, err := crypto.LoadECDSA(keyfile); err == nil { return key } // No persistent key found, generate and store a new one key, err := crypto.GenerateKey() if err != nil { glog.Fatalf("Failed to generate node key: %v", err) } if err := crypto.SaveECDSA(keyfile, key); err != nil { glog.V(logger.Error).Infof("Failed to persist node key: %v", err) } return key }
// Tests whether a message can be encrypted and decrypted using an anonymous // sender (i.e. no signature). func TestMessageAnonymousEncryptDecrypt(t *testing.T) { key, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to create recipient crypto key: %v", err) } payload := []byte("hello world") msg := NewMessage(payload) envelope, err := msg.Wrap(DefaultPoW, Options{ To: &key.PublicKey, }) if err != nil { t.Fatalf("failed to encrypt message: %v", err) } if msg.Flags&signatureFlag != 0 { t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, 0) } if len(msg.Signature) != 0 { t.Fatalf("signature found for anonymous message: 0x%x", msg.Signature) } out, err := envelope.Open(key) if err != nil { t.Fatalf("failed to open encrypted message: %v", err) } if !bytes.Equal(out.Payload, payload) { t.Errorf("payload mismatch: have 0x%x, want 0x%x", out.Payload, payload) } }
func TestEnvelopeIdentifiedOpenUntargeted(t *testing.T) { key, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to generate test identity: %v", err) } payload := []byte("hello envelope") envelope, err := NewMessage(payload).Wrap(DefaultPoW, Options{}) if err != nil { t.Fatalf("failed to wrap message: %v", err) } opened, err := envelope.Open(key) switch err { case nil: t.Fatalf("envelope opened with bad key: %v", opened) case ecies.ErrInvalidPublicKey: // Ok, key mismatch but opened default: t.Fatalf("failed to open envelope: %v", err) } if opened.To != nil { t.Fatalf("recipient mismatch: have 0x%x, want nil", opened.To) } if bytes.Compare(opened.Payload, payload) != 0 { t.Fatalf("payload mismatch: have 0x%x, want 0x%x", opened.Payload, payload) } }
func newkey() *ecdsa.PrivateKey { key, err := crypto.GenerateKey() if err != nil { panic("couldn't generate key: " + err.Error()) } return key }
func main() { logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.InfoLevel)) // Generate the peer identity key, err := crypto.GenerateKey() if err != nil { fmt.Printf("Failed to generate peer key: %v.\n", err) os.Exit(-1) } name := common.MakeName("whisper-go", "1.0") shh := whisper.New() // Create an Expanse peer to communicate through server := p2p.Server{ PrivateKey: key, MaxPeers: 10, Name: name, Protocols: []p2p.Protocol{shh.Protocol()}, ListenAddr: ":30300", NAT: nat.Any(), } fmt.Println("Starting Expanse peer...") if err := server.Start(); err != nil { fmt.Printf("Failed to start Expanse peer: %v.\n", err) os.Exit(1) } // Send a message to self to check that something works payload := fmt.Sprintf("Hello world, this is %v. In case you're wondering, the time is %v", name, time.Now()) if err := selfSend(shh, []byte(payload)); err != nil { fmt.Printf("Failed to self message: %v.\n", err) os.Exit(-1) } }
// Tests whether a message can be signed, and wrapped in plain-text. func TestMessageCleartextSignRecover(t *testing.T) { key, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to create crypto key: %v", err) } payload := []byte("hello world") msg := NewMessage(payload) if _, err := msg.Wrap(DefaultPoW, Options{ From: key, }); err != nil { t.Fatalf("failed to sign message: %v", err) } if msg.Flags&signatureFlag != signatureFlag { t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, signatureFlag) } if bytes.Compare(msg.Payload, payload) != 0 { t.Fatalf("payload mismatch after signing: have 0x%x, want 0x%x", msg.Payload, payload) } pubKey := msg.Recover() if pubKey == nil { t.Fatalf("failed to recover public key") } p1 := elliptic.Marshal(secp256k1.S256(), key.PublicKey.X, key.PublicKey.Y) p2 := elliptic.Marshal(secp256k1.S256(), pubKey.X, pubKey.Y) if !bytes.Equal(p1, p2) { t.Fatalf("public key mismatch: have 0x%x, want 0x%x", p2, p1) } }
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { db, _ := ethdb.NewMemDatabase() statedb := state.New(common.Hash{}, db) var m event.TypeMux key, _ := crypto.GenerateKey() return NewTxPool(&m, func() *state.StateDB { return statedb }, func() *big.Int { return big.NewInt(1000000) }), key }
func init() { ringKeys[0] = benchRootKey ringAddrs[0] = benchRootAddr for i := 1; i < len(ringKeys); i++ { ringKeys[i], _ = crypto.GenerateKey() ringAddrs[i] = crypto.PubkeyToAddress(ringKeys[i].PublicKey) } }
// NewIdentity generates a new cryptographic identity for the client, and injects // it into the known identities for message decryption. func (self *Whisper) NewIdentity() *ecdsa.PrivateKey { key, err := crypto.GenerateKey() if err != nil { panic(err) } self.keys[string(crypto.FromECDSAPub(&key.PublicKey))] = key return key }
// Tests whether a message can be properly signed and encrypted. func TestMessageFullCrypto(t *testing.T) { fromKey, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to create sender crypto key: %v", err) } toKey, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to create recipient crypto key: %v", err) } payload := []byte("hello world") msg := NewMessage(payload) envelope, err := msg.Wrap(DefaultPoW, Options{ From: fromKey, To: &toKey.PublicKey, }) if err != nil { t.Fatalf("failed to encrypt message: %v", err) } if msg.Flags&signatureFlag != signatureFlag { t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, signatureFlag) } if len(msg.Signature) == 0 { t.Fatalf("no signature found for signed message") } out, err := envelope.Open(toKey) if err != nil { t.Fatalf("failed to open encrypted message: %v", err) } if !bytes.Equal(out.Payload, payload) { t.Errorf("payload mismatch: have 0x%x, want 0x%x", out.Payload, payload) } pubKey := out.Recover() if pubKey == nil { t.Fatalf("failed to recover public key") } p1 := elliptic.Marshal(secp256k1.S256(), fromKey.PublicKey.X, fromKey.PublicKey.Y) p2 := elliptic.Marshal(secp256k1.S256(), pubKey.X, pubKey.Y) if !bytes.Equal(p1, p2) { t.Fatalf("public key mismatch: have 0x%x, want 0x%x", p2, p1) } }
// Tests that node keys can be correctly created, persisted, loaded and/or made // ephemeral. func TestNodeKeyPersistency(t *testing.T) { // Create a temporary folder and make sure no key is present dir, err := ioutil.TempDir("", "") if err != nil { t.Fatalf("failed to create temporary data directory: %v", err) } defer os.RemoveAll(dir) if _, err := os.Stat(filepath.Join(dir, datadirPrivateKey)); err == nil { t.Fatalf("non-created node key already exists") } // Configure a node with a preset key and ensure it's not persisted key, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to generate one-shot node key: %v", err) } if _, err := New(&Config{DataDir: dir, PrivateKey: key}); err != nil { t.Fatalf("failed to create empty stack: %v", err) } if _, err := os.Stat(filepath.Join(dir, datadirPrivateKey)); err == nil { t.Fatalf("one-shot node key persisted to data directory") } // Configure a node with no preset key and ensure it is persisted this time if _, err := New(&Config{DataDir: dir}); err != nil { t.Fatalf("failed to create newly keyed stack: %v", err) } if _, err := os.Stat(filepath.Join(dir, datadirPrivateKey)); err != nil { t.Fatalf("node key not persisted to data directory: %v", err) } key, err = crypto.LoadECDSA(filepath.Join(dir, datadirPrivateKey)) if err != nil { t.Fatalf("failed to load freshly persisted node key: %v", err) } blob1, err := ioutil.ReadFile(filepath.Join(dir, datadirPrivateKey)) if err != nil { t.Fatalf("failed to read freshly persisted node key: %v", err) } // Configure a new node and ensure the previously persisted key is loaded if _, err := New(&Config{DataDir: dir}); err != nil { t.Fatalf("failed to create previously keyed stack: %v", err) } blob2, err := ioutil.ReadFile(filepath.Join(dir, datadirPrivateKey)) if err != nil { t.Fatalf("failed to read previously persisted node key: %v", err) } if bytes.Compare(blob1, blob2) != 0 { t.Fatalf("persisted node key mismatch: have %x, want %x", blob2, blob1) } // Configure ephemeral node and ensure no key is dumped locally if _, err := New(&Config{DataDir: ""}); err != nil { t.Fatalf("failed to create ephemeral stack: %v", err) } if _, err := os.Stat(filepath.Join(".", datadirPrivateKey)); err == nil { t.Fatalf("ephemeral node key persisted to disk") } }
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, db) var m event.TypeMux key, _ := crypto.GenerateKey() newPool := NewTxPool(&m, func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) }) newPool.resetState() return newPool, key }
func TestSharedSecret(t *testing.T) { prv0, _ := crypto.GenerateKey() // = ecdsa.GenerateKey(crypto.S256(), rand.Reader) pub0 := &prv0.PublicKey prv1, _ := crypto.GenerateKey() pub1 := &prv1.PublicKey ss0, err := ecies.ImportECDSA(prv0).GenerateShared(ecies.ImportECDSAPublic(pub1), sskLen, sskLen) if err != nil { return } ss1, err := ecies.ImportECDSA(prv1).GenerateShared(ecies.ImportECDSAPublic(pub0), sskLen, sskLen) if err != nil { return } t.Logf("Secret:\n%v %x\n%v %x", len(ss0), ss0, len(ss0), ss1) if !bytes.Equal(ss0, ss1) { t.Errorf("dont match :(") } }
func main() { var ( listenAddr = flag.String("addr", ":42787", "listen address") genKey = flag.String("genkey", "", "generate a node key and quit") nodeKeyFile = flag.String("nodekey", "", "private key filename") nodeKeyHex = flag.String("nodekeyhex", "", "private key as hex (for testing)") natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)") nodeKey *ecdsa.PrivateKey err error ) flag.Var(glog.GetVerbosity(), "verbosity", "log verbosity (0-9)") flag.Var(glog.GetVModule(), "vmodule", "log verbosity pattern") glog.SetToStderr(true) flag.Parse() if *genKey != "" { key, err := crypto.GenerateKey() if err != nil { utils.Fatalf("could not generate key: %v", err) } if err := crypto.SaveECDSA(*genKey, key); err != nil { utils.Fatalf("%v", err) } os.Exit(0) } natm, err := nat.Parse(*natdesc) if err != nil { utils.Fatalf("-nat: %v", err) } switch { case *nodeKeyFile == "" && *nodeKeyHex == "": utils.Fatalf("Use -nodekey or -nodekeyhex to specify a private key") case *nodeKeyFile != "" && *nodeKeyHex != "": utils.Fatalf("Options -nodekey and -nodekeyhex are mutually exclusive") case *nodeKeyFile != "": if nodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil { utils.Fatalf("-nodekey: %v", err) } case *nodeKeyHex != "": if nodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil { utils.Fatalf("-nodekeyhex: %v", err) } } if _, err := discover.ListenUDP(nodeKey, *listenAddr, natm, ""); err != nil { utils.Fatalf("%v", err) } select {} }
// Tests that if the transaction count belonging to multiple accounts go above // some threshold, the higher transactions are dropped to prevent DOS attacks. func TestTransactionQueueGlobalLimiting(t *testing.T) { // Reduce the queue limits to shorten test time defer func(old uint64) { maxQueuedInTotal = old }(maxQueuedInTotal) maxQueuedInTotal = maxQueuedPerAccount * 3 // Create the pool to test the limit enforcement with db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, db) pool := NewTxPool(testChainConfig(), new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) }) pool.resetState() // Create a number of test accounts and fund them state, _ := pool.currentState() keys := make([]*ecdsa.PrivateKey, 5) for i := 0; i < len(keys); i++ { keys[i], _ = crypto.GenerateKey() state.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) } // Generate and queue a batch of transactions nonces := make(map[common.Address]uint64) txs := make(types.Transactions, 0, 3*maxQueuedInTotal) for len(txs) < cap(txs) { key := keys[rand.Intn(len(keys))] addr := crypto.PubkeyToAddress(key.PublicKey) txs = append(txs, transaction(nonces[addr]+1, big.NewInt(100000), key)) nonces[addr]++ } // Import the batch and verify that limits have been enforced pool.AddBatch(txs) queued := 0 for addr, list := range pool.queue { if list.Len() > int(maxQueuedPerAccount) { t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), maxQueuedPerAccount) } queued += list.Len() } if queued > int(maxQueuedInTotal) { t.Fatalf("total transactions overflow allowance: %d > %d", queued, maxQueuedInTotal) } }
func (cfg *Config) nodeKey() (*ecdsa.PrivateKey, error) { // use explicit key from command line args if set if cfg.NodeKey != nil { return cfg.NodeKey, nil } // use persistent key if present keyfile := filepath.Join(cfg.DataDir, "nodekey") key, err := crypto.LoadECDSA(keyfile) if err == nil { return key, nil } // no persistent key, generate and store a new one if key, err = crypto.GenerateKey(); err != nil { return nil, fmt.Errorf("could not generate server key: %v", err) } if err := crypto.SaveECDSA(keyfile, key); err != nil { glog.V(logger.Error).Infoln("could not persist nodekey: ", err) } return key, nil }
// Tests that transactions can be added to strict lists and list contents and // nonce boundaries are correctly maintained. func TestStrictTxListAdd(t *testing.T) { // Generate a list of transactions to insert key, _ := crypto.GenerateKey() txs := make(types.Transactions, 1024) for i := 0; i < len(txs); i++ { txs[i] = transaction(uint64(i), new(big.Int), key) } // Insert the transactions in a random order list := newTxList(true) for _, v := range rand.Perm(len(txs)) { list.Add(txs[v]) } // Verify internal state if len(list.txs.items) != len(txs) { t.Errorf("transaction count mismatch: have %d, want %d", len(list.txs.items), len(txs)) } for i, tx := range txs { if list.txs.items[tx.Nonce()] != tx { t.Errorf("item %d: transaction mismatch: have %v, want %v", i, list.txs.items[tx.Nonce()], tx) } } }
func TestEnvelopeAnonymousOpenTargeted(t *testing.T) { key, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to generate test identity: %v", err) } payload := []byte("hello envelope") envelope, err := NewMessage(payload).Wrap(DefaultPoW, Options{ To: &key.PublicKey, }) if err != nil { t.Fatalf("failed to wrap message: %v", err) } opened, err := envelope.Open(nil) if err != nil { t.Fatalf("failed to open envelope: %v", err) } if opened.To != nil { t.Fatalf("recipient mismatch: have 0x%x, want nil", opened.To) } if bytes.Compare(opened.Payload, payload) == 0 { t.Fatalf("payload match, should have been encrypted: 0x%x", opened.Payload) } }
func testEncHandshake(token []byte) error { type result struct { side string id discover.NodeID err error } var ( prv0, _ = crypto.GenerateKey() prv1, _ = crypto.GenerateKey() fd0, fd1 = net.Pipe() c0, c1 = newRLPX(fd0).(*rlpx), newRLPX(fd1).(*rlpx) output = make(chan result) ) go func() { r := result{side: "initiator"} defer func() { output <- r }() dest := &discover.Node{ID: discover.PubkeyID(&prv1.PublicKey)} r.id, r.err = c0.doEncHandshake(prv0, dest) if r.err != nil { return } id1 := discover.PubkeyID(&prv1.PublicKey) if r.id != id1 { r.err = fmt.Errorf("remote ID mismatch: got %v, want: %v", r.id, id1) } }() go func() { r := result{side: "receiver"} defer func() { output <- r }() r.id, r.err = c1.doEncHandshake(prv1, nil) if r.err != nil { return } id0 := discover.PubkeyID(&prv0.PublicKey) if r.id != id0 { r.err = fmt.Errorf("remote ID mismatch: got %v, want: %v", r.id, id0) } }() // wait for results from both sides r1, r2 := <-output, <-output if r1.err != nil { return fmt.Errorf("%s side error: %v", r1.side, r1.err) } if r2.err != nil { return fmt.Errorf("%s side error: %v", r2.side, r2.err) } // compare derived secrets if !reflect.DeepEqual(c0.rw.egressMAC, c1.rw.ingressMAC) { return fmt.Errorf("egress mac mismatch:\n c0.rw: %#v\n c1.rw: %#v", c0.rw.egressMAC, c1.rw.ingressMAC) } if !reflect.DeepEqual(c0.rw.ingressMAC, c1.rw.egressMAC) { return fmt.Errorf("ingress mac mismatch:\n c0.rw: %#v\n c1.rw: %#v", c0.rw.ingressMAC, c1.rw.egressMAC) } if !reflect.DeepEqual(c0.rw.enc, c1.rw.enc) { return fmt.Errorf("enc cipher mismatch:\n c0.rw: %#v\n c1.rw: %#v", c0.rw.enc, c1.rw.enc) } if !reflect.DeepEqual(c0.rw.dec, c1.rw.dec) { return fmt.Errorf("dec cipher mismatch:\n c0.rw: %#v\n c1.rw: %#v", c0.rw.dec, c1.rw.dec) } return nil }
func TestProtocolHandshake(t *testing.T) { var ( prv0, _ = crypto.GenerateKey() node0 = &discover.Node{ID: discover.PubkeyID(&prv0.PublicKey), IP: net.IP{1, 2, 3, 4}, TCP: 33} hs0 = &protoHandshake{Version: 3, ID: node0.ID, Caps: []Cap{{"a", 0}, {"b", 2}}} prv1, _ = crypto.GenerateKey() node1 = &discover.Node{ID: discover.PubkeyID(&prv1.PublicKey), IP: net.IP{5, 6, 7, 8}, TCP: 44} hs1 = &protoHandshake{Version: 3, ID: node1.ID, Caps: []Cap{{"c", 1}, {"d", 3}}} fd0, fd1 = net.Pipe() wg sync.WaitGroup ) wg.Add(2) go func() { defer wg.Done() defer fd1.Close() rlpx := newRLPX(fd0) remid, err := rlpx.doEncHandshake(prv0, node1) if err != nil { t.Errorf("dial side enc handshake failed: %v", err) return } if remid != node1.ID { t.Errorf("dial side remote id mismatch: got %v, want %v", remid, node1.ID) return } phs, err := rlpx.doProtoHandshake(hs0) if err != nil { t.Errorf("dial side proto handshake error: %v", err) return } phs.Rest = nil if !reflect.DeepEqual(phs, hs1) { t.Errorf("dial side proto handshake mismatch:\ngot: %s\nwant: %s\n", spew.Sdump(phs), spew.Sdump(hs1)) return } rlpx.close(DiscQuitting) }() go func() { defer wg.Done() defer fd1.Close() rlpx := newRLPX(fd1) remid, err := rlpx.doEncHandshake(prv1, nil) if err != nil { t.Errorf("listen side enc handshake failed: %v", err) return } if remid != node0.ID { t.Errorf("listen side remote id mismatch: got %v, want %v", remid, node0.ID) return } phs, err := rlpx.doProtoHandshake(hs1) if err != nil { t.Errorf("listen side proto handshake error: %v", err) return } phs.Rest = nil if !reflect.DeepEqual(phs, hs0) { t.Errorf("listen side proto handshake mismatch:\ngot: %s\nwant: %s\n", spew.Sdump(phs), spew.Sdump(hs0)) return } if err := ExpectMsg(rlpx, discMsg, []DiscReason{DiscQuitting}); err != nil { t.Errorf("error receiving disconnect: %v", err) } }() wg.Wait() }
import ( "errors" "io/ioutil" "os" "reflect" "testing" "time" "github.com/expanse-project/go-expanse/crypto" "github.com/expanse-project/go-expanse/p2p" "github.com/expanse-project/go-expanse/rpc" ) var ( testNodeKey, _ = crypto.GenerateKey() ) func testNodeConfig() *Config { return &Config{ PrivateKey: testNodeKey, Name: "test node", } } // Tests that an empty protocol stack can be started, restarted and stopped. func TestNodeLifeCycle(t *testing.T) { stack, err := New(testNodeConfig()) if err != nil { t.Fatalf("failed to create protocol stack: %v", err) }
// Tests that transactions can be correctly sorted according to their price in // decreasing order, but at the same time with increasing nonces when issued by // the same account. func TestTransactionPriceNonceSort(t *testing.T) { // Generate a batch of accounts to start with keys := make([]*ecdsa.PrivateKey, 25) for i := 0; i < len(keys); i++ { keys[i], _ = crypto.GenerateKey() } // Generate a batch of transactions with overlapping values, but shifted nonces groups := map[common.Address]Transactions{} for start, key := range keys { addr := crypto.PubkeyToAddress(key.PublicKey) for i := 0; i < 25; i++ { tx, _ := NewTransaction(uint64(start+i), common.Address{}, big.NewInt(100), big.NewInt(100), big.NewInt(int64(start+i)), nil).SignECDSA(key) groups[addr] = append(groups[addr], tx) } } // Sort the transactions and cross check the nonce ordering txset := NewTransactionsByPriceAndNonce(groups) txs := Transactions{} for { if tx := txset.Peek(); tx != nil { txs = append(txs, tx) txset.Shift() } break } for i, txi := range txs { fromi, _ := txi.From() // Make sure the nonce order is valid for j, txj := range txs[i+1:] { fromj, _ := txj.From() if fromi == fromj && txi.Nonce() > txj.Nonce() { t.Errorf("invalid nonce ordering: tx #%d (A=%x N=%v) < tx #%d (A=%x N=%v)", i, fromi[:4], txi.Nonce(), i+j, fromj[:4], txj.Nonce()) } } // Find the previous and next nonce of this account prev, next := i-1, i+1 for j := i - 1; j >= 0; j-- { if fromj, _ := txs[j].From(); fromi == fromj { prev = j break } } for j := i + 1; j < len(txs); j++ { if fromj, _ := txs[j].From(); fromi == fromj { next = j break } } // Make sure that in between the neighbor nonces, the transaction is correctly positioned price wise for j := prev + 1; j < next; j++ { fromj, _ := txs[j].From() if j < i && txs[j].GasPrice().Cmp(txi.GasPrice()) < 0 { t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) < tx #%d (A=%x P=%v)", j, fromj[:4], txs[j].GasPrice(), i, fromi[:4], txi.GasPrice()) } if j > i && txs[j].GasPrice().Cmp(txi.GasPrice()) > 0 { t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) > tx #%d (A=%x P=%v)", j, fromj[:4], txs[j].GasPrice(), i, fromi[:4], txi.GasPrice()) } } } }