本文整理匯總了Golang中github.com/NebulousLabs/Sia/encoding.ReadObject函數的典型用法代碼示例。如果您正苦於以下問題:Golang ReadObject函數的具體用法?Golang ReadObject怎麽用?Golang ReadObject使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了ReadObject函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: TestShareNodes
func TestShareNodes(t *testing.T) {
g1 := newTestingGateway("TestShareNodes1", t)
defer g1.Close()
g2 := newTestingGateway("TestShareNodes2", t)
defer g2.Close()
// add a node to g2
id := g2.mu.Lock()
g2.addNode(dummyNode)
g2.mu.Unlock(id)
// connect
err := g1.Connect(g2.Address())
if err != nil {
t.Fatal("couldn't connect:", err)
}
// g1 should have received the node
time.Sleep(100 * time.Millisecond)
id = g1.mu.Lock()
if g1.addNode(dummyNode) == nil {
t.Fatal("gateway did not receive nodes during Connect:", g1.nodes)
}
g1.mu.Unlock(id)
// remove all nodes from both peers
id = g1.mu.Lock()
g1.nodes = map[modules.NetAddress]struct{}{}
g1.mu.Unlock(id)
id = g2.mu.Lock()
g2.nodes = map[modules.NetAddress]struct{}{}
g2.mu.Unlock(id)
// SharePeers should now return no peers
var nodes []modules.NetAddress
err = g1.RPC(g2.Address(), "ShareNodes", func(conn modules.PeerConn) error {
return encoding.ReadObject(conn, &nodes, maxSharedNodes*maxAddrLength)
})
if err != nil {
t.Fatal(err)
}
if len(nodes) != 0 {
t.Fatal("gateway gave non-existent addresses:", nodes)
}
// sharing should be capped at maxSharedNodes
for i := 0; i < maxSharedNodes+10; i++ {
g2.addNode(modules.NetAddress("111.111.111.111:" + strconv.Itoa(i)))
}
err = g1.RPC(g2.Address(), "ShareNodes", func(conn modules.PeerConn) error {
return encoding.ReadObject(conn, &nodes, maxSharedNodes*maxAddrLength)
})
if err != nil {
t.Fatal(err)
}
if len(nodes) != maxSharedNodes {
t.Fatalf("gateway gave wrong number of nodes: expected %v, got %v", maxSharedNodes, len(nodes))
}
}
示例2: receiveBlocks
// receiveBlocks is the calling end of the SendBlocks RPC.
func (s *ConsensusSet) receiveBlocks(conn modules.PeerConn) error {
// get blockIDs to send
lockID := s.mu.RLock()
if !s.db.open {
s.mu.RUnlock(lockID)
return errors.New("database not open")
}
history := s.blockHistory()
s.mu.RUnlock(lockID)
if err := encoding.WriteObject(conn, history); err != nil {
return err
}
// loop until no more blocks are available
moreAvailable := true
for moreAvailable {
var newBlocks []types.Block
if err := encoding.ReadObject(conn, &newBlocks, MaxCatchUpBlocks*types.BlockSizeLimit); err != nil {
return err
}
if err := encoding.ReadObject(conn, &moreAvailable, 1); err != nil {
return err
}
// integrate received blocks.
for _, block := range newBlocks {
// Blocks received during synchronize aren't trusted; activate full
// verification.
lockID := s.mu.Lock()
if !s.db.open {
s.mu.Unlock(lockID)
return errors.New("database not open")
}
acceptErr := s.acceptBlock(block)
s.mu.Unlock(lockID)
// ErrNonExtendingBlock must be ignored until headers-first block
// sharing is implemented.
if acceptErr == modules.ErrNonExtendingBlock {
acceptErr = nil
}
if acceptErr != nil {
return acceptErr
}
// Yield the processor to give other processes time to grab a lock.
// The Lock/Unlock cycle in this loop is very tight, and has been
// known to prevent interrupts from getting lock access quickly.
runtime.Gosched()
}
}
return nil
}
示例3: managedRPCRecentRevision
// managedRPCRecentRevision sends the most recent known file contract
// revision, including signatures, to the renter, for the file contract with
// the input id.
func (h *Host) managedRPCRecentRevision(conn net.Conn) (types.FileContractID, *storageObligation, error) {
// Set the negotiation deadline.
conn.SetDeadline(time.Now().Add(modules.NegotiateRecentRevisionTime))
// Receive the file contract id from the renter.
var fcid types.FileContractID
err := encoding.ReadObject(conn, &fcid, uint64(len(fcid)))
if err != nil {
return types.FileContractID{}, nil, err
}
// Send a challenge to the renter to verify that the renter has write
// access to the revision being opened.
var challenge crypto.Hash
_, err = rand.Read(challenge[:])
if err != nil {
return types.FileContractID{}, nil, err
}
err = encoding.WriteObject(conn, challenge)
if err != nil {
return types.FileContractID{}, nil, err
}
// Read the signed response from the renter.
var challengeResponse crypto.Signature
err = encoding.ReadObject(conn, &challengeResponse, uint64(len(challengeResponse)))
if err != nil {
return types.FileContractID{}, nil, err
}
// Verify the response. In the process, fetch the related storage
// obligation, file contract revision, and transaction signatures.
so, recentRevision, revisionSigs, err := h.verifyChallengeResponse(fcid, challenge, challengeResponse)
if err != nil {
return types.FileContractID{}, nil, modules.WriteNegotiationRejection(conn, err)
}
// Send the file contract revision and the corresponding signatures to the
// renter.
err = modules.WriteNegotiationAcceptance(conn)
if err != nil {
return types.FileContractID{}, nil, err
}
err = encoding.WriteObject(conn, recentRevision)
if err != nil {
return types.FileContractID{}, nil, err
}
err = encoding.WriteObject(conn, revisionSigs)
if err != nil {
return types.FileContractID{}, nil, err
}
return fcid, so, nil
}
示例4: negotiateRevision
// negotiateRevision sends the revision and new piece data to the host.
func negotiateRevision(conn net.Conn, rev types.FileContractRevision, piece []byte, secretKey crypto.SecretKey) (types.Transaction, error) {
conn.SetDeadline(time.Now().Add(5 * time.Minute)) // sufficient to transfer 4 MB over 100 kbps
defer conn.SetDeadline(time.Time{}) // reset timeout after each revision
// create transaction containing the revision
signedTxn := types.Transaction{
FileContractRevisions: []types.FileContractRevision{rev},
TransactionSignatures: []types.TransactionSignature{{
ParentID: crypto.Hash(rev.ParentID),
CoveredFields: types.CoveredFields{FileContractRevisions: []uint64{0}},
PublicKeyIndex: 0, // renter key is always first -- see negotiateContract
}},
}
// sign the transaction
encodedSig, _ := crypto.SignHash(signedTxn.SigHash(0), secretKey) // no error possible
signedTxn.TransactionSignatures[0].Signature = encodedSig[:]
// send the transaction
if err := encoding.WriteObject(conn, signedTxn); err != nil {
return types.Transaction{}, errors.New("couldn't send revision transaction: " + err.Error())
}
// host sends acceptance
var response string
if err := encoding.ReadObject(conn, &response, 128); err != nil {
return types.Transaction{}, errors.New("couldn't read host acceptance: " + err.Error())
}
if response != modules.AcceptResponse {
return types.Transaction{}, errors.New("host rejected revision: " + response)
}
// transfer piece
if _, err := conn.Write(piece); err != nil {
return types.Transaction{}, errors.New("couldn't transfer piece: " + err.Error())
}
// read txn signed by host
var signedHostTxn types.Transaction
if err := encoding.ReadObject(conn, &signedHostTxn, types.BlockSizeLimit); err != nil {
return types.Transaction{}, errors.New("couldn't read signed revision transaction: " + err.Error())
}
if signedHostTxn.ID() != signedTxn.ID() {
return types.Transaction{}, errors.New("host sent bad signed transaction")
}
return signedHostTxn, nil
}
示例5: TestNegotiateRevisionStopResponse
// TestNegotiateRevisionStopResponse tests that when the host sends
// StopResponse, the renter continues processing the revision instead of
// immediately terminating.
func TestNegotiateRevisionStopResponse(t *testing.T) {
// simulate a renter-host connection
rConn, hConn := net.Pipe()
// handle the host's half of the pipe
go func() {
defer hConn.Close()
// read revision
encoding.ReadObject(hConn, new(types.FileContractRevision), 1<<22)
// write acceptance
modules.WriteNegotiationAcceptance(hConn)
// read txn signature
encoding.ReadObject(hConn, new(types.TransactionSignature), 1<<22)
// write StopResponse
modules.WriteNegotiationStop(hConn)
// write txn signature
encoding.WriteObject(hConn, types.TransactionSignature{})
}()
// since the host wrote StopResponse, we should proceed to validating the
// transaction. This will return a known error because we are supplying an
// empty revision.
_, err := negotiateRevision(rConn, types.FileContractRevision{}, crypto.SecretKey{})
if err != types.ErrFileContractWindowStartViolation {
t.Fatalf("expected %q, got \"%v\"", types.ErrFileContractWindowStartViolation, err)
}
rConn.Close()
// same as above, but send an error instead of StopResponse. The error
// should be returned by negotiateRevision immediately (if it is not, we
// should expect to see a transaction validation error instead).
rConn, hConn = net.Pipe()
go func() {
defer hConn.Close()
encoding.ReadObject(hConn, new(types.FileContractRevision), 1<<22)
modules.WriteNegotiationAcceptance(hConn)
encoding.ReadObject(hConn, new(types.TransactionSignature), 1<<22)
// write a sentinel error
modules.WriteNegotiationRejection(hConn, errors.New("sentinel"))
encoding.WriteObject(hConn, types.TransactionSignature{})
}()
expectedErr := "host did not accept transaction signature: sentinel"
_, err = negotiateRevision(rConn, types.FileContractRevision{}, crypto.SecretKey{})
if err == nil || err.Error() != expectedErr {
t.Fatalf("expected %q, got \"%v\"", expectedErr, err)
}
rConn.Close()
}
示例6: rpcSendBlk
// rpcSendBlk is an RPC that sends the requested block to the requesting peer.
func (cs *ConsensusSet) rpcSendBlk(conn modules.PeerConn) error {
err := cs.tg.Add()
if err != nil {
return err
}
defer cs.tg.Done()
// Decode the block id from the connection.
var id types.BlockID
err = encoding.ReadObject(conn, &id, crypto.HashSize)
if err != nil {
return err
}
// Lookup the corresponding block.
var b types.Block
cs.mu.RLock()
err = cs.db.View(func(tx *bolt.Tx) error {
pb, err := getBlockMap(tx, id)
if err != nil {
return err
}
b = pb.Block
return nil
})
cs.mu.RUnlock()
if err != nil {
return err
}
// Encode and send the block to the caller.
err = encoding.WriteObject(conn, b)
if err != nil {
return err
}
return nil
}
示例7: handleConn
// TODO: maintain compatibility
func (h *Host) handleConn(conn net.Conn) {
defer conn.Close()
// Set an initial duration that is generous, but finite. RPCs can extend
// this if so desired.
conn.SetDeadline(time.Now().Add(5 * time.Minute))
var id types.Specifier
if err := encoding.ReadObject(conn, &id, 16); err != nil {
return
}
var err error
switch id {
case modules.RPCSettings:
err = h.rpcSettings(conn)
case modules.RPCUpload:
err = h.rpcUpload(conn)
case modules.RPCRevise:
err = h.rpcRevise(conn)
case modules.RPCDownload:
err = h.rpcDownload(conn)
default:
h.log.Printf("WARN: incoming conn %v requested unknown RPC \"%v\"", conn.RemoteAddr(), id)
return
}
if err != nil {
h.log.Printf("WARN: incoming RPC \"%v\" failed: %v", id, err)
}
}
示例8: threadedHandleConn
// threadedHandleConn reads header data from a connection, then routes it to the
// appropriate handler for further processing.
func (g *Gateway) threadedHandleConn(conn modules.PeerConn) {
defer conn.Close()
var id rpcID
if err := encoding.ReadObject(conn, &id, 8); err != nil {
return
}
// call registered handler for this ID
lockid := g.mu.RLock()
fn, ok := g.handlers[id]
g.mu.RUnlock(lockid)
if !ok {
g.log.Printf("WARN: incoming conn %v requested unknown RPC \"%v\"", conn.RemoteAddr(), id)
return
}
// call fn
err := fn(conn)
// don't log benign errors
if err == modules.ErrDuplicateTransactionSet || err == modules.ErrBlockKnown {
err = nil
}
if err != nil {
g.log.Printf("WARN: incoming RPC \"%v\" failed: %v", id, err)
}
}
示例9: rpcRetrieve
// rpcRetrieve is an RPC that uploads a specified file to a client.
//
// Mutexes are applied carefully to avoid locking during I/O. All necessary
// interaction with the host involves looking up the filepath of the file being
// requested. This is done all at once.
func (h *Host) rpcRetrieve(conn net.Conn) error {
// Get the filename.
var contractID types.FileContractID
err := encoding.ReadObject(conn, &contractID, crypto.HashSize)
if err != nil {
return err
}
// Verify the file exists, using a mutex while reading the host.
lockID := h.mu.RLock()
contractObligation, exists := h.obligationsByID[contractID]
if !exists {
h.mu.RUnlock(lockID)
return errors.New("no record of that file")
}
path := filepath.Join(h.saveDir, contractObligation.Path)
h.mu.RUnlock(lockID)
// Open the file.
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
// Transmit the file.
_, err = io.CopyN(conn, file, int64(contractObligation.FileContract.FileSize))
if err != nil {
return err
}
return nil
}
示例10: rpcRelayBlock
// rpcRelayBlock is an RPC that accepts a block from a peer.
// COMPATv0.5.1
func (cs *ConsensusSet) rpcRelayBlock(conn modules.PeerConn) error {
err := cs.tg.Add()
if err != nil {
return err
}
defer cs.tg.Done()
// Decode the block from the connection.
var b types.Block
err = encoding.ReadObject(conn, &b, types.BlockSizeLimit)
if err != nil {
return err
}
// Submit the block to the consensus set and broadcast it.
err = cs.managedAcceptBlock(b)
if err == errOrphan {
// If the block is an orphan, try to find the parents. The block
// received from the peer is discarded and will be downloaded again if
// the parent is found.
go func() {
err := cs.gateway.RPC(conn.RPCAddr(), "SendBlocks", cs.managedReceiveBlocks)
if err != nil {
cs.log.Debugln("WARN: failed to get parents of orphan block:", err)
}
}()
}
if err != nil {
return err
}
cs.managedBroadcastBlock(b)
return nil
}
示例11: rpcDownload
// rpcDownload is an RPC that uploads requested segments of a file. After the
// RPC has been initiated, the host will read and process requests in a loop
// until the 'stop' signal is received or the connection times out.
func (h *Host) rpcDownload(conn net.Conn) error {
// Read the contract ID.
var contractID types.FileContractID
err := encoding.ReadObject(conn, &contractID, crypto.HashSize)
if err != nil {
return err
}
// Verify the file exists, using a mutex while reading the host.
h.mu.RLock()
co, exists := h.obligationsByID[contractID]
if !exists {
h.mu.RUnlock()
return errors.New("no record of that file")
}
h.mu.RUnlock()
// Open the file.
file, err := os.Open(co.Path)
if err != nil {
return err
}
defer file.Close()
// Process requests until 'stop' signal is received.
var request modules.DownloadRequest
for {
if err := encoding.ReadObject(conn, &request, 16); err != nil {
return err
}
// Check for termination signal.
// TODO: perform other sanity checks on offset/length?
if request.Length == 0 {
break
}
conn.SetDeadline(time.Now().Add(5 * time.Minute)) // sufficient to transfer 4 MB over 100 kbps
// Write segment to conn.
segment := io.NewSectionReader(file, int64(request.Offset), int64(request.Length))
_, err := io.Copy(conn, segment)
if err != nil {
return err
}
}
return nil
}
示例12: acceptConn
// acceptConn adds a connecting node as a peer.
func (g *Gateway) acceptConn(conn net.Conn) {
addr := modules.NetAddress(conn.RemoteAddr().String())
g.log.Printf("INFO: %v wants to connect", addr)
// read version
var remoteVersion string
if err := encoding.ReadObject(conn, &remoteVersion, maxAddrLength); err != nil {
conn.Close()
g.log.Printf("INFO: %v wanted to connect, but we could not read their version: %v", addr, err)
return
}
// check that version is acceptable
// NOTE: this version must be bumped whenever the gateway or consensus
// breaks compatibility.
if build.VersionCmp(remoteVersion, "0.3.3") < 0 {
encoding.WriteObject(conn, "reject")
conn.Close()
g.log.Printf("INFO: %v wanted to connect, but their version (%v) was unacceptable", addr, remoteVersion)
return
}
// respond with our version
if err := encoding.WriteObject(conn, build.Version); err != nil {
conn.Close()
g.log.Printf("INFO: could not write version ack to %v: %v", addr, err)
return
}
// If we are already fully connected, kick out an old peer to make room
// for the new one. Importantly, prioritize kicking a peer with the same
// IP as the connecting peer. This protects against Sybil attacks.
id := g.mu.Lock()
if len(g.peers) >= fullyConnectedThreshold {
// first choose a random peer, preferably inbound. If have only
// outbound peers, we'll wind up kicking an outbound peer; but
// subsequent inbound connections will kick each other instead of
// continuing to replace outbound peers.
kick, err := g.randomInboundPeer()
if err != nil {
kick, _ = g.randomPeer()
}
// if another peer shares this IP, choose that one instead
for p := range g.peers {
if p.Host() == addr.Host() {
kick = p
break
}
}
g.peers[kick].sess.Close()
delete(g.peers, kick)
g.log.Printf("INFO: disconnected from %v to make room for %v", kick, addr)
}
// add the peer
g.addPeer(&peer{addr: addr, sess: muxado.Server(conn), inbound: true})
g.mu.Unlock(id)
g.log.Printf("INFO: accepted connection from new peer %v (v%v)", addr, remoteVersion)
}
示例13: relayTransactionSet
// relayTransactionSet is an RPC that accepts a transaction set from a peer. If
// the accept is successful, the transaction will be relayed to the gateway's
// other peers.
func (tp *TransactionPool) relayTransactionSet(conn modules.PeerConn) error {
var ts []types.Transaction
err := encoding.ReadObject(conn, &ts, types.BlockSizeLimit)
if err != nil {
return err
}
return tp.AcceptTransactionSet(ts)
}
示例14: threadedReceiveBlocks
// threadedReceiveBlocks is the calling end of the SendBlocks RPC.
func (cs *ConsensusSet) threadedReceiveBlocks(conn modules.PeerConn) error {
// Get blockIDs to send.
var history [32]types.BlockID
err := cs.db.View(func(tx *bolt.Tx) error {
history = blockHistory(tx)
return nil
})
if err != nil {
return err
}
// Send the block ids.
if err := encoding.WriteObject(conn, history); err != nil {
return err
}
// Read blocks off of the wire and add them to the consensus set until
// there are no more blocks available.
moreAvailable := true
for moreAvailable {
// Read a slice of blocks from the wire.
var newBlocks []types.Block
if err := encoding.ReadObject(conn, &newBlocks, MaxCatchUpBlocks*types.BlockSizeLimit); err != nil {
return err
}
if err := encoding.ReadObject(conn, &moreAvailable, 1); err != nil {
return err
}
// Integrate the blocks into the consensus set.
for _, block := range newBlocks {
acceptErr := cs.AcceptBlock(block)
// ErrNonExtendingBlock must be ignored until headers-first block
// sharing is implemented, block already in database should also be
// ignored.
if acceptErr == modules.ErrNonExtendingBlock || acceptErr == modules.ErrBlockKnown {
acceptErr = nil
}
if acceptErr != nil {
return acceptErr
}
}
}
return nil
}
示例15: managedRPCRenew
// managedRPCRenew is an RPC that allows a renter to renew a file contract. The
// protocol is identical to standard contract negotiation, except that the
// Merkle root is copied over from the old contract.
func (h *Host) managedRPCRenew(conn net.Conn) error {
// Terminate connection if host is not accepting contracts.
h.mu.RLock()
accepting := h.settings.AcceptingContracts
h.mu.RUnlock()
if !accepting {
return nil
}
// read ID of contract to be renewed
var fcid types.FileContractID
if err := encoding.ReadObject(conn, &fcid, crypto.HashSize); err != nil {
return errors.New("couldn't read contract ID: " + err.Error())
}
h.mu.RLock()
obligation, exists := h.obligationsByID[fcid]
h.mu.RUnlock()
if !exists {
return errors.New("no record of that contract")
}
// need to protect against simultaneous renewals of the same contract
obligation.mu.Lock()
defer obligation.mu.Unlock()
// copy over old file data
h.mu.RLock()
h.fileCounter++
filename := filepath.Join(h.persistDir, strconv.Itoa(int(h.fileCounter)))
h.mu.RUnlock()
// TODO: What happens if the copy operation fails partway through? Does
// there need to be garbage collection at startup for failed uploads that
// might still be on disk?
old, err := os.Open(obligation.Path)
if err != nil {
return err
}
renewed, err := os.Create(filename)
if err != nil {
return err
}
_, err = io.Copy(renewed, old)
if err != nil {
return err
}
err = h.managedNegotiateContract(conn, obligation.fileSize(), obligation.merkleRoot(), filename)
if err != nil {
// Negotiation failed, delete the copied file.
err2 := os.Remove(filename)
if err2 != nil {
return errors.New(err.Error() + " and " + err2.Error())
}
return err
}
return nil
}