Coverage Summary for Class: RemascStorageProvider (co.rsk.remasc)

Class Class, % Method, % Line, %
RemascStorageProvider 0% (0/1) 0% (0/16) 0% (0/59)


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.remasc; 20  21 import co.rsk.core.Coin; 22 import co.rsk.core.RskAddress; 23 import org.ethereum.core.Repository; 24 import org.ethereum.util.RLP; 25 import org.ethereum.vm.DataWord; 26  27 /** 28  * Responsible for persisting the remasc state into the contract state 29  * @see co.rsk.peg.BridgeStorageProvider 30  * @author Oscar Guindzberg 31  */ 32 class RemascStorageProvider { 33  // Contract state keys used to store values 34  private static final String REWARD_BALANCE_KEY = "rewardBalance"; 35  private static final String BURNED_BALANCE_KEY = "burnedBalance"; 36  private static final String SIBLINGS_KEY = "siblings"; 37  private static final String BROKEN_SELECTION_RULE_KEY = "brokenSelectionRule"; 38  private static final String FEDERATION_BALANCE_KEY = "federationBalance"; 39  40  private Repository repository; 41  private RskAddress contractAddress; 42  43  // Values retrieved / to be stored on the contract state 44  private Coin rewardBalance; 45  private Coin burnedBalance; 46  private Coin federationBalance; 47  private Boolean brokenSelectionRule; 48  49  public RemascStorageProvider(Repository repository, RskAddress contractAddress) { 50  this.repository = repository; 51  this.contractAddress = contractAddress; 52  } 53  54  public Coin getFederationBalance() { 55  if (federationBalance != null) { 56  return federationBalance ; 57  } 58  59  DataWord address = DataWord.fromString(FEDERATION_BALANCE_KEY); 60  61  DataWord value = this.repository.getStorageValue(this.contractAddress, address); 62  63  if (value == null) { 64  return Coin.ZERO; 65  } 66  67  return new Coin(value.getData()); 68  } 69  70  71  public Coin getRewardBalance() { 72  if (rewardBalance != null) { 73  return rewardBalance; 74  } 75  76  DataWord address = DataWord.fromString(REWARD_BALANCE_KEY); 77  78  DataWord value = this.repository.getStorageValue(this.contractAddress, address); 79  80  if (value == null) { 81  return Coin.ZERO; 82  } 83  84  return new Coin(value.getData()); 85  } 86  87  88  public void setFederationBalance(Coin federationBalance) { 89  this.federationBalance = federationBalance; 90  } 91  92  private void saveFederationBalance() { 93  if (federationBalance == null) { 94  return; 95  } 96  97  DataWord address = DataWord.fromString(FEDERATION_BALANCE_KEY); 98  99  this.repository.addStorageRow(this.contractAddress, address, DataWord.valueOf(this.federationBalance.getBytes())); 100  } 101  102  public void setRewardBalance(Coin rewardBalance) { 103  this.rewardBalance = rewardBalance; 104  } 105  106  private void saveRewardBalance() { 107  if (rewardBalance == null) { 108  return; 109  } 110  111  DataWord address = DataWord.fromString(REWARD_BALANCE_KEY); 112  113  this.repository.addStorageRow(this.contractAddress, address, DataWord.valueOf(this.rewardBalance.getBytes())); 114  } 115  116  public Coin getBurnedBalance() { 117  if (burnedBalance != null) { 118  return burnedBalance; 119  } 120  121  DataWord address = DataWord.fromString(BURNED_BALANCE_KEY); 122  123  DataWord value = this.repository.getStorageValue(this.contractAddress, address); 124  125  if (value == null) { 126  return Coin.ZERO; 127  } 128  129  return new Coin(value.getData()); 130  } 131  132  public void setBurnedBalance(Coin burnedBalance) { 133  this.burnedBalance = burnedBalance; 134  } 135  136  public void addToBurnBalance(Coin amountToBurn) { 137  this.burnedBalance = this.getBurnedBalance().add(amountToBurn); 138  } 139  140  private void saveBurnedBalance() { 141  if (burnedBalance == null) { 142  return; 143  } 144  145  DataWord address = DataWord.fromString(BURNED_BALANCE_KEY); 146  147  this.repository.addStorageRow(this.contractAddress, address, DataWord.valueOf(this.burnedBalance.getBytes())); 148  } 149  150  private void saveSiblings() { 151  DataWord address = DataWord.fromString(SIBLINGS_KEY); 152  153  // we add an empty list because Remasc state expects to have an empty siblings list after 0.5.0 activation 154  this.repository.addStorageBytes(this.contractAddress, address, RLP.encodedEmptyList()); 155  } 156  157  public Boolean getBrokenSelectionRule() { 158  if (brokenSelectionRule!= null) { 159  return brokenSelectionRule; 160  } 161  162  DataWord address = DataWord.fromString(BROKEN_SELECTION_RULE_KEY); 163  164  byte[] bytes = this.repository.getStorageBytes(this.contractAddress, address); 165  166  if (bytes == null || bytes.length == 0) { 167  return Boolean.FALSE; 168  } 169  170  if (bytes[0] == 0) { 171  return Boolean.FALSE; 172  } else { 173  return Boolean.TRUE; 174  } 175  } 176  177  public void setBrokenSelectionRule(Boolean brokenSelectionRule) { 178  this.brokenSelectionRule = brokenSelectionRule; 179  } 180  181  private void saveBrokenSelectionRule() { 182  if (brokenSelectionRule == null) { 183  return; 184  } 185  186  DataWord address = DataWord.fromString(BROKEN_SELECTION_RULE_KEY); 187  188  byte[] bytes = new byte[1]; 189  190  bytes[0] = (byte)(this.brokenSelectionRule ? 1 : 0); 191  192  this.repository.addStorageBytes(this.contractAddress, address, bytes); 193  } 194  195  /* 196  * Persist all the contract data into the contract state 197  */ 198  public void save() { 199  saveRewardBalance(); 200  saveBurnedBalance(); 201  // This could be done only once because it will never change 202  saveSiblings(); 203  saveBrokenSelectionRule(); 204  saveFederationBalance(); 205  } 206 }