Coverage Summary for Class: LockWhitelist (co.rsk.peg.whitelist)
Class |
Class, %
|
Method, %
|
Line, %
|
LockWhitelist |
0%
(0/1)
|
0%
(0/19)
|
0%
(0/36)
|
1 /*
2 * This file is part of RskJ
3 * Copyright (C) 2017 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 co.rsk.peg.whitelist;
20
21 import co.rsk.bitcoinj.core.Address;
22 import co.rsk.bitcoinj.core.Coin;
23 import com.google.common.primitives.UnsignedBytes;
24
25 import java.util.*;
26 import java.util.stream.Collectors;
27
28 /**
29 * Represents a lock whitelist
30 * for btc lock transactions.
31 * It's basically a list of btc addresses
32 * with operations to manipulate and query it.
33 *
34 * @author Ariel Mendelzon
35 */
36 public class LockWhitelist {
37
38 private static final Comparator<Address> LEXICOGRAPHICAL_COMPARATOR
39 = Comparator.comparing(Address::getHash160, UnsignedBytes.lexicographicalComparator());
40
41 private SortedMap<Address, LockWhitelistEntry> whitelistedAddresses;
42 private int disableBlockHeight;
43
44 public LockWhitelist(Map<Address, LockWhitelistEntry> whitelistedAddresses) {
45 this(whitelistedAddresses, Integer.MAX_VALUE);
46 }
47
48 public LockWhitelist(Map<Address, LockWhitelistEntry> whitelistedAddresses, int disableBlockHeight) {
49 // Save a copy so that this can't be modified from the outside
50 SortedMap<Address, LockWhitelistEntry> sortedWhitelistedAddresses = new TreeMap<>(LEXICOGRAPHICAL_COMPARATOR);
51 sortedWhitelistedAddresses.putAll(whitelistedAddresses);
52 this.whitelistedAddresses = sortedWhitelistedAddresses;
53 this.disableBlockHeight = disableBlockHeight;
54 }
55
56 public boolean isWhitelisted(Address address) {
57 return whitelistedAddresses.containsKey(address);
58 }
59
60 public boolean isWhitelisted(byte[] address) {
61 return whitelistedAddresses.keySet().stream()
62 .map(Address::getHash160)
63 .anyMatch(hash -> Arrays.equals(hash, address));
64 }
65
66 public boolean isWhitelistedFor(Address address, Coin amount, int height) {
67 if (height > disableBlockHeight) {
68 // Whitelist disabled
69 return true;
70 }
71
72 LockWhitelistEntry entry = this.whitelistedAddresses.get(address);
73 return (entry != null && entry.canLock(amount));
74 }
75
76 public Integer getSize() {
77 return whitelistedAddresses.size();
78 }
79
80 public List<Address> getAddresses() {
81 // Return a copy so that this can't be modified from the outside
82 return new ArrayList<>(whitelistedAddresses.keySet());
83 }
84
85 public <T extends LockWhitelistEntry> List<T> getAll(Class<T> type) {
86 return whitelistedAddresses.values().stream()
87 .filter(e -> e.getClass() == type)
88 .map(type::cast)
89 .collect(Collectors.toList());
90 }
91
92 public List<LockWhitelistEntry> getAll() {
93 // Return a copy so that this can't be modified from the outside
94 return new ArrayList<>(whitelistedAddresses.values());
95 }
96
97 public LockWhitelistEntry get(Address address) {
98 return this.whitelistedAddresses.get(address);
99 }
100
101 public boolean put(Address address, LockWhitelistEntry entry) {
102 if (whitelistedAddresses.containsKey(address)) {
103 return false;
104 }
105
106 whitelistedAddresses.put(address, entry);
107 return true;
108 }
109
110 public boolean remove(Address address) {
111 return whitelistedAddresses.remove(address) != null;
112 }
113
114 /**
115 * Marks the whitelisted address as consumed. This will reduce the number of usages, and if it gets down to zero remaining usages it will remove the address
116 * @param address
117 */
118 public void consume(Address address) {
119 LockWhitelistEntry entry = whitelistedAddresses.get(address);
120 if (entry == null) {
121 return;
122 }
123 entry.consume();
124
125 if (entry.isConsumed()) {
126 this.remove(address);
127 }
128 }
129
130 public int getDisableBlockHeight() {
131 return disableBlockHeight;
132 }
133
134 public void setDisableBlockHeight(int disableBlockHeight) {
135 this.disableBlockHeight = disableBlockHeight;
136 }
137
138 public boolean isDisableBlockSet() {
139 return disableBlockHeight < Integer.MAX_VALUE;
140 }
141 }