【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 的相关文章

  • 思腾合力赞助CCF YOCSEF太原第十一届学术委员会第三次全体会议

    2024年1月6日 由思腾合力赞助的 CCF YOCSEF太原第十一届学术委员会第三次全体会议暨AC换届选举活动 在山西大学举办 华北区教育行业负责人宋肖敏出席本次会议 会议汇聚了众多学术界和企业界的精英 共同探讨人工智能和计算机科学的未来
  • 在win10和Linux上配置SSH 无密码登录

    文章目录 一 用途 二 在本地机器上使用ssh keygen产生公钥私钥对 1 在Linux 或macOS 上产生SSH公私钥的方法 2 在win10上产生SSH公私钥的方法 a 检查windows 本地是否安装有ssh b 在本地生成SS
  • 性能分析与调优: Linux 内存观测工具

    目录 一 实验 1 环境 2 vmstat 3 PSI 4 swapon 5 sar 6 slabtop 7 numstat 8 ps 9 top 10 pmap 11 perf 12 bpftrace 二 问题 1 接口读写报错 2 sl
  • AIDL通信过程中设置死亡代理

    概述 在进行进程间通信的过程中 如何服务端进程由于某种原因异常终止 我们的远程调用就会失败 影响我们的功能 那么怎么样能够知道服务端进程是否终止了呢 那就是给Binder设置死亡代理 下面看看如何设置 Override public voi
  • Linux ls命令

    目录 一 配置项 1 1 ls l 1 2 ls a 1 3 ls lrt 1 4 ls ld 二 案例 2 1 查看指定文件夹下文件的数量
  • 服务器OS是什么意思?

    一 什么是服务器操作系统 服务器不仅仅是由高性能硬件组成 并且是要求客户端操作系统 如Windows和Mac OS 服务器还需要一个称为服务器操作系统的操作系统 二 与客户端OS的区别 无论是Windows还是Mac OS 家庭或办公室使用
  • 盘点那些年我们一起玩过的网络安全工具

    大家好 我是IT共享者 这篇文章给大家盘点那些年 我们一起玩过的网络安全工具 一 反恶意代码软件 1 Malwarebytes 这是一个检测和删除恶意的软件 包括蠕虫 后门 流氓 拨号器 间谍软件等等 快如闪电的扫描速度 具有隔离功能 并让
  • nohup - 后台执行

    nohup no hang up 语法 nohup Command Arg 使用示例 nohup python a py 日志将被保留在 当前文件夹下的 nohup out 将日志放到文件 不输出到终端 echo hello gt 1 tx
  • 服务器集群是如何提高计算性能的?

    服务器集群是一种将多台服务器连接起来协同工作的技术 通过集群配置 可以提高计算性能 可靠性和可扩展性 以下是服务器集群如何提高计算性能的详细解释 一 并行处理能力 服务器集群的核心优势在于其并行处理能力 通过将多个服务器组成一个集群 可以将
  • 如何解决Mybatis-plus与Mybatis不兼容的问题:An attempt was made to call a method that does not exist. The attempt

    博主猫头虎的技术世界 欢迎来到 猫头虎的博客 探索技术的无限可能 专栏链接 精选专栏 面试题大全 面试准备的宝典 IDEA开发秘籍 提升你的IDEA技能 100天精通Golang Go语言学习之旅 领域矩阵 猫头虎技术领域矩阵 深入探索各技
  • Django Fabric 同步数据库

    您将如何运行此 django 命令来自动与 Fabric 同步数据库 python manage py syncdb settings app settings test 如果尝试运行 它会卡在 是否要创建超级用户帐户 处 是否可以传递 是
  • Jenkins 插件下载速度慢、安装失败了!我教你怎么解决!

    Jenkins部署完毕 如果不安装插件的话 那它就是一个光杆司令 啥事也做不了 所以首先要登陆管理员账号然后点击系统管理再点击右边的插件管理安装CI CD必要插件 但是问题来了 jenkins下载插件速度非常慢 而且经常提示下载插件失败 真
  • 步骤详图 教你在linux搭建容器环境

    警告 切勿在没有配置 Docker YUM 源的情况下直接使用 yum 命令安装 Docker 1 准备工作 系统要求 要安装Docker CE 社区版 操作系统的最低要求是CentOS7 7以下版本都不被支持 卸载旧版本 Docker改版
  • 什么是充放电振子理论?

    CHAT回复 充放电振子模型 Charging Reversal Oscillator Model 是一种解释ENSO现象的理论模型 这个模型把ENSO现象比喻成一个 热力学振荡系统 在这个模型中 ENSO现象由三个组成部分 充电 Char
  • ssh:connect to host github.com port 22: Connection timed out

    解决流程 1 将github的端口由22改为443 ssh T p 443 git ssh github com 2 接着输入yes进行确认 The authenticity of host ssh github com 443 192 1
  • Python - 如何验证与 Fabric 模块的 SSH 连接?

    我正在尝试使用 Fabric 模块通过以太网通过 SSH 连接到子网上的 Raspberry Pi 但我不知道如何验证连接 到目前为止我的代码如下 import fabric c fabric Connection host 192 168
  • 导入错误:没有名为“fabric.contrib”的模块

    Fabric 2 0 1 运行调用 fabfile py 的项目时出错 我使用的是 Python 3 5 1 有谁知道为什么会发生这种情况 Traceback most recent call last File bootstrap pex
  • 如何发现 Python Fabric 中的当前角色

    这是一个非常Fabric http docs fabfile org具体问题 但更有经验的 python 黑客可能能够回答这个问题 即使他们不了解 Fabric 我试图根据命令运行的角色来指定不同的行为 即 def restart if S
  • Fabric sudo 无密码解决方案

    这个问题是关于最佳实践的 我正在使用 Fabric 运行部署脚本 我的部署用户 deploy 需要 sudo 来重新启动服务 因此 我使用 Fabric 中的 sudo 函数在脚本中运行这些命令 这工作正常 但在脚本执行期间提示输入密码 我
  • 在 Fabric 中如何从远程路径创建全局列表

    与Python的Fabric http docs fabfile org en 2 4 index html我想将文件传输到远程服务器或从远程服务器传输文件 我需要从 glob 表达式生成要传输的文件列表 例如 or txt 然后应用一些额

随机推荐

  • 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