Skip to content

Commit 88e8724

Browse files
author
Temirlan "Qjawko" Yermagambet
committed
add Plato hardfork support
1 parent 2a23b2a commit 88e8724

File tree

11 files changed

+213
-20
lines changed

11 files changed

+213
-20
lines changed

cmd/sentry/sentry/sentry_grpc_server.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,28 @@ func handShake(
322322
}
323323
}
324324

325+
if version >= eth.ETH67 {
326+
extensionRaw, err := (&eth.UpgradeStatusExtension{}).Encode()
327+
if err != nil {
328+
return err
329+
}
330+
go func() {
331+
errc <- p2p.Send(rw, eth.UpgradeStatusMsg, &eth.UpgradeStatusPacket{Extension: extensionRaw})
332+
}()
333+
//todo: receive UpgradeStatus from bsc and set txBroadcast
334+
// go func() {
335+
// errc <- p.readUpgradeStatus(&upgradeStatus)
336+
// }()
337+
select {
338+
case err := <-errc:
339+
if err != nil {
340+
return err
341+
}
342+
case <-timeout.C:
343+
return p2p.DiscReadTimeout
344+
}
345+
}
346+
325347
return nil
326348
}
327349

consensus/parlia/parlia.go

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -656,13 +656,8 @@ func (p *Parlia) verifySeal(chain consensus.ChainHeaderReader, header *types.Hea
656656
return fmt.Errorf("parlia.verifySeal: headerNum=%d, validator=%x, %w", header.Number.Uint64(), signer.Bytes(), errUnauthorizedValidator)
657657
}
658658

659-
for seen, recent := range snap.Recents {
660-
if recent == signer {
661-
// Signer is among recents, only fail if the current block doesn't shift it out
662-
if limit := uint64(len(snap.Validators)/2 + 1); seen > number-limit {
663-
return errRecentlySigned
664-
}
665-
}
659+
if snap.SignRecently(signer) {
660+
return errRecentlySigned
666661
}
667662

668663
// Ensure that the difficulty corresponds to the turn-ness of the signer
@@ -989,12 +984,17 @@ func (p *Parlia) finalize(header *types.Header, state *state.IntraBlockState, tx
989984
if header.Difficulty.Cmp(diffInTurn) != 0 {
990985
spoiledVal := snap.supposeValidator()
991986
signedRecently := false
992-
for _, recent := range snap.Recents {
993-
if recent == spoiledVal {
994-
signedRecently = true
995-
break
987+
if p.chainConfig.IsPlato(number) {
988+
signedRecently = snap.SignRecently(spoiledVal)
989+
} else {
990+
for _, recent := range snap.Recents {
991+
if recent == spoiledVal {
992+
signedRecently = true
993+
break
994+
}
996995
}
997996
}
997+
998998
if !signedRecently {
999999
//log.Trace("slash validator", "block hash", header.Hash(), "address", spoiledVal)
10001000
var tx types.Transaction
@@ -1161,14 +1161,9 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res
11611161
}
11621162

11631163
// If we're amongst the recent signers, wait for the next block
1164-
for seen, recent := range snap.Recents {
1165-
if recent == val {
1166-
// Signer is among recent, only wait if the current block doesn't shift it out
1167-
if limit := uint64(len(snap.Validators)/2 + 1); number < limit || seen > number-limit {
1168-
log.Info("[parlia] Signed recently, must wait for others")
1169-
return nil
1170-
}
1171-
}
1164+
if snap.SignRecently(val) {
1165+
log.Info("Signed recently, must wait for others")
1166+
return nil
11721167
}
11731168

11741169
// Sweet, the protocol permits us to sign the block, wait for our time

consensus/parlia/snapshot.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,17 @@ func (s *Snapshot) updateAttestation(header *types.Header, chainConfig *chain.Co
209209
}
210210
}
211211

212+
func (s *Snapshot) SignRecently(validator common.Address) bool {
213+
for seen, recent := range s.Recents {
214+
if recent == validator {
215+
if limit := uint64(len(s.Validators)/2 + 1); s.Number+1 < limit || seen > s.Number+1-limit {
216+
return true
217+
}
218+
}
219+
}
220+
return false
221+
}
222+
212223
func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderReader, parents []*types.Header, chainConfig *chain.Config, verifiedAttestations map[libcommon.Hash]struct{}, doLog bool) (*Snapshot, error) {
213224
// Allow passing in no headers for cleaner code
214225
if len(headers) == 0 {

core/systemcontracts/upgrade.go

Lines changed: 52 additions & 1 deletion
Large diffs are not rendered by default.

core/vm/contracts.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,27 @@ var PrecompiledContractsLuban = map[libcommon.Address]PrecompiledContract{
192192
libcommon.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{},
193193
}
194194

195+
// PrecompiledContractsPlato contains the default set of pre-compiled Ethereum
196+
// contracts used in the Plato release.
197+
var PrecompiledContractsPlato = map[libcommon.Address]PrecompiledContract{
198+
libcommon.BytesToAddress([]byte{1}): &ecrecover{},
199+
libcommon.BytesToAddress([]byte{2}): &sha256hash{},
200+
libcommon.BytesToAddress([]byte{3}): &ripemd160hash{},
201+
libcommon.BytesToAddress([]byte{4}): &dataCopy{},
202+
libcommon.BytesToAddress([]byte{5}): &bigModExp{},
203+
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
204+
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
205+
libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
206+
libcommon.BytesToAddress([]byte{9}): &blake2F{},
207+
208+
libcommon.BytesToAddress([]byte{100}): &tmHeaderValidate{},
209+
libcommon.BytesToAddress([]byte{101}): &iavlMerkleProofValidatePlato{},
210+
libcommon.BytesToAddress([]byte{102}): &blsSignatureVerify{},
211+
libcommon.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{},
212+
}
213+
195214
var (
215+
PrecompiledAddressesPlato []libcommon.Address
196216
PrecompiledAddressesLuban []libcommon.Address
197217
PrecompiledAddressesPlanck []libcommon.Address
198218
PrecompiledAddressesMoran []libcommon.Address
@@ -233,11 +253,17 @@ func init() {
233253
for k := range PrecompiledContractsLuban {
234254
PrecompiledAddressesLuban = append(PrecompiledAddressesLuban, k)
235255
}
256+
257+
for k := range PrecompiledContractsPlato {
258+
PrecompiledAddressesPlato = append(PrecompiledAddressesPlato, k)
259+
}
236260
}
237261

238262
// ActivePrecompiles returns the precompiles enabled with the current configuration.
239263
func ActivePrecompiles(rules *chain.Rules) []libcommon.Address {
240264
switch {
265+
case rules.IsPlato:
266+
return PrecompiledAddressesPlato
241267
case rules.IsLuban:
242268
return PrecompiledAddressesLuban
243269
case rules.IsPlanck:

core/vm/contracts_lightclient.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,27 @@ func (c *iavlMerkleProofValidatePlanck) Run(input []byte) (result []byte, err er
183183
return c.basicIavlMerkleProofValidate.Run(input)
184184
}
185185

186+
type iavlMerkleProofValidatePlato struct {
187+
basicIavlMerkleProofValidate
188+
}
189+
190+
func (c *iavlMerkleProofValidatePlato) RequiredGas(_ []byte) uint64 {
191+
return params.IAVLMerkleProofValidateGas
192+
}
193+
194+
func (c *iavlMerkleProofValidatePlato) Run(input []byte) (result []byte, err error) {
195+
c.basicIavlMerkleProofValidate.proofRuntime = v1.Ics23ProofRuntime()
196+
c.basicIavlMerkleProofValidate.verifiers = []merkle.ProofOpVerifier{
197+
forbiddenAbsenceOpVerifier,
198+
singleValueOpVerifier,
199+
multiStoreOpVerifier,
200+
forbiddenSimpleValueOpVerifier,
201+
}
202+
c.basicIavlMerkleProofValidate.keyVerifier = keyVerifier
203+
c.basicIavlMerkleProofValidate.opsVerifier = proofOpsVerifier
204+
return c.basicIavlMerkleProofValidate.Run(input)
205+
}
206+
186207
func successfulMerkleResult() []byte {
187208
result := make([]byte, merkleProofValidateResultLength)
188209
binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-uint64TypeLength:], 0x01)

core/vm/contracts_lightclient_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,43 @@ func TestIcs23Proof(t *testing.T) {
154154
require.Equal(t, expectedResult, success)
155155
}
156156

157+
func TestIcs23ProofPlato(t *testing.T) {
158+
appHash, err := hex.DecodeString("ae6d1123fc362b3297bfb19c9f9fabbcbd1e2555b923dead261905b8a2ff6db6")
159+
require.NoError(t, err)
160+
key, err := hex.DecodeString("77696e64")
161+
require.NoError(t, err)
162+
value, err := hex.DecodeString("626c6f7773")
163+
require.NoError(t, err)
164+
proofBytes, err := hex.DecodeString("0a300a0a69637332333a6961766c120477696e641a1c0a1a0a0477696e641205626c6f77731a0b0801180120012a030002040a9d010a0c69637332333a73696d706c6512036962631a87010a84010a036962631220141acb8632cfb808f293f2649cb9aabaca74fc18640900ffd0d48e2994b2a1521a090801180120012a0100222708011201011a205f0ba08283de309300409486e978a3ea59d82bccc838b07c7d39bd87c16a5034222708011201011a20455b81ef5591150bd24d3e57a769f65518b16de93487f0fab02271b3d69e2852")
165+
require.NoError(t, err)
166+
167+
merkleProofInput := make([]byte, 32+32+len(key)+32+len(value)+32+len(proofBytes))
168+
copy(merkleProofInput[:32], "ibc")
169+
binary.BigEndian.PutUint64(merkleProofInput[32+24:32+32], uint64(len(key)))
170+
copy(merkleProofInput[32+32:32+32+len(key)], key)
171+
172+
binary.BigEndian.PutUint64(merkleProofInput[32+32+len(key)+24:32+32+len(key)+32], uint64(len(value)))
173+
copy(merkleProofInput[32+32+len(key)+32:32+32+len(key)+32+len(value)], value)
174+
175+
copy(merkleProofInput[32+32+len(key)+32+len(value):32+32+len(key)+32+len(value)+32], appHash)
176+
copy(merkleProofInput[32+32+len(key)+32+len(value)+32:], proofBytes)
177+
178+
totalLengthPrefix := make([]byte, 32)
179+
binary.BigEndian.PutUint64(totalLengthPrefix[0:8], 0)
180+
binary.BigEndian.PutUint64(totalLengthPrefix[8:16], 0)
181+
binary.BigEndian.PutUint64(totalLengthPrefix[16:24], 0)
182+
binary.BigEndian.PutUint64(totalLengthPrefix[24:], uint64(len(merkleProofInput)))
183+
184+
input := append(totalLengthPrefix, merkleProofInput...)
185+
186+
validator := iavlMerkleProofValidatePlato{}
187+
success, err := validator.Run(input)
188+
require.NoError(t, err)
189+
expectedResult := make([]byte, 32)
190+
binary.BigEndian.PutUint64(expectedResult[24:], 0x01)
191+
require.Equal(t, expectedResult, success)
192+
}
193+
157194
func TestMerkleProofValidateMoran(t *testing.T) {
158195
// Bytest1 is the inputs of exploit tx 0x05356fd06ce56a9ec5b4eaf9c075abd740cae4c21eab1676440ab5cd2fe5c57a
159196
bytest1, _ := hex.DecodeString("00000000000000000000000000000000000000000000000000000000000005086962630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000100380200000000010dd9ac0000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000000000f870a0424e4200000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000008ad3c21bcecceda100000094489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec94489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec846553f10072cda827a83531ca0fd7ac917a6b65649719aab0836722caafe0603147a523180a8d020a066961766c3a76120e00000100380200000000010dd9ac1af201f0010aed010a2b0802100318b091c73422200c10f902d266c238a4ca9e26fa9bc36483cd3ebee4e263012f5e7f40c22ee4d20a4d0801100218b091c7342220e4fd47bffd1c06e67edad92b2bf9ca63631978676288a2aa99f95c459436ef632a20121a1f9c4eca726c725796c5375fc4158986ced08e498dc8268ef94d8ed1891612001a370a0e0000010038020000000000000002122011056c6919f02d966991c10721684a8d1542e44003f9ffb47032c18995d4ac7f18b091c7341a340a0e00000100380200000000010dd9ac12202c3a561458f8527b002b5ec3cab2d308662798d6245d4588a4e6a80ebdfe30ac18010ad4050a0a6d756c746973746f726512036962631ac005be050abb050a110a066f7261636c6512070a0508b891c7340a0f0a046d61696e12070a0508b891c7340a350a08736c617368696e6712290a2708b891c7341220c8ccf341e6e695e7e1cb0ce4bf347eea0cc16947d8b4e934ec400b57c59d6f860a380a0b61746f6d69635f7377617012290a2708b891c734122042d4ecc9468f71a70288a95d46564bfcaf2c9f811051dcc5593dbef152976b010a110a0662726964676512070a0508b891c7340a300a0364657812290a2708b891c73412201773be443c27f61075cecdc050ce22eb4990c54679089e90afdc4e0e88182a230a2f0a02736312290a2708b891c7341220df7a0484b7244f76861b1642cfb7a61d923794bd2e076c8dbd05fc4ee29f3a670a330a06746f6b656e7312290a2708b891c734122064958c2f76fec1fa5d1828296e51264c259fa264f499724795a740f48fc4731b0a320a057374616b6512290a2708b891c734122015d2c302143bdf029d58fe381cc3b54cedf77ecb8834dfc5dc3e1555d68f19ab0a330a06706172616d7312290a2708b891c734122050abddcb7c115123a5a4247613ab39e6ba935a3d4f4b9123c4fedfa0895c040a0a300a0361636312290a2708b891c734122079fb5aecc4a9b87e56231103affa5e515a1bdf3d0366490a73e087980b7f1f260a0e0a0376616c12070a0508b891c7340a300a0369626312290a2708b891c7341220e09159530585455058cf1785f411ea44230f39334e6e0f6a3c54dbf069df2b620a300a03676f7612290a2708b891c7341220db85ddd37470983b14186e975a175dfb0bf301b43de685ced0aef18d28b4e0420a320a05706169727312290a2708b891c7341220a78b556bc9e73d86b4c63ceaf146db71b12ac80e4c10dd0ce6eb09c99b0c7cfe0a360a0974696d655f6c6f636b12290a2708b891c73412204775dbe01d41cab018c21ba5c2af94720e4d7119baf693670e70a40ba2a52143")

core/vm/evm.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ var emptyCodeHash = crypto.Keccak256Hash(nil)
3737
func (evm *EVM) precompile(addr libcommon.Address) (PrecompiledContract, bool) {
3838
var precompiles map[libcommon.Address]PrecompiledContract
3939
switch {
40+
case evm.chainRules.IsPlato:
41+
precompiles = PrecompiledContractsPlato
4042
case evm.chainRules.IsLuban:
4143
precompiles = PrecompiledContractsLuban
4244
case evm.chainRules.IsPlanck:

core/vm/lightclient/v1/multistoreproof.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,10 @@ func Ics23CompatibleProofRuntime() (prt *merkle.ProofRuntime) {
147147
prt.RegisterOpDecoder(ProofOpSimpleMerkleCommitment, CommitmentOpDecoder)
148148
return
149149
}
150+
151+
func Ics23ProofRuntime() (prt *merkle.ProofRuntime) {
152+
prt = merkle.NewProofRuntime()
153+
prt.RegisterOpDecoder(ProofOpIAVLCommitment, CommitmentOpDecoder)
154+
prt.RegisterOpDecoder(ProofOpSimpleMerkleCommitment, CommitmentOpDecoder)
155+
return
156+
}

eth/protocols/eth/protocol.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ const (
7272
NewPooledTransactionHashesMsg = 0x08
7373
GetPooledTransactionsMsg = 0x09
7474
PooledTransactionsMsg = 0x0a
75+
76+
//bsc eth67
77+
UpgradeStatusMsg = 0x0b
7578
)
7679

7780
var ToProto = map[uint]map[uint64]proto_sentry.MessageId{
@@ -190,6 +193,23 @@ type NewBlockHashesPacket []struct {
190193
Number uint64 // Number of one particular block being announced
191194
}
192195

196+
// bsc eth67
197+
type UpgradeStatusPacket struct {
198+
Extension *rlp.RawValue `rlp:"nil"`
199+
}
200+
type UpgradeStatusExtension struct {
201+
DisablePeerTxBroadcast bool
202+
}
203+
204+
func (e *UpgradeStatusExtension) Encode() (*rlp.RawValue, error) {
205+
rawBytes, err := rlp.EncodeToBytes(e)
206+
if err != nil {
207+
return nil, err
208+
}
209+
raw := rlp.RawValue(rawBytes)
210+
return &raw, nil
211+
}
212+
193213
// TransactionsPacket is the network packet for broadcasting new transactions.
194214
type TransactionsPacket []types.Transaction
195215

0 commit comments

Comments
 (0)