Coverage Summary for Class: TransactionSet (org.ethereum.core)
Class |
Class, %
|
Method, %
|
Line, %
|
TransactionSet |
100%
(1/1)
|
100%
(8/8)
|
61.4%
(27/44)
|
1 /*
2 * This file is part of RskJ
3 * Copyright (C) 2018 RSK Labs Ltd.
4 *
5 * This program 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 * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 package org.ethereum.core;
20
21 import co.rsk.core.RskAddress;
22 import co.rsk.crypto.Keccak256;
23
24 import java.util.*;
25 import java.util.stream.Collectors;
26
27 public class TransactionSet {
28 private final Map<Keccak256, Transaction> transactionsByHash;
29 private final Map<RskAddress, List<Transaction>> transactionsByAddress;
30
31 public TransactionSet() {
32 this(new HashMap<>(), new HashMap<>());
33 }
34
35 public TransactionSet(TransactionSet transactionSet) {
36 this(new HashMap<>(transactionSet.transactionsByHash), new HashMap<>(transactionSet.transactionsByAddress));
37 }
38
39 public TransactionSet(Map<Keccak256, Transaction> transactionsByHash, Map<RskAddress, List<Transaction>> transactionsByAddress) {
40 this.transactionsByHash = transactionsByHash;
41 this.transactionsByAddress = transactionsByAddress;
42 }
43
44 public void addTransaction(Transaction transaction) {
45 Keccak256 txhash = transaction.getHash();
46
47 if (this.transactionsByHash.containsKey(txhash)) {
48 return;
49 }
50
51 this.transactionsByHash.put(txhash, transaction);
52
53 RskAddress senderAddress = transaction.getSender();
54
55 List<Transaction> txs = this.transactionsByAddress.get(senderAddress);
56
57 if (txs == null) {
58 txs = new ArrayList<>();
59 this.transactionsByAddress.put(senderAddress, txs);
60 } else {
61 Optional<Transaction> optTxToRemove = txs.stream()
62 .filter(tx -> tx.getNonceAsInteger().equals(transaction.getNonceAsInteger()))
63 .findFirst();
64
65 if (optTxToRemove.isPresent()) {
66 Transaction txToRemove = optTxToRemove.get();
67 txs.remove(txToRemove);
68 this.transactionsByHash.remove(txToRemove.getHash());
69 }
70 }
71
72 txs.add(transaction);
73 }
74
75 public boolean hasTransaction(Transaction transaction) {
76 return this.transactionsByHash.containsKey(transaction.getHash());
77 }
78
79 public void removeTransactionByHash(Keccak256 hash) {
80 Transaction transaction = this.transactionsByHash.get(hash);
81
82 if (transaction == null) {
83 return;
84 }
85
86 this.transactionsByHash.remove(hash);
87
88 RskAddress senderAddress = transaction.getSender();
89 List<Transaction> txs = this.transactionsByAddress.get(senderAddress);
90
91 if (txs != null) {
92 txs.remove(transaction);
93
94 if (txs.isEmpty()) {
95 this.transactionsByAddress.remove(senderAddress);
96 }
97 }
98 }
99
100 public List<Transaction> getTransactions() {
101 return transactionsByHash.values().stream()
102 .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
103 }
104
105 public List<Transaction> getTransactionsWithSender(RskAddress senderAddress) {
106 List<Transaction> list = this.transactionsByAddress.get(senderAddress);
107
108 if (list == null) {
109 return Collections.emptyList();
110 }
111
112 return list;
113 }
114 }