/*
* Copyright (c) [2016] [ <ether.camp> ]
* This file is part of the ethereumJ library.
*
* The ethereumJ library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The ethereumJ library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the ethereumJ library. If not, see <http://www.gnu.org/licenses/>.
*/
package org.ethereum.db;
import org.ethereum.core.Genesis;
import org.ethereum.crypto.HashUtil;
import org.ethereum.core.Repository;
import org.ethereum.datasource.inmem.HashMapDB;
import org.ethereum.datasource.NoDeleteSource;
import org.ethereum.datasource.Source;
import org.ethereum.vm.DataWord;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.spongycastle.util.encoders.Hex;
import java.math.BigInteger;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY;
import static org.junit.Assert.*;
/**
* @author Roman Mandeleil
* @since 17.11.2014
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class RepositoryTest {
@Test
public void test1() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
repository.increaseNonce(cow);
repository.increaseNonce(horse);
assertEquals(BigInteger.ONE, repository.getNonce(cow));
// assertEquals(BigInteger.ONE, repository.getNonce(horse));
System.out.println(repository.getTrieDump());
repository.increaseNonce(cow);
System.out.println(repository.getTrieDump());
repository.close();
}
@Test
public void test2() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
repository.addBalance(cow, BigInteger.TEN);
repository.addBalance(horse, BigInteger.ONE);
assertEquals(BigInteger.TEN, repository.getBalance(cow));
assertEquals(BigInteger.ONE, repository.getBalance(horse));
repository.close();
}
@Test
public void test3() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
byte[] cowCode = Hex.decode("A1A2A3");
byte[] horseCode = Hex.decode("B1B2B3");
repository.saveCode(cow, cowCode);
repository.saveCode(horse, horseCode);
assertArrayEquals(cowCode, repository.getCode(cow));
assertArrayEquals(horseCode, repository.getCode(horse));
repository.close();
}
@Test
public void test4() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track = repository.startTracking();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
byte[] cowKey = Hex.decode("A1A2A3");
byte[] cowValue = Hex.decode("A4A5A6");
byte[] horseKey = Hex.decode("B1B2B3");
byte[] horseValue = Hex.decode("B4B5B6");
track.addStorageRow(cow, new DataWord(cowKey), new DataWord(cowValue));
track.addStorageRow(horse, new DataWord(horseKey), new DataWord(horseValue));
track.commit();
assertEquals(new DataWord(cowValue), repository.getStorageValue(cow, new DataWord(cowKey)));
assertEquals(new DataWord(horseValue), repository.getStorageValue(horse, new DataWord(horseKey)));
repository.close();
}
@Test
public void test5() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track = repository.startTracking();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(horse);
track.commit();
assertEquals(BigInteger.TEN, repository.getNonce(cow));
assertEquals(BigInteger.ONE, repository.getNonce(horse));
repository.close();
}
@Test
public void test6() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track = repository.startTracking();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(cow);
track.increaseNonce(horse);
assertEquals(BigInteger.TEN, track.getNonce(cow));
assertEquals(BigInteger.ONE, track.getNonce(horse));
track.rollback();
assertEquals(BigInteger.ZERO, repository.getNonce(cow));
assertEquals(BigInteger.ZERO, repository.getNonce(horse));
repository.close();
}
@Test
public void test7() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track = repository.startTracking();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
track.addBalance(cow, BigInteger.TEN);
track.addBalance(horse, BigInteger.ONE);
assertEquals(BigInteger.TEN, track.getBalance(cow));
assertEquals(BigInteger.ONE, track.getBalance(horse));
track.commit();
assertEquals(BigInteger.TEN, repository.getBalance(cow));
assertEquals(BigInteger.ONE, repository.getBalance(horse));
repository.close();
}
@Test
public void test8() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track = repository.startTracking();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
track.addBalance(cow, BigInteger.TEN);
track.addBalance(horse, BigInteger.ONE);
assertEquals(BigInteger.TEN, track.getBalance(cow));
assertEquals(BigInteger.ONE, track.getBalance(horse));
track.rollback();
assertEquals(BigInteger.ZERO, repository.getBalance(cow));
assertEquals(BigInteger.ZERO, repository.getBalance(horse));
repository.close();
}
@Test
public void test7_1() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track1 = repository.startTracking();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
track1.addBalance(cow, BigInteger.TEN);
track1.addBalance(horse, BigInteger.ONE);
assertEquals(BigInteger.TEN, track1.getBalance(cow));
assertEquals(BigInteger.ONE, track1.getBalance(horse));
Repository track2 = track1.startTracking();
assertEquals(BigInteger.TEN, track2.getBalance(cow));
assertEquals(BigInteger.ONE, track2.getBalance(horse));
track2.addBalance(cow, BigInteger.TEN);
track2.addBalance(cow, BigInteger.TEN);
track2.addBalance(cow, BigInteger.TEN);
track2.commit();
track1.commit();
assertEquals(new BigInteger("40"), repository.getBalance(cow));
assertEquals(BigInteger.ONE, repository.getBalance(horse));
repository.close();
}
@Test
public void test7_2() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track1 = repository.startTracking();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
track1.addBalance(cow, BigInteger.TEN);
track1.addBalance(horse, BigInteger.ONE);
assertEquals(BigInteger.TEN, track1.getBalance(cow));
assertEquals(BigInteger.ONE, track1.getBalance(horse));
Repository track2 = track1.startTracking();
assertEquals(BigInteger.TEN, track2.getBalance(cow));
assertEquals(BigInteger.ONE, track2.getBalance(horse));
track2.addBalance(cow, BigInteger.TEN);
track2.addBalance(cow, BigInteger.TEN);
track2.addBalance(cow, BigInteger.TEN);
track2.commit();
track1.rollback();
assertEquals(BigInteger.ZERO, repository.getBalance(cow));
assertEquals(BigInteger.ZERO, repository.getBalance(horse));
repository.close();
}
@Test
public void test9() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track = repository.startTracking();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
DataWord cowKey = new DataWord(Hex.decode("A1A2A3"));
DataWord cowValue = new DataWord(Hex.decode("A4A5A6"));
DataWord horseKey = new DataWord(Hex.decode("B1B2B3"));
DataWord horseValue = new DataWord(Hex.decode("B4B5B6"));
track.addStorageRow(cow, cowKey, cowValue);
track.addStorageRow(horse, horseKey, horseValue);
assertEquals(cowValue, track.getStorageValue(cow, cowKey));
assertEquals(horseValue, track.getStorageValue(horse, horseKey));
track.commit();
assertEquals(cowValue, repository.getStorageValue(cow, cowKey));
assertEquals(horseValue, repository.getStorageValue(horse, horseKey));
repository.close();
}
@Test
public void test10() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track = repository.startTracking();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
DataWord cowKey = new DataWord(Hex.decode("A1A2A3"));
DataWord cowValue = new DataWord(Hex.decode("A4A5A6"));
DataWord horseKey = new DataWord(Hex.decode("B1B2B3"));
DataWord horseValue = new DataWord(Hex.decode("B4B5B6"));
track.addStorageRow(cow, cowKey, cowValue);
track.addStorageRow(horse, horseKey, horseValue);
assertEquals(cowValue, track.getStorageValue(cow, cowKey));
assertEquals(horseValue, track.getStorageValue(horse, horseKey));
track.rollback();
assertEquals(null, repository.getStorageValue(cow, cowKey));
assertEquals(null, repository.getStorageValue(horse, horseKey));
repository.close();
}
@Test
public void test11() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track = repository.startTracking();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
byte[] cowCode = Hex.decode("A1A2A3");
byte[] horseCode = Hex.decode("B1B2B3");
track.saveCode(cow, cowCode);
track.saveCode(horse, horseCode);
assertArrayEquals(cowCode, track.getCode(cow));
assertArrayEquals(horseCode, track.getCode(horse));
track.commit();
assertArrayEquals(cowCode, repository.getCode(cow));
assertArrayEquals(horseCode, repository.getCode(horse));
repository.close();
}
@Test
public void test12() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track = repository.startTracking();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
byte[] cowCode = Hex.decode("A1A2A3");
byte[] horseCode = Hex.decode("B1B2B3");
track.saveCode(cow, cowCode);
track.saveCode(horse, horseCode);
assertArrayEquals(cowCode, track.getCode(cow));
assertArrayEquals(horseCode, track.getCode(horse));
track.rollback();
assertArrayEquals(EMPTY_BYTE_ARRAY, repository.getCode(cow));
assertArrayEquals(EMPTY_BYTE_ARRAY, repository.getCode(horse));
repository.close();
}
@Test // Let's upload genesis pre-mine just like in the real world
public void test13() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track = repository.startTracking();
Genesis genesis = (Genesis)Genesis.getInstance();
Genesis.populateRepository(track, genesis);
track.commit();
assertArrayEquals(Genesis.getInstance().getStateRoot(), repository.getRoot());
repository.close();
}
@Test
public void test14() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
final BigInteger ELEVEN = BigInteger.TEN.add(BigInteger.ONE);
// changes level_1
Repository track1 = repository.startTracking();
track1.addBalance(cow, BigInteger.TEN);
track1.addBalance(horse, BigInteger.ONE);
assertEquals(BigInteger.TEN, track1.getBalance(cow));
assertEquals(BigInteger.ONE, track1.getBalance(horse));
// changes level_2
Repository track2 = track1.startTracking();
track2.addBalance(cow, BigInteger.ONE);
track2.addBalance(horse, BigInteger.TEN);
assertEquals(ELEVEN, track2.getBalance(cow));
assertEquals(ELEVEN, track2.getBalance(horse));
track2.commit();
track1.commit();
assertEquals(ELEVEN, repository.getBalance(cow));
assertEquals(ELEVEN, repository.getBalance(horse));
repository.close();
}
@Test
public void test15() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
final BigInteger ELEVEN = BigInteger.TEN.add(BigInteger.ONE);
// changes level_1
Repository track1 = repository.startTracking();
track1.addBalance(cow, BigInteger.TEN);
track1.addBalance(horse, BigInteger.ONE);
assertEquals(BigInteger.TEN, track1.getBalance(cow));
assertEquals(BigInteger.ONE, track1.getBalance(horse));
// changes level_2
Repository track2 = track1.startTracking();
track2.addBalance(cow, BigInteger.ONE);
track2.addBalance(horse, BigInteger.TEN);
assertEquals(ELEVEN, track2.getBalance(cow));
assertEquals(ELEVEN, track2.getBalance(horse));
track2.rollback();
track1.commit();
assertEquals(BigInteger.TEN, repository.getBalance(cow));
assertEquals(BigInteger.ONE, repository.getBalance(horse));
repository.close();
}
@Test
public void test16() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
byte[] cowKey1 = "key-c-1".getBytes();
byte[] cowValue1 = "val-c-1".getBytes();
byte[] horseKey1 = "key-h-1".getBytes();
byte[] horseValue1 = "val-h-1".getBytes();
byte[] cowKey2 = "key-c-2".getBytes();
byte[] cowValue2 = "val-c-2".getBytes();
byte[] horseKey2 = "key-h-2".getBytes();
byte[] horseValue2 = "val-h-2".getBytes();
// changes level_1
Repository track1 = repository.startTracking();
track1.addStorageRow(cow, new DataWord(cowKey1), new DataWord(cowValue1));
track1.addStorageRow(horse, new DataWord(horseKey1), new DataWord(horseValue1));
assertEquals(new DataWord(cowValue1), track1.getStorageValue(cow, new DataWord(cowKey1)));
assertEquals(new DataWord(horseValue1), track1.getStorageValue(horse, new DataWord(horseKey1)));
// changes level_2
Repository track2 = track1.startTracking();
track2.addStorageRow(cow, new DataWord(cowKey2), new DataWord(cowValue2));
track2.addStorageRow(horse, new DataWord(horseKey2), new DataWord(horseValue2));
assertEquals(new DataWord(cowValue1), track2.getStorageValue(cow, new DataWord(cowKey1)));
assertEquals(new DataWord(horseValue1), track2.getStorageValue(horse, new DataWord(horseKey1)));
assertEquals(new DataWord(cowValue2), track2.getStorageValue(cow, new DataWord(cowKey2)));
assertEquals(new DataWord(horseValue2), track2.getStorageValue(horse, new DataWord(horseKey2)));
track2.commit();
// leaving level_2
assertEquals(new DataWord(cowValue1), track1.getStorageValue(cow, new DataWord(cowKey1)));
assertEquals(new DataWord(horseValue1), track1.getStorageValue(horse, new DataWord(horseKey1)));
assertEquals(new DataWord(cowValue2), track1.getStorageValue(cow, new DataWord(cowKey2)));
assertEquals(new DataWord(horseValue2), track1.getStorageValue(horse, new DataWord(horseKey2)));
track1.commit();
// leaving level_1
assertEquals(new DataWord(cowValue1), repository.getStorageValue(cow, new DataWord(cowKey1)));
assertEquals(new DataWord(horseValue1), repository.getStorageValue(horse, new DataWord(horseKey1)));
assertEquals(new DataWord(cowValue2), repository.getStorageValue(cow, new DataWord(cowKey2)));
assertEquals(new DataWord(horseValue2), repository.getStorageValue(horse, new DataWord(horseKey2)));
repository.close();
}
@Test
public void test16_2() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
byte[] cowKey1 = "key-c-1".getBytes();
byte[] cowValue1 = "val-c-1".getBytes();
byte[] horseKey1 = "key-h-1".getBytes();
byte[] horseValue1 = "val-h-1".getBytes();
byte[] cowKey2 = "key-c-2".getBytes();
byte[] cowValue2 = "val-c-2".getBytes();
byte[] horseKey2 = "key-h-2".getBytes();
byte[] horseValue2 = "val-h-2".getBytes();
// changes level_1
Repository track1 = repository.startTracking();
// changes level_2
Repository track2 = track1.startTracking();
track2.addStorageRow(cow, new DataWord(cowKey2), new DataWord(cowValue2));
track2.addStorageRow(horse, new DataWord(horseKey2), new DataWord(horseValue2));
assertNull(track2.getStorageValue(cow, new DataWord(cowKey1)));
assertNull(track2.getStorageValue(horse, new DataWord(horseKey1)));
assertEquals(new DataWord(cowValue2), track2.getStorageValue(cow, new DataWord(cowKey2)));
assertEquals(new DataWord(horseValue2), track2.getStorageValue(horse, new DataWord(horseKey2)));
track2.commit();
// leaving level_2
assertNull(track1.getStorageValue(cow, new DataWord(cowKey1)));
assertNull(track1.getStorageValue(horse, new DataWord(horseKey1)));
assertEquals(new DataWord(cowValue2), track1.getStorageValue(cow, new DataWord(cowKey2)));
assertEquals(new DataWord(horseValue2), track1.getStorageValue(horse, new DataWord(horseKey2)));
track1.commit();
// leaving level_1
assertEquals(null, repository.getStorageValue(cow, new DataWord(cowKey1)));
assertEquals(null, repository.getStorageValue(horse, new DataWord(horseKey1)));
assertEquals(new DataWord(cowValue2), repository.getStorageValue(cow, new DataWord(cowKey2)));
assertEquals(new DataWord(horseValue2), repository.getStorageValue(horse, new DataWord(horseKey2)));
repository.close();
}
@Test
public void test16_3() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
byte[] cowKey1 = "key-c-1".getBytes();
byte[] cowValue1 = "val-c-1".getBytes();
byte[] horseKey1 = "key-h-1".getBytes();
byte[] horseValue1 = "val-h-1".getBytes();
byte[] cowKey2 = "key-c-2".getBytes();
byte[] cowValue2 = "val-c-2".getBytes();
byte[] horseKey2 = "key-h-2".getBytes();
byte[] horseValue2 = "val-h-2".getBytes();
// changes level_1
Repository track1 = repository.startTracking();
// changes level_2
Repository track2 = track1.startTracking();
track2.addStorageRow(cow, new DataWord(cowKey2), new DataWord(cowValue2));
track2.addStorageRow(horse, new DataWord(horseKey2), new DataWord(horseValue2));
assertNull(track2.getStorageValue(cow, new DataWord(cowKey1)));
assertNull(track2.getStorageValue(horse, new DataWord(horseKey1)));
assertEquals(new DataWord(cowValue2), track2.getStorageValue(cow, new DataWord(cowKey2)));
assertEquals(new DataWord(horseValue2), track2.getStorageValue(horse, new DataWord(horseKey2)));
track2.commit();
// leaving level_2
assertNull(track1.getStorageValue(cow, new DataWord(cowKey1)));
assertNull(track1.getStorageValue(horse, new DataWord(horseKey1)));
assertEquals(new DataWord(cowValue2), track1.getStorageValue(cow, new DataWord(cowKey2)));
assertEquals(new DataWord(horseValue2), track1.getStorageValue(horse, new DataWord(horseKey2)));
track1.rollback();
// leaving level_1
assertNull(repository.getStorageValue(cow, new DataWord(cowKey1)));
assertNull(repository.getStorageValue(horse, new DataWord(horseKey1)));
assertNull(repository.getStorageValue(cow, new DataWord(cowKey2)));
assertNull(repository.getStorageValue(horse, new DataWord(horseKey2)));
repository.close();
}
@Test
public void test16_4() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
byte[] cowKey1 = "key-c-1".getBytes();
byte[] cowValue1 = "val-c-1".getBytes();
byte[] horseKey1 = "key-h-1".getBytes();
byte[] horseValue1 = "val-h-1".getBytes();
byte[] cowKey2 = "key-c-2".getBytes();
byte[] cowValue2 = "val-c-2".getBytes();
byte[] horseKey2 = "key-h-2".getBytes();
byte[] horseValue2 = "val-h-2".getBytes();
Repository track = repository.startTracking();
track.addStorageRow(cow, new DataWord(cowKey1), new DataWord(cowValue1));
track.commit();
// changes level_1
Repository track1 = repository.startTracking();
// changes level_2
Repository track2 = track1.startTracking();
track2.addStorageRow(cow, new DataWord(cowKey2), new DataWord(cowValue2));
track2.commit();
// leaving level_2
track1.commit();
// leaving level_1
assertEquals(new DataWord(cowValue1), track1.getStorageValue(cow, new DataWord(cowKey1)));
assertEquals(new DataWord(cowValue2), track1.getStorageValue(cow, new DataWord(cowKey2)));
repository.close();
}
@Test
public void test16_5() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
byte[] cowKey1 = "key-c-1".getBytes();
byte[] cowValue1 = "val-c-1".getBytes();
byte[] horseKey1 = "key-h-1".getBytes();
byte[] horseValue1 = "val-h-1".getBytes();
byte[] cowKey2 = "key-c-2".getBytes();
byte[] cowValue2 = "val-c-2".getBytes();
byte[] horseKey2 = "key-h-2".getBytes();
byte[] horseValue2 = "val-h-2".getBytes();
// changes level_1
Repository track1 = repository.startTracking();
track1.addStorageRow(cow, new DataWord(cowKey2), new DataWord(cowValue2));
// changes level_2
Repository track2 = track1.startTracking();
assertEquals(new DataWord(cowValue2), track1.getStorageValue(cow, new DataWord(cowKey2)));
assertNull(track1.getStorageValue(cow, new DataWord(cowKey1)));
track2.commit();
// leaving level_2
track1.commit();
// leaving level_1
assertEquals(new DataWord(cowValue2), track1.getStorageValue(cow, new DataWord(cowKey2)));
assertNull(track1.getStorageValue(cow, new DataWord(cowKey1)));
repository.close();
}
@Test
public void test17() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] cowKey1 = "key-c-1".getBytes();
byte[] cowValue1 = "val-c-1".getBytes();
// changes level_1
Repository track1 = repository.startTracking();
// changes level_2
Repository track2 = track1.startTracking();
track2.addStorageRow(cow, new DataWord(cowKey1), new DataWord(cowValue1));
assertEquals(new DataWord(cowValue1), track2.getStorageValue(cow, new DataWord(cowKey1)));
track2.rollback();
// leaving level_2
track1.commit();
// leaving level_1
Assert.assertEquals(Hex.toHexString(HashUtil.EMPTY_TRIE_HASH), Hex.toHexString(repository.getRoot()));
repository.close();
}
@Test
public void test18() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository repoTrack2 = repository.startTracking(); //track
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
byte[] pig = Hex.decode("F0B8C9D84DD2B877E0B952130B73E218106FEC04");
byte[] precompiled = Hex.decode("0000000000000000000000000000000000000002");
byte[] cowCode = Hex.decode("A1A2A3");
byte[] horseCode = Hex.decode("B1B2B3");
repository.saveCode(cow, cowCode);
repository.saveCode(horse, horseCode);
repository.delete(horse);
assertEquals(true, repoTrack2.isExist(cow));
assertEquals(false, repoTrack2.isExist(horse));
assertEquals(false, repoTrack2.isExist(pig));
assertEquals(false, repoTrack2.isExist(precompiled));
}
@Test
public void test19() {
RepositoryRoot repository = new RepositoryRoot(new HashMapDB());
Repository track = repository.startTracking();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
DataWord cowKey1 = new DataWord("c1");
DataWord cowVal1 = new DataWord("c0a1");
DataWord cowVal0 = new DataWord("c0a0");
DataWord horseKey1 = new DataWord("e1");
DataWord horseVal1 = new DataWord("c0a1");
DataWord horseVal0 = new DataWord("c0a0");
track.addStorageRow(cow, cowKey1, cowVal0);
track.addStorageRow(horse, horseKey1, horseVal0);
track.commit();
Repository track2 = repository.startTracking(); //track
track2.addStorageRow(horse, horseKey1, horseVal0);
Repository track3 = track2.startTracking();
ContractDetails cowDetails = track3.getContractDetails(cow);
cowDetails.put(cowKey1, cowVal1);
ContractDetails horseDetails = track3.getContractDetails(horse);
horseDetails.put(horseKey1, horseVal1);
track3.commit();
track2.rollback();
ContractDetails cowDetailsOrigin = repository.getContractDetails(cow);
DataWord cowValOrin = cowDetailsOrigin.get(cowKey1);
ContractDetails horseDetailsOrigin = repository.getContractDetails(horse);
DataWord horseValOrin = horseDetailsOrigin.get(horseKey1);
assertEquals(cowVal0, cowValOrin);
assertEquals(horseVal0, horseValOrin);
}
@Test // testing for snapshot
public void test20() {
// MapDB stateDB = new MapDB();
Source<byte[], byte[]> stateDB = new NoDeleteSource<>(new HashMapDB<byte[]>());
RepositoryRoot repository = new RepositoryRoot(stateDB);
byte[] root = repository.getRoot();
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
DataWord cowKey1 = new DataWord("c1");
DataWord cowKey2 = new DataWord("c2");
DataWord cowVal1 = new DataWord("c0a1");
DataWord cowVal0 = new DataWord("c0a0");
DataWord horseKey1 = new DataWord("e1");
DataWord horseKey2 = new DataWord("e2");
DataWord horseVal1 = new DataWord("c0a1");
DataWord horseVal0 = new DataWord("c0a0");
Repository track2 = repository.startTracking(); //track
track2.addStorageRow(cow, cowKey1, cowVal1);
track2.addStorageRow(horse, horseKey1, horseVal1);
track2.commit();
repository.commit();
byte[] root2 = repository.getRoot();
track2 = repository.startTracking(); //track
track2.addStorageRow(cow, cowKey2, cowVal0);
track2.addStorageRow(horse, horseKey2, horseVal0);
track2.commit();
repository.commit();
byte[] root3 = repository.getRoot();
Repository snapshot = new RepositoryRoot(stateDB, root);
ContractDetails cowDetails = snapshot.getContractDetails(cow);
ContractDetails horseDetails = snapshot.getContractDetails(horse);
assertEquals(null, cowDetails.get(cowKey1) );
assertEquals(null, cowDetails.get(cowKey2) );
assertEquals(null, horseDetails.get(horseKey1) );
assertEquals(null, horseDetails.get(horseKey2) );
snapshot = new RepositoryRoot(stateDB, root2);
cowDetails = snapshot.getContractDetails(cow);
horseDetails = snapshot.getContractDetails(horse);
assertEquals(cowVal1, cowDetails.get(cowKey1));
assertEquals(null, cowDetails.get(cowKey2));
assertEquals(horseVal1, horseDetails.get(horseKey1) );
assertEquals(null, horseDetails.get(horseKey2) );
snapshot = new RepositoryRoot(stateDB, root3);
cowDetails = snapshot.getContractDetails(cow);
horseDetails = snapshot.getContractDetails(horse);
assertEquals(cowVal1, cowDetails.get(cowKey1));
assertEquals(cowVal0, cowDetails.get(cowKey2));
assertEquals(horseVal1, horseDetails.get(horseKey1) );
assertEquals(horseVal0, horseDetails.get(horseKey2) );
}
private boolean running = true;
@Test // testing for snapshot
public void testMultiThread() throws InterruptedException {
// Add logging line to {@link org.ethereum.datasource.WriteCache} in the beginning of flushImpl() method:
// System.out.printf("Flush start: %s%n", this);
// to increase chance of failing. Also increasing waiting time may be helpful.
final RepositoryImpl repository = new RepositoryRoot(new HashMapDB());
final byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
final DataWord cowKey1 = new DataWord("c1");
final DataWord cowKey2 = new DataWord("c2");
final DataWord cowVal0 = new DataWord("c0a0");
Repository track2 = repository.startTracking(); //track
track2.addStorageRow(cow, cowKey2, cowVal0);
track2.commit();
repository.flush();
ContractDetails cowDetails = repository.getContractDetails(cow);
assertEquals(cowVal0, cowDetails.get(cowKey2));
final CountDownLatch failSema = new CountDownLatch(1);
for (int i = 0; i < 10; ++i) {
new Thread(new Runnable() {
@Override
public void run() {
try {
int cnt = 1;
while (running) {
Repository snap = repository.getSnapshotTo(repository.getRoot()).startTracking();
snap.addBalance(cow, BigInteger.TEN);
snap.addStorageRow(cow, cowKey1, new DataWord(cnt));
snap.rollback();
cnt++;
}
} catch (Throwable e) {
e.printStackTrace();
failSema.countDown();
}
}
}).start();
}
new Thread(new Runnable() {
@Override
public void run() {
int cnt = 1;
try {
while(running) {
Repository track2 = repository.startTracking(); //track
DataWord cVal = new DataWord(cnt);
track2.addStorageRow(cow, cowKey1, cVal);
track2.addBalance(cow, BigInteger.ONE);
track2.commit();
repository.flush();
assertEquals(BigInteger.valueOf(cnt), repository.getBalance(cow));
assertEquals(cVal, repository.getStorageValue(cow, cowKey1));
assertEquals(cowVal0, repository.getStorageValue(cow, cowKey2));
cnt++;
}
} catch (Throwable e) {
e.printStackTrace();
try {
repository.addStorageRow(cow, cowKey1, new DataWord(123));
} catch (Exception e1) {
e1.printStackTrace();
}
failSema.countDown();
}
}
}).start();
failSema.await(10, TimeUnit.SECONDS);
running = false;
if (failSema.getCount() == 0) {
throw new RuntimeException("Test failed.");
}
}
}