Skip to content

Commit

Permalink
rpcsrv: add getrawnotarypool, getrawnotarytransaction handlers
Browse files Browse the repository at this point in the history
`getrawnotarytransaction` takes a transaction hash and attempts to find
the corresponding transaction in the notary requests mempool. It searches
through all the verified main and fallback transactions.
`getrawnotarypool` returns hashes of all the verified transactions,
including both main and fallback transactions.

Additionally add struct result.RawNotaryPool.

Close #2951

Signed-off-by: Tatiana Nesterenko <[email protected]>
  • Loading branch information
tatiana-nspcc committed Aug 31, 2023
1 parent a6ef3ff commit 5396c94
Show file tree
Hide file tree
Showing 4 changed files with 299 additions and 66 deletions.
53 changes: 53 additions & 0 deletions pkg/neorpc/result/raw_notary_pool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package result

import (
"encoding/json"

"github.com/nspcc-dev/neo-go/pkg/util"
)

// RawNotaryPool represents a result of `getrawnotarypool` RPC call.
// The structure consist of `Hashes`. `Hashes` field is a map, where key is
// the hash of the main transaction and value is a slice of related fallback
// transaction hashes.
type RawNotaryPool struct {
Hashes map[util.Uint256][]util.Uint256
}

// rawNotaryPoolAux is an auxiliary struct for RawNotaryPool JSON marshalling.
type rawNotaryPoolAux struct {
Hashes map[string][]util.Uint256 `json:"hashes,omitempty"`
}

// MarshalJSON implements the json.Marshaler interface.
func (p RawNotaryPool) MarshalJSON() ([]byte, error) {
var aux rawNotaryPoolAux
aux.Hashes = make(map[string][]util.Uint256, len(p.Hashes))
for main, fallbacks := range p.Hashes {
mainBytes, err := main.MarshalJSON()
if err != nil {
return nil, err
}
aux.Hashes[string(mainBytes)] = fallbacks
}
return json.Marshal(aux)
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (p *RawNotaryPool) UnmarshalJSON(data []byte) error {
var (
aux rawNotaryPoolAux
hashMain util.Uint256
)
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
p.Hashes = make(map[util.Uint256][]util.Uint256, len(aux.Hashes))
for main, fallbacks := range aux.Hashes {
if err := hashMain.UnmarshalJSON([]byte(main)); err != nil {
return err
}
p.Hashes[hashMain] = fallbacks
}
return nil
}
53 changes: 53 additions & 0 deletions pkg/services/rpcsrv/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ var rpcHandlers = map[string]func(*Server, params.Params) (any, *neorpc.Error){
"getpeers": (*Server).getPeers,
"getproof": (*Server).getProof,
"getrawmempool": (*Server).getRawMempool,
"getrawnotarypool": (*Server).getRawNotaryPool,
"getrawnotarytransaction": (*Server).getRawNotaryTransaction,
"getrawtransaction": (*Server).getrawtransaction,
"getstate": (*Server).getState,
"getstateheight": (*Server).getStateHeight,
Expand Down Expand Up @@ -3090,3 +3092,54 @@ func (s *Server) Addresses() []string {
}
return res
}

func (s *Server) getRawNotaryPool(_ params.Params) (any, *neorpc.Error) {
if !s.chain.P2PSigExtensionsEnabled() {
return nil, neorpc.NewInternalServerError("P2PSignatureExtensions are disabled")
}
nrp := s.coreServer.GetNotaryPool()
res := &result.RawNotaryPool{Hashes: make(map[util.Uint256][]util.Uint256)}
nrp.IterateVerifiedTransactions(func(tx *transaction.Transaction, data any) bool {
if data != nil {
d := data.(*payload.P2PNotaryRequest)
mainHash := d.MainTransaction.Hash()
fallbackHash := d.FallbackTransaction.Hash()
res.Hashes[mainHash] = append(res.Hashes[mainHash], fallbackHash)
}
return true
})
return res, nil
}

func (s *Server) getRawNotaryTransaction(reqParams params.Params) (any, *neorpc.Error) {
if !s.chain.P2PSigExtensionsEnabled() {
return nil, neorpc.NewInternalServerError("P2PSignatureExtensions are disabled")
}

txHash, err := reqParams.Value(0).GetUint256()
if err != nil {
return nil, neorpc.ErrInvalidParams
}
nrp := s.coreServer.GetNotaryPool()
// Try to find fallback transaction.
tx, ok := nrp.TryGetValue(txHash)
if !ok {
// Try to find main transaction.
nrp.IterateVerifiedTransactions(func(t *transaction.Transaction, data any) bool {
if data != nil && data.(*payload.P2PNotaryRequest).MainTransaction.Hash().Equals(txHash) {
tx = data.(*payload.P2PNotaryRequest).MainTransaction
return false
}
return true
})
// The transaction was not found.
if tx == nil {
return nil, neorpc.ErrUnknownTransaction
}
}

if v, _ := reqParams.Value(1).GetBoolean(); v {
return tx, nil
}
return tx.Bytes(), nil
}
Loading

0 comments on commit 5396c94

Please sign in to comment.