예제 #1
0
// blockParts:     Must be parts of the block
// seenValidation: The +2/3 precommits that were seen which committed at height.
//                 If all the nodes restart after committing a block,
//                 we need this to reload the precommits to catch-up nodes to the
//                 most recent height.  Otherwise they'd stall at H-1.
func (bs *BlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, seenValidation *types.Validation) {
	height := block.Height
	if height != bs.height+1 {
		PanicSanity(Fmt("BlockStore can only save contiguous blocks. Wanted %v, got %v", bs.height+1, height))
	}
	if !blockParts.IsComplete() {
		PanicSanity(Fmt("BlockStore can only save complete block part sets"))
	}

	// Save block meta
	meta := types.NewBlockMeta(block, blockParts)
	metaBytes := wire.BinaryBytes(meta)
	bs.db.Set(calcBlockMetaKey(height), metaBytes)

	// Save block parts
	for i := 0; i < blockParts.Total(); i++ {
		bs.saveBlockPart(height, i, blockParts.GetPart(i))
	}

	// Save block validation (duplicate and separate from the Block)
	blockValidationBytes := wire.BinaryBytes(block.LastValidation)
	bs.db.Set(calcBlockValidationKey(height-1), blockValidationBytes)

	// Save seen validation (seen +2/3 precommits for block)
	seenValidationBytes := wire.BinaryBytes(seenValidation)
	bs.db.Set(calcSeenValidationKey(height), seenValidationBytes)

	// Save new BlockStoreStateJSON descriptor
	BlockStoreStateJSON{Height: height}.Save(bs.db)

	// Done!
	bs.height = height
}
예제 #2
0
func TestStateToFromVMAccount(t *testing.T) {
	acmAcc1, _ := stypes.RandAccount(true, 456)
	vmAcc := toVMAccount(acmAcc1)
	acmAcc2 := toStateAccount(vmAcc)

	acmAcc1Bytes := wire.BinaryBytes(acmAcc1)
	acmAcc2Bytes := wire.BinaryBytes(acmAcc2)
	if !bytes.Equal(acmAcc1Bytes, acmAcc2Bytes) {
		t.Errorf("Unexpected account wire bytes\n%X vs\n%X",
			acmAcc1Bytes, acmAcc2Bytes)
	}

}
예제 #3
0
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)
		}
	}
}
예제 #4
0
func (bs *BlockStore) saveBlockPart(height int, index int, part *types.Part) {
	if height != bs.height+1 {
		PanicSanity(Fmt("BlockStore can only save contiguous blocks. Wanted %v, got %v", bs.height+1, height))
	}
	partBytes := wire.BinaryBytes(part)
	bs.db.Set(calcBlockPartKey(height, index), partBytes)
}
예제 #5
0
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
}
예제 #6
0
func (voteSet *VoteSet) addVote(val *Validator, valIndex int, vote *Vote) (bool, int, error) {

	// Make sure the step matches. (or that vote is commit && round < voteSet.round)
	if (vote.Height != voteSet.height) ||
		(vote.Round != voteSet.round) ||
		(vote.Type != voteSet.type_) {
		return false, 0, ErrVoteUnexpectedStep
	}

	// Check signature.
	if !val.PubKey.VerifyBytes(acm.SignBytes(config.GetString("chain_id"), vote), vote.Signature) {
		// Bad signature.
		return false, 0, ErrVoteInvalidSignature
	}

	// If vote already exists, return false.
	if existingVote := voteSet.votes[valIndex]; existingVote != nil {
		if bytes.Equal(existingVote.BlockHash, vote.BlockHash) {
			return false, valIndex, nil
		} else {
			return false, valIndex, &ErrVoteConflictingSignature{
				VoteA: existingVote,
				VoteB: vote,
			}
		}
	}

	// Add vote.
	voteSet.votes[valIndex] = vote
	voteSet.votesBitArray.SetIndex(valIndex, true)
	blockKey := string(vote.BlockHash) + string(wire.BinaryBytes(vote.BlockPartsHeader))
	totalBlockHashVotes := voteSet.votesByBlock[blockKey] + val.VotingPower
	voteSet.votesByBlock[blockKey] = totalBlockHashVotes
	voteSet.totalVotes += val.VotingPower

	// If we just nudged it up to two thirds majority, add it.
	if totalBlockHashVotes > voteSet.valSet.TotalVotingPower()*2/3 &&
		(totalBlockHashVotes-val.VotingPower) <= voteSet.valSet.TotalVotingPower()*2/3 {
		voteSet.maj23Hash = vote.BlockHash
		voteSet.maj23PartsHeader = vote.BlockPartsHeader
		voteSet.maj23Exists = true
	}

	return true, valIndex, nil
}
예제 #7
0
func (b *Block) MakePartSet() *PartSet {
	return NewPartSetFromData(wire.BinaryBytes(b))
}
예제 #8
0
func TestSwitches(t *testing.T) {
	s1, s2 := makeSwitchPair(t, func(sw *Switch) *Switch {
		// Make two reactors of two channels each
		sw.AddReactor("foo", NewTestReactor([]*ChannelDescriptor{
			&ChannelDescriptor{Id: byte(0x00), Priority: 10},
			&ChannelDescriptor{Id: byte(0x01), Priority: 10},
		}, true))
		sw.AddReactor("bar", NewTestReactor([]*ChannelDescriptor{
			&ChannelDescriptor{Id: byte(0x02), Priority: 10},
			&ChannelDescriptor{Id: byte(0x03), Priority: 10},
		}, true))
		return sw
	})
	defer s1.Stop()
	defer s2.Stop()

	// Lets send a message from s1 to s2.
	if s1.Peers().Size() != 1 {
		t.Errorf("Expected exactly 1 peer in s1, got %v", s1.Peers().Size())
	}
	if s2.Peers().Size() != 1 {
		t.Errorf("Expected exactly 1 peer in s2, got %v", s2.Peers().Size())
	}

	ch0Msg := "channel zero"
	ch1Msg := "channel foo"
	ch2Msg := "channel bar"

	s1.Broadcast(byte(0x00), ch0Msg)
	s1.Broadcast(byte(0x01), ch1Msg)
	s1.Broadcast(byte(0x02), ch2Msg)

	// Wait for things to settle...
	time.Sleep(5000 * time.Millisecond)

	// Check message on ch0
	ch0Msgs := s2.Reactor("foo").(*TestReactor).msgsReceived[byte(0x00)]
	if len(ch0Msgs) != 1 {
		t.Errorf("Expected to have received 1 message in ch0")
	}
	if !bytes.Equal(ch0Msgs[0].Bytes, wire.BinaryBytes(ch0Msg)) {
		t.Errorf("Unexpected message bytes. Wanted: %X, Got: %X", wire.BinaryBytes(ch0Msg), ch0Msgs[0].Bytes)
	}

	// Check message on ch1
	ch1Msgs := s2.Reactor("foo").(*TestReactor).msgsReceived[byte(0x01)]
	if len(ch1Msgs) != 1 {
		t.Errorf("Expected to have received 1 message in ch1")
	}
	if !bytes.Equal(ch1Msgs[0].Bytes, wire.BinaryBytes(ch1Msg)) {
		t.Errorf("Unexpected message bytes. Wanted: %X, Got: %X", wire.BinaryBytes(ch1Msg), ch1Msgs[0].Bytes)
	}

	// Check message on ch2
	ch2Msgs := s2.Reactor("bar").(*TestReactor).msgsReceived[byte(0x02)]
	if len(ch2Msgs) != 1 {
		t.Errorf("Expected to have received 1 message in ch2")
	}
	if !bytes.Equal(ch2Msgs[0].Bytes, wire.BinaryBytes(ch2Msg)) {
		t.Errorf("Unexpected message bytes. Wanted: %X, Got: %X", wire.BinaryBytes(ch2Msg), ch2Msgs[0].Bytes)
	}

}