Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(server/v2/cometbft): Add abci unit tests #21020

Merged
merged 38 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
f294fff
coding
hieuvubk Jul 11, 2024
cbd05ce
fixing
hieuvubk Jul 16, 2024
587023f
go mod tidy all
hieuvubk Jul 19, 2024
116e283
remove fmt
hieuvubk Jul 22, 2024
462efb0
helpers
hieuvubk Jul 22, 2024
b17533e
mock store
hieuvubk Jul 22, 2024
2375aa7
add some tests
hieuvubk Jul 22, 2024
44548be
testing
hieuvubk Aug 5, 2024
eede22f
Merge branch 'main' into hieu/comet_mock
hieuvubk Aug 5, 2024
d008afd
test InitChain & FinalizeBlock
hieuvubk Aug 6, 2024
9d604c9
extend vote
hieuvubk Aug 7, 2024
d4866d9
vote
hieuvubk Aug 8, 2024
9bfe6fe
merge main
hieuvubk Aug 8, 2024
07f4fa3
check tx & prepare proposal
hieuvubk Aug 9, 2024
ee055b8
process proposal
hieuvubk Aug 9, 2024
35787e2
mock mempool
hieuvubk Aug 9, 2024
71c4570
merge main
hieuvubk Aug 14, 2024
7bf135c
clean up
hieuvubk Aug 14, 2024
3b6e7ac
merge main
hieuvubk Aug 22, 2024
76ffcaf
more tests
hieuvubk Aug 22, 2024
c1c4159
remove stf export & update tests
hieuvubk Aug 29, 2024
337515c
gofmt
hieuvubk Aug 29, 2024
5afbe85
resolve conflict
hieuvubk Aug 29, 2024
1117fa7
Merge branch 'main' into hieu/comet_mock
hieuvubk Aug 30, 2024
48f13ac
remove
hieuvubk Aug 30, 2024
6a512af
Merge branch 'main' into hieu/comet_mock
hieuvubk Aug 30, 2024
8a01fa2
Merge branch 'main' into hieu/comet_mock
hieuvubk Sep 4, 2024
12e2207
move to internal
hieuvubk Sep 4, 2024
667c1e2
Merge branch 'main' into hieu/comet_mock
hieuvubk Sep 4, 2024
ed8d2bc
Merge branch 'main' into hieu/comet_mock
hieuvubk Sep 4, 2024
7f5c111
Merge branch 'main' into hieu/comet_mock
hieuvubk Sep 5, 2024
5578d48
resolve conflict
hieuvubk Sep 9, 2024
0add40f
Merge branch 'main' into hieu/comet_mock
julienrbrt Sep 9, 2024
f4e1fa4
update max block gas
hieuvubk Sep 9, 2024
f5325d9
Merge branch 'hieu/comet_mock' of https://github.com/cosmos/cosmos-sd…
hieuvubk Sep 9, 2024
12be6e4
update
hieuvubk Sep 9, 2024
96d6f5b
Merge branch 'main' into hieu/comet_mock
hieuvubk Sep 9, 2024
8f7c343
Merge branch 'main' into hieu/comet_mock
hieuvubk Sep 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
879 changes: 879 additions & 0 deletions server/v2/cometbft/abci_test.go

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion server/v2/cometbft/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ replace (
cosmossdk.io/core/testing => ../../../core/testing
cosmossdk.io/server/v2 => ../
cosmossdk.io/server/v2/appmanager => ../appmanager
cosmossdk.io/server/v2/stf => ../stf
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be removed now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no we still need it for tests set up I think

cosmossdk.io/store => ../../../store
cosmossdk.io/store/v2 => ../../../store/v2
cosmossdk.io/x/accounts => ../../../x/accounts
Expand All @@ -27,6 +28,7 @@ require (
cosmossdk.io/log v1.4.1
cosmossdk.io/server/v2 v2.0.0-00010101000000-000000000000
cosmossdk.io/server/v2/appmanager v0.0.0-20240802110823-cffeedff643d
cosmossdk.io/server/v2/stf v0.0.0-20240708142107-25e99c54bac1
cosmossdk.io/store/v2 v2.0.0-00010101000000-000000000000
cosmossdk.io/x/consensus v0.0.0-00010101000000-000000000000
github.com/cometbft/cometbft v1.0.0-rc1
Expand All @@ -39,6 +41,7 @@ require (
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157
google.golang.org/grpc v1.65.0
google.golang.org/protobuf v1.34.2
Expand All @@ -48,6 +51,7 @@ require (
require (
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect
cosmossdk.io/collections v0.4.0 // indirect
cosmossdk.io/core/testing v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/depinject v1.0.0 // indirect
cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 // indirect
cosmossdk.io/math v1.3.0 // indirect
Expand Down Expand Up @@ -124,6 +128,7 @@ require (
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/minio/highwayhash v1.0.2 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
Expand All @@ -149,7 +154,6 @@ require (
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/supranational/blst v0.3.12 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
Expand Down
23 changes: 23 additions & 0 deletions server/v2/cometbft/mock/mock_mempool.go
hieuvubk marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package mock

import (
"context"

"cosmossdk.io/core/transaction"
"cosmossdk.io/server/v2/cometbft/mempool"
)

var _ mempool.Mempool[transaction.Tx] = (*MockMempool[transaction.Tx])(nil)

// MockMempool defines a no-op mempool. Transactions are completely discarded and
// ignored when BaseApp interacts with the mempool.
//
// Note: When this mempool is used, it assumed that an application will rely
// on CometBFT's transaction ordering defined in `RequestPrepareProposal`, which
// is FIFO-ordered by default.
type MockMempool[T transaction.Tx] struct{}

func (MockMempool[T]) Insert(context.Context, T) error { return nil }
func (MockMempool[T]) Select(context.Context, []T) mempool.Iterator[T] { return nil }
func (MockMempool[T]) CountTx() int { return 0 }
func (MockMempool[T]) Remove([]T) error { return nil }
67 changes: 67 additions & 0 deletions server/v2/cometbft/mock/mock_reader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package mock

import (
corestore "cosmossdk.io/core/store"
// ammstore "cosmossdk.io/server/v2/appmanager/store"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, remove those commented imports

// "cosmossdk.io/server/v2/stf/branch"
)

// ReaderMap defines an adapter around a RootStore that only exposes read-only
// operations. This is useful for exposing a read-only view of the RootStore at
// a specific version in history, which could also be the latest state.
type ReaderMap struct {
store *MockStore
version uint64
}

func NewMockReaderMap(v uint64, rs *MockStore) *ReaderMap {
return &ReaderMap{
store: rs,
version: v,
}
}

func (roa *ReaderMap) GetReader(actor []byte) (corestore.Reader, error) {
return NewMockReader(roa.version, roa.store, actor), nil
}

// Reader represents a read-only adapter for accessing data from the root store.
type MockReader struct {
version uint64 // The version of the data.
store *MockStore // The root store to read data from.
actor []byte // The actor associated with the data.
}

func NewMockReader(v uint64, rs *MockStore, actor []byte) *MockReader {
return &MockReader{
version: v,
store: rs,
actor: actor,
}
}

func (roa *MockReader) Has(key []byte) (bool, error) {
val, err := roa.store.GetStateStorage().Has(roa.actor, roa.version, key)
if err != nil {
return false, err
}

return val, nil
}

func (roa *MockReader) Get(key []byte) ([]byte, error) {
result, err := roa.store.GetStateStorage().Get(roa.actor, roa.version, key)
if err != nil {
return nil, err
}

return result, nil
}

func (roa *MockReader) Iterator(start, end []byte) (corestore.Iterator, error) {
return roa.store.GetStateStorage().Iterator(roa.actor, roa.version, start, end)
}

func (roa *MockReader) ReverseIterator(start, end []byte) (corestore.Iterator, error) {
return roa.store.GetStateStorage().ReverseIterator(roa.actor, roa.version, start, end)
}
142 changes: 142 additions & 0 deletions server/v2/cometbft/mock/mock_store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package mock

import (
"crypto/sha256"
"fmt"

"cosmossdk.io/core/log"
corestore "cosmossdk.io/core/store"


storev2 "cosmossdk.io/store/v2"
"cosmossdk.io/store/v2/commitment"
dbm "cosmossdk.io/store/v2/db"
"cosmossdk.io/store/v2/proof"
"cosmossdk.io/store/v2/storage"
"cosmossdk.io/store/v2/storage/sqlite"
"cosmossdk.io/store/v2/commitment/iavl"
)

type MockStore struct {
Storage storev2.VersionedDatabase
Commiter storev2.Committer
}

func NewMockStorage(logger log.Logger, dir string) storev2.VersionedDatabase {
storageDB, _ := sqlite.New(dir)
ss := storage.NewStorageStore(storageDB, logger)
return ss
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle errors in NewMockStorage.

The function does not handle errors from sqlite.New. Consider returning an error to the caller to handle potential failures.

 func NewMockStorage(logger log.Logger, dir string) (storev2.VersionedDatabase, error) {
-  storageDB, _ := sqlite.New(dir)
+  storageDB, err := sqlite.New(dir)
+  if err != nil {
+    return nil, err
+  }
  ss := storage.NewStorageStore(storageDB, logger)
  return ss, nil
}
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func NewMockStorage(logger log.Logger, dir string) storev2.VersionedDatabase {
storageDB, _ := sqlite.New(dir)
ss := storage.NewStorageStore(storageDB, logger)
return ss
}
func NewMockStorage(logger log.Logger, dir string) (storev2.VersionedDatabase, error) {
storageDB, err := sqlite.New(dir)
if err != nil {
return nil, err
}
ss := storage.NewStorageStore(storageDB, logger)
return ss, nil
}


func NewMockCommiter(logger log.Logger, actors ...string) storev2.Committer {
treeMap := make(map[string]commitment.Tree)
for _, actor := range actors {
tree := iavl.NewIavlTree(dbm.NewMemDB(), logger, iavl.DefaultConfig())
treeMap[actor] = tree
}
sc, _ := commitment.NewCommitStore(treeMap, treeMap, dbm.NewMemDB(), logger)
return sc
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle errors in NewMockCommiter.

The function does not handle errors from commitment.NewCommitStore. Consider returning an error to the caller to handle potential failures.

 func NewMockCommiter(logger log.Logger, actors ...string) (storev2.Committer, error) {
   treeMap := make(map[string]commitment.Tree)
   for _, actor := range actors {
     tree := iavl.NewIavlTree(dbm.NewMemDB(), logger, iavl.DefaultConfig())
     treeMap[actor] = tree
   }
-  sc, _ := commitment.NewCommitStore(treeMap, treeMap, dbm.NewMemDB(), logger)
+  sc, err := commitment.NewCommitStore(treeMap, treeMap, dbm.NewMemDB(), logger)
+  if err != nil {
+    return nil, err
+  }
   return sc, nil
}
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func NewMockCommiter(logger log.Logger, actors ...string) storev2.Committer {
treeMap := make(map[string]commitment.Tree)
for _, actor := range actors {
tree := iavl.NewIavlTree(dbm.NewMemDB(), logger, iavl.DefaultConfig())
treeMap[actor] = tree
}
sc, _ := commitment.NewCommitStore(treeMap, treeMap, dbm.NewMemDB(), logger)
return sc
}
func NewMockCommiter(logger log.Logger, actors ...string) (storev2.Committer, error) {
treeMap := make(map[string]commitment.Tree)
for _, actor := range actors {
tree := iavl.NewIavlTree(dbm.NewMemDB(), logger, iavl.DefaultConfig())
treeMap[actor] = tree
}
sc, err := commitment.NewCommitStore(treeMap, treeMap, dbm.NewMemDB(), logger)
if err != nil {
return nil, err
}
return sc, nil
}


func NewMockStore(ss storev2.VersionedDatabase, sc storev2.Committer) *MockStore {
return &MockStore{Storage: ss, Commiter: sc}
}

func (s *MockStore) GetLatestVersion() (uint64, error) {
lastCommitID, err := s.LastCommitID()
if err != nil {
return 0, err
}

return lastCommitID.Version, nil
}

func (s *MockStore) StateLatest() (uint64, corestore.ReaderMap, error) {
v, err := s.GetLatestVersion()
if err != nil {
return 0, nil, err
}

return v, NewMockReaderMap(v, s), nil
}

func (s *MockStore) Commit(changeset *corestore.Changeset) (corestore.Hash, error) {
v, _, _ := s.StateLatest()
err := s.Storage.ApplyChangeset(v, changeset)
if err != nil {
return []byte{}, err
}

err = s.Commiter.WriteChangeset(changeset)
if err != nil {
return []byte{}, err
}

commitInfo, err := s.Commiter.Commit(v+1)
fmt.Println("commitInfo", commitInfo, err)
return []byte{}, err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle errors in Commit.

The function does not handle the error from StateLatest. Consider returning an error to the caller to handle potential failures.

 func (s *MockStore) Commit(changeset *corestore.Changeset) (corestore.Hash, error) {
-  v, _, _ := s.StateLatest()
+  v, _, err := s.StateLatest()
+  if err != nil {
+    return []byte{}, err
+  }
   err := s.Storage.ApplyChangeset(v, changeset)
   if err != nil {
     return []byte{}, err
   }
   err = s.Commiter.WriteChangeset(changeset)
   if err != nil {
     return []byte{}, err
   }
   commitInfo, err := s.Commiter.Commit(v+1)
   fmt.Println("commitInfo", commitInfo, err)
   return []byte{}, err
}
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (s *MockStore) Commit(changeset *corestore.Changeset) (corestore.Hash, error) {
v, _, _ := s.StateLatest()
err := s.Storage.ApplyChangeset(v, changeset)
if err != nil {
return []byte{}, err
}
err = s.Commiter.WriteChangeset(changeset)
if err != nil {
return []byte{}, err
}
commitInfo, err := s.Commiter.Commit(v+1)
fmt.Println("commitInfo", commitInfo, err)
return []byte{}, err
func (s *MockStore) Commit(changeset *corestore.Changeset) (corestore.Hash, error) {
v, _, err := s.StateLatest()
if err != nil {
return []byte{}, err
}
err := s.Storage.ApplyChangeset(v, changeset)
if err != nil {
return []byte{}, err
}
err = s.Commiter.WriteChangeset(changeset)
if err != nil {
return []byte{}, err
}
commitInfo, err := s.Commiter.Commit(v+1)
fmt.Println("commitInfo", commitInfo, err)
return []byte{}, err
}

}

func (s *MockStore) StateAt(version uint64) (corestore.ReaderMap, error) {
info, err := s.Commiter.GetCommitInfo(version)
if err != nil || info == nil {
return nil, fmt.Errorf("failed to get commit info for version %d: %w", version, err)
}
return NewMockReaderMap(version, s), nil
}

func (s *MockStore) GetStateStorage() storev2.VersionedDatabase {
return s.Storage
}

func (s *MockStore) GetStateCommitment() storev2.Committer {
return s.Commiter
}

type Result struct {
key []byte
value []byte
version uint64
proofOps []proof.CommitmentOp
}

func (s *MockStore) Query(storeKey []byte, version uint64, key []byte, prove bool) (storev2.QueryResult, error) {
state, err := s.StateAt(version)
Fixed Show fixed Hide fixed
reader, err := state.GetReader(storeKey)
Fixed Show fixed Hide fixed
value, err := reader.Get(key)
res := storev2.QueryResult{
Key: key,
Value: value,
Version: version,
}
return res, err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address unused variables and handle errors in Query.

The existing comments indicate that err is unused. Additionally, the function does not handle errors from StateAt and GetReader. Consider handling these errors to ensure robustness.

 func (s *MockStore) Query(storeKey []byte, version uint64, key []byte, prove bool) (storev2.QueryResult, error) {
-  state, err := s.StateAt(version)
-  reader, err := state.GetReader(storeKey)
-  value, err := reader.Get(key)
+  state, err := s.StateAt(version)
+  if err != nil {
+    return storev2.QueryResult{}, err
+  }
+  reader, err := state.GetReader(storeKey)
+  if err != nil {
+    return storev2.QueryResult{}, err
+  }
+  value, err := reader.Get(key)
+  if err != nil {
+    return storev2.QueryResult{}, err
+  }
   res := storev2.QueryResult{
     Key:     key,
     Value:   value,
     Version: version,
   }
   return res, err
}
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (s *MockStore) Query(storeKey []byte, version uint64, key []byte, prove bool) (storev2.QueryResult, error) {
state, err := s.StateAt(version)
reader, err := state.GetReader(storeKey)
value, err := reader.Get(key)
res := storev2.QueryResult{
Key: key,
Value: value,
Version: version,
}
return res, err
func (s *MockStore) Query(storeKey []byte, version uint64, key []byte, prove bool) (storev2.QueryResult, error) {
state, err := s.StateAt(version)
if err != nil {
return storev2.QueryResult{}, err
}
reader, err := state.GetReader(storeKey)
if err != nil {
return storev2.QueryResult{}, err
}
value, err := reader.Get(key)
if err != nil {
return storev2.QueryResult{}, err
}
res := storev2.QueryResult{
Key: key,
Value: value,
Version: version,
}
return res, err
}

}

func (s *MockStore) LastCommitID() (proof.CommitID, error) {
v, err := s.GetStateCommitment().GetLatestVersion()
bz := sha256.Sum256([]byte{})
return proof.CommitID{
Version: v,
Hash: bz[:],
}, err
}

func (s *MockStore) SetInitialVersion(v uint64) error {
return s.Commiter.SetInitialVersion(v)
}

func (s *MockStore) WorkingHash(changeset *corestore.Changeset) (corestore.Hash, error) {
v, _, _ := s.StateLatest()
err := s.Storage.ApplyChangeset(v, changeset)
if err != nil {
return []byte{}, err
}

err = s.Commiter.WriteChangeset(changeset)
if err != nil {
return []byte{}, err
}
return []byte{}, nil
}


13 changes: 0 additions & 13 deletions server/v2/stf/export_test.go

This file was deleted.

31 changes: 31 additions & 0 deletions server/v2/stf/helper.go
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imho we shouldn't expose those APIs. We wouldn't want anyone to use this (even if we say it is for test only).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that hard, need someway to access to state inside 😅

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package stf

import (
"context"

"cosmossdk.io/core/store"
"cosmossdk.io/server/v2/stf/mock"
)

// There some field not be exported
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally do not like that we need to expose this.
If we make this public, anyone can use and abuse it.
Before it was in a export_test.go file, so it is public but only for stf tests, which is okay.

cc @testinginprod for thoughts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is no bueno

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed stf exports, assert by store height & commit info. Ty guys

// Helpers for cometbft test

func GetExecutionContext(ctx context.Context) *executionContext {
executionCtx, ok := ctx.(*executionContext)
if !ok {
return nil
}
return executionCtx
}

func GetStateFromContext(ctx *executionContext) store.WriterMap {
return ctx.state
}

func SetMsgRouter(s *STF[mock.Tx], msgRouter coreRouterImpl) {
s.msgRouter = msgRouter
}

func SetQueryRouter(s *STF[mock.Tx], queryRouter coreRouterImpl) {
s.queryRouter = queryRouter
}
26 changes: 14 additions & 12 deletions server/v2/stf/mock/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,56 +65,58 @@ func (t Tx) Bytes() []byte {
return tx
}

func (t *Tx) Decode(b []byte) {
func (t *Tx) Decode(b []byte) error {
rawTx := new(encodedTx)
err := json.Unmarshal(b, rawTx)
if err != nil {
panic(err)
return err
}
msgName, err := gogoproto.AnyMessageName(rawTx.Msg)
msgType := proto.MessageType(msgName).Elem()
if err != nil {
panic(err)
return err
}
msg := reflect.New(msgType).Interface().(proto.Message)
if err := gogoproto.UnmarshalAny(rawTx.Msg, msg); err != nil {
panic(err)
return err
}
t.Msg = msg
t.Sender = rawTx.Sender
t.GasLimit = rawTx.GasLimit
return nil
}

func (t *Tx) DecodeJSON(b []byte) {
func (t *Tx) DecodeJSON(b []byte) error {
rawTx := new(encodedTx)
err := json.Unmarshal(b, rawTx)
if err != nil {
panic(err)
return err
}
msgName, err := gogoproto.AnyMessageName(rawTx.Msg)
msgType := proto.MessageType(msgName).Elem()
if err != nil {
panic(err)
return err
}
msg := reflect.New(msgType).Interface().(transaction.Msg)
if err := gogoproto.UnmarshalAny(rawTx.Msg, msg); err != nil {
panic(err)
return err
}
t.Msg = msg
t.Sender = rawTx.Sender
t.GasLimit = rawTx.GasLimit
return nil
}

type TxCodec struct{}

func (TxCodec) Decode(bytes []byte) (Tx, error) {
t := new(Tx)
t.Decode(bytes)
return *t, nil
err := t.Decode(bytes)
return *t, err
}

func (TxCodec) DecodeJSON(bytes []byte) (Tx, error) {
t := new(Tx)
t.DecodeJSON(bytes)
return *t, nil
err := t.DecodeJSON(bytes)
return *t, err
}
Loading
Loading