func testProof(t *testing.T, proof *IAVLProof, keyBytes, valueBytes, rootHash []byte) { // Proof must verify. if !proof.Verify(keyBytes, valueBytes, rootHash) { t.Errorf("Invalid proof. Verification failed.") return } // Write/Read then verify. proofBytes := wire.BinaryBytes(proof) n, err := int64(0), error(nil) proof2 := wire.ReadBinary(&IAVLProof{}, bytes.NewBuffer(proofBytes), &n, &err).(*IAVLProof) if err != nil { t.Errorf("Failed to read IAVLProof from bytes: %v", err) return } if !proof2.Verify(keyBytes, valueBytes, rootHash) { // t.Log(Fmt("%X\n%X\n", proofBytes, wire.BinaryBytes(proof2))) t.Errorf("Invalid proof after write/read. Verification failed.") return } // Random mutations must not verify for i := 0; i < 5; i++ { badProofBytes := MutateByteSlice(proofBytes) n, err := int64(0), error(nil) badProof := wire.ReadBinary(&IAVLProof{}, bytes.NewBuffer(badProofBytes), &n, &err).(*IAVLProof) if err != nil { continue // This is fine. } if badProof.Verify(keyBytes, valueBytes, rootHash) { t.Errorf("Proof was still valid after a random mutation:\n%X\n%X", proofBytes, badProofBytes) } } }
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.ChainID = wire.ReadString(r, n, err) s.LastBlockHeight = wire.ReadVarint(r, n, err) s.LastBlockHash = wire.ReadByteSlice(r, n, err) s.LastBlockParts = wire.ReadBinary(types.PartSetHeader{}, r, n, err).(types.PartSetHeader) s.LastBlockTime = wire.ReadTime(r, n, err) s.BondedValidators = wire.ReadBinary(&types.ValidatorSet{}, r, n, err).(*types.ValidatorSet) s.LastBondedValidators = wire.ReadBinary(&types.ValidatorSet{}, r, n, err).(*types.ValidatorSet) s.UnbondingValidators = wire.ReadBinary(&types.ValidatorSet{}, r, n, err).(*types.ValidatorSet) accountsHash := wire.ReadByteSlice(r, n, err) s.accounts = merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, defaultAccountsCacheCapacity, db) s.accounts.Load(accountsHash) validatorInfosHash := wire.ReadByteSlice(r, n, err) s.validatorInfos = merkle.NewIAVLTree(wire.BasicCodec, types.ValidatorInfoCodec, 0, db) s.validatorInfos.Load(validatorInfosHash) nameRegHash := wire.ReadByteSlice(r, n, err) s.nameReg = merkle.NewIAVLTree(wire.BasicCodec, NameRegCodec, 0, db) s.nameReg.Load(nameRegHash) if *err != nil { // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED Exit(Fmt("Data has been corrupted or its spec has changed: %v\n", *err)) } // TODO: ensure that buf is completely read. } return s }
// NOTE: block is not necessarily valid. // This can trigger us to go into EnterPrevote asynchronously (before we timeout of propose) or to attempt to commit func (cs *ConsensusState) AddProposalBlockPart(height int, 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() { // Added and completed! var n int64 var err error cs.ProposalBlock = wire.ReadBinary(&types.Block{}, cs.ProposalBlockParts.GetReader(), &n, &err).(*types.Block) log.Info("Received complete proposal", "hash", cs.ProposalBlock.Hash()) if cs.Step == RoundStepPropose && cs.isProposalComplete() { // Move onto the next step go cs.EnterPrevote(height, cs.Round, false) } else if cs.Step == RoundStepCommit { // If we're waiting on the proposal block... cs.tryFinalizeCommit(height) } return true, err } return added, nil }
// TODO: check for unnecessary extra bytes at the end. func DecodeMessage(bz []byte) (msgType byte, msg ConsensusMessage, err error) { msgType = bz[0] n := new(int64) r := bytes.NewReader(bz) msg = wire.ReadBinary(struct{ ConsensusMessage }{}, r, n, &err).(struct{ ConsensusMessage }).ConsensusMessage return }
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) wire.WriteBinary(sig, buf, n, err) if *err != nil { t.Fatalf("Failed to write Signature: %v", err) } if len(buf.Bytes()) != ed25519.SignatureSize+1 { // 1 byte TypeByte, 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 := wire.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 shareAuthSignature(sc *SecretConnection, pubKey acm.PubKeyEd25519, signature acm.SignatureEd25519) (*authSigMessage, error) { var recvMsg authSigMessage var err1, err2 error Parallel( func() { msgBytes := wire.BinaryBytes(authSigMessage{pubKey, signature}) _, err1 = sc.Write(msgBytes) }, func() { readBuffer := make([]byte, authSigMsgSize) _, err2 = io.ReadFull(sc, readBuffer) if err2 != nil { return } n := int64(0) // not used. recvMsg = wire.ReadBinary(authSigMessage{}, bytes.NewBuffer(readBuffer), &n, &err2).(authSigMessage) }) if err1 != nil { return nil, err1 } if err2 != nil { return nil, err2 } return &recvMsg, nil }
// TODO: ensure that bz is completely read. func DecodeMessage(bz []byte) (msgType byte, msg BlockchainMessage, err error) { msgType = bz[0] n := int64(0) r := bytes.NewReader(bz) msg = wire.ReadBinary(struct{ BlockchainMessage }{}, r, &n, &err).(struct{ BlockchainMessage }).BlockchainMessage if err != nil && n != int64(len(bz)) { err = errors.New("DecodeMessage() had bytes left over.") } return }
func (bs *BlockStore) LoadBlockMeta(height int) *types.BlockMeta { var n int64 var err error r := bs.GetReader(calcBlockMetaKey(height)) if r == nil { return nil } meta := wire.ReadBinary(&types.BlockMeta{}, r, &n, &err).(*types.BlockMeta) if err != nil { PanicCrisis(Fmt("Error reading block meta: %v", err)) } return meta }
func (bs *BlockStore) LoadBlockPart(height int, index int) *types.Part { var n int64 var err error r := bs.GetReader(calcBlockPartKey(height, index)) if r == nil { return nil } part := wire.ReadBinary(&types.Part{}, r, &n, &err).(*types.Part) if err != nil { PanicCrisis(Fmt("Error reading block part: %v", err)) } return part }
func (bs *BlockStore) LoadBlock(height int) *types.Block { var n int64 var err error r := bs.GetReader(calcBlockMetaKey(height)) if r == nil { return nil } meta := wire.ReadBinary(&types.BlockMeta{}, r, &n, &err).(*types.BlockMeta) if err != nil { PanicCrisis(Fmt("Error reading block meta: %v", err)) } bytez := []byte{} for i := 0; i < meta.PartsHeader.Total; i++ { part := bs.LoadBlockPart(height, i) bytez = append(bytez, part.Bytes...) } block := wire.ReadBinary(&types.Block{}, bytes.NewReader(bytez), &n, &err).(*types.Block) if err != nil { PanicCrisis(Fmt("Error reading block: %v", err)) } return block }
// NOTE: the Precommit-vote heights are for the block at `height` func (bs *BlockStore) LoadSeenValidation(height int) *types.Validation { var n int64 var err error r := bs.GetReader(calcSeenValidationKey(height)) if r == nil { return nil } validation := wire.ReadBinary(&types.Validation{}, r, &n, &err).(*types.Validation) if err != nil { PanicCrisis(Fmt("Error reading validation: %v", err)) } return validation }
// NOTE: blocking // Before creating a peer with newPeer(), perform a handshake on connection. func peerHandshake(conn net.Conn, ourNodeInfo *types.NodeInfo) (*types.NodeInfo, error) { var peerNodeInfo = new(types.NodeInfo) var err1 error var err2 error Parallel( func() { var n int64 wire.WriteBinary(ourNodeInfo, conn, &n, &err1) }, func() { var n int64 wire.ReadBinary(peerNodeInfo, conn, &n, &err2) log.Notice("Peer handshake", "peerNodeInfo", peerNodeInfo) }) if err1 != nil { return nil, err1 } if err2 != nil { return nil, err2 } return peerNodeInfo, nil }
func ValidatorInfoDecoder(r io.Reader, n *int64, err *error) interface{} { return wire.ReadBinary(&ValidatorInfo{}, r, n, err) }
func (vc validatorCodec) Decode(r io.Reader, n *int64, err *error) interface{} { return wire.ReadBinary(&Validator{}, r, n, err) }
func NameRegDecoder(r io.Reader, n *int64, err *error) interface{} { return wire.ReadBinary(&types.NameRegEntry{}, r, n, err) }
func AccountDecoder(r io.Reader, n *int64, err *error) interface{} { return wire.ReadBinary(&Account{}, r, n, err) }