From 6bf5fbd3ace11b6f64488978c4dbcaea32cc6f37 Mon Sep 17 00:00:00 2001 From: xujiangyu Date: Tue, 15 Oct 2024 11:37:50 +0800 Subject: [PATCH 1/5] refact(math/):refact ApproxRoot for readality --- math/dec.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/math/dec.go b/math/dec.go index 3ed930d5c484..76a37113b6b8 100644 --- a/math/dec.go +++ b/math/dec.go @@ -467,33 +467,41 @@ func (d LegacyDec) ApproxRoot(root uint64) (guess LegacyDec, err error) { } }() + if root == 0 { + // Return 1 as root 0 of any number is considered 1. + return LegacyOneDec(), nil + } + if d.IsNegative() { absRoot, err := d.Neg().ApproxRoot(root) return absRoot.NegMut(), err } - // One decimal, that we invalidate later. Helps us save a heap allocation. + // Direct return for base cases: d^1 = d or when d is 0 or 1. scratchOneDec := LegacyOneDec() if root == 1 || d.IsZero() || d.Equal(scratchOneDec) { return d, nil } - if root == 0 { - return scratchOneDec, nil - } - guess, delta := scratchOneDec, LegacyOneDec() - for iter := 0; iter < maxApproxRootIterations && delta.Abs().GT(smallestDec); iter++ { + for iter := 0; iter < maxApproxRootIterations; iter++ { prev := guess.Power(root - 1) if prev.IsZero() { prev = smallestDec } + + // Compute delta = (d/prev - guess) / root delta.Set(d).QuoMut(prev) delta.SubMut(guess) delta.QuoInt64Mut(int64(root)) guess.AddMut(delta) + + // Stop when delta is small enough + if delta.Abs().LTE(smallestDec) { + break + } } return guess, nil From 3ff753f55a290667628dddd97670278d2b530038 Mon Sep 17 00:00:00 2001 From: heren-ke Date: Thu, 24 Oct 2024 19:16:15 +0800 Subject: [PATCH 2/5] test:(math/dec): add test case for ApproxRoot() --- math/dec_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/math/dec_test.go b/math/dec_test.go index 90d610199f3f..639a18f4ad1e 100644 --- a/math/dec_test.go +++ b/math/dec_test.go @@ -449,6 +449,9 @@ func (s *decimalTestSuite) TestApproxRoot() { root uint64 expected math.LegacyDec }{ + {math.LegacyNewDecFromInt(math.NewInt(2)), 0, math.LegacyOneDec()}, // 2 ^ 0 => 1.0 + {math.LegacyNewDecWithPrec(4, 2), 0, math.LegacyOneDec()}, // 0.04 ^ 0 => 1.0 + {math.LegacyNewDec(0), 0, math.LegacyNewDec(0)}, // 0 ^ 0 => 0 {math.LegacyOneDec(), 10, math.LegacyOneDec()}, // 1.0 ^ (0.1) => 1.0 {math.LegacyNewDecWithPrec(25, 2), 2, math.LegacyNewDecWithPrec(5, 1)}, // 0.25 ^ (0.5) => 0.5 {math.LegacyNewDecWithPrec(4, 2), 2, math.LegacyNewDecWithPrec(2, 1)}, // 0.04 ^ (0.5) => 0.2 From 18c263cbae02070b71f468581ef432cf3203a4be Mon Sep 17 00:00:00 2001 From: heren-ke Date: Wed, 30 Oct 2024 09:44:06 +0800 Subject: [PATCH 3/5] test: fix test case for ApproxRoot --- math/dec_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/dec_test.go b/math/dec_test.go index 639a18f4ad1e..316b6aaa63dc 100644 --- a/math/dec_test.go +++ b/math/dec_test.go @@ -451,7 +451,7 @@ func (s *decimalTestSuite) TestApproxRoot() { }{ {math.LegacyNewDecFromInt(math.NewInt(2)), 0, math.LegacyOneDec()}, // 2 ^ 0 => 1.0 {math.LegacyNewDecWithPrec(4, 2), 0, math.LegacyOneDec()}, // 0.04 ^ 0 => 1.0 - {math.LegacyNewDec(0), 0, math.LegacyNewDec(0)}, // 0 ^ 0 => 0 + {math.LegacyNewDec(0), 1, math.LegacyNewDec(0)}, // 0 ^ 1 => 0 {math.LegacyOneDec(), 10, math.LegacyOneDec()}, // 1.0 ^ (0.1) => 1.0 {math.LegacyNewDecWithPrec(25, 2), 2, math.LegacyNewDecWithPrec(5, 1)}, // 0.25 ^ (0.5) => 0.5 {math.LegacyNewDecWithPrec(4, 2), 2, math.LegacyNewDecWithPrec(2, 1)}, // 0.04 ^ (0.5) => 0.2 From 86e7052c8dea17ad227d2e6f06cab5c66f93dde2 Mon Sep 17 00:00:00 2001 From: heren-ke Date: Wed, 4 Dec 2024 18:27:47 +0800 Subject: [PATCH 4/5] test: add test cases for prefixdb.go --- store/db/prefixdb_test.go | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 store/db/prefixdb_test.go diff --git a/store/db/prefixdb_test.go b/store/db/prefixdb_test.go new file mode 100644 index 000000000000..ed2f57f2fa38 --- /dev/null +++ b/store/db/prefixdb_test.go @@ -0,0 +1,49 @@ +package db_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "cosmossdk.io/store/db" + "cosmossdk.io/store/mock" + "go.uber.org/mock/gomock" +) + +func TestPrefixDB(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockDB := mock.NewMockKVStoreWithBatch(mockCtrl) + prefix := []byte("test:") + pdb := db.NewPrefixDB(mockDB, prefix) + + key := []byte("key1") + value := []byte("value1") + mockDB.EXPECT().Set(gomock.Eq(append(prefix, key...)), gomock.Eq(value)).Return(nil) + + err := pdb.Set(key, value) + require.NoError(t, err) + + mockDB.EXPECT().Get(gomock.Eq(append(prefix, key...))).Return(value, nil) + + returnedValue, err := pdb.Get(key) + require.NoError(t, err) + require.Equal(t, value, returnedValue) + + mockDB.EXPECT().Has(gomock.Eq(append(prefix, key...))).Return(true, nil) + + has, err := pdb.Has(key) + require.NoError(t, err) + require.True(t, has) + + mockDB.EXPECT().Delete(gomock.Eq(append(prefix, key...))).Return(nil) + + err = pdb.Delete(key) + require.NoError(t, err) + + mockDB.EXPECT().Has(gomock.Eq(append(prefix, key...))).Return(false, nil) + + has, err = pdb.Has(key) + require.NoError(t, err) + require.False(t, has) +} \ No newline at end of file From e2cae822eef12d7bf2fa5a6acec68989ebd0dc1b Mon Sep 17 00:00:00 2001 From: heren-ke Date: Fri, 6 Dec 2024 21:58:27 +0800 Subject: [PATCH 5/5] format prefixdb_test.go --- store/db/prefixdb_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/store/db/prefixdb_test.go b/store/db/prefixdb_test.go index ed2f57f2fa38..199aa50d056a 100644 --- a/store/db/prefixdb_test.go +++ b/store/db/prefixdb_test.go @@ -3,9 +3,9 @@ package db_test import ( "testing" - "github.com/stretchr/testify/require" "cosmossdk.io/store/db" "cosmossdk.io/store/mock" + "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -46,4 +46,4 @@ func TestPrefixDB(t *testing.T) { has, err = pdb.Has(key) require.NoError(t, err) require.False(t, has) -} \ No newline at end of file +}