From 3723ba9e0a65e79c45a33e8ee52feb8107991385 Mon Sep 17 00:00:00 2001 From: CocoaHuke Date: Fri, 22 Jun 2018 01:14:56 -0700 Subject: [PATCH] les: Add new ODR message --- les/odr_requests.go | 59 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/les/odr_requests.go b/les/odr_requests.go index 075fcd92ca..7900929434 100644 --- a/les/odr_requests.go +++ b/les/odr_requests.go @@ -68,6 +68,8 @@ func LesRequest(req light.OdrRequest) LesOdrRequest { return (*ChtRequest)(r) case *light.BloomRequest: return (*BloomRequest)(r) + case *light.TxStatusRequest: + return (*TxStatusRequest)(r) default: return nil } @@ -564,3 +566,60 @@ func (db *readTraceDB) Has(key []byte) (bool, error) { _, err := db.Get(key) return err == nil, nil } + +type TxStatusRequest light.TxStatusRequest + +// GetCost returns the cost of the given ODR request according to the serving +// peer's cost table (implementation of LesOdrRequest) +func (r *TxStatusRequest) GetCost(peer *peer) uint64 { + return peer.GetRequestCost(GetTxStatusMsg, 1) +} + +// CanSend tells if a certain peer is suitable for serving the given request +func (r *TxStatusRequest) CanSend(peer *peer) bool { + peer.lock.RLock() + defer peer.lock.RUnlock() + + if peer.version < lpv2 { + return false + } + return true +} + +// Request sends an ODR request to the LES network (implementation of LesOdrRequest) +func (r *TxStatusRequest) Request(reqID uint64, peer *peer) error { + peer.Log().Debug("Requesting transaction status corresponding block", "TxHash", r.TxHash) + return peer.RequestTxStatus(reqID, r.GetCost(peer), []common.Hash{r.TxHash}) +} + +// Valid processes an ODR request reply message from the LES network +// returns true and stores results in memory if the message was a valid reply +// to the request (implementation of LesOdrRequest) +func (r *TxStatusRequest) Validate(db ethdb.Database, msg *Msg) error { + log.Debug("Validating transaction status corresponding block", "TxHash", r.TxHash) + + // Ensure we have a correct message with a single block receipt + if msg.MsgType != MsgTxStatus { + return errInvalidMessageType + } + + if len(msg.Obj.([]txStatus)) != 1 { + return errInvalidEntryCount + } + + //We retrieve transaction status, block hash and block index from a full node by a given transaction hash + //These information retrieve from full node is lacking of relevant data to verify + //My current solution is (Code at odr_util.go): + //Only start verification after it's been "included", to proof a transaction is valid: + //Retrieve BlockHash/BlockIndex -> Retrieve and verify BlockBody -> Verify given transaction hash whether included + + //Need support verify through pending transactions + //Share your ideas! + + status := msg.Obj.([]txStatus)[0] + + r.TxStatus = status.Status + r.TxEntry = status.Lookup + + return nil +}