屋漏偏逢连夜雨 / 也被DDOS

没错,昨天是下雨了,然而我的屋子其实并没有漏,我也没有把大小脸盆和水桶拿出来接水,也没有一晚上没睡拿个破抹布一边擦地一边怨天尤人。

说啥来啥

不过,我确实一晚上没睡,并非我投身于我极度热爱的编程事业,废寝忘食的码代码,而是,我的一台服务器被D了、D了、D了……。 话说几天前,@rivalhw 还和我聊过DDOS的事情,因为不在现场也不了解具体情况,我只能建议他向阿里云求助,是的,他用的是阿里云。

昨天早上一个客户和我反馈,说服务器有点迟钝。估计恰逢攻击者吃早餐或者睡觉去了,所以我访问的时候并不是很慢,粗略看了一下日志,一堆被屏蔽的访问的log,我就随便清理一下log、更新了一下补丁、再设设软防就去忙了。临近晚上,一看邮件,我的天啊,一堆资源超标的报警,超标到神马程度呢?我给大家看一下其中一封报警邮件:

1
2
3
4
5
Time:                    Fri Jul  7 20:07:10 2017 +0000
1 Min Load Avg: 50.23
5 Min Load Avg: 40.94
15 Min Load Avg: 36.50
Running/Total Processes: 10/816

简单的解释一下,这台服务器是CPU是两个
Intel(R) Xeon(R) CPU E5620 @ 2.40GHz

而每个CPU都是四核的,又支持超线程
所以,系统识别成16个CPU,平时负载都是这样婶的:

昨天我爬上去是这样婶的(来自和客户对话时给客户发送的截图):
20170708190331.png

无论是上边报警邮件中的 50.23还是截图中的76.08,都意味着16个CPU干着他们能力几倍的事情,结果就是累的要死。

搞错方向

然后客户急得要死,说这样不行啊,这样一晚上损失惨重啊。他们的这个站,是吸金利器,每天赚钱无数,停掉一天,少赚无数钱。然后我就被拉上和他们技术人员一起找毛病。其实我第一个反应就是被攻击了,然而晚上迷迷糊糊的,客户又一再强调不可能,然后我们就一直在站点程序上找原因,结果发现这站点程序还真是烂啊,于是我毫不留情的指出这这这、那那那、还有这这这这,这样是不对的,这样无疑会导致极其耗费资源等等。然后统计了一下,其中一个写的很大很乱的PHP每天被调用65万次,65万次是多少,我掰了半天手指头也没数明白65W次是多少,并且他们不止这一个PHP文件,并且他们不止PHP文件。然后客户说这两天更新过程序,每个HTML里都调用两次PHP、PHP里又调用无数次HTML,我醉了。

大家集中精力和PHP奋战,裁掉一个又一个,试了一次又一次,资源占用还是居高不下。最终我想了个办法,直接把站点恢复到5天以前,这样期间的更新不就都没了嘛,何必一个一个恢复。大家兴奋不已,纷纷夸奖这真实一个好主意。于是乎,开启备份恢复,漫长的几分钟过去,终于恢复到了几天前。我们满怀期待的观察负载,发现并没有什么鸟用,哭,又做无用功了。

定位毛病

然后客户对我提出重大疑义,为毛你就怀疑我的站点啊,为毛不怀疑其它站点啊,你自己的垃圾站不也在上边嘛。我的垃圾站,我哭,两年都没人访问一次,能出故障那得多令人庆幸啊。不过既然客户有疑虑,那么我们必须是要帮助其打消的。不然,以后有何脸面和人家说是你的站点问题。打消疑虑的办法很简单,他的站点在独立IP上,我直接把这个IP断线,然后在看CPU负载,一路嗷嗷下降。很快就从70、80降低到0.5以内,客户无言以对。

然后继续回到和站点奋战的过程中,观察系统日志、观察Apache的错误日志、观察用户站点的访问日志,我浑浑噩噩做着自己都不知道自己在做什么的事情,困得睁不开眼。然后和客户说要么关站吧,一了百了,你也省心我也省心不是嘛。客户说关站就得喝西北风啦。于是继续奋战。

终于解决

大脑在一片混沌中突然灵光一闪,是不是被攻击了啊?额,貌似最开始就闪过这些灵光呢。为毛折腾半天才想起来。然后和客户说起,客户也开窍的表示极有可能。可是为何机房没响应呢?那些思科网件的硬防都死了吗?这时候去联系机房?那无疑是找死的行为,我以前遇到过几次麻烦,联系他们,每次都是帮我把事情搞得更糟糕,一堆印度技术客服,轮班的上来折磨你,那之后我再也不敢联系他们了。虽然他们号称服务一流、技术一流,但是感觉没比我这三流的技术强到哪里去。于是从被攻击的角度着手,调节了一下软防的设置,比如追踪一下同一IP源的同时连接数等等,30秒内超过100个链接,无情的BAN掉。经过一系列的调整之后,服务器负载终于下降到了合理的范围。这时候天也快亮了。

漫长的雨夜就这样过去了。
嗯,或许比漏雨强一些吧。
话说那个 @rivalhw 以后不要和我聊DDOS的问题 😡


感谢阅读 / Thank you for reading.
欢迎upvote、resteem以及 following me @oflyhigh 😎


This page is synchronized from the post: 屋漏偏逢连夜雨 / 也被DDOS

非正式翻译:介绍一下 SteemData Notify / Informal translation:Introducing SteemData Notify

@furion 两天前发布了一篇新文章

你一定很好奇,这是神马东东,那么我就结合我的理解,给大家介绍一下。

简单地来说,就是你用了这个产品以后,腰不酸、背不疼了、腿也不抽筋了,一口气上六楼,牙口倍儿好,吃嘛嘛香。啊,晕,广告看多了。严肃点说, SteemData Notify就是个区块链监视服务,一旦你的账户财产变化或者有啥重大的改动,它就会给你的邮件地址或者Telegram发个通知。

应用场景

我们假设这样一个场景,Alice的钱包里有$10,000 SBD SAVINGS。不幸的是,过去她在一款她信任的APP中使用了Active key,结果呢,最近这个APP最近被黑了。

Alice正度假呢,玩的正欢实呢,没有功夫天天看钱包变动啥的。黑客拿到Alice 的 Active key, 就发起了提现操作(钱包SAVINGS变成流动性资产要等3天),黑客合计提现一到帐,就转跑,嘿嘿嘿嘿,$10,000 SBD, 这笔干完就发家了。

幸运的是,Alice 用了 SteemData Notify 服务, 黑客这边一提现,她就收到了消息通知。然后她把提现取消,又改了密码,黑客哭晕在厕所,好容易黑到一个账户,一分钱没捞到,我容易嘛我。

基于尘埃支付认证

听起来挺高大上是不?其实就是确定你在SteemData Notify上的操作是你本人设置的啦。确认方法就是它将你的设置生成个HASH,然后你往null转0.001,并把HASH值作为MEMO即可。

这个MEMO HASH是由设置对象序列化后加密签名所生成,这就保证了是账户所有者本人所做精确可核实的更改。此外,也保证了设置的完整性可以随时查验。在这个过程中,你无需提供私钥给任何第三方程序。

译者补充:
其实就是你的设置生成唯一的HASH
而转账+HASH又只能你自己发起
两者一勾搭,就说明操作是你本人操作的啦

快来试试吧: notify.steemdata.com


请知晓,SteemData Notify 是按照原样提供的免费服务,不保证正常运行时间或正确性。
源代码可以在github上查看

译者注

其实,算是半翻译半介绍吧。

@furion SteemData, SteemQ 的 SteemSports 开发者以及官方Python库的维护者
你不知道SteemData? 看这里: 简单介绍一下SteemData
你没听过 SteemSports? @steemsports 就是声望分全网第一的大户

SteemData Notify这个东西挺有意思,更有意思的是,其实我们可以基于STEEM区块链做出很多好玩并且有意义的东西,这也是我翻译并推荐这篇文章的主要目的。那么,你准备好了吗?撸起袖子加油干吧!


This page is synchronized from the post: 非正式翻译:介绍一下 SteemData Notify / Informal translation:Introducing SteemData Notify

关于收益分享功能理解的终极版(专家指点 & 代码核证)


昨天发了个帖子

讲了对帖子使用收益分享功能发奖后金额的一些疑问,主要有两个方面:

  • 收益分享,分享的是去除点赞者收益后作者实际收益的百分比吗?
  • 收益分享的SP核算价格,是current_median_history_price 还是市场价格?

收益分享功能没问题

然后经过专家级人物耐心细致的指点,大致搞明白了这个问题

其核心就是: 我看到的帖子金额,是收益分享的剩余金额

所以,就我的那个帖子而言:

  • 分给受益者(Beneficiaries):3.504 * 5 = 17.52 占了25% (5%*5)
  • 分给作者(Author): 3.504*15 = 52.56 占75% (100%-25% = 75%)
    分两部分发放, SP 26.28 , SBD 43.177
  • 分给点赞者(Curators): $20.64

一切没毛病,如果一定要找出毛病,那就是steemit UI上少显示了一部分内容,总奖励应该包含:

  • 点赞者 / Curators
  • 受益人 / Beneficiaries
  • 作者 / Curators

而STEEMIT UI上只显示了两项,造成我巨大的误解,也耽误了专家大量时间。😡

从代码上验证这个问题

尽管专家已经帮我找出了问题所在
但是今天还是粗略浏览了一下代码,看看是否真的如此

代码真的好复杂,吐血
发奖代码在process_comment_cashout()这个函数
大致就是做一些准备和判断工作,然后遍历每个Comment调用:
auto reward = cashout_comment_helper( ctx, comment );
所以这个就是为帖子发奖的代码啦: cashout_comment_helper()

其中我们需要知道是,comment.net_rshares 决定你的帖子有多少钱。
除去一些设置和初始化之类的:

1
2
const share_type reward = util::get_rshare_reward( ctx );
uint128_t reward_tokens = uint128_t( reward.value );

这个就是帖子的总收益/代币tokens

1
2
share_type curation_tokens = ( ( reward_tokens * get_curation_rewards_percent( comment ) ) / STEEMIT_100_PERCENT ).to_uint64();
share_type author_tokens = reward_tokens.to_uint64() - curation_tokens;

代币分为作者的以及点赞者的,按比例分配

1
author_tokens += pay_curators( comment, curation_tokens );

发放点赞者代币,但是呢,因为有些有早鸟惩罚,所以会剩一些,统统奖励给作者

1
2
3
4
5
6
7
            for( auto& b : comment.beneficiaries )
{
auto benefactor_tokens = ( author_tokens * b.weight ) / STEEMIT_100_PERCENT;
auto vest_created = create_vesting( get_account( b.account ), benefactor_tokens, has_hardfork( STEEMIT_HARDFORK_0_17__659 ) );
push_virtual_operation( comment_benefactor_reward_operation( b.account, comment.author, to_string( comment.permlink ), vest_created ) );
total_beneficiary += benefactor_tokens;
}

这部分就是给受益人发放奖励啦
由此可见,它是以刨除点赞者收益以后的作者总收益为基础按比例发放。

1
2
3
4
5
6
7
8
author_tokens -= total_beneficiary;

auto sbd_steem = ( author_tokens * comment.percent_steem_dollars ) / ( 2 * STEEMIT_100_PERCENT ) ;
auto vesting_steem = author_tokens - sbd_steem;

const auto& author = get_account( comment.author );
auto vest_created = create_vesting( author, vesting_steem, has_hardfork( STEEMIT_HARDFORK_0_17__659 ) );
auto sbd_payout = create_sbd( author, sbd_steem, has_hardfork( STEEMIT_HARDFORK_0_17__659 ) );

最终给作者的收益(减掉了受益人部分),根据设置,按比例发放

通过这部分代码,我们得知:

  • 帖子的收益,除去其它一些因素,由comment.net_rshares决定
  • get_rshare_reward 根据系统因素以及comment设置(拒绝收益,最大收益等)计算帖子总应得代币
  • 总应得代币按比例分成作者以及点赞者代币
  • 点赞者代币发放的剩余部分(早鸟惩罚),增加给作者
  • 作者总应得代币(作者部分+早年惩罚剩余部分)按比例分给受益者(Beneficiaries)
  • 分给受益人以后的剩余部分,按照设置发放给作者

再回头看我在专家指点下对帖子收益分享功能的理解,没毛病。

另外,经过分析,我们回头看昨天提出的问题,答案已经不言而喻了。

STEEM 以及 STEEM UI 需要改进的地方

STEEM在计算和发放奖励后,会对帖子执行一些更新操作,比如加上发奖时间,以及分给点赞者和作者的实际收益等等。但是却没有加上给受益人的收益这一信息

而STEEMIT UI上,更是只显示了

  • 作者/Author收益
  • 点赞者 / Curators 收益

并且粗暴的把这两项加到一起,显示为帖子收益(总奖励)
这能不让人误会嘛,害我拿小算草本计算半天😡

所以建议如下:

  • 链上对结算后的Comment 加上
    beneficiaries_payout_value

  • UI上对结算的帖子,加上
    受益人 / Beneficiaries 收益

顺便补充一个最重要的结论: 收益分享功能不会倒搭钱的😭


感谢阅读 / Thank you for reading.
欢迎upvote、resteem以及 following me @oflyhigh 😎


This page is synchronized from the post: 关于收益分享功能理解的终极版(专家指点 & 代码核证)

OMG, 收益分享,可怕的功能,搞迷糊了

前几天,我发了一个测试收益分享功能的帖子:

收益分享帖子

其中受益者名单和比例如下:
受益人 / Beneficiaries

1
2
3
4
5
6
7
beneficiaries = [
{'account': 'ace108', 'weight': 500},
{'account': 'deanliu', 'weight': 500},
{'account': 'laodr', 'weight': 500},
{'account': 'lemooljiang', 'weight': 500},
{'account': 'rivalhw', 'weight': 500}
]

帖子发表成功,并且选项设置也很正常

其中 500,表示占所有收益权重的5%
如果是10000,则代表100%

奖励结算

昨天,看到帖子已经结算

author-rewards条目下也可以看到:
yesterday 43.177 SBD, and 26.290 STEEM POWER for oflyhigh/test-comment-reward-beneficiaries

因为给作者的收益要去刨除点赞者的收益(Curator),所以发给我的应该是86.35 SBD
因为我选择的是50%/50%,所以分成了SBD和STEEM POWER两个部分。
43.177 SBD, and 26.290 STEEM POWER
由此可见,系统当时核算的STEEM POWER价格为 :
43.177 / 26.290 = 1.64234 SBD/STEEM Power

好,截至目前,没啥问题。

收益分享

然后,看了一下钱包(Wallet)中历史信息(HISTORY)中的条目
分享的部分是已 VESTS的形式发放的,其实就是STEEM POWER
然后好奇计算一下,到底发放了多少个STEEM POWER给茶东们呢?

VESTS与STEEM POWER的换算关系如下:
STEEM POWER = total_vesting_fund_steem/total_vesting_shares * VESTS

然后用程序取得两个值后换算了一下7247.465650 VESTS 等于多少STEEM POWER
结果是: 3.504 STEEM POWER
嗯,看起来也不是很多嘛

等等,似乎哪里看起来不对呢?
我的收益的50%是STEEM POWER : 26.290 STEEM POWER
那么5%是多少?明明应该是: 2.629 STEEM POWER
多发了: 3.504 - 2.629 = 0.875 个 STEEM POWER

这是咋回事?

就算是未刨除点赞者收益之前, 也不过应该是:
$107.00 / 1.64234 * 5% = 3.2575 STEEM POWER
也到不了 3.5啊?

疑问

对比我发帖子时以及程序设置中的期望值与结果,难免产生以下疑问:

  • 收益分享,分享的是去除点赞者收益后作者实际收益的百分比吗?
  • 收益分享的SP核算价格,是current_median_history_price 还是市场价格?

最大的疑问是,作者(文章发布者)设置收益分享后,有没有可能倒搭钱?如果那样,可就欢乐了。😀

谁能帮我解答一下呢?或者要去研究一下steem的代码?想想就想吐血了。


感谢阅读 / Thank you for reading.
欢迎upvote、resteem以及 following me @oflyhigh 😎


This page is synchronized from the post: OMG, 收益分享,可怕的功能,搞迷糊了

简单介绍一下SteemData

在之前的这篇文章中:

有朋友看后私下和我表示这些数据挺有意思,问我咋弄出来的。我回答说使用steemdata.com 筛选出来的,他对此表示很好奇,希望我能介绍一下steemdata.com所以,今天我在这里给大家简要介绍一下。

SteemData 是什么?

SteemData 简单的来讲,就是Steem区块链的数据库(MongoDB)镜像版本
这个定义可能不甚准确,但是我自己觉得还算恰当。

Steem是去中心化的区块链,我们可以通过STEEMIT.com 或者Esteem、Busy.org、ChainBB工具或者站点与之交互,比如说发表帖子或者给别人的帖子投票等等。而如果我们要查找一些内容,则相对比较麻烦,比如在steemit上逐页翻阅、或者通过google.com 等工具的站点搜索,或者使用工具直接调用Steem API来查找。

以上无论是哪种方式,使用其它都有极大的局限性,尤其是在复杂的情况下。比如使用API我们可以查看@oflyhigh 的账户数据、看看他有多少SP。但是如果我们想看看所有持有SP数量大于1万个的,API就会无能为力了。所以SteemData 应运而生。

SteemData 由 @furion 发起并维护。
详情见发表于六个月之前的帖子

大致原理就是实时随时同步steem区块链的新数据,并存储到MongoDB中。没错,用的是MongoDB, NoSQL数据库类型的代表之一。至于NoSQL数据库有何优点等等话题本文就不做探讨啦。

SteemData 连接信息以及Collections

@furion 的上述帖子中列出了数据库的连接信息,但是有些老旧
欲获得最新的连接信息可以访问SteemData官方网站: https://steemdata.com/
撰写本文时,连接信息如下:

1
2
3
4
5
Host: mongo1.steemdata.com
Port: 27017
Database: SteemData
Username: steemit
Password: steemit

SteemData有如下collections(可以近似理解成MySQL中的表格)

  • Accounts
  • Operations
  • Account Operations
  • Posts
  • Comments

其中 Accounts 包含用户信息、Operations包含所有操作信息、Account Operations包含个账户相关的操作、Posts包含主贴信息、Comments包含回复信息。

如何操作SteemData

首先SteemData给用户开放的是只读的权限,这很正常,如果大家胡乱写,那就没法用了。SteemData的作者推荐大家使用 RoboMongo 一款MongoDB的图形界面工具来了解SteemData.

另外,SteemData 直接封装了一个Python 库: steemdata, 可以通过pip 安装
pip install -U steemdata

欲了解如何使用steemdata Python 库来访问SteemData,可以访问官网的入门向导页面

我使用的是pymongo
如果你还没有安装过它,你需要使用pip安装
pip install pymongo

使用下列命令连接并登陆

看一下都有哪些collections

咦,居然还有几个collections官网页面上没有列出来
现在我们就开始我们的探索之旅啦。

查询声望分最高的10个用户

有了上述基础,你就可以做一些复杂的查询啦,比如说,查一下全网声望分最高的10个用户


是不是很简单的啦?

顺便恭喜一下这些获奖用户:

1
2
3
4
5
6
7
8
9
10
{'name': 'steemsports', 'rep': 77.83}
{'name': 'knozaki2015', 'rep': 77.2}
{'name': 'juliettal', 'rep': 76.64}
{'name': 'gavvet', 'rep': 76.62}
{'name': 'krnel', 'rep': 76.39}
{'name': 'ozchartart', 'rep': 76.02}
{'name': 'papa-pepper', 'rep': 75.27}
{'name': 'curie', 'rep': 75.17}
{'name': 'ericvancewalton', 'rep': 75.17}
{'name': 'doitvoluntarily', 'rep': 74.91}

参考连接

Thanks @furion for providing steemdata service!

好了,今天就先介绍这些啦。
如果大家感兴趣,以后在介绍更多内容。


感谢阅读 / Thank you for reading.
欢迎upvote、resteem以及 following me @oflyhigh 😎


This page is synchronized from the post: 简单介绍一下SteemData

你或许不知道的STEEMIT(STEEM)一些隐藏功能


之前写过一些帖子介绍steemit(STEEM)的一些基本功能。

比如发帖、查看收益、使用内部市场交易等等
也聊过一些复杂的操作,比如收益分享,多人维护一个账户等等
今天来随便介绍几个你或者不知道的steemit(STEEM)隐藏功能

自己创建账户 / Create Steemit Account yourself

注册账户在steemit上一直是很困难的事情,去年7月份我们刚完的时候,都要使用Facebook注册steemit,Facebook大家可能都没听过,嗯,肯定没听过,资本主义腐朽的产物,妈妈为了避免我们被其毒害,帮我们隐藏了它。但是为了注册STEEMIT,我们也拼了,搭上梯子跑出墙外,到底和Facebook勾搭上,然后注册了STEEMIT,够凄惨吧。后来据说改手机号码注册了,我曾经尝试注册一个ID,费劲周折浪费两个手机号,别问我为啥浪费两个,我也不知道,总之第一个输错验证码之后再用,就告诉我这个号码已经被用过啦。哦,说到浪费两个手机号,然后完成注册流程,然后就木有下文啦!其实无论是之前用Facebook注册,还是后来用手机注册,注册难的根本原因,就在于STEEMIT公司注册账户要花钱! 虽说后来把送STEEM改成了代理,但是还是要花钱不是。

据说硬叉20之后要改进,注册账户要方便了,但是谁知道到时候兑不兑现呢?不兑现也不能去总部打老总啊。对了,话说总部在哪?老总是谁?好了,不说打老总的事情啦,其实你还有一种其它选择,没错,自己出注册费注册。

你问我咋注册?

  • busy.org出的一个网页工具
  • client_wallet的命令行
  • python库里的函数
  • 其它工具

本文侧重介绍,具体操作就不写啦。

SP 代理 / SP delegation

无论是让自己注册的账户更有投票权,还是想把一堆马甲号的权重集中到一个大户,你都要用到SP代理。SP代理,相当于把你的STEEM POWER借给别人,和STEEM POWER有关的投票权以及点赞回报权都统统借给他人。别人有了这部分SP之后,和自己拥有这部分SP是同样的效果,唯一的区别就是不能POWER DOWN(提现)。

硬叉18之后,SP代理功能就被印记了,并且STEEMIT变得狡猾聪明了,注册新用户只送了极少的STEEM POWER,其余部分都采取代理方式啦。

SP代理如何用?

  • client_wallet的命令行
  • python库里的函数
  • Vessel ( @jesta 出品)
  • 其它工具

以下分别为 python库、 Vessel相关链接

收益分享 / Comment Reward Beneficiaries

关于收益分享,我前些天写过一篇帖子:
随便聊聊收益分享,欢迎讨论 / Comment Reward Beneficiaries
大家可以阅读那个帖子了解一些详情。

简单的讲,就是你可以把你帖子收益的一部分分享给其它人,这样帖子结算的时候,这部分收益系统自动发放到对应账户上。

使用像chainbb, busy.org, esteem这类工具发帖, 他们都自动给你的帖子设置了收益分享选项。已chainbb为例,将收益的15%设置给了自己。

Steemwhales.com 提供了一个网页表单,可以使用这个表单发帖并设置收益分享给你指定的人。

client_wallet以及python库都支持发表设置收益分享选项的帖子。
可惜官方Python库此处有BUG,并且尚未修复,导致这个功能实际上并不可用。

参考链接:

Power Down 路线 / Power Down Route

Power Down 路线, 简单地说,就是你可以将你的STEEM POWER直接Power Down到其它账户。
同时可以选择是到其它账户是否直接存成STEEM Power

如果你有多个账户,想将多个账户的Steem Power 归结到一个账户(主账户)
原本的做法是

  • 在每个账户Power Down
  • 每周检查每个账户,将其中STEEM 转账到主账户
  • 每周进入主账户,Power Up

采取Power Down 路由的方法则是

  • 为每个账户设置 Power Down route
  • 在每个账户Power Down

工作量,无疑大大减轻。

结论 / Conclusions


自己创建账户、设置SP代理、发表具有收益分享功能的帖子、设置Power Down Route来归结STEEM POWER,这些功能都是STEEMIT或者说STEEM区块链的隐藏功能。使用者需要借助一定特殊的工具来打成这些操作,至少目前STEEMIT没有直接操作这些功能的接口。

然后,为社么我总觉得这四个功能放在一起,总给人一种不干好事的感觉呢?注册N多账户、代理/委派 SP过去、设置收益分享到主账户后开始发帖、有额外点赞收益啥的可以通过Power Down Router 归结到主账户……

我是不是发现了什么了不得的秘密?会不会被灭口?好忐忑啊。


感谢阅读 / Thank you for reading.
欢迎upvote、resteem以及 following me @oflyhigh 😎


This page is synchronized from the post: 你或许不知道的STEEMIT(STEEM)一些隐藏功能

Your browser is out-of-date!

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

×