每天进步一点点:再谈HIVE/STEEM的Batching Operations

在大约三年前,我写过一篇文章将多个操作(operation)放入一个事务中(transaction),介绍了使用steem-python实现一个事务(transaction)中放置两个或者多个操作(operation)的方法。


(图源 :pixabay)

这在很多场景下都很有用,比如说给多人转账、用RC申领账户、多个账户点赞同一内容等等。(当时我文章中用的示例是发文的同时点赞,因为EIP的缘故,这个在HF21/HF22以后不适合了)

今天我来测试两种场景,一是一个用户给两个用户转账(多个用户一样),另外一个是两个用户给不同用户转账。

同一用户转账给不同用户

一个用户给两个用户转账这个好办一些,我们直接把oprations弄好并放到transaction中,因为发起者是同一个用户,那么我们用这个用户的私钥签名一次即可。

其中转账(transfer)模板如下:

1
2
3
4
5
6
op = ['transfer',{
'from': '',
'to': '',
'amount': '',
'memo': ''
}]

设置并追加第一个转账操作:

op[1]["from"] = "oflyhigh.demo"
op[1]["to"] = "oflyhigh.test"
op[1]["amount"] = "0.001 HBD"
op[1]["memo"] = "Hello 111"
trx.append_op(op)

完成后,transaction中内容如下:

image.png

设置并追加第二个转账操作:

op[1]["from"] = "oflyhigh.demo"
op[1]["to"] = "oflyhigh.abc"
op[1]["amount"] = "0.002 HBD"
op[1]["memo"] = "Hello 222"
trx.append_op(op)

完成后,transaction中内容如下:

image.png

生成摘要并使用oflyhigh.demo的active key对transaction进行签名:

trx.derive_digest(chain_id)
trx.sign_digest(wif_1)

结果如下:

image.png

使用trx.broadcast()广播交易,结果如下:

image.png

两个用户给不同用户转账

接下来我们设置两个不同用户对外转账,看看和同一用户有什么区别。

关于operation和transaction的设置暂且略过(参考上边内容就好),设置好的transaction如下:

image.png

因为是两个不同用户发起的操作,所以我们需要两个对应的active key对transaction分别签名

trx.derive_digest(chain_id)
trx.sign_digest(wif_1)
trx.sign_digest(wif_2)

使用trx.broadcast()广播交易,结果如下:

image.png

其它

除了上述操作外,我又测试了一些其它情况,比如相同用户两笔转账的情况我签名两次,那么就会出现如下错误:

'message': 'duplicate signature included:Duplicate Signature detected'

另外测试了,不同用户转账的时候调换签名顺序,发现不管用哪个私钥先签,都无所谓,也就是说和顺序无关。

总结

  • 我们可以将多个操作放到一个事务中提升效率
  • 操作发起方为同一账号时,只需用对应私钥签名一次
  • 操作发起方包含不同账户时,需要用不同的账户各签名一次

相关链接


This page is synchronized from the post: ‘每天进步一点点:再谈HIVE/STEEM的Batching Operations’

光缆一断,损失百万?

二十几年前,经常听到/看到一句口号/标语:光缆一断,损失百万,一般来讲牌子都立在地下光缆的上方,用于提示施工人员注意。


(图源 :pixabay)

二十几年来,遇到过大大小小几次光缆中断事故,一般都是都是各种市政施工,挖掘机不小心碰断光缆,尽管带来诸多不变,但是等一半天就会修复好。

最严重的莫过于零几年的时候,中美海底光缆中断事故了,那次事故导致国内几乎无法访问美国的网络,只能绕道日韩新加坡等。

当时很多用户找我,因为访问不了美国的网络,他们担心自己的业务受到影响,最终证实是海底光缆中断,也没啥办法了。

另外好比我住一个城市,然后在另外一个大城市开了一个工厂,我的城市通往大城市的道路损毁无法通车,但其实我的工厂还是正常经营的,影响会有,但是不会很大。

尽管当时算是大事件,也为此导致我被用户们折磨很久,但是时间过于久远,我甚至忘记了到底是哪年发生的,以及何时修复的。

原本以为,都2020年了,不会再发生类似中美海底光缆中断的事故了,多说会有一些局部小事故发生而已。可是大概前几天起,家里的联通网络突然访问国外站点比蜗牛还慢。

这是肿么了,我打联通客服,客服人员说给我刷新端口,让我过段时间重启光猫重试,结果投诉了N次试了N次故障依旧。

后来联通安排了技术人员上门解决,技术人员说可能是前两天联通升级导致的问题,可能和IPV6什么的相关,给我换了一台据说是最新的设备,然而故障依旧。

我怀疑是联通国际出口出了问题,但是我以为是升级导致的软件问题或者是防火墙配置不当等等,我把我的怀疑和联通技术人员说明,让他继续帮我关注着。

昨天联通技术人员打来电话,告诉我他们收到上级部门通知,造成这个问题的原因是联通通往美国的海底光缆出故障了,正在全力抢修中。

其实在他打电话给我之前,我就已经从其它渠道获取了这个信息,只是没想到会发生这样的事情,到底是因为什么导致的中断呢?技术原因?自然灾害?人为破坏,这些就不得而知了。


(图源 :pixabay)

只是有些感慨,光缆一断,损失百万,这个口号还适合吗?包括联通本身以及各类用户的损失,上亿都未必能够吧?再多的数字就是我想象力无法处理的啦。


This page is synchronized from the post: ‘光缆一断,损失百万?’

每天进步一点点:在内存中replay HIVE/STEEM节点

好久以前在试过在内存中replay HIVE/STEEM节点,但是后来每次replay的时候都是主备切换着来,所以并不急,也就一直没用内存模式。


(图源 :pixabay)

最近被朋友问及在内存中操作,发现已经忘记的差不多了,于是在电脑上试着弄一遍。

准备/dev/shm

在这之前,我们先来了解一下/dev/shm,如果你听过ramdisk,那么对这个东西一定不会陌生,简单来讲就是在内存中开辟的磁盘,可以像磁盘一样使用,又能享受内存的超快读写速度。

在内存中Replay节点,首先要保证/dev/shm分配的空间大于Replay完成后的shared_memory.bin文件的大小,否则有可能出问题。

我的系统上,系统自动为我分配了63G的/dev/shm空间,倒是足够了:

tmpfs 63G 0 63G 0% /dev/shm

如果觉得不够用,可以用以下命令调整:

sudo mount -o remount,size=68G /dev/shm

修改shared-file-dir & Replay

在节点配置文件中
将:shared-file-dir = "blockchain"
修改为:shared-file-dir = /dev/shm

然后使用如下指令Replay区块链:

steemd --replay-blockchain

恢复设置

如果服务器/电脑内存不吃紧,那么Replay 完成后,可以让shared_memory.bin一直放在/dev/shm下运行,否则我们需要把它弄回磁盘上去(ssd)。

大致步骤如下:

  • 使用Ctrl+C关闭程序
  • 复制/dev/shm/shared_memory.binblockchain目录(根据你自己的设置)
  • 修改shared-file-dir = "blockchain"

然后,重新启动程序就行。

/dev/shm的恢复

可以使用之前的命令将/dev/shm容量恢复成之前的大小。

当然还有一种方法就是重启系统,将其恢复至默认状态。(重启之前不要忘记先关闭节点,否则数据会损坏)。

效率提升多少

我使用当前最新的block_log文件(北京时间4月21日上午10时),包含区块数为:42720937, 全部Replay完,耗时情况如下:

Done reindexing, elapsed time: 19888.23536099999910221 sec

有图有真相:

image.png

折算下来约为5小时30分,而我在硬盘(ssd)上弄,大概需要8-10小时左右(还是之前区块更少一些的时候)。

所以在内存中Replay,对效率还是会有提升的。

其它

Replay完成的时间与程序编译时的参数开启的插件CPU主频硬盘读写速度block_log的新旧(亦即大小)等都高度相关,本文中使用的时间仅供参考。


This page is synchronized from the post: ‘每天进步一点点:在内存中replay HIVE/STEEM节点’

讲不出再见

之前写过一篇文章选择或许比坚持更重要,而我自己,就不小心选择了一个和胶片相机、传呼机一样走向没落的产业,并且坚持了十六年整。


(图源 :pixabay)

其实早在几年前甚至更早一些时候,我的这个业务就已经不赚钱了,有段时间甚至一直赔钱。不过终结这个业务也是一件很难的事情,因为有余量客户在用,并且对此极为依赖。

早在三两年前,就在客户中做过一个调查,如果我们停掉服务,是否有备选的方案,很多客户表示用惯了我们的服务,不想再换也不知道换哪家。

就这样,拖来拖去、拖来拖去,一直拖到了今天,不但浪费着我的金钱,还浪费我大量的精力,最近断然决定一段时间后终止服务。

原以为这样做,可能会让客户们很麻烦,这是我所不想看到的情况,如果给用户添麻烦,我会十分愧疚,我觉得客户们可能会因此恼火。

不过与我设想的恰恰相反,很多客户竟然主动上来和我聊天,问我是不是遇到了什么麻烦事情,有什么他们能帮我解决的。

当我表示没什么麻烦,就是又累又不赚钱,坚持好多年,继续坚持有点难,客户们纷纷表示理解。很多客户非常诚挚地对我说:“感谢这么多年以来的关照。”

这让我感到十分的温暖,这些年尽心尽责,每个客户都真诚对待,每个问题都耐心回答,每次故障都及时解决,让这些用户由客户变成了朋友。

一个客户和我说:“天下没有不散的宴席,在服务商/客户这块我们的宴席散了,但是我们是朋友,有机会到彼此的城市,一定要聚会要喝酒要摆宴席。”

最搞笑的一个客户朋友上来和我说:“你不会是受新冠疫情影响了吧?要不要我给你寄些口罩什么的防护用品?”这都哪跟哪啊?


(图源 :pixabay)

原本提到关服务,真的很伤感,讲不出再见。不过和这些可爱的用户沟通过后,心情非常轻松,是啊,十几年的交往,我们都是朋友了,关服务不会影响我们之前的友情。而且没有了金钱/服务等关系,这友情之花会更加娇艳。


This page is synchronized from the post: ‘讲不出再见’

Python之再遇 (传值/引用) 错误

昨晚写了一小段测试代码,打算实现在一个事务(transaction)中放置多个操作(oprations),思路很简单,就是定义一个transfer opration的模板,然后设置,追加到transaction中,再设置一个新值,然后再次追加到transaction中。


(图源 :pixabay)

模板如下:

1
2
3
4
5
6
op = ['transfer',{
'from': '',
'to': '',
'amount': '',
'memo': ''
}]

设置过程大致如下:

op[1]["from"] = "oflyhigh.demo"
op[1]["to"] = "oflyhigh.test"
op[1]["amount"] = "0.005 HBD"
op[1]["memo"] = "Hello 1"
tx["operations"].append(op)

然后对op值进行重新设置,再次追加op到tx:

op[1]["from"] = "oflyhigh.demo"
op[1]["to"] = "oflyhigh.test"
op[1]["amount"] = "0.010 HBD"
op[1]["memo"] = "Hello 2"
tx["operations"].append(op)

然后对tx进行签名并广播,结果却发现写到链上变成了这个样子:

image.png

什么?怎么是两条一模一样的转账内容呢?不过稍一思索马上就想通了,据说Python当中一个变量保存的内容除了基本类型保存的是值外,其它都是引用

因为是按引用传递,那么我第一次追加后,第二次再修改op,修改的都是同一个op,所以最后的结果就是两个op都是相同的,都被替换成了第二个。

解决起来其实很简单,用copy.deepcopy处理一下就好啦,再测试就成功啦(op内容我改动了一点):

image.png

颇为感慨的是,其实这个问题我遇到过不止一次,比如在这个帖子中就写遇到的这个错误,然而每次遇到类似情况还是总犯错。

哎,年纪大了,记性不好啦。

相关链接


This page is synchronized from the post: ‘Python之再遇 (传值/引用) 错误’

挖个大深坑(换下水管道)

最近有几次感觉厨房的下水有些不畅通,找物业从外边下水井那边清理了一下,才好一些。不过物业说主要的问题还是下水管道的问题,想彻底解决就得更换管道。


(图源 :pixabay)

所谓的下水管道,就是从我厨房下水出口到外边下水井之间的这段管道,要换起来可是相当麻烦了。不过物业这两天联系我,说要给我更换下水管。

因为下水管是深埋在地下的,所以首先要处理的问题就是挖坑,物业的施工人员先是挖后边院墙到下水井之间这个段的大坑,可惜我有两根刺嫩芽在路径上,被无情地破坏了。

除了刺嫩芽,后院墙外边有竹竿打的栅栏,管道上边对应的这段,也被无情地拆除了。物业拆之前征求了我的意见,我告诉只要有需要,他们随便弄。

挖完院墙外的这段,他们开始挖后花园内院墙到楼墙之间这段,而这段距离上边,有我花园的小夜灯,还有我一棵樱桃树,还有花园的石头小路以及绿化的水盆。

这些无可避免的都被统统拆除了,施工人员有些不好意思,我和他们说这有啥,你们帮我解决问题,我这边肯定全力做好配合啊。

拆完这些之后,继续挖坑,目测至少挖到1.5米深才看到下水管,不过让工人们郁闷的是,有一段管道上边,有一大块混凝土块,长宽均约为1米左右,厚度大概也有50厘米。

工人们找来电镐开始突突突搞破碎,搞了半天发现小电镐不给力,又换了大电稿继续搞,这次给力多了,可惜搞着搞着又下起了雨只好雨休了。


(图源 :pixabay)

原来换下水管道这么费劲,不过看他们挖的大深坑,我不禁思索,我要不要和他们说不要填上这个坑,然后继续往周边挖,弄个大大的地下室呢?哈哈。


This page is synchronized from the post: ‘挖个大深坑(换下水管道)’

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×