From a41e189f754ae31c95dbcf6edee6a2626f321563 Mon Sep 17 00:00:00 2001 From: evan-forbes Date: Fri, 19 Feb 2021 10:13:17 -0600 Subject: [PATCH] review feedback: follow the spec and pad shares when generating the share commitment instead of not allowing chains update failing test to new expected result now that the square size is 128 instead of 64 --- x/lazyledgerapp/types/payformessage.go | 25 +++++++++++++++-- x/lazyledgerapp/types/payformessage_test.go | 31 +++++++++++++++++++-- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/x/lazyledgerapp/types/payformessage.go b/x/lazyledgerapp/types/payformessage.go index 0f8128e4ed..b5337f2887 100644 --- a/x/lazyledgerapp/types/payformessage.go +++ b/x/lazyledgerapp/types/payformessage.go @@ -206,7 +206,10 @@ func (msg *SignedTransactionDataPayForMessage) GetSigners() []sdk.AccAddress { // https://github.com/lazyledger/lazyledger-specs/blob/master/rationale/message_block_layout.md#non-interactive-default-rules func CreateCommit(k uint64, namespace, message []byte) ([]byte, error) { // break message into shares - shares := ChunkMessage(message) + shares := chunkMessage(message) + + // add padding if necessary + shares = addSharePadding(shares) // organize shares for merkle mountain range heights := PowerOf2MountainRange(uint64(len(shares)), k) @@ -234,8 +237,8 @@ func CreateCommit(k uint64, namespace, message []byte) ([]byte, error) { return merkle.HashFromByteSlices(subTreeRoots), nil } -// ChunkMessage breaks the message into 256 byte pieces -func ChunkMessage(message []byte) [][]byte { +// chunkMessage breaks the message into 256 byte pieces +func chunkMessage(message []byte) [][]byte { var shares [][]byte for i := 0; i < len(message); i += ShareSize { end := i + ShareSize @@ -247,6 +250,22 @@ func ChunkMessage(message []byte) [][]byte { return shares } +// addSharePadding will add padding to the last share if necessary +func addSharePadding(shares [][]byte) [][]byte { + if len(shares) == 0 { + return shares + } + + // add padding to the last share if necessary + if len(shares[len(shares)-1]) != ShareSize { + padded := make([]byte, ShareSize) + copy(padded, shares[len(shares)-1]) + shares[len(shares)-1] = padded + } + + return shares +} + // PowerOf2MountainRange returns the heights of the subtrees for binary merkle // mountian range func PowerOf2MountainRange(l, k uint64) []uint64 { diff --git a/x/lazyledgerapp/types/payformessage_test.go b/x/lazyledgerapp/types/payformessage_test.go index dfa78c571f..8700bf54cb 100644 --- a/x/lazyledgerapp/types/payformessage_test.go +++ b/x/lazyledgerapp/types/payformessage_test.go @@ -111,12 +111,39 @@ func TestGetCommitmentSignBytes(t *testing.T) { TipRateMax: 1000, }, }, - expected: []byte(`{"fee":{"base_rate_max":"10000","tip_rate_max":"1000"},"message_namespace_id":"AQIDBAECAwQ=","message_share_commitment":"kLkMnfL0wruFOdgRJ4KnyjJBLJWlKxbEyks8SI0cfZs=","message_size":"4","nonce":"1"}`), + expected: []byte(`{"fee":{"base_rate_max":"10000","tip_rate_max":"1000"},"message_namespace_id":"AQIDBAECAwQ=","message_share_commitment":"byozRVIrw5NF/rU1PPyq6BAo3g2ny3uLTiOFedtgSwo=","message_size":"4","nonce":"1"}`), }, } for _, tt := range tests { - res, err := tt.msg.GetCommitmentSignBytes(64) + res, err := tt.msg.GetCommitmentSignBytes(SquareSize) assert.NoError(t, err) assert.Equal(t, tt.expected, res) } } + +func TestShareChunkingAndPadding(t *testing.T) { + type test struct { + input []byte + expect [][]byte + } + tests := []test{ + { + input: []byte{1}, + expect: [][]byte{append([]byte{1}, bytes.Repeat([]byte{0}, ShareSize-1)...)}, + }, + { + input: bytes.Repeat([]byte{1}, ShareSize), + expect: [][]byte{bytes.Repeat([]byte{1}, ShareSize)}, + }, + } + for _, tt := range tests { + shares := chunkMessage(tt.input) + shares = addSharePadding(shares) + for _, share := range shares { + if len(share) != ShareSize { + t.Errorf("invalid share length: got %d wanted core.ShareSize (%d)", len(share), ShareSize) + } + } + assert.Equal(t, tt.expect, shares) + } +}