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 }