예제 #1
0
파일: state.go 프로젝트: jaekwon/GuppyCamp
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
}
예제 #2
0
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")
	}
}
예제 #3
0
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)
	}
}
예제 #4
0
파일: peer.go 프로젝트: jaekwon/GuppyCamp
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
}
예제 #5
0
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
}
예제 #6
0
파일: state.go 프로젝트: jaekwon/GuppyCamp
// 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
}
예제 #7
0
파일: state.go 프로젝트: jaekwon/GuppyCamp
// 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
}
예제 #8
0
파일: store.go 프로젝트: jaekwon/GuppyCamp
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
}
예제 #9
0
파일: store.go 프로젝트: jaekwon/GuppyCamp
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
}
예제 #10
0
파일: store.go 프로젝트: jaekwon/GuppyCamp
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
}
예제 #11
0
파일: store.go 프로젝트: jaekwon/GuppyCamp
// 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
}
예제 #12
0
파일: gen_tx.go 프로젝트: jaekwon/GuppyCamp
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))
}
예제 #13
0
// 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
	}
}
예제 #14
0
func ValidatorInfoDecoder(r io.Reader, n *int64, err *error) interface{} {
	return binary.ReadBinary(&ValidatorInfo{}, r, n, err)
}
예제 #15
0
func (vc validatorCodec) Decode(r io.Reader, n *int64, err *error) interface{} {
	return binary.ReadBinary(&Validator{}, r, n, err)
}
예제 #16
0
func AccountDecoder(r io.Reader, n *int64, err *error) interface{} {
	return binary.ReadBinary(&Account{}, r, n, err)
}