Skip to content

Commit

Permalink
Merge branch 'main' into marko/configurable-govBurn
Browse files Browse the repository at this point in the history
  • Loading branch information
tac0turtle authored Feb 27, 2023
2 parents 79a6c6c + 7c9245d commit dfb65ce
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 72 deletions.
54 changes: 20 additions & 34 deletions CHANGELOG.md

Large diffs are not rendered by default.

69 changes: 45 additions & 24 deletions store/snapshots/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package snapshots
import (
"crypto/sha256"
"encoding/binary"
"hash"
"io"
"math"
"os"
Expand Down Expand Up @@ -256,44 +257,64 @@ func (s *Store) Save(
Height: height,
Format: format,
}

dirCreated := false
index := uint32(0)
snapshotHasher := sha256.New()
chunkHasher := sha256.New()
for chunkBody := range chunks {
defer chunkBody.Close() //nolint:staticcheck
dir := s.pathSnapshot(height, format)
err = os.MkdirAll(dir, 0o755)
if err != nil {
return nil, errors.Wrapf(err, "failed to create snapshot directory %q", dir)
}
path := s.pathChunk(height, format, index)
file, err := os.Create(path)
if err != nil {
return nil, errors.Wrapf(err, "failed to create snapshot chunk file %q", path)
}
defer file.Close() //nolint:staticcheck
// Only create the snapshot directory on encountering the first chunk.
// If the directory disappears during chunk saving,
// the whole operation will fail anyway.
if !dirCreated {
dir := s.pathSnapshot(height, format)
if err := os.MkdirAll(dir, 0o755); err != nil {
return nil, errors.Wrapf(err, "failed to create snapshot directory %q", dir)
}

chunkHasher.Reset()
_, err = io.Copy(io.MultiWriter(file, chunkHasher, snapshotHasher), chunkBody)
if err != nil {
return nil, errors.Wrapf(err, "failed to generate snapshot chunk %v", index)
}
err = file.Close()
if err != nil {
return nil, errors.Wrapf(err, "failed to close snapshot chunk %v", index)
dirCreated = true
}
err = chunkBody.Close()
if err != nil {
return nil, errors.Wrapf(err, "failed to close snapshot chunk %v", index)

if err := s.saveChunk(chunkBody, index, snapshot, chunkHasher, snapshotHasher); err != nil {
return nil, err
}
snapshot.Metadata.ChunkHashes = append(snapshot.Metadata.ChunkHashes, chunkHasher.Sum(nil))
index++
}
snapshot.Chunks = index
snapshot.Hash = snapshotHasher.Sum(nil)
return snapshot, s.saveSnapshot(snapshot)
}

// saveChunk saves the given chunkBody with the given index to its appropriate path on disk.
// The hash of the chunk is appended to the snapshot's metadata,
// and the overall snapshot hash is updated with the chunk content too.
func (s *Store) saveChunk(chunkBody io.ReadCloser, index uint32, snapshot *types.Snapshot, chunkHasher, snapshotHasher hash.Hash) error {
defer chunkBody.Close()

path := s.pathChunk(snapshot.Height, snapshot.Format, index)
chunkFile, err := os.Create(path)
if err != nil {
return errors.Wrapf(err, "failed to create snapshot chunk file %q", path)
}
defer chunkFile.Close()

chunkHasher.Reset()
if _, err := io.Copy(io.MultiWriter(chunkFile, chunkHasher, snapshotHasher), chunkBody); err != nil {
return errors.Wrapf(err, "failed to generate snapshot chunk %d", index)
}

if err := chunkFile.Close(); err != nil {
return errors.Wrapf(err, "failed to close snapshot chunk file %d", index)
}

if err := chunkBody.Close(); err != nil {
return errors.Wrapf(err, "failed to close snapshot chunk body %d", index)
}

snapshot.Metadata.ChunkHashes = append(snapshot.Metadata.ChunkHashes, chunkHasher.Sum(nil))
return nil
}

// saveSnapshot saves snapshot metadata to the database.
func (s *Store) saveSnapshot(snapshot *types.Snapshot) error {
value, err := proto.Marshal(snapshot)
Expand Down
2 changes: 1 addition & 1 deletion types/mempool/sender_nonce.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type SenderNonceMempool struct {
existingTx map[txKey]bool
}

type SenderNonceOptions func(mp *SenderNonceMempool)
type SenderNonceOptions func(*SenderNonceMempool)

type txKey struct {
address string
Expand Down
18 changes: 17 additions & 1 deletion x/tx/textual/dec.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package textual
import (
"context"
"fmt"
"math/big"
"strings"

"google.golang.org/protobuf/reflect/protoreflect"
Expand All @@ -21,7 +22,22 @@ type decValueRenderer struct{}
var _ ValueRenderer = decValueRenderer{}

func (vr decValueRenderer) Format(_ context.Context, v protoreflect.Value) ([]Screen, error) {
formatted, err := math.FormatDec(v.String())
decStr := v.String()

// If the decimal doesn't contain a point, we assume it's a value formatted using the legacy
// `sdk.Dec`. So we try to parse it as an integer and then convert it to a
// decimal.
if !strings.Contains(decStr, ".") {
parsedInt, ok := new(big.Int).SetString(decStr, 10)
if !ok {
return nil, fmt.Errorf("invalid decimal: %s", decStr)
}

// We assume the decimal has 18 digits of precision.
decStr = math.LegacyNewDecFromBigIntWithPrec(parsedInt, math.LegacyPrecision).String()
}

formatted, err := math.FormatDec(decStr)
if err != nil {
return nil, err
}
Expand Down
35 changes: 34 additions & 1 deletion x/tx/textual/dec_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package textual_test

import (
"context"
"encoding/json"
"math/big"
"os"
"strings"
"testing"

"github.com/stretchr/testify/require"
"google.golang.org/protobuf/reflect/protoreflect"

"cosmossdk.io/math"
"cosmossdk.io/x/tx/textual"
)

Expand All @@ -27,7 +31,36 @@ func TestDecJsonTestcases(t *testing.T) {
r, err := textual.GetFieldValueRenderer(fieldDescriptorFromName("SDKDEC"))
require.NoError(t, err)

checkNumberTest(t, r, protoreflect.ValueOf(tc[0]), tc[1])
checkDecTest(t, r, protoreflect.ValueOf(tc[0]), tc[1])
})
}
}

func checkDecTest(t *testing.T, r textual.ValueRenderer, pv protoreflect.Value, expected string) {
screens, err := r.Format(context.Background(), pv)
require.NoError(t, err)
require.Len(t, screens, 1)
require.Zero(t, screens[0].Indent)
require.False(t, screens[0].Expert)

require.Equal(t, expected, screens[0].Content)

// Round trip.
value, err := r.Parse(context.Background(), screens)
require.NoError(t, err)

v1, err := math.LegacyNewDecFromStr(value.String())
require.NoError(t, err)

decStr := pv.String()
if !strings.Contains(decStr, ".") {
n, ok := new(big.Int).SetString(decStr, 10)
require.True(t, ok)
decStr = math.LegacyNewDecFromBigIntWithPrec(n, 18).String()
}

v, err := math.LegacyNewDecFromStr(decStr)
require.NoError(t, err)

require.Truef(t, v.Equal(v1), "%s != %s", v, v1)
}
6 changes: 3 additions & 3 deletions x/tx/textual/int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ func checkNumberTest(t *testing.T, r textual.ValueRenderer, pv protoreflect.Valu
screens, err := r.Format(context.Background(), pv)
require.NoError(t, err)
require.Len(t, screens, 1)
require.Equal(t, 0, screens[0].Indent)
require.Equal(t, false, screens[0].Expert)
require.Zero(t, screens[0].Indent)
require.False(t, screens[0].Expert)

require.Equal(t, expected, screens[0].Content)

Expand All @@ -78,5 +78,5 @@ func checkNumberTest(t *testing.T, r textual.ValueRenderer, pv protoreflect.Valu
v1, err := math.LegacyNewDecFromStr(value.String())
require.NoError(t, err)

require.True(t, v.Equal(v1))
require.Truef(t, v.Equal(v1), "%s != %s", v, v1)
}
68 changes: 60 additions & 8 deletions x/tx/textual/internal/testdata/decimals.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[
["0", "0"],
["1", "1"],
["12", "12"],
["123", "123"],
["1234", "1'234"],
["0.0", "0"],
["1.0", "1"],
["12.0", "12"],
["123.0", "123"],
["1234.0", "1'234"],
["0.1", "0.1"],
["0.01", "0.01"],
["0.001", "0.001"],
Expand Down Expand Up @@ -41,7 +41,59 @@
["0.000000000000000010", "0.00000000000000001"],
["0.000000000000000001", "0.000000000000000001"],
["-10.0", "-10"],
["-10000", "-10'000"],
["-9999", "-9'999"],
["-999999999999", "-999'999'999'999"]
["-10000.0", "-10'000"],
["-9999.0", "-9'999"],
["-999999999999.0", "-999'999'999'999"],
["1000000000000000000000000", "1'000'000"],
["1000000000000000000000000", "1'000'000"],
["100000000000000000000000", "100'000"],
["10000000000000000000000", "10'000"],
["1000000000000000000000", "1'000"],
["100000000000000000000", "100"],
["10000000000000000000", "10"],
["1000000000000000000", "1"],
["100000000000000000", "0.1"],
["10000000000000000", "0.01"],
["1000000000000000", "0.001"],
["100000000000000", "0.0001"],
["10000000000000", "0.00001"],
["1000000000000", "0.000001"],
["100000000000", "0.0000001"],
["10000000000", "0.00000001"],
["1000000000", "0.000000001"],
["100000000", "0.0000000001"],
["10000000", "0.00000000001"],
["1000000", "0.000000000001"],
["100000", "0.0000000000001"],
["10000", "0.00000000000001"],
["1000", "0.000000000000001"],
["100", "0.0000000000000001"],
["10", "0.00000000000000001"],
["1", "0.000000000000000001"],
["-1000000000000000000000000", "-1'000'000"],
["-1000000000000000000000000", "-1'000'000"],
["-100000000000000000000000", "-100'000"],
["-10000000000000000000000", "-10'000"],
["-1000000000000000000000", "-1'000"],
["-100000000000000000000", "-100"],
["-10000000000000000000", "-10"],
["-1000000000000000000", "-1"],
["-100000000000000000", "-0.1"],
["-10000000000000000", "-0.01"],
["-1000000000000000", "-0.001"],
["-100000000000000", "-0.0001"],
["-10000000000000", "-0.00001"],
["-1000000000000", "-0.000001"],
["-100000000000", "-0.0000001"],
["-10000000000", "-0.00000001"],
["-1000000000", "-0.000000001"],
["-100000000", "-0.0000000001"],
["-10000000", "-0.00000000001"],
["-1000000", "-0.000000000001"],
["-100000", "-0.0000000000001"],
["-10000", "-0.00000000000001"],
["-1000", "-0.000000000000001"],
["-100", "-0.0000000000000001"],
["-10", "-0.00000000000000001"],
["-1", "-0.000000000000000001"]
]

0 comments on commit dfb65ce

Please sign in to comment.