本文整理匯總了Golang中github.com/NebulousLabs/Sia/encoding.WriteObject函數的典型用法代碼示例。如果您正苦於以下問題:Golang WriteObject函數的具體用法?Golang WriteObject怎麽用?Golang WriteObject使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了WriteObject函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: newHostUploader
// newHostUploader initiates the contract revision process with a host, and
// returns a hostUploader, which satisfies the Uploader interface.
func (hdb *HostDB) newHostUploader(hc hostContract) (*hostUploader, error) {
hdb.mu.RLock()
settings, ok := hdb.allHosts[hc.IP] // or activeHosts?
hdb.mu.RUnlock()
if !ok {
return nil, errors.New("no record of that host")
}
// TODO: check for excessive price again?
// initiate revision loop
conn, err := net.DialTimeout("tcp", string(hc.IP), 15*time.Second)
if err != nil {
return nil, err
}
if err := encoding.WriteObject(conn, modules.RPCRevise); err != nil {
return nil, err
}
if err := encoding.WriteObject(conn, hc.ID); err != nil {
return nil, err
}
// TODO: some sort of acceptance would be good here, so that we know the
// uploader will actually work. Maybe send the Merkle root?
hu := &hostUploader{
contract: hc,
price: settings.Price,
tree: crypto.NewTree(),
conn: conn,
hdb: hdb,
}
return hu, nil
}
示例2: downloadPiece
// downloadPiece attempts to retrieve a file piece from a host.
func (d *Download) downloadPiece(piece filePiece) error {
conn, err := net.DialTimeout("tcp", string(piece.HostIP), 10e9)
if err != nil {
return err
}
defer conn.Close()
err = encoding.WriteObject(conn, [8]byte{'R', 'e', 't', 'r', 'i', 'e', 'v', 'e'})
if err != nil {
return err
}
// Send the ID of the contract for the file piece we're requesting.
if err := encoding.WriteObject(conn, piece.ContractID); err != nil {
return err
}
// Simultaneously download, decrypt, and calculate the Merkle root of the file.
tee := io.TeeReader(
// Use a LimitedReader to ensure we don't read indefinitely.
io.LimitReader(conn, int64(piece.Contract.FileSize)),
// Write the decrypted bytes to the file.
piece.EncryptionKey.NewWriter(d),
)
merkleRoot, err := crypto.ReaderMerkleRoot(tee)
if err != nil {
return err
}
if merkleRoot != piece.Contract.FileMerkleRoot {
return errors.New("host provided a file that's invalid")
}
return nil
}
示例3: newHostUploader
func (r *Renter) newHostUploader(settings modules.HostSettings, filesize uint64, duration types.BlockHeight, masterKey crypto.TwofishKey) (*hostUploader, error) {
hu := &hostUploader{
settings: settings,
masterKey: masterKey,
tree: crypto.NewTree(),
renter: r,
}
// TODO: maybe do this later?
err := hu.negotiateContract(filesize, duration)
if err != nil {
return nil, err
}
// initiate the revision loop
hu.conn, err = net.DialTimeout("tcp", string(hu.settings.IPAddress), 15*time.Second)
if err != nil {
return nil, err
}
if err := encoding.WriteObject(hu.conn, modules.RPCRevise); err != nil {
return nil, err
}
if err := encoding.WriteObject(hu.conn, hu.contract.ID); err != nil {
return nil, err
}
return hu, nil
}
示例4: newHostFetcher
// newHostFetcher creates a new hostFetcher by connecting to a host.
// TODO: We may not wind up requesting data from this, which means we will
// connect and then disconnect without making any actual requests (but holding
// the connection open the entire time). This is wasteful of host resources.
// Consider only opening the connection after the first request has been made.
func newHostFetcher(fc fileContract, pieceSize uint64, masterKey crypto.TwofishKey) (*hostFetcher, error) {
conn, err := net.DialTimeout("tcp", string(fc.IP), 15*time.Second)
if err != nil {
return nil, err
}
conn.SetDeadline(time.Now().Add(15 * time.Second))
defer conn.SetDeadline(time.Time{})
// send RPC
err = encoding.WriteObject(conn, modules.RPCDownload)
if err != nil {
return nil, err
}
// send contract ID
err = encoding.WriteObject(conn, fc.ID)
if err != nil {
return nil, err
}
// make piece map
pieceMap := make(map[uint64][]pieceData)
for _, p := range fc.Pieces {
pieceMap[p.Chunk] = append(pieceMap[p.Chunk], p)
}
return &hostFetcher{
conn: conn,
pieceMap: pieceMap,
pieceSize: pieceSize + crypto.TwofishOverhead,
masterKey: masterKey,
}, nil
}
示例5: 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)
}
示例6: TestThreadedHandleConn
func TestThreadedHandleConn(t *testing.T) {
g1 := newTestingGateway("TestThreadedHandleConn1", t)
defer g1.Close()
g2 := newTestingGateway("TestThreadedHandleConn2", t)
defer g2.Close()
err := g1.Connect(g2.Address())
if err != nil {
t.Fatal("failed to connect:", err)
}
g2.RegisterRPC("Foo", func(conn modules.PeerConn) error {
var i uint64
err := encoding.ReadObject(conn, &i, 8)
if err != nil {
return err
} else if i == 0xdeadbeef {
return encoding.WriteObject(conn, "foo")
} else {
return encoding.WriteObject(conn, "bar")
}
})
// custom rpc fn (doesn't automatically write rpcID)
rpcFn := func(fn func(modules.PeerConn) error) error {
conn, err := g1.peers[g2.Address()].open()
if err != nil {
return err
}
defer conn.Close()
return fn(conn)
}
// bad rpcID
err = rpcFn(func(conn modules.PeerConn) error {
return encoding.WriteObject(conn, [3]byte{1, 2, 3})
})
if err != nil {
t.Fatal("rpcFn failed:", err)
}
// unknown rpcID
err = rpcFn(func(conn modules.PeerConn) error {
return encoding.WriteObject(conn, handlerName("bar"))
})
if err != nil {
t.Fatal("rpcFn failed:", err)
}
// valid rpcID
err = rpcFn(func(conn modules.PeerConn) error {
return encoding.WriteObject(conn, handlerName("Foo"))
})
if err != nil {
t.Fatal("rpcFn failed:", err)
}
}
示例7: negotiateRevision
// negotiateRevision sends a revision and actions to the host for approval,
// completing one iteration of the revision loop.
func negotiateRevision(conn net.Conn, rev types.FileContractRevision, secretKey crypto.SecretKey) (types.Transaction, error) {
// 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 formContract
}},
}
// sign the transaction
encodedSig, _ := crypto.SignHash(signedTxn.SigHash(0), secretKey) // no error possible
signedTxn.TransactionSignatures[0].Signature = encodedSig[:]
// send the revision
if err := encoding.WriteObject(conn, rev); err != nil {
return types.Transaction{}, errors.New("couldn't send revision: " + err.Error())
}
// read acceptance
if err := modules.ReadNegotiationAcceptance(conn); err != nil {
return types.Transaction{}, errors.New("host did not accept revision: " + err.Error())
}
// send the new transaction signature
if err := encoding.WriteObject(conn, signedTxn.TransactionSignatures[0]); err != nil {
return types.Transaction{}, errors.New("couldn't send transaction signature: " + err.Error())
}
// read the host's acceptance and transaction signature
// NOTE: if the host sends ErrStopResponse, we should continue processing
// the revision, but return the error anyway.
responseErr := modules.ReadNegotiationAcceptance(conn)
if responseErr != nil && responseErr != modules.ErrStopResponse {
return types.Transaction{}, errors.New("host did not accept transaction signature: " + responseErr.Error())
}
var hostSig types.TransactionSignature
if err := encoding.ReadObject(conn, &hostSig, 16e3); err != nil {
return types.Transaction{}, errors.New("couldn't read host's signature: " + err.Error())
}
// add the signature to the transaction and verify it
// NOTE: we can fake the blockheight here because it doesn't affect
// verification; it just needs to be above the fork height and below the
// contract expiration (which was checked earlier).
verificationHeight := rev.NewWindowStart - 1
signedTxn.TransactionSignatures = append(signedTxn.TransactionSignatures, hostSig)
if err := signedTxn.StandaloneValid(verificationHeight); err != nil {
return types.Transaction{}, err
}
// if the host sent ErrStopResponse, return it
return signedTxn, responseErr
}
示例8: 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
}
示例9: 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()
}
示例10: WriteNegotiationRejection
// WriteNegotiationRejection will write a rejection response to w (usually a
// net.Conn) and return the input error. If the write fails, the write error
// is joined with the input error.
func WriteNegotiationRejection(w io.Writer, err error) error {
writeErr := encoding.WriteObject(w, err.Error())
if writeErr != nil {
return build.JoinErrors([]error{err, writeErr}, "; ")
}
return err
}
示例11: NewEditor
// NewEditor initiates the contract revision process with a host, and returns
// an Editor.
func NewEditor(host modules.HostDBEntry, contract modules.RenterContract, currentHeight types.BlockHeight) (*Editor, error) {
// check that contract has enough value to support an upload
if len(contract.LastRevision.NewValidProofOutputs) != 2 {
return nil, errors.New("invalid contract")
}
// initiate revision loop
conn, err := net.DialTimeout("tcp", string(contract.NetAddress), 15*time.Second)
if err != nil {
return nil, err
}
// allot 2 minutes for RPC request + revision exchange
extendDeadline(conn, modules.NegotiateRecentRevisionTime)
defer extendDeadline(conn, time.Hour)
if err := encoding.WriteObject(conn, modules.RPCReviseContract); err != nil {
conn.Close()
return nil, errors.New("couldn't initiate RPC: " + err.Error())
}
if err := verifyRecentRevision(conn, contract); err != nil {
conn.Close() // TODO: close gracefully if host has entered revision loop
return nil, err
}
// the host is now ready to accept revisions
return &Editor{
host: host,
height: currentHeight,
contract: contract,
conn: conn,
}, nil
}
示例12: threadedProbeHosts
// threadedProbeHosts tries to fetch the settings of a host. If successful, the
// host is put in the set of active hosts. If unsuccessful, the host id deleted
// from the set of active hosts.
func (hdb *HostDB) threadedProbeHosts() {
defer hdb.threadGroup.Done()
for hostEntry := range hdb.scanPool {
// Request settings from the queued host entry.
// TODO: use dialer.Cancel to shutdown quickly
hdb.log.Debugln("Scanning", hostEntry.NetAddress, hostEntry.PublicKey)
var settings modules.HostExternalSettings
err := func() error {
conn, err := hdb.dialer.DialTimeout(hostEntry.NetAddress, hostRequestTimeout)
if err != nil {
return err
}
defer conn.Close()
err = encoding.WriteObject(conn, modules.RPCSettings)
if err != nil {
return err
}
var pubkey crypto.PublicKey
copy(pubkey[:], hostEntry.PublicKey.Key)
return crypto.ReadSignedObject(conn, &settings, maxSettingsLen, pubkey)
}()
if err != nil {
hdb.log.Debugln("Scanning", hostEntry.NetAddress, hostEntry.PublicKey, "failed", err)
} else {
hdb.log.Debugln("Scanning", hostEntry.NetAddress, hostEntry.PublicKey, "succeeded")
}
// Update the host tree to have a new entry.
hdb.managedUpdateEntry(hostEntry, settings, err)
}
}
示例13: connectPortHandshake
// connectPortHandshake performs the port handshake and should be called on the
// side initiating the connection request. This shares our port with the peer
// so they can connect to us in the future.
func connectPortHandshake(conn net.Conn, port string) error {
err := encoding.WriteObject(conn, port)
if err != nil {
return errors.New("could not write port #: " + err.Error())
}
return nil
}
示例14: RPC
// RPC calls an RPC on the given address. RPC cannot be called on an address
// that the Gateway is not connected to.
func (g *Gateway) RPC(addr modules.NetAddress, name string, fn modules.RPCFunc) error {
id := g.mu.RLock()
peer, ok := g.peers[addr]
g.mu.RUnlock(id)
if !ok {
return errors.New("can't call RPC on unconnected peer " + string(addr))
}
conn, err := peer.open()
if err != nil {
return err
}
defer conn.Close()
// write header
if err := encoding.WriteObject(conn, handlerName(name)); err != nil {
return err
}
// call fn
err = fn(conn)
if err != nil {
g.log.Printf("WARN: calling RPC \"%v\" on peer %v returned error: %v", name, addr, err)
}
return err
}
示例15: RPC
// RPC calls an RPC on the given address. RPC cannot be called on an address
// that the Gateway is not connected to.
func (g *Gateway) RPC(addr modules.NetAddress, name string, fn modules.RPCFunc) error {
if err := g.threads.Add(); err != nil {
return err
}
defer g.threads.Done()
g.mu.RLock()
peer, ok := g.peers[addr]
g.mu.RUnlock()
if !ok {
return errors.New("can't call RPC on unconnected peer " + string(addr))
}
conn, err := peer.open()
if err != nil {
return err
}
defer conn.Close()
// write header
if err := encoding.WriteObject(conn, handlerName(name)); err != nil {
return err
}
// call fn
return fn(conn)
}