<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def step( self, peer_table=None, zonefile_queue=None, path=None ):
 """ Run one step of this algorithm. Push the zonefile to all the peers that need it. Return the number of peers we sent to """

        if path is None:
            path = self.atlasdb_path

        if BLOCKSTACK_TEST:
            log.debug("%s: %s step" % (self.hostport, self.__class__.__name__))

        if self.push_timeout is None:
            self.push_timeout = atlas_push_zonefiles_timeout()

        zfinfo = atlas_zonefile_push_dequeue( zonefile_queue=zonefile_queue )
        if zfinfo is None:
            return 0

        zfhash = zfinfo['zonefile_hash']
        zfdata_txt = zfinfo['zonefile']
        name = zfinfo['name']
        txid = zfinfo['txid']

        zfbits = atlasdb_get_zonefile_bits( zfhash, path=path )
        if len(zfbits) == 0:
            # not recognized 
            return 0

        # it's a valid zonefile.  store it.
        rc = add_atlas_zonefile_data( str(zfdata_txt), self.zonefile_dir )
        if not rc:
            log.error("Failed to replicate zonefile %s to external storage" % zfhash)

        peers = None
        
        # see if we can send this somewhere
        with AtlasPeerTableLocked(peer_table) as ptbl:
            peers = atlas_zonefile_find_push_peers( zfhash, peer_table=ptbl, zonefile_bits=zfbits )

        if len(peers) == 0:
            # everyone has it
            log.debug("%s: All peers have zonefile %s" % (self.hostport, zfhash))
            return 0

        # push it off
        ret = 0
        for peer in peers:
            log.debug("%s: Push to %s" % (self.hostport, peer))
            atlas_zonefile_push( self.hostport, peer, zfdata_txt, timeout=self.push_timeout )
            ret += 1

        return ret