func TestStateDeltaCryptoHash(t *testing.T) { stateDelta := NewStateDelta() testutil.AssertNil(t, stateDelta.ComputeCryptoHash()) stateDelta.Set("chaincodeID1", "key2", []byte("value2"), nil) stateDelta.Set("chaincodeID1", "key1", []byte("value1"), nil) stateDelta.Set("chaincodeID2", "key2", []byte("value2"), nil) stateDelta.Set("chaincodeID2", "key1", []byte("value1"), nil) testutil.AssertEquals(t, stateDelta.ComputeCryptoHash(), testutil.ComputeCryptoHash([]byte("chaincodeID1key1value1key2value2chaincodeID2key1value1key2value2"))) stateDelta.Delete("chaincodeID2", "key1", nil) testutil.AssertEquals(t, stateDelta.ComputeCryptoHash(), testutil.ComputeCryptoHash([]byte("chaincodeID1key1value1key2value2chaincodeID2key1key2value2"))) }
func TestStateImpl_ComputeHash_AllInMemory_1(t *testing.T) { // number of buckets at each level 26,9,3,1 testHasher, stateImplTestWrapper, stateDelta := createFreshDBAndInitTestStateImplWithCustomHasher(t, 26, 3) testHasher.populate("chaincodeID1", "key1", 0) testHasher.populate("chaincodeID2", "key2", 0) testHasher.populate("chaincodeID3", "key3", 0) testHasher.populate("chaincodeID4", "key4", 3) stateDelta.Set("chaincodeID1", "key1", []byte("value1"), nil) stateDelta.Set("chaincodeID2", "key2", []byte("value2"), nil) stateDelta.Set("chaincodeID3", "key3", []byte("value3"), nil) stateDelta.Set("chaincodeID4", "key4", []byte("value4"), nil) rootHash := stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta) expectedHashBucket3_1 := expectedBucketHashForTest( []string{"chaincodeID1", "key1", "value1"}, []string{"chaincodeID2", "key2", "value2"}, []string{"chaincodeID3", "key3", "value3"}, ) expectedHashBucket3_4 := expectedBucketHashForTest( []string{"chaincodeID4", "key4", "value4"}, ) expectedHash := testutil.ComputeCryptoHash(expectedHashBucket3_1, expectedHashBucket3_4) testutil.AssertEquals(t, rootHash, expectedHash) }
func TestBucketNodeComputeHash(t *testing.T) { conf = newConfig(26, 3, fnvHash) bucketNode := newBucketNode(newBucketKey(2, 7)) testutil.AssertEquals(t, bucketNode.computeCryptoHash(), nil) childKey1 := newBucketKey(3, 19) bucketNode.setChildCryptoHash(childKey1, []byte("cryptoHashChild1")) testutil.AssertEquals(t, bucketNode.computeCryptoHash(), []byte("cryptoHashChild1")) childKey3 := newBucketKey(3, 21) bucketNode.setChildCryptoHash(childKey3, []byte("cryptoHashChild3")) testutil.AssertEquals(t, bucketNode.computeCryptoHash(), testutil.ComputeCryptoHash([]byte("cryptoHashChild1cryptoHashChild3"))) childKey2 := newBucketKey(3, 20) bucketNode.setChildCryptoHash(childKey2, []byte("cryptoHashChild2")) testutil.AssertEquals(t, bucketNode.computeCryptoHash(), testutil.ComputeCryptoHash([]byte("cryptoHashChild1cryptoHashChild2cryptoHashChild3"))) }
func TestStateImpl_ComputeHash_AllInMemory_2(t *testing.T) { // number of buckets at each level 26,13,7,4,2,1 testHasher, stateImplTestWrapper, stateDelta := createFreshDBAndInitTestStateImplWithCustomHasher(t, 26, 2) // first two buckets - meet at next level testHasher.populate("chaincodeID1", "key1", 0) testHasher.populate("chaincodeID2", "key2", 1) // middle two buckets testHasher.populate("chaincodeID3", "key3", 5) testHasher.populate("chaincodeID4", "key4", 9) // last two buckets - meet at next level testHasher.populate("chaincodeID5", "key5", 24) testHasher.populate("chaincodeID6", "key6", 25) stateDelta.Set("chaincodeID1", "key1", []byte("value1"), nil) stateDelta.Set("chaincodeID2", "key2", []byte("value2"), nil) stateDelta.Set("chaincodeID3", "key3", []byte("value3"), nil) stateDelta.Set("chaincodeID4", "key4", []byte("value4"), nil) stateDelta.Set("chaincodeID5", "key5", []byte("value5"), nil) stateDelta.Set("chaincodeID6", "key6", []byte("value6"), nil) rootHash := stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta) expectedHashBucket5_1 := expectedBucketHashForTest([]string{"chaincodeID1", "key1", "value1"}) expectedHashBucket5_2 := expectedBucketHashForTest([]string{"chaincodeID2", "key2", "value2"}) expectedHashBucket5_6 := expectedBucketHashForTest([]string{"chaincodeID3", "key3", "value3"}) expectedHashBucket5_10 := expectedBucketHashForTest([]string{"chaincodeID4", "key4", "value4"}) expectedHashBucket5_25 := expectedBucketHashForTest([]string{"chaincodeID5", "key5", "value5"}) expectedHashBucket5_26 := expectedBucketHashForTest([]string{"chaincodeID6", "key6", "value6"}) expectedHashBucket4_1 := testutil.ComputeCryptoHash(expectedHashBucket5_1, expectedHashBucket5_2) expectedHashBucket4_13 := testutil.ComputeCryptoHash(expectedHashBucket5_25, expectedHashBucket5_26) expectedHashBucket2_1 := testutil.ComputeCryptoHash(expectedHashBucket4_1, expectedHashBucket5_6) expectedHashBucket1_1 := testutil.ComputeCryptoHash(expectedHashBucket2_1, expectedHashBucket5_10) expectedHash := testutil.ComputeCryptoHash(expectedHashBucket1_1, expectedHashBucket4_13) testutil.AssertEquals(t, rootHash, expectedHash) }
func TestLedgerGetTempStateHashWithTxDeltaStateHashes(t *testing.T) { ledgerTestWrapper := createFreshDBAndTestLedgerWrapper(t) ledger := ledgerTestWrapper.ledger ledger.BeginTxBatch(1) ledger.TxBegin("txUuid1") ledger.SetState("chaincode1", "key1", []byte("value1")) ledger.TxFinished("txUuid1", true) ledger.TxBegin("txUuid2") ledger.SetState("chaincode2", "key2", []byte("value2")) ledger.TxFinished("txUuid2", true) ledger.TxBegin("txUuid3") ledger.TxFinished("txUuid3", true) ledger.TxBegin("txUuid4") ledger.SetState("chaincode4", "key4", []byte("value4")) ledger.TxFinished("txUuid4", false) _, txDeltaHashes, _ := ledger.GetTempStateHashWithTxDeltaStateHashes() testutil.AssertEquals(t, testutil.ComputeCryptoHash([]byte("chaincode1key1value1")), txDeltaHashes["txUuid1"]) testutil.AssertEquals(t, testutil.ComputeCryptoHash([]byte("chaincode2key2value2")), txDeltaHashes["txUuid2"]) testutil.AssertNil(t, txDeltaHashes["txUuid3"]) _, ok := txDeltaHashes["txUuid4"] if ok { t.Fatalf("Entry for a failed Tx should not be present in txDeltaHashes map") } ledger.CommitTxBatch(1, []*protos.Transaction{}, nil, []byte("proof")) ledger.BeginTxBatch(2) ledger.TxBegin("txUuid1") ledger.SetState("chaincode1", "key1", []byte("value1")) ledger.TxFinished("txUuid1", true) _, txDeltaHashes, _ = ledger.GetTempStateHashWithTxDeltaStateHashes() if len(txDeltaHashes) != 1 { t.Fatalf("Entries in txDeltaHashes map should only be from current batch") } }
func TestBucketHashCalculator(t *testing.T) { initConfig(nil) c := newBucketHashCalculator(newBucketKey(1, 1)) testutil.AssertEquals(t, c.computeCryptoHash(), nil) c.addNextNode(newDataNode(newDataKey("chaincodeID1", "key1"), []byte("value1"))) c.addNextNode(newDataNode(newDataKey("chaincodeID_2", "key_1"), []byte("value_1"))) c.addNextNode(newDataNode(newDataKey("chaincodeID_2", "key_2"), []byte("value_2"))) c.addNextNode(newDataNode(newDataKey("chaincodeID3", "key1"), []byte("value1"))) c.addNextNode(newDataNode(newDataKey("chaincodeID3", "key2"), []byte("value2"))) c.addNextNode(newDataNode(newDataKey("chaincodeID3", "key3"), []byte("value3"))) hash := c.computeCryptoHash() expectedHashContent := expectedBucketHashContentForTest( []string{"chaincodeID1", "key1", "value1"}, []string{"chaincodeID_2", "key_1", "value_1", "key_2", "value_2"}, []string{"chaincodeID3", "key1", "value1", "key2", "value2", "key3", "value3"}, ) t.Logf("Actual HashContent = %#v\n Expected HashContent = %#v", c.hashingData, expectedHashContent) testutil.AssertEquals(t, hash, testutil.ComputeCryptoHash(expectedHashContent)) }
func expectedBucketHashForTest(data ...[]string) []byte { return testutil.ComputeCryptoHash(expectedBucketHashContentForTest(data...)) }
func TestStateImpl_ComputeHash_DB_2(t *testing.T) { // number of buckets at each level 26,13,7,4,2,1 testHasher, stateImplTestWrapper, stateDelta := createFreshDBAndInitTestStateImplWithCustomHasher(t, 26, 2) testHasher.populate("chaincodeID1", "key1", 0) testHasher.populate("chaincodeID2", "key2", 1) testHasher.populate("chaincodeID3", "key3", 5) testHasher.populate("chaincodeID4", "key4", 9) testHasher.populate("chaincodeID5", "key5", 24) testHasher.populate("chaincodeID6", "key6", 25) stateDelta.Set("chaincodeID1", "key1", []byte("value1"), nil) stateDelta.Set("chaincodeID2", "key2", []byte("value2"), nil) stateDelta.Set("chaincodeID3", "key3", []byte("value3"), nil) stateDelta.Set("chaincodeID4", "key4", []byte("value4"), nil) stateDelta.Set("chaincodeID5", "key5", []byte("value5"), nil) stateDelta.Set("chaincodeID6", "key6", []byte("value6"), nil) stateImplTestWrapper.prepareWorkingSet(stateDelta) // Populate DB stateImplTestWrapper.persistChangesAndResetInMemoryChanges() //////////// Test - constrcuting a new state tree simulates starting state tree when db already has some data //////// stateImplTestWrapper.constructNewStateImpl() rootHash := stateImplTestWrapper.computeCryptoHash() /*************************** bucket-tree-structure *************** 1 1 1 1 1 1 2 1 1 1 1 1 6 3 2 1 1 1 10 5 3 2 1 1 25 13 7 4 2 1 26 13 7 4 2 1 *******************************************************************/ expectedHashBucket5_1 := expectedBucketHashForTest([]string{"chaincodeID1", "key1", "value1"}) expectedHashBucket5_2 := expectedBucketHashForTest([]string{"chaincodeID2", "key2", "value2"}) expectedHashBucket5_6 := expectedBucketHashForTest([]string{"chaincodeID3", "key3", "value3"}) expectedHashBucket5_10 := expectedBucketHashForTest([]string{"chaincodeID4", "key4", "value4"}) expectedHashBucket5_25 := expectedBucketHashForTest([]string{"chaincodeID5", "key5", "value5"}) expectedHashBucket5_26 := expectedBucketHashForTest([]string{"chaincodeID6", "key6", "value6"}) expectedHashBucket4_1 := testutil.ComputeCryptoHash(expectedHashBucket5_1, expectedHashBucket5_2) expectedHashBucket4_13 := testutil.ComputeCryptoHash(expectedHashBucket5_25, expectedHashBucket5_26) expectedHashBucket2_1 := testutil.ComputeCryptoHash(expectedHashBucket4_1, expectedHashBucket5_6) expectedHashBucket1_1 := testutil.ComputeCryptoHash(expectedHashBucket2_1, expectedHashBucket5_10) expectedHash := testutil.ComputeCryptoHash(expectedHashBucket1_1, expectedHashBucket4_13) testutil.AssertEquals(t, rootHash, expectedHash) ////////////// Test - Add a few more keys (include keys in the existing buckes and new buckets) ///////////////////// stateDelta = statemgmt.NewStateDelta() testHasher.populate("chaincodeID7", "key7", 1) testHasher.populate("chaincodeID8", "key8", 7) testHasher.populate("chaincodeID9", "key9", 9) testHasher.populate("chaincodeID10", "key10", 20) stateDelta.Set("chaincodeID7", "key7", []byte("value7"), nil) stateDelta.Set("chaincodeID8", "key8", []byte("value8"), nil) stateDelta.Set("chaincodeID9", "key9", []byte("value9"), nil) stateDelta.Set("chaincodeID10", "key10", []byte("value10"), nil) /*************************** bucket-tree-structure after adding keys *************** 1 1 1 1 1 1 2 1 1 1 1 1 6 3 2 1 1 1 8 4 2 1 1 1 10 5 3 2 1 1 21 11 6 3 2 1 25 13 7 4 2 1 26 13 7 4 2 1 ***********************************************************************************/ rootHash = stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta) expectedHashBucket5_2 = expectedBucketHashForTest( []string{"chaincodeID2", "key2", "value2"}, []string{"chaincodeID7", "key7", "value7"}, ) expectedHashBucket5_8 := expectedBucketHashForTest([]string{"chaincodeID8", "key8", "value8"}) expectedHashBucket5_10 = expectedBucketHashForTest([]string{"chaincodeID4", "key4", "value4"}, []string{"chaincodeID9", "key9", "value9"}) expectedHashBucket5_21 := expectedBucketHashForTest([]string{"chaincodeID10", "key10", "value10"}) expectedHashBucket4_1 = testutil.ComputeCryptoHash(expectedHashBucket5_1, expectedHashBucket5_2) expectedHashBucket3_2 := testutil.ComputeCryptoHash(expectedHashBucket5_6, expectedHashBucket5_8) expectedHashBucket2_1 = testutil.ComputeCryptoHash(expectedHashBucket4_1, expectedHashBucket3_2) expectedHashBucket1_1 = testutil.ComputeCryptoHash(expectedHashBucket2_1, expectedHashBucket5_10) expectedHashBucket1_2 := testutil.ComputeCryptoHash(expectedHashBucket5_21, expectedHashBucket4_13) expectedHash = testutil.ComputeCryptoHash(expectedHashBucket1_1, expectedHashBucket1_2) testutil.AssertEquals(t, rootHash, expectedHash) stateImplTestWrapper.persistChangesAndResetInMemoryChanges() ////////////// Test - overwrite an existing key ///////////////////// stateDelta = statemgmt.NewStateDelta() stateDelta.Set("chaincodeID7", "key7", []byte("value7_new"), nil) rootHash = stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta) expectedHashBucket5_2 = expectedBucketHashForTest( []string{"chaincodeID2", "key2", "value2"}, []string{"chaincodeID7", "key7", "value7_new"}, ) expectedHashBucket4_1 = testutil.ComputeCryptoHash(expectedHashBucket5_1, expectedHashBucket5_2) expectedHashBucket2_1 = testutil.ComputeCryptoHash(expectedHashBucket4_1, expectedHashBucket3_2) expectedHashBucket1_1 = testutil.ComputeCryptoHash(expectedHashBucket2_1, expectedHashBucket5_10) expectedHash = testutil.ComputeCryptoHash(expectedHashBucket1_1, expectedHashBucket1_2) testutil.AssertEquals(t, rootHash, expectedHash) stateImplTestWrapper.persistChangesAndResetInMemoryChanges() testutil.AssertEquals(t, stateImplTestWrapper.get("chaincodeID7", "key7"), []byte("value7_new")) // ////////////// Test - delete an existing key ///////////////////// stateDelta = statemgmt.NewStateDelta() stateDelta.Delete("chaincodeID2", "key2", nil) rootHash = stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta) expectedHashBucket5_2 = expectedBucketHashForTest([]string{"chaincodeID7", "key7", "value7_new"}) expectedHashBucket4_1 = testutil.ComputeCryptoHash(expectedHashBucket5_1, expectedHashBucket5_2) expectedHashBucket2_1 = testutil.ComputeCryptoHash(expectedHashBucket4_1, expectedHashBucket3_2) expectedHashBucket1_1 = testutil.ComputeCryptoHash(expectedHashBucket2_1, expectedHashBucket5_10) expectedHash = testutil.ComputeCryptoHash(expectedHashBucket1_1, expectedHashBucket1_2) testutil.AssertEquals(t, rootHash, expectedHash) stateImplTestWrapper.persistChangesAndResetInMemoryChanges() testutil.AssertNil(t, stateImplTestWrapper.get("chaincodeID2", "key2")) }