From 4d0da50e4144aff38697b630b4b0032126d9f170 Mon Sep 17 00:00:00 2001 From: Callum Waters Date: Tue, 24 Aug 2021 13:24:44 +0200 Subject: [PATCH] move abci types into pkg --- {abci/types => pkg/abci}/application.go | 2 +- {abci/types => pkg/abci}/messages.go | 2 +- {abci/types => pkg/abci}/messages_test.go | 2 +- {abci/types => pkg/abci}/pubkey.go | 2 +- {abci/types => pkg/abci}/result.go | 2 +- pkg/abci/results.go | 53 ++++++++++++++++++++++ pkg/abci/results_test.go | 54 +++++++++++++++++++++++ {abci/types => pkg/abci}/types.pb.go | 2 +- {abci/types => pkg/abci}/util.go | 2 +- 9 files changed, 114 insertions(+), 7 deletions(-) rename {abci/types => pkg/abci}/application.go (99%) rename {abci/types => pkg/abci}/messages.go (99%) rename {abci/types => pkg/abci}/messages_test.go (99%) rename {abci/types => pkg/abci}/pubkey.go (98%) rename {abci/types => pkg/abci}/result.go (99%) create mode 100644 pkg/abci/results.go create mode 100644 pkg/abci/results_test.go rename {abci/types => pkg/abci}/types.pb.go (99%) rename {abci/types => pkg/abci}/util.go (98%) diff --git a/abci/types/application.go b/pkg/abci/application.go similarity index 99% rename from abci/types/application.go rename to pkg/abci/application.go index 2a3cabd8b..1d672ecaf 100644 --- a/abci/types/application.go +++ b/pkg/abci/application.go @@ -1,4 +1,4 @@ -package types +package abci import ( "context" diff --git a/abci/types/messages.go b/pkg/abci/messages.go similarity index 99% rename from abci/types/messages.go rename to pkg/abci/messages.go index 74f3cc75c..d908697fb 100644 --- a/abci/types/messages.go +++ b/pkg/abci/messages.go @@ -1,4 +1,4 @@ -package types +package abci import ( "io" diff --git a/abci/types/messages_test.go b/pkg/abci/messages_test.go similarity index 99% rename from abci/types/messages_test.go rename to pkg/abci/messages_test.go index 491d10c7f..d8adcb103 100644 --- a/abci/types/messages_test.go +++ b/pkg/abci/messages_test.go @@ -1,4 +1,4 @@ -package types +package abci import ( "bytes" diff --git a/abci/types/pubkey.go b/pkg/abci/pubkey.go similarity index 98% rename from abci/types/pubkey.go rename to pkg/abci/pubkey.go index a0f746992..a2eeed8a2 100644 --- a/abci/types/pubkey.go +++ b/pkg/abci/pubkey.go @@ -1,4 +1,4 @@ -package types +package abci import ( fmt "fmt" diff --git a/abci/types/result.go b/pkg/abci/result.go similarity index 99% rename from abci/types/result.go rename to pkg/abci/result.go index dba6bfd15..a9279474d 100644 --- a/abci/types/result.go +++ b/pkg/abci/result.go @@ -1,4 +1,4 @@ -package types +package abci import ( "bytes" diff --git a/pkg/abci/results.go b/pkg/abci/results.go new file mode 100644 index 000000000..3d5b76e1f --- /dev/null +++ b/pkg/abci/results.go @@ -0,0 +1,53 @@ +package abci + +import ( + "github.com/tendermint/tendermint/crypto/merkle" +) + +// ABCIResults wraps the deliver tx results to return a proof. +type ABCIResults []*ResponseDeliverTx + +// NewResults strips non-deterministic fields from ResponseDeliverTx responses +// and returns ABCIResults. +func NewResults(responses []*ResponseDeliverTx) ABCIResults { + res := make(ABCIResults, len(responses)) + for i, d := range responses { + res[i] = deterministicResponseDeliverTx(d) + } + return res +} + +// Hash returns a merkle hash of all results. +func (a ABCIResults) Hash() []byte { + return merkle.HashFromByteSlices(a.toByteSlices()) +} + +// ProveResult returns a merkle proof of one result from the set +func (a ABCIResults) ProveResult(i int) merkle.Proof { + _, proofs := merkle.ProofsFromByteSlices(a.toByteSlices()) + return *proofs[i] +} + +func (a ABCIResults) toByteSlices() [][]byte { + l := len(a) + bzs := make([][]byte, l) + for i := 0; i < l; i++ { + bz, err := a[i].Marshal() + if err != nil { + panic(err) + } + bzs[i] = bz + } + return bzs +} + +// deterministicResponseDeliverTx strips non-deterministic fields from +// ResponseDeliverTx and returns another ResponseDeliverTx. +func deterministicResponseDeliverTx(response *ResponseDeliverTx) *ResponseDeliverTx { + return &ResponseDeliverTx{ + Code: response.Code, + Data: response.Data, + GasWanted: response.GasWanted, + GasUsed: response.GasUsed, + } +} diff --git a/pkg/abci/results_test.go b/pkg/abci/results_test.go new file mode 100644 index 000000000..2240682ce --- /dev/null +++ b/pkg/abci/results_test.go @@ -0,0 +1,54 @@ +package abci_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/tendermint/tendermint/pkg/abci" +) + +func TestABCIResults(t *testing.T) { + a := &abci.ResponseDeliverTx{Code: 0, Data: nil} + b := &abci.ResponseDeliverTx{Code: 0, Data: []byte{}} + c := &abci.ResponseDeliverTx{Code: 0, Data: []byte("one")} + d := &abci.ResponseDeliverTx{Code: 14, Data: nil} + e := &abci.ResponseDeliverTx{Code: 14, Data: []byte("foo")} + f := &abci.ResponseDeliverTx{Code: 14, Data: []byte("bar")} + + // Nil and []byte{} should produce the same bytes + bzA, err := a.Marshal() + require.NoError(t, err) + bzB, err := b.Marshal() + require.NoError(t, err) + + require.Equal(t, bzA, bzB) + + // a and b should be the same, don't go in results. + results := abci.ABCIResults{a, c, d, e, f} + + // Make sure each result serializes differently + last := []byte{} + assert.Equal(t, last, bzA) // first one is empty + for i, res := range results[1:] { + bz, err := res.Marshal() + require.NoError(t, err) + + assert.NotEqual(t, last, bz, "%d", i) + last = bz + } + + // Make sure that we can get a root hash from results and verify proofs. + root := results.Hash() + assert.NotEmpty(t, root) + + for i, res := range results { + bz, err := res.Marshal() + require.NoError(t, err) + + proof := results.ProveResult(i) + valid := proof.Verify(root, bz) + assert.NoError(t, valid, "%d", i) + } +} diff --git a/abci/types/types.pb.go b/pkg/abci/types.pb.go similarity index 99% rename from abci/types/types.pb.go rename to pkg/abci/types.pb.go index 6b00c587a..0881ff394 100644 --- a/abci/types/types.pb.go +++ b/pkg/abci/types.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: tendermint/abci/types.proto -package types +package abci import ( context "context" diff --git a/abci/types/util.go b/pkg/abci/util.go similarity index 98% rename from abci/types/util.go rename to pkg/abci/util.go index 8205fef7e..0ca04b510 100644 --- a/abci/types/util.go +++ b/pkg/abci/util.go @@ -1,4 +1,4 @@ -package types +package abci import ( "sort"