【Hyperledger Fabric 源码解读】solo

2023-11-19

release 2.2
orderer/consensus/solo/consensus.go

/*
Copyright IBM Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

package solo

import (
	"fmt"
	"time"

	cb "github.com/hyperledger/fabric-protos-go/common"
	"github.com/hyperledger/fabric/common/flogging"
	"github.com/hyperledger/fabric/orderer/consensus"
	"github.com/pkg/errors"
)

var logger = flogging.MustGetLogger("orderer.consensus.solo")

type consenter struct{}

type chain struct {
	support  consensus.ConsenterSupport
	sendChan chan *message
	exitChan chan struct{}
}

type message struct {
	configSeq uint64
	normalMsg *cb.Envelope
	configMsg *cb.Envelope
}

// New creates a new consenter for the solo consensus scheme.
// The solo consensus scheme is very simple, and allows only one consenter for a given chain (this process).
// It accepts messages being delivered via Order/Configure, orders them, and then uses the blockcutter to form the messages
// into blocks before writing to the given ledger
func New() consensus.Consenter {
	return &consenter{}
}

func (solo *consenter) HandleChain(support consensus.ConsenterSupport, metadata *cb.Metadata) (consensus.Chain, error) {
	logger.Warningf("Use of the Solo orderer is deprecated and remains only for use in test environments but may be removed in the future.")
	return newChain(support), nil
}

func (c *consenter) JoinChain(support consensus.ConsenterSupport, joinBlock *cb.Block) (consensus.Chain, error) {
	return nil, errors.New("the Solo orderer does not support JoinChain")
}

func newChain(support consensus.ConsenterSupport) *chain {
	return &chain{
		support:  support,
		sendChan: make(chan *message),
		exitChan: make(chan struct{}),
	}
}

func (ch *chain) Start() {
	go ch.main()
}

func (ch *chain) Halt() {
	select {
	case <-ch.exitChan:
		// Allow multiple halts without panic
	default:
		close(ch.exitChan)
	}
}

func (ch *chain) WaitReady() error {
	return nil
}

// Order accepts normal messages for ordering
func (ch *chain) Order(env *cb.Envelope, configSeq uint64) error {
	select {
	case ch.sendChan <- &message{
		configSeq: configSeq,
		normalMsg: env,
	}:
		return nil
	case <-ch.exitChan:
		return fmt.Errorf("Exiting")
	}
}

// Configure accepts configuration update messages for ordering
func (ch *chain) Configure(config *cb.Envelope, configSeq uint64) error {
	select {
	case ch.sendChan <- &message{
		configSeq: configSeq,
		configMsg: config,
	}:
		return nil
	case <-ch.exitChan:
		return fmt.Errorf("Exiting")
	}
}

// Errored only closes on exit
func (ch *chain) Errored() <-chan struct{} {
	return ch.exitChan
}

func (ch *chain) main() {
	var timer <-chan time.Time
	var err error

	for {
		seq := ch.support.Sequence()
		err = nil
		select {
		case msg := <-ch.sendChan:
			if msg.configMsg == nil {
				// NormalMsg
				if msg.configSeq < seq {
					_, err = ch.support.ProcessNormalMsg(msg.normalMsg)
					if err != nil {
						logger.Warningf("Discarding bad normal message: %s", err)
						continue
					}
				}
				batches, pending := ch.support.BlockCutter().Ordered(msg.normalMsg)

				for _, batch := range batches {
					block := ch.support.CreateNextBlock(batch)
					ch.support.WriteBlock(block, nil)
				}

				switch {
				case timer != nil && !pending:
					// Timer is already running but there are no messages pending, stop the timer
					timer = nil
				case timer == nil && pending:
					// Timer is not already running and there are messages pending, so start it
					timer = time.After(ch.support.SharedConfig().BatchTimeout())
					logger.Debugf("Just began %s batch timer", ch.support.SharedConfig().BatchTimeout().String())
				default:
					// Do nothing when:
					// 1. Timer is already running and there are messages pending
					// 2. Timer is not set and there are no messages pending
				}

			} else {
				// ConfigMsg
				if msg.configSeq < seq {
					msg.configMsg, _, err = ch.support.ProcessConfigMsg(msg.configMsg)
					if err != nil {
						logger.Warningf("Discarding bad config message: %s", err)
						continue
					}
				}
				batch := ch.support.BlockCutter().Cut()
				if batch != nil {
					block := ch.support.CreateNextBlock(batch)
					ch.support.WriteBlock(block, nil)
				}

				block := ch.support.CreateNextBlock([]*cb.Envelope{msg.configMsg})
				ch.support.WriteConfigBlock(block, nil)
				timer = nil
			}
		case <-timer:
			//clear the timer
			timer = nil

			batch := ch.support.BlockCutter().Cut()
			if len(batch) == 0 {
				logger.Warningf("Batch timer expired with no pending requests, this might indicate a bug")
				continue
			}
			logger.Debugf("Batch timer expired, creating block")
			block := ch.support.CreateNextBlock(batch)
			ch.support.WriteBlock(block, nil)
		case <-ch.exitChan:
			logger.Debugf("Exiting")
			return
		}
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Hyperledger Fabric 源码解读】solo 的相关文章

  • 如何解决stata数据管理器中变量变红的问题

    目标 解决open变量变红的问题 网上说可以通过以下代码解决 实际上是缘木求鱼 encode encode 红色数字的变量名 gen 新产生的变量名 自己尝试用这个代码之后 发现对应变量不是红色了 但变成了蓝色 我开始以为问题已经解决了 但
  • Spring Security,没有看起来那么复杂(附源码)

    权限管理是每个项目必备的功能 只是各自要求的复杂程度不同 简单的项目可能一个 Filter 或 Interceptor 就解决了 复杂一点的就可能会引入安全框架 如 Shiro Spring Security 等 其中 Spring Sec

随机推荐

  • margin:0 auto是什么意思

    margin是外边距的意 当一个元素样式属性里有dumargin 0 auto时 并且父元素的宽度是确定的 意思是这个元素处于其父元素的居中位置 并且这个元素的上下外边距为0 即 上下外边距为0 左右自动 实际效果为左右居中 补充 marg
  • 缺少msvcp120.dll、msvcr120.dll解决办法

    缺少msvcp120 dll msvcr120 dll解决办法 丢失或缺少msvcp120 dll msvcr120 dll等这些报错是因为我们没有安装vc 运行库 看一下报错对应的数字对应的版本 msvcp msvcr60 71和80 d
  • Python--内建函数大全

    Python 解释器内置了许多函数和类型 列表如下 按字母排序 省略了几个我没用过或者不常用的 内建函数表 abs delattr hash memoryview set
  • 结构体排序------蓝桥杯

    题目 给出 nn 个人的语文 数学 英语的成绩 你需要把他们的成绩降序输出 排序的规则 先按总分排序 如果总分相等 就按语文成绩降序排序 如果语文成绩还相等 就按数学成绩降序排序 如果数学成绩还相等 就按姓名字典序升序排序 输入 第一行是一
  • Python中MongoDB的使用方法

    一 MongoDB是什么 在百度上查询的时候主要看到三个关键字 数据库 非关系型 查询功能强大 总结为查询功能强大的非关系型数据库 什么是数据库 应该是用来存储数据的 非关系型的意思 不不不 关系型的意思我都不懂 查询功能强大的意思应该是查
  • python matplotlib pyplot绘制散点图

    pyplot散点图示例 import matplotlib pyplot as plt import numpy as np import math import random plt rcParams font sans serif Si
  • 【Blender】快捷键整理

    Z 弹出着色模式菜单 shift Z 线框展示 Ctrl 空格 最大化视窗切换 N 隐藏侧栏 T 显示隐藏左侧工具菜单 小键盘 在视口内最大化显示当前选择物体 FN home 在视口内最大化显示场景内所有物体 SHIFT C 查看全部 sh
  • N沟道和P沟道MOS管的四个不同点

    作者 快捷芯 功率半导体创新品牌 1 芯片材质不同 虽然芯片都是硅基 但是掺杂的材质是不同 使得N沟道MOS管是通过电子形成电流沟道 P沟道MOS管是用空穴流作为载流子 具体原理可以参考一些教科书 属于工艺方面的问题 2 同等参数P沟道MO
  • Upload-labs 1-21关 靶场通关攻略(全网最全最完整)

    Pass 01 前端验证 因为是进行前端JS校验 因此可以直接在浏览器检查代码把checkFile 函数 即如下图红色框选中的函数 删了或者也可以把红色框改成true 并按回车 即可成功上传php文件 复制图片地址并用蚁剑进行连接 Pass
  • Hiv练习题之网站连续登陆天数分析

    数据源 有如下登录信息 userId day 1 2019 05 01 1 2019 05 02 1 2019 05 03 1 2019 05 04 1 2019 05 05 1 2019 05 06 1 2019 05 07 1 2019
  • Leetcode28. 找出字符串中第一个匹配项的下标

    代码 class Solution public int strStr String haystack String needle if haystack equals needle return 0 int len needle leng
  • IDEA中创建单元测试过程 JUnit

    1 在src同级别下创意一个test目录 2 右键这个test文件夹 设置为测试专用文件夹 然后在在下面创建一个java目录 根据你的需求 多级建目录 3 选择一个类 比如xxxServiceImpl xxDaoImpl 然后邮件 选择go
  • synchronized关键字修饰static方法和非static方法学习测试结论

    最近在学习研究synchronized关键字 发现有个疑问 在同一个类中 有多个sync方法 当线程调用其中的一个方法的时候 其他的线程能调用其他的sync方法么 为此做了简单的测试 详细的测试过程略过 读者可使用测试代码自行操作 得出结论
  • OKHttp详解

    OkHttp 是一套处理 HTTP 网络请求的依赖库 由 Square 公司设计研发并开源 目前可以在 Java 和 Kotlin 中使用 对于 Android App 来说 OkHttp 现在几乎已经占据了所有的网络请求操作 RetroF
  • Web项目实战

    文章目录 运行环境 1 前言 2 挑选模板 2 1 前端模板 2 2 后端模板 2 3 总结 3 实现注册与登陆 3 1 项目结构 3 2 注册 3 2 1 JDBC连接池连接 3 2 2 dao层实现JDBC的判重 插入 3 2 3 设计
  • Linux字符设备驱动的register_chrdev()与unregister_chrdev()

    Linux下的设备驱动程序被组织为一组完成不同任务的函数的集合 通过这些函数使得Windows的设备操作犹如文件一般 在应用程序看来 硬件设备只是一个设备文件 应用程序可以象操作普通文件一样对硬件设备进行操作 如open close rea
  • 【RDMA】RDMA编程入门--编辑中

    目录 一 前言 二 基本概念 1 队列和队列成员 2 传输模式 简介 单边双边传输流程简述 3 编程接口 verbs API 三 编程示例 工作大致流程说明 四 编程代码实例 5 RDMA编程概述 5 1 传输操作 5 2传输模式 5 3相
  • easyexcel分批次导出excel文件

    使用easyexcel进行分批次导出1000万条数据的步骤如下 首先 需要在pom xml文件中添加easyexcel的依赖 例如
  • ChatGPT也不会的k8s安装方法——极简安装法

    要学习k8s 首先要有一个k8s 那么如何才能获得一个k8s呢 这不由得让我想到了最近比较火的ChatGPT 以下简称小恰 俗话说 遇事不决问小恰 解决效率翻上翻 让我们先来看看小恰怎么回答的吧 问小恰 由于众所周知的原因 国内使用小恰比较
  • 【Hyperledger Fabric 源码解读】solo

    release 2 2 orderer consensus solo consensus go Copyright IBM Corp All Rights Reserved SPDX License Identifier Apache 2