@@ -492,6 +492,84 @@ class AlethInterpreterSstoreTestFixture : public SstoreTestFixture
492492 AlethInterpreterSstoreTestFixture () : SstoreTestFixture{new EVMC{evmc_create_interpreter ()}} {}
493493};
494494
495+ class SelfBalanceFixture : public TestOutputHelperFixture
496+ {
497+ public:
498+ explicit SelfBalanceFixture (VMFace* _vm) : vm{_vm} { state.addBalance (address, 1 * ether); }
499+
500+ void testSelfBalanceWorksInIstanbul ()
501+ {
502+ ExtVM extVm (state, envInfo, *se, address, address, address, value, gasPrice, {}, ref (code),
503+ sha3 (code), version, depth, isCreate, staticCall);
504+
505+ owning_bytes_ref ret = vm->exec (gas, extVm, OnOpFunc{});
506+
507+ BOOST_REQUIRE_EQUAL (fromBigEndian<u256>(ret), 1 * ether);
508+ }
509+
510+ void testSelfBalanceHasCorrectCost ()
511+ {
512+ ExtVM extVm (state, envInfo, *se, address, address, address, value, gasPrice, {}, ref (code),
513+ sha3 (code), version, depth, isCreate, staticCall);
514+
515+ bigint gasBefore;
516+ bigint gasAfter;
517+ auto onOp = [&gasBefore, &gasAfter](uint64_t /* steps*/ , uint64_t /* PC */ ,
518+ Instruction _instr, bigint /* newMemSize*/ , bigint /* gasCost*/ , bigint _gas,
519+ VMFace const *, ExtVMFace const *) {
520+ if (_instr == Instruction::SELFBALANCE)
521+ gasBefore = _gas;
522+ else if (gasBefore != 0 && gasAfter == 0 )
523+ gasAfter = _gas;
524+ };
525+
526+ vm->exec (gas, extVm, onOp);
527+
528+ BOOST_REQUIRE_EQUAL (gasBefore - gasAfter, 5 );
529+ }
530+
531+ void testSelfBalanceisInvalidBeforeIstanbul ()
532+ {
533+ se.reset (ChainParams (genesisInfo (Network::ConstantinopleFixTest)).createSealEngine ());
534+ version = ConstantinopleFixSchedule.accountVersion ;
535+
536+ ExtVM extVm (state, envInfo, *se, address, address, address, value, gasPrice, {}, ref (code),
537+ sha3 (code), version, depth, isCreate, staticCall);
538+
539+ BOOST_REQUIRE_THROW (vm->exec (gas, extVm, OnOpFunc{}), BadInstruction);
540+ }
541+
542+
543+ BlockHeader blockHeader{initBlockHeader ()};
544+ LastBlockHashes lastBlockHashes;
545+ Address address{KeyPair::create ().address ()};
546+ State state{0 };
547+ std::unique_ptr<SealEngineFace> se{
548+ ChainParams (genesisInfo (Network::IstanbulTest)).createSealEngine ()};
549+ EnvInfo envInfo{blockHeader, lastBlockHashes, 0 };
550+
551+ u256 value = 0 ;
552+ u256 gasPrice = 1 ;
553+ u256 version = IstanbulSchedule.accountVersion;
554+ int depth = 0 ;
555+ bool isCreate = false ;
556+ bool staticCall = false ;
557+ u256 gas = 1000000 ;
558+
559+ // let b : = selfbalance()
560+ // mstore(0, b)
561+ // return(0, 32)
562+ bytes code = fromHex(" 478060005260206000f350" );
563+
564+ std::unique_ptr<VMFace> vm;
565+ };
566+
567+ class LegacyVMSelfBalanceFixture : public SelfBalanceFixture
568+ {
569+ public:
570+ LegacyVMSelfBalanceFixture () : SelfBalanceFixture{new LegacyVM} {}
571+ };
572+
495573} // namespace
496574
497575BOOST_FIXTURE_TEST_SUITE (LegacyVMSuite, TestOutputHelperFixture)
@@ -670,6 +748,24 @@ BOOST_AUTO_TEST_CASE(LegacyVMSstoreEip1283Case17)
670748 testEip1283Case17 ();
671749}
672750
751+ BOOST_AUTO_TEST_SUITE_END ()
752+
753+ BOOST_FIXTURE_TEST_SUITE(LegacyVMSelfBalanceSuite, LegacyVMSelfBalanceFixture)
754+
755+ BOOST_AUTO_TEST_CASE(LegacyVMSelfBalanceworksInIstanbul)
756+ {
757+ testSelfBalanceWorksInIstanbul ();
758+ }
759+
760+ BOOST_AUTO_TEST_CASE (LegacyVMSelfBalanceHasCorrectCost)
761+ {
762+ testSelfBalanceHasCorrectCost ();
763+ }
764+
765+ BOOST_AUTO_TEST_CASE (LegacyVMSelfBalanceisInvalidBeforeIstanbul)
766+ {
767+ testSelfBalanceisInvalidBeforeIstanbul ();
768+ }
673769BOOST_AUTO_TEST_SUITE_END ()
674770BOOST_AUTO_TEST_SUITE_END()
675771
0 commit comments