added comments

This commit is contained in:
zsfelfoldi 2015-10-29 16:43:39 +01:00
parent 7a44bab77b
commit 934cc7d9e2
8 changed files with 28 additions and 0 deletions

View file

@ -56,15 +56,18 @@ type ChainAccess struct {
type requestFunc func(*Peer) error
type validatorFunc func(*Msg) bool
// Request waiting for an answer that satisfies its valFunc
type sentReq struct {
valFunc validatorFunc
deliverChan chan *Msg
}
// Create a ChainAccess with ODR disabled
func NewDbChainAccess(db ethdb.Database) *ChainAccess {
return NewChainAccess(db, false)
}
// Create a ChainAccess
func NewChainAccess(db ethdb.Database, odr bool) *ChainAccess {
return &ChainAccess{
db: db,
@ -107,6 +110,11 @@ type Msg struct {
Obj interface{}
}
// ODR request interface (passed to Retrieve, functions called by Retrieve and Deliver)
// DbGet() tries to retrieve the object from the local database (object is stored by the request struct in memory if retrieved)
// DbPut() stores it in the local database
// Request(*Peer) requests it from a LES peer
// Valid(*Msg) checks if a message is a valid answer to this request and stores the retrieved object in memory
type ObjectAccess interface {
// database storage
DbGet() bool
@ -116,6 +124,7 @@ type ObjectAccess interface {
Valid(*Msg) bool // if true, keeps the retrieved object
}
// Deliver is called by the LES protocol manager to deliver ODR reply messages to waiting requests
func (self *ChainAccess) Deliver(id string, msg *Msg) (processed bool) {
self.lock.Lock()
defer self.lock.Unlock()
@ -130,6 +139,7 @@ func (self *ChainAccess) Deliver(id string, msg *Msg) (processed bool) {
return false
}
// Send a request to known peers until an answer is received or the context is cancelled
func (self *ChainAccess) networkRequest(rqFunc requestFunc, valFunc validatorFunc, ctx *OdrContext) (*Msg, error) {
req := &sentReq{
deliverChan: make(chan *Msg),
@ -175,6 +185,8 @@ func (self *ChainAccess) networkRequest(rqFunc requestFunc, valFunc validatorFun
}
}
// Retrieve tries to fetch an object from the local db, then from the LES network.
// If the network retrieval was successful, it stores the object in local db.
func (self *ChainAccess) Retrieve(obj ObjectAccess, ctx *OdrContext) (err error) {
// look in db
if obj.DbGet() {

View file

@ -23,6 +23,7 @@ import (
"time"
)
// Context for ODR requests, can be timed out or cancelled manually
type OdrContext struct {
cancel, cancelOrTimeout chan struct{}
id *OdrChannelID
@ -64,6 +65,10 @@ func (self *OdrContext) IsCancelled() bool {
return atomic.LoadInt32(&self.cancelled) == 1
}
// While contexts are created for each request, channel ID is a permanent
// identifier of a source from where requests can come (like an RPC channel).
// (needed for future functions like "list of my waiting requests" and
// "cancel all requests from this channel")
type OdrChannelID struct {
timeout time.Duration
}

View file

@ -42,6 +42,7 @@ type getNodeDataFn func([]common.Hash) error
type getReceiptsFn func([]common.Hash) error
type getProofsFn func([]*ProofReq) error
// access.Peer stores ODR-specific information about LES peers that are able to serve requests
type Peer struct {
id string // Unique identifier of the peer
head common.Hash // Hash of the peers latest known block

View file

@ -374,6 +374,7 @@ func (self *BlockChain) CurrentBlock() *types.Block {
return self.CurrentBlockOdr(access.NoOdr)
}
// CurrentBlockOdr retrieves the current head block, using ODR in light mode
func (self *BlockChain) CurrentBlockOdr(ctx *access.OdrContext) *types.Block {
self.mu.RLock()
defer self.mu.RUnlock()

View file

@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
// ODR request type for block bodies, see access.ObjectAccess interface
type BlockAccess struct {
db ethdb.Database
blockHash common.Hash
@ -87,6 +88,7 @@ func (self *BlockAccess) DbPut() {
glog.V(access.LogLevel).Infof("ODR: put body %08x len = %d", self.blockHash[:4], len(self.rlp))
}
// ODR request type for block receipts by block hash, see access.ObjectAccess interface
type ReceiptsAccess struct {
db ethdb.Database
blockHash common.Hash

View file

@ -53,6 +53,7 @@ func (self *TrieAccess) OdrEnabled() bool {
return self.ca.OdrEnabled()
}
// ODR request type for state/storage trie entries, see access.ObjectAccess interface
type TrieEntryAccess struct {
root common.Hash
trieDb trie.Database
@ -101,6 +102,7 @@ func (self *TrieEntryAccess) DbPut() {
trie.StoreProof(self.trieDb, self.proof)
}
// ODR request type for node data (used for retrieving contract code), see access.ObjectAccess interface
type NodeDataAccess struct {
db ethdb.Database
hash common.Hash

View file

@ -54,6 +54,7 @@ type StateDB struct {
}
// Create a new state from a given trie
// When ODR is used, context is specified when creating/copying a state.
func New(root common.Hash, ca *access.ChainAccess, ctx *access.OdrContext) (*StateDB, error) {
tr, err := trie.NewSecure(root, ca.Db(), NewTrieAccess(ca, root, ca.Db()))
if err != nil {
@ -297,10 +298,12 @@ func (self *StateDB) CreateAccount(addr common.Address) vm.Account {
// Setting, copying of the state methods
//
// Copy state, keep the original ODR context
func (self *StateDB) CopyWithCtx() *StateDB {
return self.Copy(self.ctx)
}
// Copy with a new context
func (self *StateDB) Copy(ctx *access.OdrContext) *StateDB {
// ignore error - we assume state-to-be-copied always exists
state, _ := New(common.Hash{}, self.ca, ctx)

View file

@ -40,6 +40,8 @@ type EthereumApi interface {
}
// RPC request
// (ODR context is propagated inside the request struct because every
// request has its own context. It does not influence JSON encoding.)
type Request struct {
Id interface{} `json:"id"`
Jsonrpc string `json:"jsonrpc"`