func LoadState(db dbm.DB) *State { s := &State{DB: db} buf := db.Get(stateKey) if len(buf) == 0 { return nil } else { r, n, err := bytes.NewReader(buf), new(int64), new(error) s.LastBlockHeight = binary.ReadUvarint(r, n, err) s.LastBlockHash = binary.ReadByteSlice(r, n, err) s.LastBlockParts = binary.ReadBinary(types.PartSetHeader{}, r, n, err).(types.PartSetHeader) s.LastBlockTime = binary.ReadTime(r, n, err) s.BondedValidators = binary.ReadBinary(&ValidatorSet{}, r, n, err).(*ValidatorSet) s.LastBondedValidators = binary.ReadBinary(&ValidatorSet{}, r, n, err).(*ValidatorSet) s.UnbondingValidators = binary.ReadBinary(&ValidatorSet{}, r, n, err).(*ValidatorSet) accountsHash := binary.ReadByteSlice(r, n, err) s.accounts = merkle.NewIAVLTree(binary.BasicCodec, account.AccountCodec, defaultAccountsCacheCapacity, db) s.accounts.Load(accountsHash) validatorInfosHash := binary.ReadByteSlice(r, n, err) s.validatorInfos = merkle.NewIAVLTree(binary.BasicCodec, ValidatorInfoCodec, 0, db) s.validatorInfos.Load(validatorInfosHash) if *err != nil { panic(*err) } // TODO: ensure that buf is completely read. } return s }
func TestBinaryDecode(t *testing.T) { privAccount := GenPrivAccount() pubKey := privAccount.PubKey privKey := privAccount.PrivKey msg := CRandBytes(128) sig := privKey.Sign(msg) t.Logf("msg: %X, sig: %X", msg, sig) buf, n, err := new(bytes.Buffer), new(int64), new(error) binary.WriteBinary(sig, buf, n, err) if *err != nil { t.Fatalf("Failed to write Signature: %v", err) } if len(buf.Bytes()) != ed25519.SignatureSize+3 { // 1 byte TypeByte, 2 bytes length, 64 bytes signature bytes t.Fatalf("Unexpected signature write size: %v", len(buf.Bytes())) } if buf.Bytes()[0] != SignatureTypeEd25519 { t.Fatalf("Unexpected signature type byte") } sig2, ok := binary.ReadBinary(SignatureEd25519{}, buf, n, err).(SignatureEd25519) if !ok || *err != nil { t.Fatalf("Failed to read Signature: %v", err) } // Test the signature if !pubKey.VerifyBytes(msg, sig2) { t.Errorf("Account message signature verification failed") } }
func TestReadWrite(t *testing.T) { height, round := uint(1), uint(2) _, valSet, privValidators := randVoteSet(height, round, types.VoteTypePrevote, 10, 1) // Make a POL with +2/3 votes. blockHash := RandBytes(32) pol := &POL{ Height: height, Round: round, BlockHash: blockHash, Votes: make([]POLVoteSignature, valSet.Size()), } voteProto := &types.Vote{ Height: height, Round: round, Type: types.VoteTypePrevote, BlockHash: blockHash, } for i := 0; i < 7; i++ { signAddPOLVoteSignature(privValidators[i], valSet, voteProto, pol) } // Write it to a buffer. buf, n, err := new(bytes.Buffer), new(int64), new(error) binary.WriteBinary(pol, buf, n, err) if *err != nil { t.Fatalf("Failed to write POL: %v", *err) } // Read from buffer. pol2 := binary.ReadBinary(&POL{}, buf, n, err).(*POL) if *err != nil { t.Fatalf("Failed to read POL: %v", *err) } // Check that validation succeeds. if err := pol2.Verify(valSet); err != nil { t.Errorf("POL.Verify() failed: %v", err) } }
func peerHandshake(conn net.Conn, ourNodeInfo *types.NodeInfo) (*types.NodeInfo, error) { var peerNodeInfo = new(types.NodeInfo) var wg sync.WaitGroup var err1 error var err2 error wg.Add(2) go func() { var n int64 binary.WriteBinary(ourNodeInfo, conn, &n, &err1) wg.Done() }() go func() { var n int64 binary.ReadBinary(peerNodeInfo, conn, &n, &err2) log.Info("Peer handshake", "peerNodeInfo", peerNodeInfo) wg.Done() }() wg.Wait() if err1 != nil { return nil, err1 } if err2 != nil { return nil, err2 } return peerNodeInfo, nil }
func DecodeMessage(bz []byte) (msgType byte, msg BlockchainMessage, err error) { msgType = bz[0] n := new(int64) r := bytes.NewReader(bz) msg = binary.ReadBinary(struct{ BlockchainMessage }{}, r, n, &err).(struct{ BlockchainMessage }).BlockchainMessage return }
// NOTE: POL is not necessarily valid. func (cs *ConsensusState) AddProposalPOLPart(height uint, round uint, part *types.Part) (added bool, err error) { cs.mtx.Lock() defer cs.mtx.Unlock() if cs.Height != height || cs.Round != round { return false, nil } // We're not expecting a POL part. if cs.ProposalPOLParts == nil { return false, nil // TODO: bad peer? Return error? } added, err = cs.ProposalPOLParts.AddPart(part) if err != nil { return added, err } if added && cs.ProposalPOLParts.IsComplete() { var n int64 var err error cs.ProposalPOL = binary.ReadBinary(&POL{}, cs.ProposalPOLParts.GetReader(), &n, &err).(*POL) return true, err } return true, nil }
// NOTE: block is not necessarily valid. // NOTE: This function may increment the height. func (cs *ConsensusState) AddProposalBlockPart(height uint, round uint, part *types.Part) (added bool, err error) { cs.mtx.Lock() defer cs.mtx.Unlock() // Blocks might be reused, so round mismatch is OK if cs.Height != height { return false, nil } // We're not expecting a block part. if cs.ProposalBlockParts == nil { return false, nil // TODO: bad peer? Return error? } added, err = cs.ProposalBlockParts.AddPart(part) if err != nil { return added, err } if added && cs.ProposalBlockParts.IsComplete() { var n int64 var err error cs.ProposalBlock = binary.ReadBinary(&types.Block{}, cs.ProposalBlockParts.GetReader(), &n, &err).(*types.Block) log.Debug("Received complete proposal", "hash", cs.ProposalBlock.Hash()) // If we're already in the commit step, try to finalize round. if cs.Step == RoundStepCommit { cs.queueAction(RoundAction{cs.Height, cs.Round, RoundActionTryFinalize}) } // XXX If POL is valid, consider unlocking. return true, err } return true, nil }
func (bs *BlockStore) LoadBlockMeta(height uint) *types.BlockMeta { var n int64 var err error r := bs.GetReader(calcBlockMetaKey(height)) if r == nil { panic(Fmt("BlockMeta does not exist for height %v", height)) } meta := binary.ReadBinary(&types.BlockMeta{}, r, &n, &err).(*types.BlockMeta) if err != nil { panic(Fmt("Error reading block meta: %v", err)) } return meta }
func (bs *BlockStore) LoadBlockPart(height uint, index uint) *types.Part { var n int64 var err error r := bs.GetReader(calcBlockPartKey(height, index)) if r == nil { panic(Fmt("BlockPart does not exist for height %v index %v", height, index)) } part := binary.ReadBinary(&types.Part{}, r, &n, &err).(*types.Part) if err != nil { panic(Fmt("Error reading block part: %v", err)) } return part }
func (bs *BlockStore) LoadBlock(height uint) *types.Block { var n int64 var err error r := bs.GetReader(calcBlockMetaKey(height)) if r == nil { panic(Fmt("Block does not exist at height %v", height)) } meta := binary.ReadBinary(&types.BlockMeta{}, r, &n, &err).(*types.BlockMeta) if err != nil { panic(Fmt("Error reading block meta: %v", err)) } bytez := []byte{} for i := uint(0); i < meta.Parts.Total; i++ { part := bs.LoadBlockPart(height, i) bytez = append(bytez, part.Bytes...) } block := binary.ReadBinary(&types.Block{}, bytes.NewReader(bytez), &n, &err).(*types.Block) if err != nil { panic(Fmt("Error reading block: %v", err)) } return block }
// NOTE: the Commit-vote heights are for the block at `height` func (bs *BlockStore) LoadSeenValidation(height uint) *types.Validation { var n int64 var err error r := bs.GetReader(calcSeenValidationKey(height)) if r == nil { panic(Fmt("SeenValidation does not exist for height %v", height)) } validation := binary.ReadBinary(&types.Validation{}, r, &n, &err).(*types.Validation) if err != nil { panic(Fmt("Error reading validation: %v", err)) } return validation }
func gen_tx() { // Get State, which may be nil. stateDB := dbm.GetDB("state") state := sm.LoadState(stateDB) // Get source pubkey srcPubKeyBytes := getByteSliceFromHex("Enter source pubkey: ") r, n, err := bytes.NewReader(srcPubKeyBytes), new(int64), new(error) srcPubKey := binary.ReadBinary(struct{ account.PubKey }{}, r, n, err).(struct{ account.PubKey }).PubKey if *err != nil { Exit(Fmt("Invalid PubKey. Error: %v", err)) } // Get the state of the account. var srcAccount *account.Account var srcAccountAddress = srcPubKey.Address() var srcAccountBalanceStr = "unknown" var srcAccountSequenceStr = "unknown" srcAddress := srcPubKey.Address() if state != nil { srcAccount = state.GetAccount(srcAddress) srcAccountBalanceStr = Fmt("%v", srcAccount.Balance) srcAccountSequenceStr = Fmt("%v", srcAccount.Sequence+1) } // Get the amount to send from src account srcSendAmount := getUint64(Fmt("Enter amount to send from %X (total: %v): ", srcAccountAddress, srcAccountBalanceStr)) // Get the next sequence of src account srcSendSequence := uint(getUint64(Fmt("Enter next sequence for %X (guess: %v): ", srcAccountAddress, srcAccountSequenceStr))) // Get dest address dstAddress := getByteSliceFromHex("Enter destination address: ") // Get the amount to send to dst account dstSendAmount := getUint64(Fmt("Enter amount to send to %X: ", dstAddress)) // Construct SendTx tx := &types.SendTx{ Inputs: []*types.TxInput{ &types.TxInput{ Address: srcAddress, Amount: srcSendAmount, Sequence: srcSendSequence, Signature: account.SignatureEd25519{}, PubKey: srcPubKey, }, }, Outputs: []*types.TxOutput{ &types.TxOutput{ Address: dstAddress, Amount: dstSendAmount, }, }, } // Show the intermediate form. fmt.Printf("Generated tx: %X\n", binary.BinaryBytes(tx)) // Get source privkey (for signing) srcPrivKeyBytes := getByteSliceFromHex("Enter source privkey (for signing): ") r, n, err = bytes.NewReader(srcPrivKeyBytes), new(int64), new(error) srcPrivKey := binary.ReadBinary(struct{ account.PrivKey }{}, r, n, err).(struct{ account.PrivKey }).PrivKey if *err != nil { Exit(Fmt("Invalid PrivKey. Error: %v", err)) } // Sign tx.Inputs[0].Signature = srcPrivKey.Sign(account.SignBytes(tx)) fmt.Printf("Signed tx: %X\n", binary.BinaryBytes(tx)) }
// recvRoutine reads msgPackets and reconstructs the message using the channels' "recving" buffer. // After a whole message has been assembled, it's pushed to onReceive(). // Blocks depending on how the connection is throttled. func (c *MConnection) recvRoutine() { defer c._recover() FOR_LOOP: for { // Block until .recvMonitor says we can read. c.recvMonitor.Limit(maxMsgPacketSize, atomic.LoadInt64(&c.recvRate), true) /* // Peek into bufReader for debugging if numBytes := c.bufReader.Buffered(); numBytes > 0 { log.Debug("Peek connection buffer", "numBytes", numBytes, "bytes", log15.Lazy{func() []byte { bytes, err := c.bufReader.Peek(MinInt(numBytes, 100)) if err == nil { return bytes } else { log.Warn("Error peeking connection buffer", "error", err) return nil } }}) } */ // Read packet type var n int64 var err error pktType := binary.ReadByte(c.bufReader, &n, &err) c.recvMonitor.Update(int(n)) if err != nil { if atomic.LoadUint32(&c.stopped) != 1 { log.Warn("Connection failed @ recvRoutine (reading byte)", "connection", c, "error", err) c.stopForError(err) } break FOR_LOOP } // Read more depending on packet type. switch pktType { case packetTypePing: // TODO: prevent abuse, as they cause flush()'s. log.Debug("Receive Ping") c.pong <- struct{}{} case packetTypePong: // do nothing log.Debug("Receive Pong") case packetTypeMsg: pkt, n, err := msgPacket{}, new(int64), new(error) binary.ReadBinary(&pkt, c.bufReader, n, err) c.recvMonitor.Update(int(*n)) if *err != nil { if atomic.LoadUint32(&c.stopped) != 1 { log.Warn("Connection failed @ recvRoutine", "connection", c, "error", *err) c.stopForError(*err) } break FOR_LOOP } channel, ok := c.channelsIdx[pkt.ChannelId] if !ok || channel == nil { panic(Fmt("Unknown channel %X", pkt.ChannelId)) } msgBytes := channel.recvMsgPacket(pkt) if msgBytes != nil { //log.Debug("Received bytes", "chId", pkt.ChannelId, "msgBytes", msgBytes) c.onReceive(pkt.ChannelId, msgBytes) } default: panic(Fmt("Unknown message type %X", pktType)) } // TODO: shouldn't this go in the sendRoutine? // Better to send a ping packet when *we* haven't sent anything for a while. c.pingTimer.Reset() } // Cleanup close(c.pong) for _ = range c.pong { // Drain } }
func ValidatorInfoDecoder(r io.Reader, n *int64, err *error) interface{} { return binary.ReadBinary(&ValidatorInfo{}, r, n, err) }
func (vc validatorCodec) Decode(r io.Reader, n *int64, err *error) interface{} { return binary.ReadBinary(&Validator{}, r, n, err) }
func AccountDecoder(r io.Reader, n *int64, err *error) interface{} { return binary.ReadBinary(&Account{}, r, n, err) }