1
using System.Collections.Generic;
2
using System.Collections.Immutable;
3
using System.Linq;
4
using System.Security.Cryptography;
5
using Bencodex.Types;
6
using Libplanet.Store;
7
using Libplanet.Store.Trie;
8
using Xunit;
9

10
namespace Libplanet.Tests.Store
11
{
12
    public class TrieStateStoreTest
13
    {
14
        private readonly IKeyValueStore _stateKeyValueStore;
15
        private readonly IKeyValueStore _stateHashKeyValueStore;
16

17
        private readonly IImmutableDictionary<string, IValue> _prestoredValues;
18

19
        private readonly DefaultStoreFixture _fx;
20

21 1
        public TrieStateStoreTest()
22 1
        {
23 1
            _fx = new DefaultStoreFixture();
24

25 1
            _stateKeyValueStore = new DefaultKeyValueStore(null);
26 1
            _stateHashKeyValueStore = new DefaultKeyValueStore(null);
27

28 1
            _prestoredValues = ImmutableDictionary<string, IValue>.Empty
29 1
                .Add("foo", (Binary)TestUtils.GetRandomBytes(32))
30 1
                .Add("bar", (Text)ByteUtil.Hex(TestUtils.GetRandomBytes(32)))
31 1
                .Add("baz", (Bencodex.Types.Boolean)false)
32 1
                .Add("qux", Bencodex.Types.Dictionary.Empty);
33 1
        }
34

35
        [Theory]
36
        [InlineData(true)]
37
        [InlineData(false)]
38
        public void SetStates(bool secure)
39 1
        {
40 1
            var stateStore = MakeTrieStateStoreFixture(secure);
41
            // Check to set and to get.
42 1
            Assert.Throws<KeyNotFoundException>(() => stateStore.GetRootHash(_fx.Block1.Hash));
43 1
            Assert.False(stateStore.ContainsBlockStates(_fx.Block1.Hash));
44 1
            var states = ImmutableDictionary<string, IValue>.Empty
45 1
                .Add("foo", (Text)"value");
46 1
            stateStore.SetStates(_fx.Block1, states);
47 1
            Assert.Equal((Text)"value", stateStore.GetState("foo", _fx.Block1.Hash));
48 1
            Assert.IsType<HashDigest<SHA256>>(stateStore.GetRootHash(_fx.Block1.Hash));
49 1
            Assert.True(stateStore.ContainsBlockStates(_fx.Block1.Hash));
50

51 1
            stateStore.SetStates(_fx.Block2, _prestoredValues);
52

53
            // Check same states have same state hash.
54 1
            Assert.NotEqual(
55 1
                stateStore.GetRootHash(_fx.GenesisBlock.Hash),
56 1
                stateStore.GetRootHash(_fx.Block1.Hash));
57 1
            Assert.Equal(
58 1
                stateStore.GetRootHash(_fx.GenesisBlock.Hash),
59 1
                stateStore.GetRootHash(_fx.Block2.Hash));
60 1
        }
61

62
        [Theory]
63
        [InlineData(true)]
64
        [InlineData(false)]
65
        public void GetState(bool secure)
66 1
        {
67 1
            var stateStore = MakeTrieStateStoreFixture(secure);
68 1
            foreach (var pair in _prestoredValues)
69 1
            {
70 1
                Assert.Equal(
71 1
                    pair.Value,
72 1
                    stateStore.GetState(pair.Key, _fx.GenesisBlock.Hash));
73 1
            }
74 1
        }
75

76
        [Theory]
77
        [InlineData(true)]
78
        [InlineData(false)]
79
        public void ExistsBlockState(bool secure)
80 1
        {
81 1
            var stateStore = MakeTrieStateStoreFixture(secure);
82
            HashDigest<SHA256> randomBlockHash;
83
            do
84 1
            {
85 1
                randomBlockHash =
86 1
                    new HashDigest<SHA256>(TestUtils.GetRandomBytes(HashDigest<SHA256>.Size));
87 1
            }
88 1
            while (randomBlockHash.Equals(_fx.GenesisBlock.Hash));
89

90 1
            Assert.False(stateStore.ContainsBlockStates(randomBlockHash));
91 1
            Assert.True(stateStore.ContainsBlockStates(_fx.GenesisBlock.Hash));
92 1
        }
93

94
        [Theory]
95
        [InlineData(true)]
96
        [InlineData(false)]
97
        public void PruneStates(bool secure)
98 1
        {
99 1
            var stateStore = MakeTrieStateStoreFixture(secure);
100 1
            int prevStateHashesCount = _stateHashKeyValueStore.ListKeys().Count(),
101 1
                prevStatesCount = _stateKeyValueStore.ListKeys().Count();
102 1
            var nextStates = _prestoredValues.SetItem("foo", (Binary)TestUtils.GetRandomBytes(32));
103 1
            stateStore.SetStates(_fx.Block1, nextStates);
104

105
            // Hash of _fx.Block1
106 1
            Assert.Equal(prevStateHashesCount + 1, _stateHashKeyValueStore.ListKeys().Count());
107
            // foo = 0x666f6f
108
            // updated branch node (0x6, aka root) + updated branch node (0x66) +
109
            // updated short node + new value node
110 1
            Assert.Equal(prevStatesCount + 4, _stateKeyValueStore.ListKeys().Count());
111

112 1
            stateStore.PruneStates(
113 1
                ImmutableHashSet<HashDigest<SHA256>>.Empty.Add(_fx.Block1.Hash));
114 1
            Assert.Single(_stateHashKeyValueStore.ListKeys());
115
            // It will stay at the same count of nodes.
116 1
            Assert.Equal(prevStatesCount, _stateKeyValueStore.ListKeys().Count());
117 1
        }
118

119
        private TrieStateStore MakeTrieStateStoreFixture(bool secure)
120 1
        {
121 1
            var stateStore = new TrieStateStore(
122 1
                _stateKeyValueStore, _stateHashKeyValueStore, secure);
123 1
            stateStore.SetStates(_fx.GenesisBlock, _prestoredValues);
124 1
            return stateStore;
125 1
        }
126
    }
127
}

Read our documentation on viewing source code .

Loading