From fed6230e308bc1434dbebe520156e27703b18aec Mon Sep 17 00:00:00 2001 From: Silas Davis Date: Thu, 10 Oct 2019 13:02:42 -0500 Subject: [PATCH 1/2] Split out metadata cache and interfaces to avoid forcing downstream to implement them Signed-off-by: Silas Davis --- acm/acmstate/metadata_cache.go | 82 ++++++++++++++++++++++++++++ acm/acmstate/state.go | 11 ++-- acm/acmstate/state_cache.go | 60 -------------------- core/processes.go | 8 +-- execution/contexts/call_context.go | 30 ++++++---- execution/execution.go | 26 +++++---- execution/native/account.go | 4 +- execution/native/state.go | 8 --- execution/simulated_call.go | 11 ++-- execution/state/state.go | 1 + integration/rpctransact/call_test.go | 6 +- rpc/rpcquery/query_server.go | 66 +++++++++++----------- 12 files changed, 170 insertions(+), 143 deletions(-) create mode 100644 acm/acmstate/metadata_cache.go diff --git a/acm/acmstate/metadata_cache.go b/acm/acmstate/metadata_cache.go new file mode 100644 index 000000000..acbe60a05 --- /dev/null +++ b/acm/acmstate/metadata_cache.go @@ -0,0 +1,82 @@ +package acmstate + +import ( + "sync" +) + +type metadataInfo struct { + metadata string + updated bool +} + +type MetadataCache struct { + backend MetadataReader + m sync.Map +} + +func NewMetadataCache(backend MetadataReader) *MetadataCache { + return &MetadataCache{ + backend: backend, + } +} + +func (cache *MetadataCache) SetMetadata(metahash MetadataHash, metadata string) error { + cache.m.Store(metahash, &metadataInfo{updated: true, metadata: metadata}) + return nil +} + +func (cache *MetadataCache) GetMetadata(metahash MetadataHash) (string, error) { + metaInfo, err := cache.getMetadata(metahash) + if err != nil { + return "", err + } + + return metaInfo.metadata, nil +} + +// Syncs changes to the backend in deterministic order. Sends storage updates before updating +// the account they belong so that storage values can be taken account of in the update. +func (cache *MetadataCache) Sync(st MetadataWriter) error { + var err error + cache.m.Range(func(key, value interface{}) bool { + hash := key.(MetadataHash) + info := value.(*metadataInfo) + if info.updated { + err = st.SetMetadata(hash, info.metadata) + if err != nil { + return false + } + } + return true + }) + if err != nil { + return err + } + return nil +} + +func (cache *MetadataCache) Flush(output MetadataWriter, backend MetadataReader) error { + err := cache.Sync(output) + if err != nil { + return err + } + cache.m = sync.Map{} + return nil +} + +// Get the cache accountInfo item creating it if necessary +func (cache *MetadataCache) getMetadata(metahash MetadataHash) (*metadataInfo, error) { + value, ok := cache.m.Load(metahash) + if !ok { + metadata, err := cache.backend.GetMetadata(metahash) + if err != nil { + return nil, err + } + metaInfo := &metadataInfo{ + metadata: metadata, + } + cache.m.Store(metahash, metaInfo) + return metaInfo, nil + } + return value.(*metadataInfo), nil +} diff --git a/acm/acmstate/state.go b/acm/acmstate/state.go index 6d7b92adc..b7ba23f21 100644 --- a/acm/acmstate/state.go +++ b/acm/acmstate/state.go @@ -110,12 +110,12 @@ type StorageIterable interface { IterateStorage(address crypto.Address, consumer func(key binary.Word256, value []byte) error) (err error) } -type MetadataGetter interface { +type MetadataReader interface { // Get an Metadata by its hash. This is content-addressed GetMetadata(metahash MetadataHash) (string, error) } -type MetadataSetter interface { +type MetadataWriter interface { // Set an Metadata according to it keccak-256 hash. SetMetadata(metahash MetadataHash, metadata string) error } @@ -135,7 +135,6 @@ type AccountStatsGetter interface { type Reader interface { AccountGetter StorageGetter - MetadataGetter } type Iterable interface { @@ -158,7 +157,6 @@ type IterableStatsReader interface { type Writer interface { AccountUpdater StorageSetter - MetadataSetter } // Read and write account and storage state @@ -167,6 +165,11 @@ type ReaderWriter interface { Writer } +type MetadataReaderWriter interface { + MetadataReader + MetadataWriter +} + type IterableReaderWriter interface { Iterable Reader diff --git a/acm/acmstate/state_cache.go b/acm/acmstate/state_cache.go index baf801c1c..e6fac7fdb 100644 --- a/acm/acmstate/state_cache.go +++ b/acm/acmstate/state_cache.go @@ -19,7 +19,6 @@ type Cache struct { name string backend Reader accounts map[crypto.Address]*accountInfo - metadata map[MetadataHash]*metadataInfo readonly bool } @@ -31,11 +30,6 @@ type accountInfo struct { updated bool } -type metadataInfo struct { - metadata string - updated bool -} - type CacheOption func(*Cache) *Cache // Returns a Cache that wraps an underlying Reader to use on a cache miss, can write to an output Writer @@ -44,7 +38,6 @@ func NewCache(backend Reader, options ...CacheOption) *Cache { cache := &Cache{ backend: backend, accounts: make(map[crypto.Address]*accountInfo), - metadata: make(map[MetadataHash]*metadataInfo), } for _, option := range options { option(cache) @@ -99,28 +92,6 @@ func (cache *Cache) UpdateAccount(account *acm.Account) error { return nil } -func (cache *Cache) GetMetadata(metahash MetadataHash) (string, error) { - metaInfo, err := cache.getMetadata(metahash) - if err != nil { - return "", err - } - - return metaInfo.metadata, nil -} - -func (cache *Cache) SetMetadata(metahash MetadataHash, metadata string) error { - if cache.readonly { - return errors.Errorf(errors.Codes.IllegalWrite, "SetMetadata called in read-only context on metadata hash: %v", metahash) - } - - cache.Lock() - defer cache.Unlock() - - cache.metadata[metahash] = &metadataInfo{updated: true, metadata: metadata} - - return nil -} - func (cache *Cache) RemoveAccount(address crypto.Address) error { if cache.readonly { return errors.Errorf(errors.Codes.IllegalWrite, "RemoveAccount called on read-only account %v", address) @@ -268,14 +239,6 @@ func (cache *Cache) Sync(st Writer) error { accInfo.RUnlock() } - for metahash, metadataInfo := range cache.metadata { - if metadataInfo.updated { - err := st.SetMetadata(metahash, metadataInfo.metadata) - if err != nil { - return err - } - } - } return nil } @@ -327,26 +290,3 @@ func (cache *Cache) get(address crypto.Address) (*accountInfo, error) { } return accInfo, nil } - -// Get the cache accountInfo item creating it if necessary -func (cache *Cache) getMetadata(metahash MetadataHash) (*metadataInfo, error) { - cache.RLock() - metaInfo := cache.metadata[metahash] - cache.RUnlock() - if metaInfo == nil { - cache.Lock() - defer cache.Unlock() - metaInfo = cache.metadata[metahash] - if metaInfo == nil { - metadata, err := cache.backend.GetMetadata(metahash) - if err != nil { - return nil, err - } - metaInfo = &metadataInfo{ - metadata: metadata, - } - cache.metadata[metahash] = metaInfo - } - } - return metaInfo, nil -} diff --git a/core/processes.go b/core/processes.go index 3dd1cb5a7..5a1146529 100644 --- a/core/processes.go +++ b/core/processes.go @@ -309,12 +309,8 @@ func GRPCLauncher(kern *Kernel, conf *rpc.ServerConfig, keyConfig *keys.KeysConf } keys.RegisterKeysServer(grpcServer, ks) } - - nameRegState := kern.State - nodeRegState := kern.State - proposalRegState := kern.State - rpcquery.RegisterQueryServer(grpcServer, rpcquery.NewQueryServer(kern.State, nameRegState, nodeRegState, proposalRegState, - kern.Blockchain, kern.State, nodeView, kern.Logger)) + rpcquery.RegisterQueryServer(grpcServer, rpcquery.NewQueryServer(kern.State, kern.Blockchain, nodeView, + kern.Logger)) txCodec := txs.NewProtobufCodec() rpctransact.RegisterTransactServer(grpcServer, diff --git a/execution/contexts/call_context.go b/execution/contexts/call_context.go index 4d94d047a..299725b75 100644 --- a/execution/contexts/call_context.go +++ b/execution/contexts/call_context.go @@ -21,13 +21,14 @@ import ( const GasLimit = uint64(1000000) type CallContext struct { - EVM *evm.EVM - State acmstate.ReaderWriter - Blockchain engine.Blockchain - RunCall bool - Logger *logging.Logger - tx *payload.CallTx - txe *exec.TxExecution + EVM *evm.EVM + State acmstate.ReaderWriter + MetadataState acmstate.MetadataReaderWriter + Blockchain engine.Blockchain + RunCall bool + Logger *logging.Logger + tx *payload.CallTx + txe *exec.TxExecution } func (ctx *CallContext) Execute(txe *exec.TxExecution, p payload.Payload) error { @@ -121,6 +122,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error createContract := ctx.tx.Address == nil caller := inAcc.Address txCache := acmstate.NewCache(ctx.State, acmstate.Named("TxCache")) + metaCache := acmstate.NewMetadataCache(ctx.MetadataState) var callee crypto.Address var code []byte @@ -141,7 +143,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error "init_code", code) // store abis - err = native.UpdateContractMeta(txCache, callee, ctx.tx.ContractMeta) + err = native.UpdateContractMeta(txCache, metaCache, callee, ctx.tx.ContractMeta) if err != nil { return err } @@ -198,7 +200,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error ctx.txe.PushError(errors.Wrap(err, "call error")) } else { ctx.Logger.TraceMsg("Successful execution") - err := txCache.Sync(ctx.State) + err = ctx.Sync(txCache, metaCache) if err != nil { return err } @@ -234,7 +236,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error return err } } - err := txCache.Sync(ctx.State) + err = ctx.Sync(txCache, metaCache) if err != nil { return err } @@ -259,3 +261,11 @@ func (ctx *CallContext) CallEvents(err error) { ctx.txe.Input(*ctx.tx.Address, errors.AsException(err)) } } + +func (ctx *CallContext) Sync(cache *acmstate.Cache, metaCache *acmstate.MetadataCache) error { + err := cache.Sync(ctx.State) + if err != nil { + return err + } + return metaCache.Sync(ctx.MetadataState) +} diff --git a/execution/execution.go b/execution/execution.go index 547638c83..a9c03fa50 100644 --- a/execution/execution.go +++ b/execution/execution.go @@ -45,10 +45,11 @@ func (f ExecutorFunc) Execute(txEnv *txs.Envelope) (*exec.TxExecution, error) { type ExecutorState interface { Update(updater func(ws state.Updatable) error) (hash []byte, version int64, err error) + acmstate.IterableReader + acmstate.MetadataReader names.Reader registry.Reader proposal.Reader - acmstate.IterableReader validator.IterableReader } @@ -76,6 +77,7 @@ type executor struct { params Params state ExecutorState stateCache *acmstate.Cache + metadataCache *acmstate.MetadataCache nameRegCache *names.Cache nodeRegCache *registry.Cache proposalRegCache *proposal.Cache @@ -124,6 +126,7 @@ func newExecutor(name string, runCall bool, params Params, backend ExecutorState params: params, state: backend, stateCache: acmstate.NewCache(backend, acmstate.Named(name)), + metadataCache: acmstate.NewMetadataCache(backend), nameRegCache: names.NewCache(backend), nodeRegCache: registry.NewCache(backend), proposalRegCache: proposal.NewCache(backend), @@ -140,11 +143,12 @@ func newExecutor(name string, runCall bool, params Params, backend ExecutorState baseContexts := map[payload.Type]contexts.Context{ payload.TypeCall: &contexts.CallContext{ - EVM: evm.New(exe.vmOptions), - Blockchain: blockchain, - State: exe.stateCache, - RunCall: runCall, - Logger: exe.logger, + EVM: evm.New(exe.vmOptions), + Blockchain: blockchain, + State: exe.stateCache, + MetadataState: exe.metadataCache, + RunCall: runCall, + Logger: exe.logger, }, payload.TypeSend: &contexts.SendContext{ State: exe.stateCache, @@ -355,6 +359,10 @@ func (exe *executor) Commit(header *abciTypes.Header) (stateHash []byte, err err if err != nil { return err } + err = exe.metadataCache.Flush(ws, exe.state) + if err != nil { + return err + } err = exe.nameRegCache.Flush(ws, exe.state) if err != nil { return err @@ -411,12 +419,6 @@ func (exe *executor) GetAccount(address crypto.Address) (*acm.Account, error) { return exe.stateCache.GetAccount(address) } -func (exe *executor) GetMetadata(metahash acmstate.MetadataHash) (string, error) { - exe.RLock() - defer exe.RUnlock() - return exe.stateCache.GetMetadata(metahash) -} - // Storage func (exe *executor) GetStorage(address crypto.Address, key binary.Word256) ([]byte, error) { exe.RLock() diff --git a/execution/native/account.go b/execution/native/account.go index 945a40b4e..fd073aae2 100644 --- a/execution/native/account.go +++ b/execution/native/account.go @@ -155,7 +155,7 @@ func Transfer(st acmstate.ReaderWriter, from, to crypto.Address, amount uint64) }) } -func UpdateContractMeta(st acmstate.ReaderWriter, address crypto.Address, payloadMeta []*payload.ContractMeta) error { +func UpdateContractMeta(st acmstate.ReaderWriter, metaSt acmstate.MetadataWriter, address crypto.Address, payloadMeta []*payload.ContractMeta) error { if len(payloadMeta) == 0 { return nil } @@ -171,7 +171,7 @@ func UpdateContractMeta(st acmstate.ReaderWriter, address crypto.Address, payloa MetadataHash: metahash[:], CodeHash: abi.CodeHash, } - err = st.SetMetadata(metahash, abi.Meta) + err = metaSt.SetMetadata(metahash, abi.Meta) if err != nil { return errors.Errorf(errors.Codes.IllegalWrite, "cannot update metadata for %v: %v", address, err) diff --git a/execution/native/state.go b/execution/native/state.go index f0982f0dc..96d2dc3a7 100644 --- a/execution/native/state.go +++ b/execution/native/state.go @@ -64,14 +64,6 @@ func (s *State) SetStorage(address crypto.Address, key binary.Word256, value []b return s.backend.SetStorage(address, key, value) } -func (s *State) GetMetadata(metahash acmstate.MetadataHash) (string, error) { - return s.backend.GetMetadata(metahash) -} - -func (s *State) SetMetadata(metahash acmstate.MetadataHash, metadata string) error { - return s.backend.SetMetadata(metahash, metadata) -} - func (s *State) ensureNonNative(address crypto.Address, action string) error { contract := s.natives.GetByAddress(address) if contract != nil { diff --git a/execution/simulated_call.go b/execution/simulated_call.go index 0c8cfb0af..5af263ec1 100644 --- a/execution/simulated_call.go +++ b/execution/simulated_call.go @@ -20,11 +20,12 @@ func CallSim(reader acmstate.Reader, blockchain bcm.BlockchainInfo, fromAddress, cache := acmstate.NewCache(reader) exe := contexts.CallContext{ - EVM: evm.Default(), - RunCall: true, - State: cache, - Blockchain: blockchain, - Logger: logger, + EVM: evm.Default(), + RunCall: true, + State: cache, + MetadataState: acmstate.NewMemoryState(), + Blockchain: blockchain, + Logger: logger, } txe := exec.NewTxExecution(txs.Enclose(blockchain.ChainID(), &payload.CallTx{ diff --git a/execution/state/state.go b/execution/state/state.go index e6ffad094..538e598f2 100644 --- a/execution/state/state.go +++ b/execution/state/state.go @@ -93,6 +93,7 @@ type Updatable interface { proposal.Writer registry.Writer validator.Writer + acmstate.MetadataWriter AddBlock(blockExecution *exec.BlockExecution) error } diff --git a/integration/rpctransact/call_test.go b/integration/rpctransact/call_test.go index b77b83dc3..8778d1e7b 100644 --- a/integration/rpctransact/call_test.go +++ b/integration/rpctransact/call_test.go @@ -310,7 +310,7 @@ func testCallTx(t *testing.T, kern *core.Kernel, cli rpctransact.TransactClient) qcli := rpctest.NewQueryClient(t, kern.GRPCListenAddress().String()) res, err := qcli.GetMetadata(context.Background(), &rpcquery.GetMetadataParam{Address: &addressA}) require.NoError(t, err) - assert.Equal(t, res.Metadata, string(solidity.Abi_A)) + assert.Equal(t, string(solidity.Abi_A), res.Metadata) // CreateB spec, err := abi.ReadSpec(solidity.Abi_A) require.NoError(t, err) @@ -323,7 +323,7 @@ func testCallTx(t *testing.T, kern *core.Kernel, cli rpctransact.TransactClient) // check ABI for contract B res, err = qcli.GetMetadata(context.Background(), &rpcquery.GetMetadataParam{Address: &addressB}) require.NoError(t, err) - assert.Equal(t, res.Metadata, string(solidity.Abi_B)) + assert.Equal(t, string(solidity.Abi_B), res.Metadata) // CreateC spec, err = abi.ReadSpec(solidity.Abi_B) require.NoError(t, err) @@ -336,7 +336,7 @@ func testCallTx(t *testing.T, kern *core.Kernel, cli rpctransact.TransactClient) // check abi for contract C res, err = qcli.GetMetadata(context.Background(), &rpcquery.GetMetadataParam{Address: &addressC}) require.NoError(t, err) - assert.Equal(t, res.Metadata, string(solidity.Abi_C)) + assert.Equal(t, string(solidity.Abi_C), res.Metadata) return }) diff --git a/rpc/rpcquery/query_server.go b/rpc/rpcquery/query_server.go index f67ff58b5..7254b4378 100644 --- a/rpc/rpcquery/query_server.go +++ b/rpc/rpcquery/query_server.go @@ -25,40 +25,40 @@ import ( ) type queryServer struct { - accounts acmstate.IterableStatsReader - nameReg names.IterableReader - nodeReg registry.IterableReader - proposalReg proposal.IterableReader - blockchain bcm.BlockchainInfo - validators validator.History - nodeView *tendermint.NodeView - logger *logging.Logger + state QueryState + blockchain bcm.BlockchainInfo + nodeView *tendermint.NodeView + logger *logging.Logger } var _ QueryServer = &queryServer{} -func NewQueryServer(state acmstate.IterableStatsReader, nameReg names.IterableReader, nodeReg registry.IterableReader, proposalReg proposal.IterableReader, - blockchain bcm.BlockchainInfo, validators validator.History, nodeView *tendermint.NodeView, logger *logging.Logger) *queryServer { +type QueryState interface { + acmstate.IterableStatsReader + acmstate.MetadataReader + names.IterableReader + registry.IterableReader + proposal.IterableReader + validator.History +} + +func NewQueryServer(state QueryState, blockchain bcm.BlockchainInfo, nodeView *tendermint.NodeView, logger *logging.Logger) *queryServer { return &queryServer{ - accounts: state, - nameReg: nameReg, - nodeReg: nodeReg, - proposalReg: proposalReg, - blockchain: blockchain, - validators: validators, - nodeView: nodeView, - logger: logger, + state: state, + blockchain: blockchain, + nodeView: nodeView, + logger: logger, } } func (qs *queryServer) Status(ctx context.Context, param *StatusParam) (*rpc.ResultStatus, error) { - return rpc.Status(qs.blockchain, qs.validators, qs.nodeView, param.BlockTimeWithin, param.BlockSeenTimeWithin) + return rpc.Status(qs.blockchain, qs.state, qs.nodeView, param.BlockTimeWithin, param.BlockSeenTimeWithin) } // Account state func (qs *queryServer) GetAccount(ctx context.Context, param *GetAccountParam) (*acm.Account, error) { - acc, err := qs.accounts.GetAccount(param.Address) + acc, err := qs.state.GetAccount(param.Address) if acc == nil { acc = &acm.Account{} } @@ -72,14 +72,14 @@ func (qs *queryServer) GetMetadata(ctx context.Context, param *GetMetadataParam) var contractMeta *acm.ContractMeta var err error if param.Address != nil { - acc, err := qs.accounts.GetAccount(*param.Address) + acc, err := qs.state.GetAccount(*param.Address) if err != nil { return metadata, err } if acc != nil && acc.CodeHash != nil { codehash := acc.CodeHash if acc.Forebear != nil { - acc, err = qs.accounts.GetAccount(*acc.Forebear) + acc, err = qs.state.GetAccount(*acc.Forebear) if err != nil { return metadata, err } @@ -116,13 +116,13 @@ func (qs *queryServer) GetMetadata(ctx context.Context, param *GetMetadataParam) } else { var metadataHash acmstate.MetadataHash copy(metadataHash[:], contractMeta.MetadataHash) - metadata.Metadata, err = qs.accounts.GetMetadata(metadataHash) + metadata.Metadata, err = qs.state.GetMetadata(metadataHash) } return metadata, err } func (qs *queryServer) GetStorage(ctx context.Context, param *GetStorageParam) (*StorageValue, error) { - val, err := qs.accounts.GetStorage(param.Address, param.Key) + val, err := qs.state.GetStorage(param.Address, param.Key) return &StorageValue{Value: val}, err } @@ -132,7 +132,7 @@ func (qs *queryServer) ListAccounts(param *ListAccountsParam, stream Query_ListA return err } var streamErr error - err = qs.accounts.IterateAccounts(func(acc *acm.Account) error { + err = qs.state.IterateAccounts(func(acc *acm.Account) error { if qry.Matches(acc) { return stream.Send(acc) } else { @@ -148,7 +148,7 @@ func (qs *queryServer) ListAccounts(param *ListAccountsParam, stream Query_ListA // Names func (qs *queryServer) GetName(ctx context.Context, param *GetNameParam) (entry *names.Entry, err error) { - entry, err = qs.nameReg.GetName(param.Name) + entry, err = qs.state.GetName(param.Name) if entry == nil && err == nil { err = fmt.Errorf("name %s not found", param.Name) } @@ -161,7 +161,7 @@ func (qs *queryServer) ListNames(param *ListNamesParam, stream Query_ListNamesSe return err } var streamErr error - err = qs.nameReg.IterateNames(func(entry *names.Entry) error { + err = qs.state.IterateNames(func(entry *names.Entry) error { if qry.Matches(entry) { return stream.Send(entry) } else { @@ -177,7 +177,7 @@ func (qs *queryServer) ListNames(param *ListNamesParam, stream Query_ListNamesSe // Validators func (qs *queryServer) GetValidatorSet(ctx context.Context, param *GetValidatorSetParam) (*ValidatorSet, error) { - set := validator.Copy(qs.validators.Validators(0)) + set := validator.Copy(qs.state.Validators(0)) return &ValidatorSet{ Set: set.Validators(), }, nil @@ -197,7 +197,7 @@ func (qs *queryServer) GetValidatorSetHistory(ctx context.Context, param *GetVal } history := &ValidatorSetHistory{} for i := 0; i < lookback; i++ { - set := validator.Copy(qs.validators.Validators(i)) + set := validator.Copy(qs.state.Validators(i)) vs := &ValidatorSet{ Height: height - uint64(i), Set: set.Validators(), @@ -209,7 +209,7 @@ func (qs *queryServer) GetValidatorSetHistory(ctx context.Context, param *GetVal func (qs *queryServer) GetNetworkRegistry(ctx context.Context, param *GetNetworkRegistryParam) (*NetworkRegistry, error) { rv := make([]*RegisteredValidator, 0) - err := qs.nodeReg.IterateNodes(func(id crypto.Address, rn *registry.NodeIdentity) error { + err := qs.state.IterateNodes(func(id crypto.Address, rn *registry.NodeIdentity) error { rv = append(rv, &RegisteredValidator{ Address: rn.ValidatorPublicKey.GetAddress(), Node: rn, @@ -222,7 +222,7 @@ func (qs *queryServer) GetNetworkRegistry(ctx context.Context, param *GetNetwork // Proposals func (qs *queryServer) GetProposal(ctx context.Context, param *GetProposalParam) (proposal *payload.Ballot, err error) { - proposal, err = qs.proposalReg.GetProposal(param.Hash) + proposal, err = qs.state.GetProposal(param.Hash) if proposal == nil && err == nil { err = fmt.Errorf("proposal %x not found", param.Hash) } @@ -231,7 +231,7 @@ func (qs *queryServer) GetProposal(ctx context.Context, param *GetProposalParam) func (qs *queryServer) ListProposals(param *ListProposalsParam, stream Query_ListProposalsServer) error { var streamErr error - err := qs.proposalReg.IterateProposals(func(hash []byte, ballot *payload.Ballot) error { + err := qs.state.IterateProposals(func(hash []byte, ballot *payload.Ballot) error { if !param.GetProposed() || ballot.ProposalState == payload.Ballot_PROPOSED { return stream.Send(&ProposalResult{Hash: hash, Ballot: ballot}) } else { @@ -245,7 +245,7 @@ func (qs *queryServer) ListProposals(param *ListProposalsParam, stream Query_Lis } func (qs *queryServer) GetStats(ctx context.Context, param *GetStatsParam) (*Stats, error) { - stats := qs.accounts.GetAccountStats() + stats := qs.state.GetAccountStats() return &Stats{ AccountsWithCode: stats.AccountsWithCode, From 0b49481cc18ef788bb33767c98f084d6c5f12af9 Mon Sep 17 00:00:00 2001 From: Silas Davis Date: Thu, 10 Oct 2019 16:16:16 -0500 Subject: [PATCH 2/2] Prep 0.29.1 release Signed-off-by: Silas Davis --- CHANGELOG.md | 6 ++++++ NOTES.md | 23 +---------------------- project/history.go | 4 ++++ 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ce638ba9..f320c041d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ # [Hyperledger Burrow](https://github.com/hyperledger/burrow) Changelog +## [0.29.1] - 2019-10-10 +### Changed +- [State] Split metadata and account state to be kinder to downstream EVM integrators + + ## [0.29.0] - 2019-10-08 ### Changed - [Config] Reverted rename of ValidatorAddress to Address in config (each Burrow node has a specific validator key it uses for signing whether or not it is running as a validator right now) @@ -578,6 +583,7 @@ This release marks the start of Eris-DB as the full permissioned blockchain node - [Blockchain] Fix getBlocks to respect block height cap. +[0.29.1]: https://github.com/hyperledger/burrow/compare/v0.29.0...v0.29.1 [0.29.0]: https://github.com/hyperledger/burrow/compare/v0.28.2...v0.29.0 [0.28.2]: https://github.com/hyperledger/burrow/compare/v0.28.1...v0.28.2 [0.28.1]: https://github.com/hyperledger/burrow/compare/v0.28.0...v0.28.1 diff --git a/NOTES.md b/NOTES.md index a87f96172..4e53357e7 100644 --- a/NOTES.md +++ b/NOTES.md @@ -1,24 +1,3 @@ ### Changed -- [Config] Reverted rename of ValidatorAddress to Address in config (each Burrow node has a specific validator key it uses for signing whether or not it is running as a validator right now) - -### Fixed -- [EVM] Return integer overflow error code (not stack overflow) for integer overflow errors -- [Docs] Fix broken examples -- [Deploy] Set input on QueryContract jobs correctly -- [EVM] Fix byte-printing for DebugOpcodes run mode -- [Crypto] Use Tendermint-compatible secp256k1 addressing -- [Natives] Make natives first class contracts and establish Dispatcher and Callable as a common calling convention for natives, EVM, and WASM (pending for WASM). -- [Natives] Fix Ethereum precompile addresses (addresses were padded on right instead of the left) - - -### Added -- [Web3] Implemented Ethereum web3 JSON RPC including sendRawTransaction! -- [Docs] Much docs (see also: https://www.hyperledger.org/blog/2019/10/08/burrow-the-boring-blockchain) -- [Docs] Generate github pages docs index with docsify: https://hyperledger.github.io/burrow/ -- [JS] Publish burrow.js to @hyperledger/burrow -- [State] Store EVM ABI and contract metadata on-chain see [GetMetadata](https://github.com/hyperledger/burrow/blob/e80aad5d8fac1f67dbfec61ea75670f9a38c61a1/protobuf/rpcquery.proto#L25) -- [Tendermint] Upgrade to v0.32.3 -- [Execution] Added IdentifyTx for introducing nodes (binding their NodeID to ValidatorAddress) -- [Natives] Implement Ethereum precompile number 5 - modular exponentiation - +- [State] Split metadata and account state to be kinder to downstream EVM integrators diff --git a/project/history.go b/project/history.go index 53c3682e9..08b43ccbc 100644 --- a/project/history.go +++ b/project/history.go @@ -48,6 +48,10 @@ func FullVersion() string { // release tagging script: ./scripts/tag_release.sh var History relic.ImmutableHistory = relic.NewHistory("Hyperledger Burrow", "https://github.com/hyperledger/burrow"). MustDeclareReleases( + "0.29.1 - 2019-10-10", + `### Changed +- [State] Split metadata and account state to be kinder to downstream EVM integrators +`, "0.29.0 - 2019-10-08", `### Changed - [Config] Reverted rename of ValidatorAddress to Address in config (each Burrow node has a specific validator key it uses for signing whether or not it is running as a validator right now)